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包内容 ¶
接口 ProxyCommon 和 结构 ProxyCommonStruct 给 这个架构定义了标准.
而 Client 和 Server 接口 是 具体利用该架构的 客户端 和 服务端,都位于VSI中的第八层.
使用 RegisterClient 和 RegisterServer 来注册新的实现.
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
- func GetFullName(pc BaseInterface) string
- func GetFullconeFromUrl(url *url.URL) bool
- func GetVSI_url(pc BaseInterface) string
- func LoadConfig(configFileName, listenURL, dialURL string, jsonMode int) (standardConf StandardConf, simpleConf SimpleConf, confMode int, ...)
- func PrintAllClientNames()
- func PrintAllServerNames()
- func RegisterClient(name string, c ClientCreator)
- func RegisterServer(name string, c ServerCreator)
- func SetCommonReadTimeout(c net.Conn) error
- func TestTCP(protocol string, version int, port string, t *testing.T)
- func TestUDP(protocol string, version int, proxyPort string, use_multi int, t *testing.T)
- type AppConf
- 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 (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) MiddleName() string
- func (b *Base) Network() string
- func (b *Base) SetAddrStr(a string)
- func (b *Base) Sniffing() bool
- func (b *Base) Stop()
- type BaseInterface
- type Client
- type ClientCreator
- type CommonConf
- type DialConf
- type DirectClient
- type DirectCreator
- type LesserConf
- type ListenConf
- type MuxMarker
- type MuxMarkerConn
- type RejectClient
- type RejectCreator
- type RejectServer
- type RoutingEnv
- type Server
- type ServerCreator
- type SimpleConf
- type SniffConf
- type StandardConf
- type UserClient
- type UserServer
Constants ¶
const ( SimpleMode = iota StandardMode V2rayCompatibleMode ErrStrNoListenUrl = "no listen URL provided" )
配置文件格式
const ( DirectName = "direct" DirectURL = DirectName + "://" )
const CommonReadTimeout = time.Second * 4
default recommended handshake read timeout
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 ¶
This section is empty.
Functions ¶
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 GetFullconeFromUrl ¶ added in v1.2.3
func GetVSI_url ¶
func GetVSI_url(pc BaseInterface) string
return GetFullName(pc) + "://" + pc.AddrStr() (+ #tag)
func LoadConfig ¶
func LoadConfig(configFileName, listenURL, dialURL string, jsonMode int) (standardConf StandardConf, simpleConf SimpleConf, confMode int, mainFallback *httpLayer.ClassicFallback, err error)
先检查configFileName是否存在,存在就尝试加载文件到 standardConf or simpleConf,否则尝试 listenURL, dialURL 参数. 若 返回的是 simpleConf, 则还可能返回 mainFallback.
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 SetCommonReadTimeout ¶ added in v1.2.3
set read timeout after CommonReadTimeout
Types ¶
type AppConf ¶
type AppConf struct { LogLevel *int `toml:"loglevel"` //需要为指针, 否则无法判断0到底是未给出的默认值还是 显式声明的0 LogFile *string `toml:"logfile"` DefaultUUID string `toml:"default_uuid"` MyCountryISO_3166 string `toml:"mycountry" json:"mycountry"` //加了mycountry后,就会自动按照geoip分流,也会对顶级域名进行国别分流 NoReadV bool `toml:"noreadv"` AdminPass string `toml:"admin_pass"` //用于apiServer等情况 UDP_timeout *int `toml:"udp_timeout"` }
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 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 }
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) MiddleName ¶ added in v1.2.0
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() 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 { NewClient(*DialConf) (Client, error) NewClientFromURL(url *url.URL) (Client, error) }
可通过两种配置方式来初始化。
type CommonConf ¶
type CommonConf struct { Tag string `toml:"tag"` //可选 Extra map[string]any `toml:"extra"` //用于包含任意其它数据.虽然本包自己定义的协议肯定都是已知的,但是如果其他人使用了本包的话,那就有可能添加一些 新协议 特定的数据. 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; 理论上来说应该用 transportLayer,但是怕小白不懂,所以使用 network作为名称。而且也不算错,因为go的net包 也是用 network来指示 传输层/网络层协议的. 比如 net.Listen()第一个参数可以用 ip, tcp, udp 等。 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"` //在direct会用到, fullcone的话因为不能关闭udp连接, 所以 时间长后, 可能会导致too many open files. fullcone 的话一般人是用不到的, 所以 有需要的人自行手动打开 即可 TLS bool `toml:"tls"` //tls层; 可选. 如果不使用 's' 后缀法,则还可以配置这一项来更清晰第标明使用tls 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:"advancedLayer"` //高级层; 可选 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 要用到。 }
CommonConf is the common part of ListenConf and DialConf.
func (*CommonConf) GetAddrStr ¶
func (cc *CommonConf) GetAddrStr() string
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 DialConf ¶
type DialConf struct { CommonConf Utls bool `toml:"utls"` //是否使用 uTls 库 替换 go官方tls库 Mux bool `toml:"use_mux"` //是否使用内层mux。在某些支持mux命令的协议中(vless v1/trojan), 开启此开关会让 dial 使用 内层mux。 }
config for dialing, user can be called dialer or outClient.
CommonConf.Host , CommonConf.IP, CommonConf.Port is 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.
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{}
implements ClientCreator for direct
func (DirectCreator) NewClient ¶ added in v1.2.0
func (DirectCreator) NewClient(dc *DialConf) (Client, error)
func (DirectCreator) NewClientFromURL ¶ added in v1.2.0
func (DirectCreator) NewClientFromURL(url *url.URL) (Client, error)
type LesserConf ¶ added in v1.2.3
用于 tproxy 或 tun/tap 这种 只有 网络层 和传输层的情况
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 MuxMarker ¶
type MuxMarker interface { io.ReadWriteCloser IsMux() }
规定,如果 proxy的server的handshake如果返回的是具有内层mux的连接,该连接要实现 MuxMarker 接口.
type MuxMarkerConn ¶
type MuxMarkerConn struct {
netLayer.ReadWrapper
}
实现 MuxMarker
func (*MuxMarkerConn) IsMux ¶
func (mh *MuxMarkerConn) IsMux()
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
type RejectCreator ¶
type RejectCreator struct{}
implements ClientCreator for reject
func (RejectCreator) NewClientFromURL ¶
func (RejectCreator) NewClientFromURL(url *url.URL) (Client, error)
func (RejectCreator) NewServer ¶ added in v1.2.4
func (RejectCreator) NewServer(lc *ListenConf) (Server, error)
func (RejectCreator) NewServerFromURL ¶
func (RejectCreator) NewServerFromURL(url *url.URL) (Server, 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 MainFallback *httpLayer.ClassicFallback DnsMachine *netLayer.DNSMachine ClientsTagMap map[string]Client //用于分流到某个tag的Client, 所以需要知道所有的client ClientsTagMapMutex sync.RWMutex }
used in real relay progress. See source code of v2ray_simple for details.
func LoadEnvFromStandardConf ¶
func LoadEnvFromStandardConf(standardConf *StandardConf) (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 //ReadWriteCloser is for TCP request, net.PacketConn 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 }
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)
type ServerCreator ¶
type ServerCreator interface { NewServer(*ListenConf) (Server, error) NewServerFromURL(url *url.URL) (Server, error) }
可通过两种配置方式来初始化。
type SimpleConf ¶
type SimpleConf struct { ListenUrl string `json:"listen"` DialUrl string `json:"dial"` Route []*netLayer.RuleConf `json:"route"` Fallbacks []*httpLayer.FallbackConf `json:"fallbacks"` MyCountryISO_3166 string `json:"mycountry"` }
极简配置模式;只支持json
func LoadSimpleConfigFile ¶
func LoadSimpleConfigFile(fileNamePath string) (config SimpleConf, hasError bool, E utils.ErrInErr)
func LoadSimpleConfigFromStr ¶
func LoadSimpleConfigFromStr(str string) (config SimpleConf, hasE bool, E utils.ErrInErr)
type StandardConf ¶
type StandardConf struct { App *AppConf `toml:"app"` 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 LoadTomlConfFile ¶
func LoadTomlConfFile(fileNamePath string) (StandardConf, error)
func LoadTomlConfStr ¶
func LoadTomlConfStr(str string) (c StandardConf, err error)
type UserClient ¶
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 protocol for proxy.Server and proxy.Client.
|
Package simplesocks implements SimpleSocks 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 trojan implements trojan protocol for proxy.Client and proxy.Server.
|
package trojan implements trojan protocol for proxy.Client and proxy.Server. |
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 client.
|
Package vmess implements vmess client. |