proxy

package
v1.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 28, 2022 License: MIT Imports: 22 Imported by: 0

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

View Source
const (
	UrlMode = iota
	StandardMode
	V2rayCompatibleMode

	ErrStrNoListenUrl = "no listen URL provided"
)

配置文件格式

View Source
const (
	UrlNativeFormat   = iota //proxy对应的标准文档所定义的url模式,一般散布于对应github的文档上
	UrlStandardFormat        //VS定义的 供 所有proxy 使用的 标准 url模式

	Url_FormatUnknown
)
View Source
const (
	DirectName = "direct"
	DirectURL  = DirectName + "://"
)
View Source
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 的情况

View Source
const RejectName = "reject"

Variables

View Source
var StandardConfBytesSynonyms [][2][]byte
View Source
var StandardConfSynonyms = [][2]string{
	{"advancedLayer", "adv"},
	{"tls_rejectUnknownSni", "rejectUnknownSni"},
	{"utls = true", `tls_type = "utls"`},
	{"use_mux = true", "mux = true"},
}

第一种情况是 将一些较长的配置项 以较短的缩写 作为同义词. 然后代码读取时 只使用短的词. 第二种情况是 为了向后兼容,将已经不存在的配置替换为新配置

View Source
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 TestTCP

func TestTCP(protocol string, specialUUID string, version int, port string, extraQuery string, t *testing.T)

func TestUDP

func TestUDP(protocol string, version int, proxyPort string, use_multi int, t *testing.T)

完整模拟整个 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

func URLToDialConf(u *url.URL, conf *DialConf) error

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) AddrStr added in v1.2.0

func (b *Base) AddrStr() string

func (*Base) AdvancedLayer added in v1.2.0

func (b *Base) AdvancedLayer() string

func (*Base) CanFallback added in v1.2.0

func (b *Base) CanFallback() bool

return false. As a placeholder.

func (*Base) CantRoute added in v1.2.0

func (b *Base) CantRoute() bool

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) DialTCP added in v1.2.4

func (d *Base) DialTCP(target netLayer.Addr) (result net.Conn, err error)

func (*Base) DialUDP added in v1.2.4

func (d *Base) DialUDP(target netLayer.Addr) (mc *netLayer.UDPMsgConn, err error)

func (*Base) GetAdvClient added in v1.2.0

func (b *Base) GetAdvClient() advLayer.Client

func (*Base) GetAdvServer added in v1.2.0

func (b *Base) GetAdvServer() advLayer.Server

func (*Base) GetBase added in v1.2.0

func (b *Base) GetBase() *Base

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 (b *Base) GetFallback() *netLayer.Addr

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 (b *Base) GetSockopt() *netLayer.Sockopt

func (*Base) GetTLS_Client added in v1.2.0

func (b *Base) GetTLS_Client() *tlsLayer.Client

func (*Base) GetTLS_Server added in v1.2.0

func (b *Base) GetTLS_Server() *tlsLayer.Server

func (*Base) GetTag added in v1.2.0

func (b *Base) GetTag() string

func (*Base) GetXver added in v1.2.0

func (b *Base) GetXver() int

func (*Base) HasHeader added in v1.2.0

func (b *Base) HasHeader() *httpLayer.HeaderPreset

func (*Base) HasInnerMux added in v1.2.0

func (b *Base) HasInnerMux() (int, string)

placeholder

func (*Base) InitAdvLayer added in v1.2.0

func (b *Base) InitAdvLayer()

高级层就像代理层一样重要,可以注册多种包,配置选项也比较多。

func (*Base) InnerMuxEstablished added in v1.2.0

func (b *Base) InnerMuxEstablished() bool

func (*Base) IsLazyTls added in v1.2.2

func (b *Base) IsLazyTls() bool

func (*Base) IsUDP_MultiChannel added in v1.2.0

func (b *Base) IsUDP_MultiChannel() bool

return false. As a placeholder.

func (*Base) IsUseTLS added in v1.2.0

func (b *Base) IsUseTLS() bool

func (*Base) LocalTCPAddr added in v1.2.4

func (b *Base) LocalTCPAddr() *net.TCPAddr

func (*Base) LocalUDPAddr added in v1.2.4

func (b *Base) LocalUDPAddr() *net.UDPAddr

func (*Base) MiddleName added in v1.2.0

func (b *Base) MiddleName() string

func (*Base) Network added in v1.2.0

func (b *Base) Network() string

func (*Base) SelfListen added in v1.2.4

func (d *Base) SelfListen() (is bool, tcp, udp int)

func (*Base) SetAddrStr added in v1.2.0

func (b *Base) SetAddrStr(a string)

func (*Base) Sniffing added in v1.2.2

func (b *Base) Sniffing() bool

func (*Base) Stop added in v1.2.0

func (b *Base) Stop()

try close inner mux and stop AdvS

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

func ClientFromURL(s string) (Client, error)

ClientFromURL calls the registered creator to create client. The returned bool is true if has err.

func NewClient

func NewClient(dc *DialConf) (Client, error)

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

func (DirectCreator) URLToDialConf(url *url.URL, iv *DialConf, format int) (*DialConf, error)

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

func (*RejectClient) Handshake

func (c *RejectClient) Handshake(underlay net.Conn, _ []byte, _ netLayer.Addr) (result io.ReadWriteCloser, err error)

optionally response 403 and close the underlay, return io.EOF.

func (*RejectClient) Name

func (*RejectClient) Name() string

type RejectCreator

type RejectCreator struct{ CreatorCommonStruct }

implements ClientCreator and ServerCreator for reject

func (RejectCreator) NewClient

func (RejectCreator) NewClient(dc *DialConf) (Client, error)

func (RejectCreator) NewServer added in v1.2.4

func (RejectCreator) NewServer(lc *ListenConf) (Server, error)

func (RejectCreator) URLToDialConf added in v1.2.4

func (rc RejectCreator) URLToDialConf(url *url.URL, iv *DialConf, format int) (*DialConf, error)

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

func (*RejectServer) Handshake added in v1.2.4

func (s *RejectServer) Handshake(underlay net.Conn) (_ net.Conn, _ netLayer.MsgConn, _ netLayer.Addr, e error)

return utils.ErrHandled

func (*RejectServer) Name added in v1.2.4

func (*RejectServer) Name() string

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

func ServerFromURL(s string) (Server, error)

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 SniffConf added in v1.2.2

type SniffConf struct {
	Enable bool `toml:"enabled"`
}

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

type UrlConf struct {
	ListenUrl string `json:"listen"`
	DialUrl   string `json:"dial"`
}

func LoadUrlConf added in v1.2.5

func LoadUrlConf(listenURL, dialURL string) (urlConf UrlConf, err error)

listenURL 不可为空。dialURL如果为空,会自动被设为 DirectURL

type UserClient

type UserClient interface {
	Client
	GetUser() utils.User
}

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
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL