Documentation ¶
Overview ¶
Package netLayer contains definitions in network layer AND transport layer.
本包有 geoip, geosite, route, udp, readv, splice, relay, dns, listen/dial/sockopt 等相关功能。
以后如果要添加 kcp 或 raw socket 等底层协议时,也要在此包 或子包里实现.
Tags ¶
本包提供 embed_geoip 这个 build tag。
若给出 embed_geoip,则会尝试内嵌 GeoLite2-Country.mmdb.tgz 文件;默认不内嵌。
Index ¶
- Constants
- Variables
- func ATypeToSocks5Standard(atype byte) byte
- func CanSpliceDirectly(r any) bool
- func CanSpliceEventually(r any) bool
- func ClassicCopy(w io.Writer, r io.Reader) (written int64, err error)
- func DNSQuery(domain string, dns_type uint16, conn *dns.Conn, theMux *sync.Mutex, ...) (net.IP, error)
- func DialDnsAddr(addr *Addr) (conn net.Conn, err error)
- func DownloadCommunity_DomainListFiles(proxyurl string)
- func GetIP_ISO(ip net.IP) string
- func GetIP_ISO_byReader(db *maxminddb.Reader, ip net.IP) string
- func GetRandLocalAddr(mustValid, isudp bool) string
- func GetRandLocalPrivateAddr(mustValid, isudp bool) string
- func GetRawConn(reader io.Reader) syscall.RawConn
- func HasEmbedGeoip() bool
- func HasFullOrSubDomain(domain string, ds DomainHaser) bool
- func HasIpv6Interface() bool
- func IsBasicConn(r interface{}) bool
- func IsConnGoodForReadv(c net.Conn) (r int, rawReadConn syscall.RawConn, mr utils.MultiReader)
- func IsDomainInsideGeosite(geositeName string, domain string) bool
- func IsStrUDP_network(s string) bool
- func Is_DNSQuery_returnType_ReadErr(err error) bool
- func Is_DNSQuery_returnType_ReadFatalErr(err error) bool
- func ListenAndAccept(network, addr string, sockopt *Sockopt, acceptFunc func(net.Conn)) (listener net.Listener, err error)
- func LoadGeositeFiles() (err error)
- func LoadMaxmindGeoipFile(fn string)
- func LoadRulesForRoutePolicy(rules []*RuleConf, policy *RoutePolicy)
- func ParseStrToAddr(s string) (atyp byte, addr []byte, port_uint16 uint16, err error)
- func Prepare()
- func RandPort(mustValid, isudp bool) (p int)
- func RandPortStr(mustValid, isudp bool) string
- func RandPort_andStr(mustValid, isudp bool) (int, string)
- func ReadBuffersFrom(c io.Reader, rawReadConn syscall.RawConn, mr utils.MultiReader) (buffers [][]byte, err error)
- func Relay(realTargetAddr *Addr, rc, lc io.ReadWriteCloser, ...) int64
- func RelayUDP(rc, lc MsgConn, downloadByteCount, uploadByteCount *uint64) uint64
- func RelayUDP_separate(rc, lc MsgConn, firstAddr *Addr, downloadByteCount, uploadByteCount *uint64, ...) uint64
- func SetSockOpt(fd int, sockopt *Sockopt, isudp bool, isipv6 bool)
- func SetSockOptForListener(tcplistener ListenerWithFile, sockopt *Sockopt, isudp bool, isipv6 bool)
- func StrToTransportProtocol(s string) uint16
- func TryCopy(writeConn io.Writer, readConn io.Reader) (allnum int64, err error)
- func TryCopyOnce(writeConn io.Writer, readConn io.Reader) (allnum int64, err error)
- func TryReadFrom_withSplice(classicWriter io.Writer, maySpliceConn net.Conn, r io.Reader, ...) (written int64, err error)
- func UDPAddr2AddrPort(ua *net.UDPAddr) netip.AddrPort
- func UDPAddr_v4_to_Bytes(addr *net.UDPAddr) [6]byte
- func WritePROXYprotocol(xver int, wlc NetAddresser, wrc io.Writer) (n int, err error)
- type Addr
- func (a *Addr) AddressBytes() (addr []byte, atyp byte)
- func (a *Addr) Dial() (net.Conn, error)
- func (a Addr) DialWithOpt(sockopt *Sockopt) (net.Conn, error)
- func (a *Addr) GetHashable() (ha HashableAddr)
- func (a *Addr) GetNetIPAddr() (na netip.Addr)
- func (a *Addr) HostStr() string
- func (a *Addr) IsEmpty() bool
- func (a *Addr) IsIpv6() bool
- func (a *Addr) IsUDP() bool
- func (a Addr) ListenUDP_withOpt(sockopt *Sockopt) (net.PacketConn, error)
- func (a *Addr) String() string
- func (a *Addr) ToTCPAddr() *net.TCPAddr
- func (a *Addr) ToUDPAddr() *net.UDPAddr
- func (a *Addr) UrlString() string
- type AddrData
- type ConnWithFile
- type DNSMachine
- type DnsConf
- type DnsConn
- type DomainHaser
- type EasyDeadline
- func (ed *EasyDeadline) InitEasyDeadline()
- func (ed *EasyDeadline) ReadTimeoutChan() chan struct{}
- func (ed *EasyDeadline) SetDeadline(t time.Time) error
- func (ed *EasyDeadline) SetReadDeadline(t time.Time) error
- func (ed *EasyDeadline) SetWriteDeadline(t time.Time) error
- func (ed *EasyDeadline) WriteTimeoutChan() chan struct{}
- type EasyNetAddresser
- type GeositeAttr
- type GeositeDomain
- type GeositeList
- type GeositeRawList
- type HashableAddr
- type IOWrapper
- type ListenerWithFile
- type MapDomainHaser
- type MapGeositeDomainHaser
- type MsgConn
- type NetAddresser
- type NetDeadliner
- type PipeDeadline
- type ReadWrapper
- type RoutePolicy
- type RouteSet
- type RuleConf
- type Sockopt
- type SpecialDnsServerConf
- type Splicer
- type TargetDescription
- type UDPAddrData
- type UDPConn
- func (uc *UDPConn) Close() error
- func (uc *UDPConn) CloseConnWithRaddr(_ Addr) error
- func (uc *UDPConn) CloseMsgChan()
- func (uc *UDPConn) GetReadChan() chan UDPAddrData
- func (uc *UDPConn) LocalAddr() net.Addr
- func (uc *UDPConn) Read(buf []byte) (n int, err error)
- func (uc *UDPConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
- func (uc *UDPConn) ReadMsg() (b []byte, err error)
- func (uc *UDPConn) ReadMsgFrom() ([]byte, Addr, error)
- func (uc *UDPConn) RemoteAddr() net.Addr
- func (uc *UDPConn) RemoteUDPAddr() *net.UDPAddr
- func (uc *UDPConn) Write(buf []byte) (n int, err error)
- func (uc *UDPConn) WriteMsgTo(buf []byte, addr Addr) error
- func (uc *UDPConn) WriteTo(p []byte, _ net.Addr) (n int, err error)
- type UDPListener
- type UDPMsgConn
- type UniTargetMsgConn
Constants ¶
const ( AtypIP4 byte = 1 AtypDomain byte = 2 AtypIP6 byte = 3 )
Atyp, for vless and vmess; 注意与 trojan和socks5的区别,trojan和socks5的相同含义的值是1,3,4
const ( TCP uint16 = 1 << iota UDP UNIX //unix domain socket Raw_socket KCP Quic //quic是一个横跨多个层的协议,这里也算一个,毕竟与kcp类似 )
const ( ReadvSingleBufLen = 4096 DefaultReadvOption = true )
const (
MaxUDP_packetLen = 64 * 1024 // 关于 udp包数据长度,可参考 https://cloud.tencent.com/developer/article/1021196
)
const SystemCanSplice = runtime.GOARCH != "wasm" && runtime.GOOS != "windows"
Variables ¶
var ( ErrMachineCantConnectToIpv6 = errors.New("ErrMachineCanConnectToIpv6") ErrTimeout = errors.New("timeout") )
var ErrRecursion = errors.New("multiple recursion not allowed")
var (
GeoipFileName string
)
var GeositeListMap = make(map[string]*GeositeList)
var ( //udp不能无限监听, 否则每一个udp申请都对应打开了一个本地udp端口,一直监听的话时间一长,就会导致 too many open files // 因为实际上udp在网页代理中主要用于dns请求, 所以不妨设的小一点。 // 放心,只要能持续不断地从远程服务器收到数据, 建立的udp连接就会持续地更新Deadline 而续命一段时间. UDP_timeout = time.Minute * 3 )
var ( // 是否会在转发过程中使用readv UseReadv bool )
Functions ¶
func ATypeToSocks5Standard ¶
默认netLayer的 AType (AtypIP4,AtypIP6,AtypDomain) 遵循v2ray标准的定义; 如果需要符合 socks5/trojan标准, 需要用本函数转换一下。 即从 123 转换到 134
func CanSpliceDirectly ¶
这里认为能 splice 或 sendfile的 都算,具体可参考go标准代码的实现, 总之就是tcp和 unix domain socket 可以. 若不是基本Conn,则会试图转换为Splicer并获取底层Conn
func CanSpliceEventually ¶
func ClassicCopy ¶
拷贝自 io.CopyBuffer。 因为原始的 CopyBuffer会又调用ReadFrom, 如果splice调用的话会产生无限递归。
这里删掉了ReadFrom, 直接进行经典拷贝
func DNSQuery ¶
func DNSQuery(domain string, dns_type uint16, conn *dns.Conn, theMux *sync.Mutex, recursionCount int) (net.IP, error)
domain必须是 dns.Fqdn 函数 包过的, 本函数不检查是否包过。如果不包过就传入,会报错。 dns_type 为 miekg/dns 包中定义的类型, 如 TypeA, TypeAAAA, TypeCNAME. conn是一个建立好的 dns.Conn, 必须非空, 本函数不检查. theMux是与 conn相匹配的mutex, 这是为了防止同时有多个请求导致无法对口;内部若判断为nil,会主动使用一个全局mux. recursionCount 使用者统一填0 即可,用于内部 遇到cname时进一步查询时防止无限递归.
如果从conn中Read后成功返回, 则可能返回如下几种错误 os.ErrNotExist (表示查无此记录), dns.ErrRcode (表示dns返回的 Rcode 不是 dns.RcodeSuccess), ErrRecursion, 如果不是这三个error, 那就是 从 该 conn 读取数据时出错了.
func DialDnsAddr ¶
建立一个与dns服务器连接, 可为纯udp dns or DoT. if DoT, 则要求 addr.Network == "tls", 如果是纯udp的,要求 addr.IsUDP() == true
func DownloadCommunity_DomainListFiles ¶
func DownloadCommunity_DomainListFiles(proxyurl string)
DownloadCommunity_DomainListFiles 从 v2fly/domain-list-community 下载数据文件, 并放到 geosite文件夹中。 如果已存在geosite文件夹,return immediately.
该函数适用于系统中没有git的情况, 如果有git我们直接 git clone就行了,而且还能不断pull进行滚动更新
func GetIP_ISO_byReader ¶
返回 iso 3166 字符串, 见 https://dev.maxmind.com/geoip/legacy/codes?lang=en ,大写,两字节
func GetRandLocalAddr ¶
func GetRandLocalPrivateAddr ¶
func HasEmbedGeoip ¶
func HasEmbedGeoip() bool
func HasFullOrSubDomain ¶
func HasFullOrSubDomain(domain string, ds DomainHaser) bool
会以点号分裂domain判断每一个子域名是否被包含,最终会试图匹配整个字符串.
func HasIpv6Interface ¶
func HasIpv6Interface() bool
func IsBasicConn ¶
func IsBasicConn(r interface{}) bool
net.IPConn, net.TCPConn, net.UDPConn, net.UnixConn
func IsConnGoodForReadv ¶
if r!=0, then it means c can be used in readv. 1 means syscall.RawConn, 2 means utils.MultiReader
func IsDomainInsideGeosite ¶
func Is_DNSQuery_returnType_ReadErr ¶
判断 DNSQuery 返回的错误 是否是 Read底层连接 的错误
func Is_DNSQuery_returnType_ReadFatalErr ¶
筛除掉 Is_DNSQuery_returnType_ReadErr 时,err 为 net.Error.Timeout() 的情况
func ListenAndAccept ¶
func ListenAndAccept(network, addr string, sockopt *Sockopt, acceptFunc func(net.Conn)) (listener net.Listener, err error)
ListenAndAccept 试图监听 tcp, udp 和 unix domain socket 这三种传输层协议.
非阻塞,在自己的goroutine中监听.
func LoadGeositeFiles ¶
func LoadGeositeFiles() (err error)
从 geosite/data 文件夹中读取所有文件并加载到 GeositeListMap 中.
该 geosite/data 就是 github.com/v2fly/domain-list-community 项目的 data文件夹.
func LoadMaxmindGeoipFile ¶
func LoadMaxmindGeoipFile(fn string)
将一个外部的文件加载为我们默认的 geoip文件;若fn=="",则会自动使用 GeoipFileName 的值
func LoadRulesForRoutePolicy ¶
func LoadRulesForRoutePolicy(rules []*RuleConf, policy *RoutePolicy)
func ParseStrToAddr ¶
ParseAddr 分析字符串,并按照特定方式返回 地址类型 atyp,地址数据 addr []byte,以及端口号,
如果解析出的地址是ip,则 addr返回 net.IP; 如果解析出的地址是 域名,则第一字节为域名总长度, 剩余字节为域名内容
func RandPort ¶
if mustValid is true, a valid port is assured. isudp is used to determine whether you want to use udp
func RandPortStr ¶
func RandPort_andStr ¶
func ReadBuffersFrom ¶
func ReadBuffersFrom(c io.Reader, rawReadConn syscall.RawConn, mr utils.MultiReader) (buffers [][]byte, err error)
依次试图使用 readv、ReadBuffers 以及 原始 Read 读取数据
func Relay ¶
func Relay(realTargetAddr *Addr, rc, lc io.ReadWriteCloser, downloadByteCount, uploadByteCount *uint64) int64
从 rc 读取 写入到 lc ,并同时从 lc 读取写入 rc. 阻塞. rc是指 remoteConn, lc 是指localConn; 一般lc由自己监听的Accept产生, rc 由自己拨号产生. UseReadv==true 时 内部使用 TryCopy 进行拷贝, 会自动优选 splice,readv,不行则使用经典拷贝.
拷贝完成后会主动关闭双方连接. 返回从 rc读取到的总字节长度(即下载流量). 如果 downloadByteCount, uploadByteCount 给出, 则会 分别原子更新 上传和下载的总字节数
func RelayUDP_separate ¶
func RelayUDP_separate(rc, lc MsgConn, firstAddr *Addr, downloadByteCount, uploadByteCount *uint64, dialfunc func(raddr Addr) MsgConn) uint64
RelayUDP_separate 对 lc 读到的每一个新raddr地址 都新拨号一个rc. 这样就避开了经典的udp多路复用转发的效率低下问题. separate含义就是 【分离信道】。随着时间推移, 会创建多个rc。 分离信道法还有个好处,就是fullcone时,不必一直保留某连接, 如果超时/读取错误, 可以断开单个rc连接, 释放占用的端口资源. 不过分离信道只能用于代理,不能用于 direct, 因为direct为了实现fullcone, 对所有rc连接都用的同一个udp端口。 阻塞. 返回从 rc 下载的总字节数. 拷贝完成后自动关闭双端连接.
func SetSockOptForListener ¶
func SetSockOptForListener(tcplistener ListenerWithFile, sockopt *Sockopt, isudp bool, isipv6 bool)
func StrToTransportProtocol ¶
func TryCopy ¶
TryCopy 尝试 循环 从 readConn 读取数据并写入 writeConn, 直到错误发生。 会接连尝试 splice、循环readv 以及 原始Copy方法。如果 UseReadv 的值为false,则不会使用readv。
func TryCopyOnce ¶
类似TryCopy,但是只会读写一次; 因为只读写一次,所以没办法splice
func TryReadFrom_withSplice ¶
func TryReadFrom_withSplice(classicWriter io.Writer, maySpliceConn net.Conn, r io.Reader, canDirectFunc func() bool) (written int64, err error)
从r读取数据,写入 maySpliceConn / classicWriter, 在条件合适时会使用splice进行加速。 本函数主要应用于裸奔时,一端是socks5/直连,另一端是vless/vless+ws的情况, 因为vless等协议就算裸奔也是要处理一下数据头等情况的, 所以需要进行处理才可裸奔.
注意,splice只有在 maySpliceConn【本身是】/【变成】 basicConn, 且 r 也是 basicConn时,才会发生。 如果r本身就不是 basicConn,则调用本函数没有意义, 因为既然拿不到basicConn那就不是裸奔,也就不可能splice。
func UDPAddr_v4_to_Bytes ¶
func WritePROXYprotocol ¶ added in v1.2.0
PROXY protocol。 Reference: http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
xver 必须是 1或者2, 本函数若遇到其他值会直接panic。wlc 为监听的连接,wrc为转发的连接。
Types ¶
type Addr ¶
type Addr struct { Network string Name string // domain name, or unix domain socket 的 文件路径 IP net.IP Port int }
Addr represents a address that you want to access by proxy. Either Name or IP is used exclusively. Addr完整地表示了一个 传输层的目标,同时用 Network 字段 来记录网络层协议名 Addr 还可以用Dial 方法直接进行拨号
func NewAddrByHostPort ¶
hostPortStr格式 必须为 host:port,本函数不对此检查
func NewAddrByURL ¶
如 tcp://127.0.0.1:443 , tcp://google.com:443 ; 不支持unix domain socket, 因为它是文件路径, / 还需要转义,太麻烦;不是我们代码麻烦, 而是怕用户嫌麻烦
func NewAddrFromAny ¶
会根据thing的类型 生成实际addr; 可以为数字端口, 或 类似tcp://ip:port的url, 或ip:port字符串,或一个 文件路径(unix domain socket), or *net.TCPAddr / *net.UDPAddr / net.Addr
func NewAddrFromTCPAddr ¶ added in v1.2.0
func NewAddrFromUDPAddr ¶
func (*Addr) AddressBytes ¶
如果a的ip不为空,则会返回 AtypIP4 或 AtypIP6, 否则会返回 AtypDomain Return address bytes and type 如果atyp类型是 域名,则 第一字节为该域名的总长度, 其余字节为域名内容。 如果类型是ip,则会拷贝出该ip的数据的副本。
func (*Addr) GetHashable ¶
func (a *Addr) GetHashable() (ha HashableAddr)
func (*Addr) GetNetIPAddr ¶
func (Addr) ListenUDP_withOpt ¶
func (a Addr) ListenUDP_withOpt(sockopt *Sockopt) (net.PacketConn, error)
type ConnWithFile ¶
net.UnixConn, net.UDPConn, net.TCPConn, net.IPConn
type DNSMachine ¶
type DNSMachine struct { TypeStrategy int64 // 0, 4, 6, 40, 60 SpecialIPPollicy map[string][]netip.Addr SpecialServerPollicy map[string]string //domain -> dns server name // contains filtered or unexported fields }
dns machine维持与多个dns服务器的连接(最好是udp这种无状态的),并可以发起dns请求。 会缓存dns记录; 该设施是一个状态机, 所以叫 DNSMachine SpecialIPPollicy 用于指定特殊的 域名-ip映射,这样遇到这种域名时,不经过dns查询,直接返回预设ip SpecialServerPollicy 用于为特殊的 域名指定特殊的 dns服务器,这样遇到这种域名时,会通过该特定服务器查询
func LoadDnsMachine ¶
func LoadDnsMachine(conf *DnsConf) *DNSMachine
func (*DNSMachine) AddNewServer ¶
func (dm *DNSMachine) AddNewServer(name string, addr *Addr) error
添加一个 特定的DNS服务器 , name为该dns服务器的名称. 若第一次调用, 则会设为 dm.DefaultConn
func (*DNSMachine) QueryType ¶
func (dm *DNSMachine) QueryType(domain string, dns_type uint16) (ip net.IP)
传入的domain必须是不带尾缀点号的domain, 即没有包过 Fqdn
func (*DNSMachine) SetDefaultConn ¶
func (dm *DNSMachine) SetDefaultConn(c net.Conn, addr *Addr)
type DnsConf ¶
type DnsConf struct { Strategy int64 `toml:"strategy"` //0表示默认(和4含义相同), 4表示先查ip4后查ip6, 6表示先查6后查4; 40表示只查ipv4, 60 表示只查ipv6 Hosts map[string]any `toml:"hosts"` //用于强制指定哪些域名会被解析为哪些具体的ip;可以为一个ip字符串,or a []string, 内可以是A,AAAA或CNAME Servers []any `toml:"servers"` //可以为一个地址url字符串,or a SpecialDnsServerConf; 如果第一个元素是url字符串形式,则此第一个元素将会被用作默认dns服务器 }
type DnsConn ¶
type DnsConn struct { *dns.Conn Name string //我们这里惯例,直接使用配置文件中配置的url字符串作为Name // contains filtered or unexported fields }
给 miekg/dns.Conn 加一个互斥锁, 可保证同一时间仅有一个请求发生 这样就不会造成并发时的混乱
type EasyDeadline ¶ added in v1.2.0
type EasyDeadline struct {
// contains filtered or unexported fields
}
implements NetDeadliner. Must call InitEasyDeadline before use. Can be embed to a struct to make it have SetWriteDeadline, SetReadDeadline and SetDeadline method. And use select and ReadTimeoutChan or WriteTimeoutChan when reading or writing.
func (*EasyDeadline) InitEasyDeadline ¶ added in v1.2.0
func (ed *EasyDeadline) InitEasyDeadline()
func (*EasyDeadline) ReadTimeoutChan ¶ added in v1.2.0
func (ed *EasyDeadline) ReadTimeoutChan() chan struct{}
try receive this to see if read timeout happens
func (*EasyDeadline) SetDeadline ¶ added in v1.2.0
func (ed *EasyDeadline) SetDeadline(t time.Time) error
func (*EasyDeadline) SetReadDeadline ¶ added in v1.2.0
func (ed *EasyDeadline) SetReadDeadline(t time.Time) error
func (*EasyDeadline) SetWriteDeadline ¶ added in v1.2.0
func (ed *EasyDeadline) SetWriteDeadline(t time.Time) error
func (*EasyDeadline) WriteTimeoutChan ¶ added in v1.2.0
func (ed *EasyDeadline) WriteTimeoutChan() chan struct{}
try receive this to see if write timeout happens
type EasyNetAddresser ¶ added in v1.2.0
实现 NetAddresser
func (*EasyNetAddresser) LocalAddr ¶ added in v1.2.0
func (iw *EasyNetAddresser) LocalAddr() net.Addr
func (*EasyNetAddresser) RemoteAddr ¶ added in v1.2.0
func (iw *EasyNetAddresser) RemoteAddr() net.Addr
type GeositeAttr ¶
type GeositeDomain ¶
type GeositeDomain struct { Type string //domain, regexp, full Value string Attrs []GeositeAttr }
type GeositeList ¶
type GeositeList struct { //Name实际上就是v2fly Community的protobuf里的 CountryCode. Geosite本意是给一个国家的域名分类, 但是实际上功能越来越多,绝大部分Name现在实际上都是网站名称,只有 CN, GEOLOCATION-CN 的是国家名. 其它的还有很多分类名称,比如 CATEGORY-ECOMMERCE // 在parse过后,可以发现所有的Name都被转换成了大写字符的形式 Name string FullDomains map[string]GeositeDomain Domains map[string]GeositeDomain RegexDomains []*regexp.Regexp }
GeositeList 用于内存中匹配使用
type GeositeRawList ¶
type GeositeRawList struct { Name string Domains []GeositeDomain }
GeositeRawList 用于序列化
func LoadGeositeFile ¶
func LoadGeositeFile(path string) (*GeositeRawList, error)
func ParseGeositeList ¶
func ParseGeositeList(list *GeositeRawList, ref map[string]*GeositeRawList) (*GeositeRawList, error)
这里从v2fly改动了一些. 因为发现 Inclusion最终不会被用到
func (*GeositeRawList) ToGeositeList ¶
func (grl *GeositeRawList) ToGeositeList() (gl *GeositeList)
type HashableAddr ¶
type IOWrapper ¶ added in v1.2.0
type IOWrapper struct { EasyNetAddresser EasyDeadline io.Reader //不可为nil io.Writer //不可为nil io.Closer FirstWriteChan chan struct{} //用于确保先Write然后再Read,可为nil CloseChan chan struct{} //可为nil,用于接收关闭信号 // contains filtered or unexported fields }
一个自定义的由多个组件组成的实现 net.Conn 的结构
type ListenerWithFile ¶
net.TCPListener, net.UnixListener
type MapDomainHaser ¶
func (MapDomainHaser) HasDomain ¶
func (mdh MapDomainHaser) HasDomain(d string) bool
type MapGeositeDomainHaser ¶
type MapGeositeDomainHaser map[string]GeositeDomain
func (MapGeositeDomainHaser) HasDomain ¶
func (mdh MapGeositeDomainHaser) HasDomain(d string) bool
type MsgConn ¶
type MsgConn interface { ReadMsgFrom() ([]byte, Addr, error) WriteMsgTo([]byte, Addr) error CloseConnWithRaddr(raddr Addr) error //关闭特定连接 Close() error //关闭所有连接 Fullcone() bool //若Fullcone, 则在转发因另一端关闭而结束后, RelayUDP函数不会Close它. }
MsgConn一般用于 udp. 是一种类似 net.PacketConn 的包装. 实现 MsgConn接口 的类型 可以被用于 RelayUDP 进行转发。
ReadMsgFrom直接返回数据, 这样可以尽量避免多次数据拷贝。
使用Addr,是因为有可能请求地址是个域名,而不是ip; 而且通过Addr, MsgConn实际上有可能支持通用的情况, 即可以用于 客户端 一会 请求tcp,一会又请求udp,一会又请求什么其它网络层 这种奇葩情况.
type NetAddresser ¶ added in v1.2.0
part of net.Conn
type NetDeadliner ¶ added in v1.2.0
type NetDeadliner interface { SetDeadline(t time.Time) error // SetReadDeadline sets the deadline for future Read calls // and any currently-blocked Read call. // A zero value for t means Read will not time out. SetReadDeadline(t time.Time) error // SetWriteDeadline sets the deadline for future Write calls // and any currently-blocked Write call. // Even if write times out, it may return n > 0, indicating that // some of the data was successfully written. // A zero value for t means Write will not time out. SetWriteDeadline(t time.Time) error }
part of net.Conn
type PipeDeadline ¶
type PipeDeadline struct {
// contains filtered or unexported fields
}
PipeDeadline is an abstraction for handling timeouts. copied from golang standard package net
func MakePipeDeadline ¶
func MakePipeDeadline() PipeDeadline
func (*PipeDeadline) Set ¶
func (d *PipeDeadline) Set(t time.Time)
set sets the point in time when the deadline will time out. A timeout event is signaled by closing the channel returned by waiter. Once a timeout has occurred, the deadline can be refreshed by specifying a t value in the future.
A zero value for t prevents timeout.
func (*PipeDeadline) Wait ¶
func (d *PipeDeadline) Wait() chan struct{}
wait returns a channel that is closed when the deadline is exceeded.
type ReadWrapper ¶
选择性从 OptionalReader读取, 直到 RemainFirstBufLen 小于等于0 为止;
func (*ReadWrapper) WriteBuffers ¶
func (rw *ReadWrapper) WriteBuffers(buffers [][]byte) (int64, error)
type RoutePolicy ¶
type RoutePolicy struct {
List []*RouteSet
}
一个完整的 所有RouteSet的列表,进行路由时,直接遍历即可。 所谓的路由实际上就是分流。
func NewRoutePolicy ¶
func NewRoutePolicy() *RoutePolicy
func (*RoutePolicy) AddRouteSet ¶
func (rp *RoutePolicy) AddRouteSet(rs *RouteSet)
func (*RoutePolicy) GetOutTag ¶
func (rp *RoutePolicy) GetOutTag(td *TargetDescription) string
返回一个 proxy.Client 的 tag。 默认情况下,始终具有direct这个tag以及 proxy这个tag,无需用户额外在配置文件中指定。 默认如果不匹配任何值的话,就会流向 "proxy" tag,也就是客户设置的 remoteClient的值。
type RouteSet ¶
type RouteSet struct { //网络层 NetRanger cidranger.Ranger //一个范围 IPs map[netip.Addr]bool //一个确定值 //Match 匹配任意字符串 //Domains匹配子域名,当此域名是目标域名或其子域名时,该规则生效 //Full只匹配完整域名 Domains, Full, InTags, Countries map[string]bool // Countries 使用 ISO 3166 字符串 作为key //Regex是正则匹配域名 Regex []*regexp.Regexp Match, Geosites []string //传输层 AllowedTransportLayerProtocols uint16 OutTag string //目标 OutTags []string //目标列表 }
Set 是 “集合” 的意思, 是一组相同类型的数据放到一起。
这里的相同点,就是它们同属于 将发往一个方向, 即同属一个路由策略。
任意一个参数匹配后,都将发往相同的方向,由该方向OutTag 指定。 RouteSet 只负责把一些属性相同的 “网络层/传输层 特征” 放到一起。
这里主要通过 ip,域名 和 inTag 进行分流。域名的匹配又分多种方式。
func LoadRuleForRouteSet ¶
func NewFullRouteSet ¶
func NewFullRouteSet() *RouteSet
func NewRouteSetForMyCountry ¶
func (*RouteSet) IsAddrNetworkAllowed ¶
func (*RouteSet) IsIn ¶
func (sg *RouteSet) IsIn(td *TargetDescription) bool
func (*RouteSet) IsTCPAllowed ¶
func (*RouteSet) IsTransportProtocolAllowed ¶
func (*RouteSet) IsUDPAllowed ¶
type Sockopt ¶
type Sockopt struct { TProxy bool `toml:"tproxy"` Somark int `toml:"mark"` Device string `toml:"device"` }
用于 listen和 dial 配置一些底层参数.
type SpecialDnsServerConf ¶
type TargetDescription ¶
TargetDescription 可以完整地描述一个网络层/传输层上的一个特定目标, 一般来说,一个具体的监听配置就会分配一个tag
type UDPAddrData ¶
type UDPConn ¶
type UDPConn struct { EasyDeadline // contains filtered or unexported fields }
UDPConn 将一个udp连接包装成一个 向单一目标发送数据的 连接。 UDPConn 主要服务于 UDPListener。如果有udp客户端需求, 最好使用 UDPMsgConn, 以更好地支持 fullcone或symmetric.
UDPConn 也有能力接收来自其它目标的数据,以及向其它目标发送数据。然而, 本结构并没有记录链接端口, 所以无法实现 symmetric. 如果用 DialUDP 函数初始化的 UDPConn, 则无法使用 WriteMsgTo方法向其它地址发消息.
UDPConn 实现了 net.Conn , net.PacketConn , MsgConn
func DialUDP ¶
我们这里为了保证udp连接不会一直滞留导致 too many open files的情况, 主动设置了 内层udp连接的 read的 timeout为 UDP_timeout。 你依然可以设置 DialUDP 所返回的 net.Conn 的 Deadline, 这属于外层的Deadline, 不会影响底层 udp所强制设置的 deadline.
func NewUDPConn ¶
如果isClient为true,则本函数返回后,必须要调用一次 Write,才能在Read读到数据. 这是udp的原理所决定的。 在客户端没有Write之前,该udp连接实际上根本没有被建立, Read也就不可能/不应该 读到任何东西.
func (*UDPConn) CloseConnWithRaddr ¶
func (*UDPConn) CloseMsgChan ¶
func (uc *UDPConn) CloseMsgChan()
func (*UDPConn) GetReadChan ¶
func (uc *UDPConn) GetReadChan() chan UDPAddrData
func (*UDPConn) RemoteAddr ¶
func (*UDPConn) RemoteUDPAddr ¶
type UDPListener ¶
type UDPListener struct {
// contains filtered or unexported fields
}
UDPListener 实现了 net.Listener. UDPListener 监听 UDPAddr,不断读取请求,对新远程地址 创建 新UDPConn并提供给 Accept;
记录遇到过的所有地址 以及 对应的 UDPConn.
将读到的信息缓存到 UDPConn 的 chan 中,让它能在Read时读到.
UDPListener can also dial a remote host by calling NewConn.
func NewUDPListener ¶
func NewUDPListener(laddr *net.UDPAddr) (*UDPListener, error)
NewUDPListener 返回一个 *UDPListener, 该Listener实现了 net.Listener
func NewUDPListenerConn ¶
func NewUDPListenerConn(conn *net.UDPConn) (*UDPListener, error)
func (*UDPListener) Addr ¶
func (ul *UDPListener) Addr() net.Addr
func (*UDPListener) Close ¶
func (ul *UDPListener) Close() error
Once closed, it cannot be used again. it calls ul.CloseClients()
func (*UDPListener) DeleteConn ¶
func (ul *UDPListener) DeleteConn(addrport netip.AddrPort)
type UDPMsgConn ¶
type UDPMsgConn struct { IsServer bool // contains filtered or unexported fields }
UDPMsgConn 实现 MsgConn。 可满足fullcone/symmetric. 在proxy/direct 被用到.
func NewUDPMsgConn ¶
NewUDPMsgConn 创建一个 UDPMsgConn 并使用传入的 laddr 监听udp; 若未给出laddr, 将使用一个随机可用的端口监听. 如果是普通的单目标的客户端,用 (nil,false,false) 即可.
满足fullcone/symmetric, 由 fullcone 的值决定.
func (*UDPMsgConn) Close ¶
func (u *UDPMsgConn) Close() error
func (*UDPMsgConn) CloseConnWithRaddr ¶
func (u *UDPMsgConn) CloseConnWithRaddr(raddr Addr) error
func (*UDPMsgConn) Fullcone ¶
func (u *UDPMsgConn) Fullcone() bool
func (*UDPMsgConn) ReadMsgFrom ¶
func (u *UDPMsgConn) ReadMsgFrom() ([]byte, Addr, error)
func (*UDPMsgConn) WriteMsgTo ¶
func (u *UDPMsgConn) WriteMsgTo(bs []byte, raddr Addr) error
type UniTargetMsgConn ¶
symmetric, proxy/dokodemo 有用到. 实现 MsgConn
func (UniTargetMsgConn) Close ¶
func (u UniTargetMsgConn) Close() error
func (UniTargetMsgConn) CloseConnWithRaddr ¶
func (u UniTargetMsgConn) CloseConnWithRaddr(raddr Addr) error
func (UniTargetMsgConn) Fullcone ¶
func (u UniTargetMsgConn) Fullcone() bool
func (UniTargetMsgConn) ReadMsgFrom ¶
func (u UniTargetMsgConn) ReadMsgFrom() ([]byte, Addr, error)
func (UniTargetMsgConn) WriteMsgTo ¶
func (u UniTargetMsgConn) WriteMsgTo(bs []byte, _ Addr) error