Documentation ¶
Overview ¶
Package proxy defines necessary components for proxy.
Config Format 配置格式 ¶
一共有三种配置格式,极简模式,标准模式,兼容模式。
“极简模式”(即 verysimple mode),入口和出口仅有一个,而且都是使用共享链接的url格式来配置.
标准模式使用toml格式。
兼容模式可以兼容v2ray现有json格式。(暂未实现)。
极简模式的理念是,配置文件的字符尽量少,尽量短小精悍;
还有个命令行模式,就是直接把极简模式的url 放到命令行参数中,比如:
verysimple -L socks5://sfdfsaf -D direct://
Layer Discussion ¶
目前认为,一个传输过程大概由四个部分组成,基础连接(udp/tcp),TLS(可选),中间层(ws、grpc、http等,可选),具体协议(socks5,vless,trojan等).
其中,ws和grpc被认为是 高级应用层,http(伪装)属于 header 层.
TLS - Transport Layer Security 顾名思义TLS作用于传输层,第四层,但是我们tcp也是第四层,所以在本项目中,认为不需要“会话层”,且单独加一个专用于tls的层比较稳妥.
New Model - VSI 新的VSI 模型 ¶
那么我们提出一个 verysimple Interconnection Model, 简称vsi模型。1到4层与OSI相同(物理、链路、网络、传输).
把第五层替换成“加密层”,把TLS放进去;把第六层改为 http头(1.1) 层
第七层 改为高级应用层,ws/grpc/http2 属于这一层, 简称高级层;第八层定为 代理层,vless/trojan 在这层.
第九层为 承载数据层,承载的为 另一大串 第四层的数据.
不过有时比如 trojan-go 的 smux 和 v2ray 的 mux.cool ,实际上属于 高级层,那么它们就是 代理层里面又包了一层高级层.
一般来说,如果内层高级层是普通的协议的话,实际上是透明的, 不必单列出一个层级.
这里的关键地方是【内层多路复用】. 因为在内层多路复用时,一个连接会被抽象出多个子连接,在流量的走向方面开始分叉,所以确实有实质性不同。
内层多路复用的性质是,多路复用分离出一个个子协议后,子协议又是代理层。
所以第九层除了承载数据外, 还可以为 inner mux 层, 第十层可以为 inner proxy 层, 此时第11层才是承载数据.
我们verysimple 的架构 实际上是 基于 “层” 的架构,或称 可分层结构. 如下:
11| -------------- (client real tcp/udp data) -------------------------------------------------------------------------------- 10| (simplesocks) | (inner proxy layer) -------------------------------------------------------------------------------- 9 | [client real tcp/udp data] or [inner mux Layer] -------------------------------------------------------------------------------- 8 | vless/trojan/socks5 | proxy layer -------------------------------------------------------------------------------- 7 | ws/grpc/quic | advanced layer -------------------------------------------------------------------------------- 6 | http header | http layer -------------------------------------------------------------------------------- 5 | tls | tls layer -------------------------------------------------------------------------------- 4 | tcp/udp/unix domain socket/kcp | transport layer --------------------------------------------------------------------------------
另外,实际上quic属于一种超级协议,横跨传输层一直到高级层,不过为了分类方便,这里认为它也是一种 高级层。 也就是说,如果遇到横跨多个层的协议,我们认为它属于其中最高的层级。
基本上5-8层都是可控的.第四层也可以给出一些参数进行控制,比如在tproxy时。
对应的理想配置文件应该如下.
{ "layer3_settings": { //or network_settings, //可以配置一些网络层分流(ip) }, "layer4_settings": { //or transportLayer_settings, "tcp":{} //可以设置一些缓存大小等配置. 和传输层协议分流(tcp/udp) }, "layer5_settings": { //or tls_settings, "tls":{"insecure": true}, "utls":{} // 可以配置tls 层分流/回落(sni 和 alpn) }, "layer6_settings": { //or http_settings //可以配置http path分流 /回落 or header分流/回落 }, "layer7_settings": { //or advancedLayer_settings "ws":{}, "grpc":{}, "quic":{} }, "layer8_settings": { //or proxy_settings "vless":{}, "trojan":{} }, "layer9_settings": { //or innerMux_settings "smux":{} }, "layer10_settings": { //or innerProxy_settings "simplesocks":{} }, }
我们项目的文件夹,netLayer 第3,4层,tlsLayer文件夹代表第5层; httpLayer第六层, advLayer文件夹 代表第七层, proxy文件夹代表第8层或第10层, 同时连带 处理了 第九层.
同级的ws和grpc是独占的,可以都放到一个layer里,然后比如第八层配置了一个vless一个trojan,那么排列组合就是4种,vless+ws, vless+ grpc, trojan+ws, trojan+grpc.
这就大大减轻了各种”一键脚本“的 使用需求,咱们只要选择自己喜欢的各个层,程序自动就为我们生成所有配置.
运行时,如果所有配置都要有,那么就需要多种端口;共用端口的话可以用nginx.
也可以程序指定一种 特定的情况,比如开始运行程序时,冒出交互界面,自己按项选择好后,就自动运行,然后自动生成客户端分享url.
可以在脑海里想象 “穿鞋带” 的画面,有很多洞可以经过,都穿好了 鞋带就系好了。或手机手势解锁的情况.
这种好处是,每次运行都可以采用不同的配置,不同的uuid,手机一扫码就能连上.
然而,这种“高级模式”是不容易实现、也不好理解的,目前初始阶段先不考虑。
目前的标准模式的配置文件中,整个一个节点的配置完全是扁平化的,所有的层的配置都会在同一级别中。比如tls的配置完全和节点本身的配置放在一起。
总之 verysimple 的思路就是,要不就完全扁平化,要不就完全分层。
本作认为,所有的代理是都可以有tls层、http层和ws/grpc这种advLayer 的,所以就统一嵌入所有的代理协议的配置当中,直接扁平化了.
Contents of proxy package - proxy包内容 ¶
接口 BaseInterface 和 结构 Base 给 这个架构定义了标准.
而 Client 和 Server 接口 是 具体利用该架构的 客户端 和 服务端,都位于VSI中的第八层.
使用 RegisterClient 和 RegisterServer 来注册新的实现(Creator).
一般Client和Server都要内嵌Base结构,这样可以快速实现BaseInterface接口,然后自行实现Name方法以及
Client接口中的方法 和 Server接口中的方法 ¶
Server and Client ¶
我们服务端和 客户端的程序,都是有至少一个入口和一个出口的。入口我们叫做 inServer ,出口我们叫做 outClient.
这两个词的含义和 v2ray的 inbound 和 outbound 是等价的.
在 inServer 中,我们负责监听未知连接;在 outClient 中,我们负责拨号特定目标服务器.
proxy中默认实现了 direct 和 reject 这两种 Client。默认实现了 reject Server
reject作为Client和Server 的作用基本是一致的,就是读取一下用户的请求,查看是否为 http请求,然后根据情况 返回 对应的 http1.1 的 4xx 响应,然后关闭连接。
Comparison ¶
层级清晰、详细的好处就是 转发路径十分清晰,转发路径在读取完配置后就是确定的,性能可以得到提高。
与本作架构对立的架构是 支持转发链 或者说 “链式转发” 的架构,如gost。
实际上 v2ray的架构 更接近 gost 这种架构, 而本作的架构比较独特。
目前本作架构基本上无法实现链式转发,如果要支持,要进行一些重构。应该是可以做到的。
Index ¶
- Constants
- Variables
- func AllClientTypeList() []string
- func AllServerTypeList() []string
- func GetFullName(pc BaseInterface) string
- func GetVSI_url(pc BaseInterface, targetNetwork string) string
- func PrintAllClientNames()
- func PrintAllServerNames()
- func RegisterClient(name string, c ClientCreator)
- func RegisterServer(name string, c ServerCreator)
- func TestTCP(protocol string, specialUUID string, version int, port string, ...)
- func TestUDP(protocol string, version int, proxyPort string, use_multi int, t *testing.T)
- func ToStandardUrl(cc *CommonConf, dc *DialConf, lc *ListenConf) string
- func URLToCommonConf(u *url.URL, conf *CommonConf) error
- func URLToDialConf(u *url.URL, conf *DialConf) error
- func URLToListenConf(u *url.URL, conf *ListenConf) error
- type Base
- func (b *Base) AddrStr() string
- func (b *Base) AdvancedLayer() string
- func (b *Base) CanFallback() bool
- func (b *Base) CantRoute() bool
- func (b *Base) CloseInnerMuxSession()
- func (b *Base) ConfigCommon(cc *CommonConf)
- func (d *Base) DialTCP(target netLayer.Addr) (result net.Conn, err error)
- func (d *Base) DialUDP(target netLayer.Addr) (mc *netLayer.UDPMsgConn, err error)
- func (b *Base) GetAdvClient() advLayer.Client
- func (b *Base) GetAdvServer() advLayer.Server
- func (b *Base) GetBase() *Base
- func (b *Base) GetClientInnerMuxSession(wrc io.ReadWriteCloser) *smux.Session
- func (b *Base) GetFallback() *netLayer.Addr
- func (*Base) GetServerInnerMuxSession(wlc io.ReadWriteCloser) *smux.Session
- func (b *Base) GetSockopt() *netLayer.Sockopt
- func (b *Base) GetTLS_Client() *tlsLayer.Client
- func (b *Base) GetTLS_Server() *tlsLayer.Server
- func (b *Base) GetTag() string
- func (b *Base) GetXver() int
- func (b *Base) HasHeader() *httpLayer.HeaderPreset
- func (b *Base) HasInnerMux() (int, string)
- func (b *Base) InitAdvLayer()
- func (b *Base) InnerMuxEstablished() bool
- func (b *Base) IsLazyTls() bool
- func (b *Base) IsUDP_MultiChannel() bool
- func (b *Base) IsUseTLS() bool
- func (b *Base) LocalTCPAddr() *net.TCPAddr
- func (b *Base) LocalUDPAddr() *net.UDPAddr
- func (b *Base) MiddleName() string
- func (b *Base) Network() string
- func (d *Base) SelfListen() (is bool, tcp, udp int)
- func (b *Base) SetAddrStr(a string)
- func (b *Base) Sniffing() bool
- func (b *Base) Stop()
- type BaseInterface
- type Client
- type ClientCreator
- type CommonConf
- type CreatorCommon
- type CreatorCommonStruct
- type DialConf
- type DirectClient
- func (d *DirectClient) EstablishUDPChannel(_ net.Conn, firstPayload []byte, target netLayer.Addr) (netLayer.MsgConn, error)
- func (*DirectClient) GetCreator() ClientCreator
- func (d *DirectClient) Handshake(underlay net.Conn, firstPayload []byte, target netLayer.Addr) (result io.ReadWriteCloser, err error)
- func (*DirectClient) Name() string
- type DirectCreator
- type ListenConf
- type ListenerServer
- type MuxMarker
- type RejectClient
- func (c *RejectClient) EstablishUDPChannel(underlay net.Conn, _ []byte, _ netLayer.Addr) (netLayer.MsgConn, error)
- func (*RejectClient) GetCreator() ClientCreator
- func (c *RejectClient) Handshake(underlay net.Conn, _ []byte, _ netLayer.Addr) (result io.ReadWriteCloser, err error)
- func (*RejectClient) Name() string
- type RejectCreator
- func (RejectCreator) NewClient(dc *DialConf) (Client, error)
- func (RejectCreator) NewServer(lc *ListenConf) (Server, error)
- func (rc RejectCreator) URLToDialConf(url *url.URL, iv *DialConf, format int) (*DialConf, error)
- func (rc RejectCreator) URLToListenConf(url *url.URL, iv *ListenConf, format int) (*ListenConf, error)
- type RejectServer
- type RoutingEnv
- type Server
- type ServerCreator
- type SniffConf
- type StandardConf
- type UrlConf
- type UserClient
- type UserReadWrapper
- type UserServer
Constants ¶
const ( UrlMode = iota StandardMode V2rayCompatibleMode ErrStrNoListenUrl = "no listen URL provided" )
配置文件格式
const ( UrlNativeFormat = iota //proxy对应的标准文档所定义的url模式,一般散布于对应github的文档上 UrlStandardFormat //VS定义的 供 所有proxy 使用的 标准 url模式 Url_FormatUnknown )
const ( DirectName = "direct" DirectURL = DirectName + "://" )
const FirstPayloadTimeout = time.Millisecond * 100
some client may 建立tcp连接后首先由客户端读服务端的数据?虽较少见但确实存在. Anyway firstpayload might not be read, and we should try to reduce this delay. 也有可能是有人用 nc 来测试,也会遇到这种读不到 firstpayload 的情况
const RejectName = "reject"
Variables ¶
var StandardConfBytesSynonyms [][2][]byte
var StandardConfSynonyms = [][2]string{
{"advancedLayer", "adv"},
{"tls_rejectUnknownSni", "rejectUnknownSni"},
{"utls = true", `tls_type = "utls"`},
{"use_mux = true", "mux = true"},
}
第一种情况是 将一些较长的配置项 以较短的缩写 作为同义词. 然后代码读取时 只使用短的词. 第二种情况是 为了向后兼容,将已经不存在的配置替换为新配置
var ( // Url格式 设置以何种方式解析 命令行模式/极简模式 中出现的url配置 // //关于url格式的详细, 见 docs/url.md UrlFormat = UrlStandardFormat )
Functions ¶
func AllClientTypeList ¶ added in v1.2.5
func AllClientTypeList() []string
func AllServerTypeList ¶ added in v1.2.5
func AllServerTypeList() []string
func GetFullName ¶
func GetFullName(pc BaseInterface) string
FullName can fully represent the VSI model for a proxy. We think tcp/udp/kcp/raw_socket is FirstName,protocol of the proxy is LastName, and the rest is MiddleName。
An Example of a full name: tcp+tls+ws+vless.
func GetVSI_url ¶
func GetVSI_url(pc BaseInterface, targetNetwork string) string
return GetFullName(pc) + "://" + pc.AddrStr() (+ #tag)
func PrintAllClientNames ¶
func PrintAllClientNames()
func PrintAllServerNames ¶
func PrintAllServerNames()
func RegisterClient ¶
func RegisterClient(name string, c ClientCreator)
规定,每个 实现Client的包必须使用本函数进行注册。 direct 和 reject 统一使用本包提供的方法, 自定义协议不得覆盖 direct 和 reject。
func RegisterServer ¶
func RegisterServer(name string, c ServerCreator)
规定,每个 实现 Server 的包必须使用本函数进行注册
func TestUDP ¶
完整模拟整个 protocol 的udp请求 过程,即 客户端连接代理服务器,代理服务器试图访问远程服务器,这里是使用的模拟的办法模拟出一个远程udp服务器; 其他tcp测试因为比较简单,不需要第二步测试,而这里需要
func ToStandardUrl ¶ added in v1.2.5
func ToStandardUrl(cc *CommonConf, dc *DialConf, lc *ListenConf) string
convert DialConf or ListenConf to verysimple Official URL format. cc must not be nil or it will panic. See docs/url.md and https://github.com/e1732a364fed/v2ray_simple/discussions/163
func URLToCommonConf ¶ added in v1.2.4
func URLToCommonConf(u *url.URL, conf *CommonConf) error
setup conf with vs standard url format
func URLToDialConf ¶ added in v1.2.4
setup conf with vs standard URL format
func URLToListenConf ¶ added in v1.2.4
func URLToListenConf(u *url.URL, conf *ListenConf) error
setup conf with vs standard URL format
Types ¶
type Base ¶ added in v1.2.0
type Base struct { ListenConf *ListenConf DialConf *DialConf Addr string TLS bool Tag string //可用于路由, 见 netLayer.route.go TransportLayer string Sockopt *netLayer.Sockopt Xver int IsFullcone bool Tls_s *tlsLayer.Server Tls_c *tlsLayer.Client TlsConf tlsLayer.Conf Header *httpLayer.HeaderPreset IsCantRoute bool //for inServer, 若为true,则 inServer 读得的数据 不会经过分流,一定会通过用户指定的remoteclient发出 AdvancedL string AdvC advLayer.Client AdvS advLayer.Server FallbackAddr *netLayer.Addr Innermux *smux.Session //用于存储 client的已拨号的mux连接 sync.Mutex //用于sendthrough LTA *net.TCPAddr LUA *net.UDPAddr }
Base 实现 BaseInterface 中除了Name 之外的其他方法. 规定,所有的proxy都要内嵌本struct. 我们用这种方式实现 "继承". 这是verysimple的架构所要求的。 verysimple规定,在加载完配置文件后,listen/dial 所使用的全部层级都是完整确定了的.
因为所有使用的层级都是确定的,就可以进行针对性优化
func (*Base) AdvancedLayer ¶ added in v1.2.0
func (*Base) CanFallback ¶ added in v1.2.0
return false. As a placeholder.
func (*Base) CloseInnerMuxSession ¶ added in v1.2.0
func (b *Base) CloseInnerMuxSession()
func (*Base) ConfigCommon ¶ added in v1.2.0
func (b *Base) ConfigCommon(cc *CommonConf)
setNetwork, Xver, Tag,Sockopt, IsFullcone, Header,AdvancedL, InitAdvLayer
func (*Base) GetAdvClient ¶ added in v1.2.0
func (*Base) GetAdvServer ¶ added in v1.2.0
func (*Base) GetClientInnerMuxSession ¶ added in v1.2.0
func (b *Base) GetClientInnerMuxSession(wrc io.ReadWriteCloser) *smux.Session
func (*Base) GetFallback ¶ added in v1.2.0
func (*Base) GetServerInnerMuxSession ¶ added in v1.2.0
func (*Base) GetServerInnerMuxSession(wlc io.ReadWriteCloser) *smux.Session
func (*Base) GetSockopt ¶ added in v1.2.0
func (*Base) GetTLS_Client ¶ added in v1.2.0
func (*Base) GetTLS_Server ¶ added in v1.2.0
func (*Base) HasHeader ¶ added in v1.2.0
func (b *Base) HasHeader() *httpLayer.HeaderPreset
func (*Base) InitAdvLayer ¶ added in v1.2.0
func (b *Base) InitAdvLayer()
高级层就像代理层一样重要,可以注册多种包,配置选项也比较多。
func (*Base) InnerMuxEstablished ¶ added in v1.2.0
func (*Base) IsUDP_MultiChannel ¶ added in v1.2.0
return false. As a placeholder.
func (*Base) LocalTCPAddr ¶ added in v1.2.4
func (*Base) LocalUDPAddr ¶ added in v1.2.4
func (*Base) MiddleName ¶ added in v1.2.0
func (*Base) SelfListen ¶ added in v1.2.4
func (*Base) SetAddrStr ¶ added in v1.2.0
type BaseInterface ¶ added in v1.2.0
type BaseInterface interface { Name() string //代理协议名称, 如vless MiddleName() string //不包含传输层 和 代理层的 其它VSI层 所使用的协议,前后被加了加号,如 +tls+ws+ Stop() GetBase() *Base GetTag() string // 地址,若tcp/udp的话则为 ip:port/host:port的形式, 若是 unix domain socket 则是文件路径 , // 在 inServer就是监听地址,在 outClient就是拨号地址 AddrStr() string SetAddrStr(string) GetSockopt() *netLayer.Sockopt CantRoute() bool //for inServer Network() string //传输层协议,如 tcp, udp, unix, kcp, etc. 这里叫做Network而不是transport, 是遵循 golang 标准包 net包的用法。我们兼容 net的Listen等方法, 可把Network直接作为 net.Listen等方法的 network 参数。 GetXver() int Sniffing() bool //for inServer, 是否开启嗅探功能 IsUseTLS() bool IsLazyTls() bool GetTLS_Server() *tlsLayer.Server GetTLS_Client() *tlsLayer.Client HasHeader() *httpLayer.HeaderPreset //默认回落地址. GetFallback() *netLayer.Addr CanFallback() bool //如果能fallback,则handshake失败后,可能会专门返回 httpLayer.FallbackErr,如监测到返回了 FallbackErr, 则main函数会进行 回落处理. AdvancedLayer() string //所使用的高级层的协议名称 GetAdvClient() advLayer.Client GetAdvServer() advLayer.Server // 判断是否有内层mux。 //0 为不会有 innermux, 1 为有可能有 innermux, 2 为总是使用 innerMux; // 规定是,客户端 只能返回0/2, 服务端 只能返回 0/1(除非服务端协议不支持不mux的情况,此时可以返回2)。 // string 为 innermux内部的 代理 协议 名称。(一般用simplesocks) HasInnerMux() (int, string) }
BaseInterface provides supports for all VSI model layers except proxy layer.
type Client ¶
type Client interface { BaseInterface //Perform handshake when request is TCP。firstPayload 用于如 vless/trojan 这种 没有握手包的协议,可为空。 Handshake(underlay net.Conn, firstPayload []byte, target netLayer.Addr) (wrappedConn io.ReadWriteCloser, err error) //Establish a channel and constantly request data for each UDP addr through this channel. firstpayload and target can be empty theoretically, depending on the implementation. EstablishUDPChannel(underlay net.Conn, firstPayload []byte, target netLayer.Addr) (netLayer.MsgConn, error) //If udp is send through multiple connection or not IsUDP_MultiChannel() bool //get/listen a useable inner mux GetClientInnerMuxSession(wrc io.ReadWriteCloser) *smux.Session InnerMuxEstablished() bool CloseInnerMuxSession() //用于在拨号时选用一个特定的ip拨号。 LocalTCPAddr() *net.TCPAddr LocalUDPAddr() *net.UDPAddr GetCreator() ClientCreator sync.Locker //用于锁定 innerMux }
Client is used to dial a server. Because Server is "target agnostic", Client's Handshake requires a target addr as param.
A Client has all the data of all layers in its VSI model. Once a Client is fully defined, the flow of the data is fully defined.
func ClientFromURL ¶
ClientFromURL calls the registered creator to create client. The returned bool is true if has err.
type ClientCreator ¶
type ClientCreator interface { CreatorCommon //大部分通用内容都会被proxy包解析,方法只需要处理proxy包未知的内容 NewClient(*DialConf) (Client, error) //标准配置 //URLToDialConf 执行proxy自定义的非标准代码; //iv: initial value, can be nil. URLToDialConf(url *url.URL, iv *DialConf, format int) (*DialConf, error) }
可通过标准配置或url 来初始化。
func GetRealProtocolFromClientUrl ¶ added in v1.2.4
func GetRealProtocolFromClientUrl(s string) (u *url.URL, schemeName string, creator ClientCreator, okTls bool, err error)
try find from map, trim tail s if necessary
type CommonConf ¶
type CommonConf struct { Tag string `toml:"tag"` //可选 Extra map[string]any `toml:"extra"` //用于包含任意其它数据.虽然本包自己定义的协议肯定都是已知的,但是如果其他人使用了本包的话,那就有可能添加一些 新协议 特定的数据. 而且这也便于扁平化,避免出现大量各种子块。任何子块内容都放在extra中,比如 quic的就是 extra.quic_xxx Host string `toml:"host"` //ip 或域名. 若unix domain socket 则为文件路径 IP string `toml:"ip"` //给出Host后,该项可以省略; 既有Host又有ip的情况比较适合cdn Network string `toml:"network"` //传输层协议; 默认使用tcp, network可选值为 tcp, udp, unix; Sockopt *netLayer.Sockopt `toml:"sockopt"` //可选 Port int `toml:"port"` //若Network不为 unix , 则port项必填 Xver int `toml:"xver"` //可选,只能为0/1/2. 若不为0, 则使用 PROXY protocol 协议头. Fullcone bool `toml:"fullcone"` //在udp会用到, fullcone的话因为不能关闭udp连接, 所以 时间长后, 可能会导致too many open files. fullcone 的话一般人是用不到的, 所以 有需要的人自行手动打开 即可 TLS bool `toml:"tls"` //tls层; 可选. 如果不使用 's' 后缀法,则还可以配置这一项来更清晰地标明使用tls TlsType string `toml:"tls_type"` //可选,可以为 utls或者shadowTls, 若不给出或为空, 则为golang的标准tls. utls 只在客户端有效。 Insecure bool `toml:"insecure"` //tls 是否安全 Alpn []string `toml:"alpn"` TLSCert string `toml:"cert"` //可选 TLSKey string `toml:"key"` //可选 Lazy bool `toml:"lazy"` //可选, 是否开启 tls_lazy_encrypt 功能 HttpHeader *httpLayer.HeaderPreset `toml:"header"` //http伪装头; 可选 Path string `toml:"path"` //ws 的path 或 grpc的 serviceName。为了简便我们在同一位置给出. AdvancedLayer string `toml:"adv"` //高级层; 可选 IsEarly bool `toml:"early"` //是否启用 0-rtt Protocol string `toml:"protocol"` //代理层; 约定,如果一个Protocol尾缀去掉了一个's'后仍然是一个有效协议,则该协议使用了 tls。这种方法继承自 v2simple,适合极简模式 UUID string `toml:"uuid"` //代理层用户的唯一标识,视代理层协议而定,一般使用uuid,但trojan协议是随便的password, 而socks5 和 http 则使用 user+pass 的形式。 我们为了简洁、一致,就统一放到了 这个字段里。 Version int `toml:"version"` //可选,代理层协议版本号,vless v1 要用到。 EncryptAlgo string `toml:"encrypt_algo"` //内部加密算法,vmess/ss 等协议可指定 }
CommonConf is the common part of ListenConf and DialConf.
func (*CommonConf) GetAddrStr ¶
func (cc *CommonConf) GetAddrStr() string
和 GetAddrStrForListenOrDial 的区别是,它优先使用host,其次再使用ip
func (*CommonConf) GetAddrStrForListenOrDial ¶
func (cc *CommonConf) GetAddrStrForListenOrDial() string
if network is unix domain socket, return Host,or return ip:port / host:port; 和 GetAddr的区别是,它优先使用ip,其次再使用host
type CreatorCommon ¶ added in v1.2.4
type CreatorCommon interface { //若为true,则表明该协议可同时使用tcp和udp来传输数据。direct, socks5 和 shadowsocks 都为true。 //此时,是否开启udp取决于Network(), 如果为dual, 则均支持; 如果仅为tcp或者udp,则不支持。 // direct的默认Network为dual。 MultiTransportLayer() bool }
type CreatorCommonStruct ¶ added in v1.2.4
type CreatorCommonStruct struct{}
func (CreatorCommonStruct) AfterCommonConfServer ¶ added in v1.2.4
func (CreatorCommonStruct) AfterCommonConfServer(Server) error
func (CreatorCommonStruct) MultiTransportLayer ¶ added in v1.2.4
func (CreatorCommonStruct) MultiTransportLayer() bool
type DialConf ¶
type DialConf struct { CommonConf SendThrough string `toml:"sendThrough"` //可选,用于发送数据的 IP 地址, 可以是ip:port, 或者 tcp:ip:port\nudp:ip:port Mux bool `toml:"mux"` //是否使用内层mux。在某些支持mux命令的协议中(vless v1/trojan), 开启此开关会让 dial 使用 内层mux。 }
config for dialing, user can be called dialer or outClient.
CommonConf.Host , CommonConf.IP, CommonConf.Port are the addr and port for dialing.
type DirectClient ¶
type DirectClient struct {
Base
}
func (*DirectClient) EstablishUDPChannel ¶
func (d *DirectClient) EstablishUDPChannel(_ net.Conn, firstPayload []byte, target netLayer.Addr) (netLayer.MsgConn, error)
direct的Client的 EstablishUDPChannel 直接 监听一个udp端口,无视传入的net.Conn. 这是因为要考虑到fullcone.
func (*DirectClient) GetCreator ¶ added in v1.2.4
func (*DirectClient) GetCreator() ClientCreator
func (*DirectClient) Handshake ¶
func (d *DirectClient) Handshake(underlay net.Conn, firstPayload []byte, target netLayer.Addr) (result io.ReadWriteCloser, err error)
若 underlay 为nil,则会对target进行拨号, 否则返回underlay本身
func (*DirectClient) Name ¶
func (*DirectClient) Name() string
type DirectCreator ¶ added in v1.2.0
type DirectCreator struct{ CreatorCommonStruct }
implements ClientCreator for direct
func (DirectCreator) MultiTransportLayer ¶ added in v1.2.4
func (DirectCreator) MultiTransportLayer() bool
true
func (DirectCreator) NewClient ¶ added in v1.2.0
func (DirectCreator) NewClient(dc *DialConf) (Client, error)
func (DirectCreator) URLToDialConf ¶ added in v1.2.4
type ListenConf ¶
type ListenConf struct { CommonConf Users []utils.UserConf `toml:"users"` //可选, 用于储存多个用户/密码 信息。 CA string `toml:"ca"` //可选,用于 验证"客户端证书" SniffConf *SniffConf `toml:"sniffing"` //用于嗅探出 host 来帮助 分流。 Fallback any `toml:"fallback"` //可选,默认回落的地址,一般可为 ip:port,数字port or unix socket的文件名 //noroute 意味着 传入的数据 不会被分流,一定会被转发到默认的 dial // 这一项是针对 分流功能的. 如果不设noroute, 则所有listen 得到的流量都会被 试图 进行分流 NoRoute bool `toml:"noroute"` TargetAddr string `toml:"target"` //若使用dokodemo协议,则这一项会给出. 格式为url, 如 tcp://127.0.0.1:443 , 必须带scheme,以及端口。只能为tcp或udp }
config for listening, the user can be called as listener or inServer.
CommonConf.Host , CommonConf.IP, CommonConf.Port is the addr and port for listening
type ListenerServer ¶ added in v1.2.4
type ListenerServer interface { Server //非阻塞 StartListen(func(netLayer.TCPRequestInfo), func(netLayer.UDPRequestInfo)) io.Closer }
type MuxMarker ¶
type MuxMarker interface { io.ReadWriteCloser IsMux() bool }
规定,如果 proxy的server的handshake如果返回的是具有内层mux的连接,该连接要实现 MuxMarker 接口.
type RejectClient ¶
type RejectClient struct {
// contains filtered or unexported fields
}
RejectClient implements Client, optionally response a 403 and close the underlay immediately.
v2ray的 "blackhole" 名字不准确, 本作 使用 "reject".
正常的 blackhole,并不会立即关闭连接,而是悄无声息地 读 数据,并舍弃。 而 v2ray的 blackhole是 选择性返回 403错误 后立即关闭连接. 完全是 Reject的特性。
而且 理想情况下 应该分析一下请求,如果请求是合法的http请求,则返回403,否则 应该返回 400错误.
所以我们在v2ray的基础上,再推出一个 "nginx"类型,来达到上面的分类返回不同错误的效果。
默认为 "" 空类型,直接 close,不反回任何信息。 若设为 http,则返回一个403错误;若设为nginx,则分类返回400/403错误。
func (*RejectClient) EstablishUDPChannel ¶
func (c *RejectClient) EstablishUDPChannel(underlay net.Conn, _ []byte, _ netLayer.Addr) (netLayer.MsgConn, error)
function the same as Handshake
func (*RejectClient) GetCreator ¶ added in v1.2.4
func (*RejectClient) GetCreator() ClientCreator
type RejectCreator ¶
type RejectCreator struct{ CreatorCommonStruct }
implements ClientCreator and ServerCreator for reject
func (RejectCreator) NewServer ¶ added in v1.2.4
func (RejectCreator) NewServer(lc *ListenConf) (Server, error)
func (RejectCreator) URLToDialConf ¶ added in v1.2.4
func (RejectCreator) URLToListenConf ¶ added in v1.2.4
func (rc RejectCreator) URLToListenConf(url *url.URL, iv *ListenConf, format int) (*ListenConf, error)
type RejectServer ¶ added in v1.2.4
type RejectServer struct {
// contains filtered or unexported fields
}
mimic the behavior of RejectClient
type RoutingEnv ¶
type RoutingEnv struct { RoutePolicy *netLayer.RoutePolicy Fallback *httpLayer.ClassicFallback DnsMachine *netLayer.DNSMachine ClientsTagMap map[string]Client //ClientsTagMap 存储 tag 对应的 Client;因为分流时,需要通过某个tag找到Client对象。 若要访问map,请用 Get*, Set*, Del* 方法 // contains filtered or unexported fields }
used in real relay progress. See source code of v2ray_simple for details.
func LoadEnvFromStandardConf ¶
func LoadEnvFromStandardConf(standardConf *StandardConf, myCountryISO_3166 string) (routingEnv RoutingEnv)
func (*RoutingEnv) DelClient ¶ added in v1.2.0
func (re *RoutingEnv) DelClient(tag string)
func (*RoutingEnv) GetClient ¶ added in v1.2.0
func (re *RoutingEnv) GetClient(tag string) (c Client)
func (*RoutingEnv) SetClient ¶ added in v1.2.0
func (re *RoutingEnv) SetClient(tag string, c Client)
type Server ¶
type Server interface { BaseInterface //net.Conn is for TCP request, netLayer.MsgConn is for UDP request. // 约定,如果error返回的是 utils.ErrHandled, 则调用代码停止进一步处理。 Handshake(underlay net.Conn) (net.Conn, netLayer.MsgConn, netLayer.Addr, error) //get/listen a useable inner mux GetServerInnerMuxSession(wlc io.ReadWriteCloser) *smux.Session //tproxy,tun 和 shadowsocks(udp) 都用到了 SelfListen // //is表示开启自监听; 此时若 tcp=1, 表示监听tcp, 若tcp=0, 表示自己不监听tcp, 但需要vs进行监听; 若tcp<0, 则表示自己不监听, 也不要vs监听; udp同理; 开启SelfListen同时表明 Server实现了 ListenerServer SelfListen() (is bool, tcp, udp int) }
Server is used for listening clients. Because Server is "target agnostic",Handshake should return the target addr that the Client requested.
A Server has all the data of all layers in its VSI model. Once a Server is fully defined, the flow of the data is fully defined.
func NewServer ¶
func NewServer(lc *ListenConf) (Server, error)
func ServerFromURL ¶
ServerFromURL calls the registered creator to create proxy servers.
type ServerCreator ¶
type ServerCreator interface { CreatorCommon NewServer(*ListenConf) (Server, error) AfterCommonConfServer(Server) error URLToListenConf(url *url.URL, iv *ListenConf, format int) (*ListenConf, error) }
可通过标准配置或url 来初始化。
func GetRealProtocolFromServerUrl ¶ added in v1.2.4
func GetRealProtocolFromServerUrl(s string) (u *url.URL, schemeName string, creator ServerCreator, okTls bool, err error)
try find from map, trim tail s if necessary
type StandardConf ¶
type StandardConf struct { DnsConf *netLayer.DnsConf `toml:"dns"` Listen []*ListenConf `toml:"listen"` Dial []*DialConf `toml:"dial"` Route []*netLayer.RuleConf `toml:"route"` Fallbacks []*httpLayer.FallbackConf `toml:"fallback"` }
标准配置,使用toml格式。 toml:https://toml.io/cn/
English: https://toml.io/en/
func LoadStandardConfFromTomlStr ¶ added in v1.2.4
func LoadStandardConfFromTomlStr(str string) (c StandardConf, err error)
convenient function for loading StandardConf from a string. Calls utils.ReplaceStringsSynonyms(str, StandardConfSynonyms)
type UrlConf ¶ added in v1.2.5
func LoadUrlConf ¶ added in v1.2.5
listenURL 不可为空。dialURL如果为空,会自动被设为 DirectURL
type UserClient ¶
type UserReadWrapper ¶ added in v1.2.5
type UserReadWrapper struct { utils.User netLayer.ReadWrapper Mux bool }
实现 utils.MuxMarker, utils.User
func (*UserReadWrapper) IsMux ¶ added in v1.2.5
func (w *UserReadWrapper) IsMux() bool
type UserServer ¶
type UserServer interface { Server utils.UserContainer }
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package dokodemo implements a dokodemo-door proxy.Server.
|
Package dokodemo implements a dokodemo-door proxy.Server. |
Package http implements http proxy for proxy.Server.
|
Package http implements http proxy for proxy.Server. |
Package shadowsocks implements shadowsocks protocol.
|
Package shadowsocks implements shadowsocks protocol. |
Package simplesocks implements SimpleSocks (defined by trojan-go) protocol for proxy.Server and proxy.Client.
|
Package simplesocks implements SimpleSocks (defined by trojan-go) protocol for proxy.Server and proxy.Client. |
Package socks5 provies socks5 proxy for proxy.Client and proxy.Server.
|
Package socks5 provies socks5 proxy for proxy.Client and proxy.Server. |
Package socks5http provides listening both socks5 and http at one port.
|
Package socks5http provides listening both socks5 and http at one port. |
Package tproxy implements proxy.Server for tproxy.
|
Package tproxy implements proxy.Server for tproxy. |
Package trojan implements trojan protocol for proxy.Client and proxy.Server.
|
Package trojan implements trojan protocol for proxy.Client and proxy.Server. |
Package tun implements proxy.Server for tun device.
|
Package tun implements proxy.Server for tun device. |
Package vless implements vless v0/v1 for proxy.Client and proxy.Server.
|
Package vless implements vless v0/v1 for proxy.Client and proxy.Server. |
Package vmess implements vmess for proxy.Client and proxy.Server.
|
Package vmess implements vmess for proxy.Client and proxy.Server. |