netLayer

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: 38 Imported by: 0

Documentation

Overview

Package netLayer contains definitions in network layer AND transport layer.

本包有 geoip, geosite, route, udp, readv, splice, relay, dns, listen/dial/sockopt, proxy protocol 等相关功能。

以后如果要添加 kcp 或 raw socket 等底层协议时,也要在此包 或子包里实现.

Tags

本包提供 embed_geoip 这个 build tag。

若给出 embed_geoip,则会尝试内嵌 GeoLite2-Country.mmdb.tgz 文件;默认不内嵌。

Index

Constants

View Source
const (
	AtypIP4    byte = 1
	AtypDomain byte = 2
	AtypIP6    byte = 3
)

Atyp, for vless and vmess; 注意与 trojan和socks5的区别,trojan和socks5的相同含义的值是1,3,4

View Source
const (
	// Transport Layer Protocols, 使用uint16 mask,所以最多支持16种
	TCP uint16 = 1 << iota
	UDP
	Dual //use both tcp and udp
	UNIX //unix domain socket
	IP
	Raw_socket
	KCP
	Quic //quic是一个横跨多个层的协议,这里也算一个,毕竟与kcp类似

)
View Source
const (
	MaxUDP_packetLen = 64 * 1024 // 关于 udp包数据长度,可参考 https://cloud.tencent.com/developer/article/1021196

	DefaultUDP_timeout          = time.Minute * 3
	DefaultUDP_fullcone_timeout = time.Minute * 30
)
View Source
const DefaultCommonReadTimeout = time.Second * 4

default recommended handshake read timeout

View Source
const (
	DefaultDialTimeout = time.Second * 8 //作为对照,v2ray默认是16秒
)
View Source
const DefaultGeositeFolder = "geosite/data"
View Source
const (
	DefaultReadvOption = true
)
View Source
const DualNetworkName = "dual"
View Source
const MMDB_DownloadLink = "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb"
View Source
const UnknownNetwork = 0

Variables

View Source
var (
	//你可以通过向这个map插入 自定义函数的方式 来拓展 vs的 拨号功能, 可以拨号 其它 net包无法拨号的 network
	CustomDialerMap = make(map[string]func(address string, timeout time.Duration) (net.Conn, error))

	DialTimeout time.Duration = DefaultDialTimeout
)
View Source
var (
	GeositeListMap = make(map[string]*GeositeList)
	GeositeFolder  = DefaultGeositeFolder
)
View Source
var (
	//udp不能无限监听, 否则每一个udp申请都对应打开了一个本地udp端口,一直监听的话时间一长,就会导致 too many open files
	// 因为实际上udp在网页代理中主要用于dns请求, 所以不妨设的小一点。
	// 放心,只要能持续不断地从远程服务器收到数据, 建立的udp连接就会持续地更新Deadline 而续命一段时间.
	UDP_timeout = DefaultUDP_timeout

	/*
		fullcone时,wlc 监听本地随机udp端口,而且时刻准备接收 其它端口发来的信息,所以 某个 wrc 被关闭后,wlc 不能随意被关闭;相反,如果 wlc的读取 或写入 遇到 错误而推出后,可以关闭 wrc 和 wlc。

		又因为 vless v1 普通模式 和 trojan 是 在多路复用的 一个通道上 传输 udp的,所以 就算 wrc 发生错误,wlc依然不应该被关闭,否则会影响到 其它流量的传输;

		还有就是,因为 udp 是 无状态的,所以 基本上很难遇到 udp读取失败的情况,一般都是会一直卡住,所以确实需要我们设置超时
	*/
	UDP_fullcone_timeout = DefaultUDP_fullcone_timeout
)
View Source
var CommonReadTimeout = DefaultCommonReadTimeout
View Source
var (
	//你可以通过向这个map插入 自定义函数的方式 来拓展 vs的 监听功能, 可以监听 其它 net包无法监听的 network
	CustomListenerMap = make(map[string]func(address string) (net.Listener, error))
)
View Source
var (
	ErrMachineCantConnectToIpv6 = errors.New("ErrMachineCanConnectToIpv6")
)
View Source
var ErrRecursion = errors.New("multiple recursion not allowed")
View Source
var (
	ErrTimeout = errors.New("timeout")
)
View Source
var (
	GeoipFileName string
)
View Source
var GetSystemDNS = func() (result []string) {
	if ce := utils.CanLogErr("GetSystemDNS: not implemented"); ce != nil {
		ce.Write(zap.String("platform", runtime.GOOS))
	}
	return
}
View Source
var GetSystemProxyState = func(isSocks5 bool) (ok, enabled bool, addr, port string) {
	if ce := utils.CanLogErr("GetSystemProxyState: not implemented"); ce != nil {
		ce.Write(zap.String("platform", runtime.GOOS))
	}
	return
}
View Source
var SetSystemDNS = func(dns string) {
	if ce := utils.CanLogErr("SetSystemDNS: not implemented"); ce != nil {
		ce.Write(zap.String("platform", runtime.GOOS))
	}

}
View Source
var SystemCanSplice = runtime.GOARCH != "wasm" && runtime.GOOS != "windows"
View Source
var ToggleSystemProxy = func(isSocks5 bool, addr, port string, enable bool) {
	if ce := utils.CanLogErr("ToggleSystemProxy: not implemented"); ce != nil {
		ce.Write(zap.String("platform", runtime.GOOS))
	}

}
View Source
var (

	// 是否会在转发过程中使用readv
	UseReadv bool
)

Functions

func ATypeToSocks5Standard

func ATypeToSocks5Standard(atype byte) byte

默认netLayer的 AType (AtypIP4,AtypIP6,AtypDomain) 遵循v2ray标准的定义; 如果需要符合 socks5/trojan标准, 需要用本函数转换一下。 即从 123 转换到 134

func CanRSplice added in v1.2.4

func CanRSplice(r io.Reader) bool

tcp, unix

func CanSpliceDirectly

func CanSpliceDirectly(w io.Writer, r io.Reader) bool

这里认为能 splice 或 sendfile的 都算,具体可参考go标准代码的实现, 之前以为tcp和 unix domain socket 可以,仔细观察才发现,只有tcp可以。unix只是可以接受tcp的splice,但是不能主动进行splice。 就是说,tcp可以从tcp或者 stream oriented unix 来读取数据,用 splice 来写入tcp。但是unix不能被splice写入。

func CanSpliceEventually

func CanSpliceEventually(r any) bool

func CanWEverSplice added in v1.2.5

func CanWEverSplice(writeConn io.Writer) (wCanSplice bool)

func CanWSplice added in v1.2.4

func CanWSplice(w io.Writer) bool

tcp

func DNSQuery

func DNSQuery(domain string, dns_type uint16, conn *dns.Conn, theMux *sync.Mutex, recursionCount int) (ip net.IP, ttl uint32, err 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

func DialDnsAddr(addr *Addr) (conn net.Conn, err error)

建立一个与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.

该函数适用于系统中没有git的情况, 如果有git我们直接 git clone就行了,而且还能不断pull进行滚动更新

func GetDeviceNameIndex added in v1.2.5

func GetDeviceNameIndex(idx int) string

func GetGateway added in v1.2.5

func GetGateway() (ip net.IP, ifName string, err error)

https://github.com/jackpal/gateway/blob/master/gateway_parsers.go

func GetIP_ISO

func GetIP_ISO(ip net.IP) string

使用默认的 geoip文件,会调用 GetIP_ISO_byReader

func GetIP_ISO_byReader

func GetIP_ISO_byReader(db *maxminddb.Reader, ip net.IP) string

返回 iso 3166 字符串 ,大写,两字节, 见 https://dev.maxmind.com/geoip/legacy/codes?lang=en

func GetRandLocalAddr

func GetRandLocalAddr(mustValid, isudp bool) string

func GetRandLocalPrivateAddr

func GetRandLocalPrivateAddr(mustValid, isudp bool) string

func GetRawConn

func GetRawConn(reader io.Reader) syscall.RawConn

func HasEmbedGeoip

func HasEmbedGeoip() bool

func HasFullOrSubDomain

func HasFullOrSubDomain(domain string, ds DomainHaser) bool

会以点号分裂domain判断每一个子域名是否被包含,最终会试图匹配整个字符串.

func HasGeositeFolder added in v1.2.4

func HasGeositeFolder() bool

func HasIpv6Interface

func HasIpv6Interface() bool

func IsBasicConn

func IsBasicConn(r interface{}) bool

net.IPConn, net.TCPConn, net.UDPConn, net.UnixConn

func IsConnGoodForReadv

func IsConnGoodForReadv(c net.Conn) (r int, rawReadConn syscall.RawConn)

if r!=0, then it means c can be used in readv. -1 means syscall.RawConn,1 means utils.BuffersReader, 2 means utils.Readver

func IsDomainInsideGeosite

func IsDomainInsideGeosite(geositeName string, domain string) bool

func IsStrUDP_network

func IsStrUDP_network(s string) bool

"udp", "udp4", "udp6"

func IsTCP added in v1.2.4

func IsTCP(r any) *net.TCPConn

func IsUnix added in v1.2.5

func IsUnix(r any) *net.UnixConn

func Is_DNSQuery_returnType_ReadErr

func Is_DNSQuery_returnType_ReadErr(err error) bool

判断 DNSQuery 返回的错误 是否是 Read底层连接 的错误

func Is_DNSQuery_returnType_ReadFatalErr

func Is_DNSQuery_returnType_ReadFatalErr(err error) bool

筛除掉 Is_DNSQuery_returnType_ReadErr 时,err 为 net.Error.Timeout() 的情况

func ListenAndAccept

func ListenAndAccept(network, addr string, sockopt *Sockopt, xver int, acceptFunc func(net.Conn)) (listener net.Listener, err error)

ListenAndAccept 试图监听 tcp, udp 和 unix domain socket 这三种传输层协议.

非阻塞,在自己的goroutine中监听.

func LoadGeositeFiles

func LoadGeositeFiles() (err error)

从 GeositeFolder (geosite/data) 文件夹中读取所有文件并加载到 GeositeListMap 中.

该 geosite/data 就是 github.com/v2fly/domain-list-community 项目的 data文件夹.

todo: 直接加载tar, 而不是分别加载碎片文件. 实现加载tar后,就可以把geosite内嵌到vs中。

func LoadMaxmindGeoipFile

func LoadMaxmindGeoipFile(fn string)

将一个外部的文件加载为我们默认的 geoip文件;若fn=="",则会自动使用 GeoipFileName 的值

func NetworkHasNoPortField added in v1.2.5

func NetworkHasNoPortField(s string) bool

func ParseStrToAddr

func ParseStrToAddr(s string) (atyp byte, addr []byte, port_uint16 uint16, err error)

ParseAddr 分析字符串,并按照特定方式返回 地址类型 atyp,地址数据 addr []byte,以及端口号,

 如果解析出的地址是ip,则 addr返回 net.IP;
如果解析出的地址是 域名,则第一字节为域名总长度, 剩余字节为域名内容

func PersistConn added in v1.2.1

func PersistConn(c net.Conn)

c.SetDeadline(time.Time{})

func PersistRead added in v1.2.5

func PersistRead(c net.Conn)

func PersistWrite added in v1.2.5

func PersistWrite(c net.Conn)

func PrepareInterfaces added in v1.2.2

func PrepareInterfaces()

做一些网络层的资料准备工作, 可以优化本包其它函数的调用。

func PrintAllInterface added in v1.2.5

func PrintAllInterface(w io.Writer)

func RandPort

func RandPort(mustValid, isudp bool, depth int) (p int)

if mustValid is true, a valid port is assured. isudp is used to determine whether you want to use udp. depth 填0 即可,用于递归。

func RandPortStr

func RandPortStr(mustValid, isudp bool) string

func RandPortStr_safe added in v1.2.4

func RandPortStr_safe(mustValid, isudp bool) string

use a new seed each time called

func RandPort_andStr

func RandPort_andStr(mustValid, isudp bool) (int, string)

func Relay

func Relay(realTargetAddr *Addr, rc, lc io.ReadWriteCloser, identity uint32, downloadByteCount, uploadByteCount *uint64) int64

从 rc 读取 写入到 lc ,并同时从 lc 读取写入 rc. 阻塞. rc是指 remoteConn, lc 是指localConn; 一般lc由自己监听的Accept产生, rc 由自己拨号产生. UseReadv==true 时 内部使用 TryCopy 进行拷贝, 会自动优选 splice,readv,不行则使用经典拷贝.

拷贝完成后会主动关闭双方连接. 返回从 rc读取到的总字节长度(即下载流量). 如果 downloadByteCount, uploadByteCount 给出, 则会 分别原子更新 上传和下载的总字节数. identity 用于输出日志。

func RelayUDP

func RelayUDP(rc, lc MsgConn, downloadByteCount, uploadByteCount *uint64) uint64
阻塞. 返回从 rc 下载的总字节数. 拷贝完成后,如不为fullcone,则自动关闭双端连接.

若为fullcone,则 rc错误时,rc可以关闭,而 lc 则不可以随意关闭; 若lc错误时,则两端都可关闭

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 ReturnSpliceRead added in v1.2.5

func ReturnSpliceRead(c net.Conn) (bool, *net.TCPConn, *net.UnixConn)

func SetCommonReadTimeout added in v1.2.5

func SetCommonReadTimeout(c net.Conn) error

set read timeout after CommonReadTimeout

func SetCommonWriteTimeout added in v1.2.5

func SetCommonWriteTimeout(c net.Conn) error

暂时也使用 CommonReadTimeout

func SetSockOpt

func SetSockOpt(fd int, sockopt *Sockopt, isudp bool, isipv6 bool)

func SetSockOptForListener

func SetSockOptForListener(tcplistener ListenerWithFile, sockopt *Sockopt, isudp bool, isipv6 bool)

func StrToNetAddr added in v1.2.4

func StrToNetAddr(network, s string) (net.Addr, error)

func StrToTransportProtocol

func StrToTransportProtocol(s string) uint16

若字符串无法被解析为网络类型,则返回 UnknownNetwork

func TryCopy

func TryCopy(writeConn io.Writer, readConn io.Reader, id uint32) (allnum int64, err error)

TryCopy 尝试 循环 从 readConn 读取数据并写入 writeConn, 直到错误发生。 会接连尝试 splice、循环readv 以及 原始Copy方法。如果 UseReadv 的值为false,则不会使用readv。

identity只用于debug 日志输出.

func TryCopyOnce

func TryCopyOnce(writeConn io.Writer, readConn io.Reader) (allnum int64, err error)

类似TryCopy,但是只会读写一次; 因为只读写一次,所以没办法splice

func TryReadFrom_withSplice

func TryReadFrom_withSplice(classicWriter io.Writer, maySpliceW io.Writer, r io.Reader, canDirectFunc func() bool) (written int64, err error)

从r读取数据,写入 maySpliceConn / classicWriter, 在条件合适时会使用splice进行加速。

若maySpliceConn不是基本Conn,则会试图转换为Splicer并获取底层Conn. 本函数主要应用于裸奔时,一端是socks5/直连,另一端是vless/vless+ws的情况, 因为vless等协议就算裸奔也是要处理一下数据头等情况的, 所以需要进行处理才可裸奔.

注意,splice只有在 maySpliceConn【本身是】/【变成】 basicConn, 且 r 也是 basicConn时,才会发生。 如果r本身就不是 basicConn,则调用本函数没有意义, 因为既然拿不到basicConn那就不是裸奔,也就不可能splice。

func UDPAddr2AddrPort

func UDPAddr2AddrPort(ua *net.UDPAddr) netip.AddrPort

func UDPAddr_v4_to_Bytes

func UDPAddr_v4_to_Bytes(addr *net.UDPAddr) [6]byte

func WritePROXYprotocol added in v1.2.0

func WritePROXYprotocol(xver int, wlc NetAddresser, wrc io.Writer) (n int, err error)

PROXY protocol。 Reference: http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

xver 必须是 1或者2, 本函数若遇到其他值会直接panic。wlc 为监听的连接,wrc为转发的连接。 另外,本函数只支持tcp。proxy protocol的 v2 是支持 udp的,但是本函数不支持udp。

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 NewAddr

func NewAddr(addrStr string) (Addr, error)

addrStr格式一般为 host:port ;如果不含冒号,将直接认为该字符串是域名或文件名

func NewAddrByHostPort

func NewAddrByHostPort(hostPortStr string) (Addr, error)

hostPortStr格式 必须为 host:port,本函数不对此检查

func NewAddrByURL

func NewAddrByURL(addrStr string) (Addr, error)

如 tcp://127.0.0.1:443 , tcp://google.com:443 ; 不使用转义的方式, 不使用url包,直接用分割字符串的办法。 会把 [xxx] 格式的字符串当作 ipv6地址, 去掉中括号并试图解析

func NewAddrFromAny

func NewAddrFromAny(thing any) (addr Addr, err error)

会根据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 NewAddrFromTCPAddr(addr *net.TCPAddr) Addr

func NewAddrFromUDPAddr

func NewAddrFromUDPAddr(addr *net.UDPAddr) Addr

func V2rayGetAddrFrom added in v1.2.3

func V2rayGetAddrFrom(buf utils.ByteReader) (addr Addr, err error)

依照 vmess/vless 协议的格式 依次读取 地址的 port, 域名/ip 信息

func (*Addr) AddressBytes

func (a *Addr) AddressBytes() (addr []byte, atyp byte)

如果a的ip不为空,则会返回 AtypIP4 或 AtypIP6, 否则会返回 AtypDomain Return address bytes and type 如果atyp类型是 域名,则 第一字节为该域名的总长度, 其余字节为域名内容。 如果类型是ip,则会拷贝出该ip的数据的副本。

func (*Addr) Dial

func (a *Addr) Dial(sockopt *Sockopt, localAddr net.Addr) (net.Conn, error)

Dial 可以拨号tcp、udp、unix domain socket、tls 这几种协议。 如果不是这几种之一,则会尝试查询 CustomDialerMap 找出匹配的函数进行拨号。 如果找不到,则会使用net包的方法进行拨号(其会返回错误)。

localAddr可为nil,如果不为nil,则其为 为 拨号 所指定的 本地地址。

func (Addr) DialWithOpt

func (a Addr) DialWithOpt(sockopt *Sockopt, localAddr net.Addr) (net.Conn, error)

比Dial更低级的方法,专用于使用sockopt的情况。 a的Network只能为golang支持的那几种。

func (*Addr) GetHashable

func (a *Addr) GetHashable() (ha HashableAddr)

func (*Addr) GetNetIPAddr

func (a *Addr) GetNetIPAddr() (na netip.Addr)

func (*Addr) HostStr

func (a *Addr) HostStr() string

if a.IP!=nil, return IP.String() else return a.Name

func (*Addr) IsEmpty

func (a *Addr) IsEmpty() bool

func (*Addr) IsIpv6

func (a *Addr) IsIpv6() bool

func (*Addr) IsUDP

func (a *Addr) IsUDP() bool

IsStrUDP_network(a.Network)

func (Addr) ListenUDP_withOpt

func (a Addr) ListenUDP_withOpt(sockopt *Sockopt) (net.PacketConn, error)

func (*Addr) RawUrlString added in v1.2.5

func (a *Addr) RawUrlString() string

返回以url表示的 地址.不转义

func (*Addr) String

func (a *Addr) String() string

Return host:port string. 若网络为unix,直接返回 a.Name. 若有Name而没有ip,则返回 a.Name:a.Port . 否则返回 a.IP: a.Port;

func (*Addr) ToAddr added in v1.2.4

func (a *Addr) ToAddr() net.Addr

func (*Addr) ToTCPAddr

func (a *Addr) ToTCPAddr() *net.TCPAddr

func (*Addr) ToUDPAddr

func (a *Addr) ToUDPAddr() *net.UDPAddr

如果a里只含有域名,则会自动解析域名为IP。注意,若出现错误,则会返回nil

func (*Addr) UrlString

func (a *Addr) UrlString() string

返回以url表示的 地址. unix的话会被url转义。ipv6的中括号不会被转义

type AddrData

type AddrData struct {
	Addr Addr
	Data []byte
}

type ChanCloseConn added in v1.2.5

type ChanCloseConn struct {
	net.Conn
	CChan chan struct{}
}

func (*ChanCloseConn) Close added in v1.2.5

func (c *ChanCloseConn) Close() error

type ConnList added in v1.2.5

type ConnList struct {
	sync.Mutex
	// contains filtered or unexported fields
}

ConnList 是一个 多线程安全 的用于保存Conn的列表

func (*ConnList) CloseDelete added in v1.2.5

func (cl *ConnList) CloseDelete(c net.Conn)

func (*ConnList) CloseDeleteAll added in v1.2.5

func (cl *ConnList) CloseDeleteAll()

func (*ConnList) Delete added in v1.2.5

func (cl *ConnList) Delete(c net.Conn)

func (*ConnList) Insert added in v1.2.5

func (cl *ConnList) Insert(c net.Conn)

type ConnWithFile

type ConnWithFile interface {
	net.Conn
	File() (f *os.File, err error)
}

net.UnixConn, net.UDPConn, net.TCPConn, net.IPConn

type ConnWrapper added in v1.2.2

type ConnWrapper interface {
	Upstream() net.Conn
}

返回它所包装前的 那一层 net.Conn, 不一定是 基本连接, 所以仍然可以继续 被识别为 ConnWrapper 并继续解包.

type DNSMachine

type DNSMachine struct {
	TypeStrategy int64  // 0, 4, 6, 40, 60
	TTLStrategy  uint32 // 0, 1, arbitrary,见 DnsConf 中的定义

	SpecialIPPollicy map[string][]netip.Addr

	SpecialServerPolicy 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.Conn为空, 则会设为 dm.DefaultConn

func (*DNSMachine) ListenUrl added in v1.2.5

func (dm *DNSMachine) ListenUrl(addr string) error

非阻塞, addr 为 url格式

func (*DNSMachine) Query

func (dm *DNSMachine) Query(domain string) (ip net.IP)

func (*DNSMachine) QueryType

func (dm *DNSMachine) QueryType(domain string, dns_type uint16) (ip net.IP, ttl uint32)

传入的domain必须是不带尾缀点号的domain, 即没有包过 Fqdn

func (*DNSMachine) ServeDNS added in v1.2.5

func (dm *DNSMachine) ServeDNS(w dns.ResponseWriter, r *dns.Msg)

实现 miekg/dns.Handler, 用于监听。不要直接调用该方法。 只查第一个question

func (*DNSMachine) SetDefaultConn

func (dm *DNSMachine) SetDefaultConn(c net.Conn, addr *Addr)

func (*DNSMachine) StartListen added in v1.2.5

func (dm *DNSMachine) StartListen()

使用通过配置设置好的监听地址进行监听

func (*DNSMachine) Stop added in v1.2.5

func (dm *DNSMachine) Stop()

如果调用过Listen,则Stop会关闭 dns监听

type DnsConf

type DnsConf struct {
	Listen string `toml:"listen"` // 格式: udp://127.0.0.1:8053 , 如果有效,则尝试监听该地址,否则不监听. 可以为 udp,tcp 或 tls

	Strategy    int64          `toml:"strategy"`     //0表示默认(和4含义相同), 4表示先查ip4后查ip6, 6表示先查6后查4; 40表示只查ipv4, 60 表示只查ipv6
	TTLStrategy uint32         `toml:"ttl_strategy"` //0表示默认(记录永不过期), 1表示严格按照dns查询到的TTL, 其他值则为自定义的秒数,然后程序会按这个时间周期性清理缓存。
	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
}

func (*DnsConn) Dial

func (c *DnsConn) Dial() error

Dial通过 c 内部设置好的地址进行拨号,并将 c.Conn.Conn 设为 新建立好的连接

type DomainHaser

type DomainHaser interface {
	HasDomain(string) bool
}

用于 HasFullOrSubDomain函数

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 MUST use select and ReadTimeoutChan or WriteTimeoutChan when reading or writing.

see IOWrapper for reference.

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

type EasyNetAddresser struct {
	LA, RA net.Addr
}

实现 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 GeositeAttr struct {
	Key   string
	Value any //bool or int64
}

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 HashableAddr struct {
	Network, Name string
	netip.AddrPort
}

type IOWrapper added in v1.2.0

type IOWrapper struct {
	EasyNetAddresser
	EasyDeadline //无需再调用 InitEasyDeadline,内部已经处理好了。

	io.Reader //不可为nil
	io.Writer //不可为nil
	io.Closer

	FirstWriteChan chan struct{} //用于确保先Write然后再Read,可为nil

	CloseChan chan struct{} //可为nil,用于接收关闭信号

	Rejecter RejectConn
	// contains filtered or unexported fields
}

一个自定义的由多个组件组成的实现 net.Conn 的结构, 也通过设置 Rejecter 实现 RejectConn

func (*IOWrapper) Close added in v1.2.0

func (iw *IOWrapper) Close() error

func (*IOWrapper) Read added in v1.2.0

func (iw *IOWrapper) Read(p []byte) (int, error)

func (*IOWrapper) Reject added in v1.2.4

func (iw *IOWrapper) Reject()

func (*IOWrapper) RejectBehaviorDefined added in v1.2.4

func (iw *IOWrapper) RejectBehaviorDefined() bool

func (*IOWrapper) Write added in v1.2.0

func (iw *IOWrapper) Write(p []byte) (int, error)

type IPRecord added in v1.2.4

type IPRecord struct {
	IP         net.IP
	TTL        uint32 //seconds
	RecordTime time.Time
}

type ListenerWithFile

type ListenerWithFile interface {
	net.Listener
	File() (f *os.File, err error)
}

net.TCPListener, net.UnixListener

type MapDomainHaser

type MapDomainHaser map[string]bool

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 {
	NetDeadliner

	ReadMsg() (data []byte, peer Addr, err error)

	WriteMsg(data []byte, peer Addr) error

	CloseConnWithRaddr(raddr Addr) error //关闭特定连接
	Close() error                        //关闭所有连接
	Fullcone() bool                      //若Fullcone, 则在转发因另一端关闭而结束后, RelayUDP函数不会Close它.
}

MsgConn一般用于 udp. 是一种类似 net.PacketConn 的包装. MsgConn专门针对代理进行设计。

实现 MsgConn接口 的类型 可以被用于 RelayUDP 进行转发。

ReadMsg直接返回数据, 这样可以尽量避免多次数据拷贝。

使用Addr,是因为有可能请求地址是个域名,而不是ip; 而且通过Addr, MsgConn实际上有可能支持通用的情况, 即可以用于 客户端 一会 请求tcp,一会又请求udp,一会又请求什么其它网络层 这种奇葩情况.

type MsgConnForPacketConn added in v1.2.4

type MsgConnForPacketConn struct {
	net.PacketConn
}

Wraps net.PacketConn and implements MsgConn

func (*MsgConnForPacketConn) Close added in v1.2.4

func (mc *MsgConnForPacketConn) Close() error

func (*MsgConnForPacketConn) CloseConnWithRaddr added in v1.2.4

func (mc *MsgConnForPacketConn) CloseConnWithRaddr(raddr Addr) error

func (*MsgConnForPacketConn) Fullcone added in v1.2.4

func (mc *MsgConnForPacketConn) Fullcone() bool

func (*MsgConnForPacketConn) ReadMsg added in v1.2.5

func (mc *MsgConnForPacketConn) ReadMsg() ([]byte, Addr, error)

func (*MsgConnForPacketConn) WriteMsg added in v1.2.5

func (mc *MsgConnForPacketConn) WriteMsg(p []byte, a Addr) error

type MsgConnNetAdapter added in v1.2.5

type MsgConnNetAdapter struct {
	MsgConn
	LA, RA net.Addr
}

将MsgConn适配为Net.Conn

func (MsgConnNetAdapter) LocalAddr added in v1.2.5

func (ma MsgConnNetAdapter) LocalAddr() net.Addr

func (MsgConnNetAdapter) Read added in v1.2.5

func (ma MsgConnNetAdapter) Read(p []byte) (int, error)

func (MsgConnNetAdapter) RemoteAddr added in v1.2.5

func (ma MsgConnNetAdapter) RemoteAddr() net.Addr

func (MsgConnNetAdapter) Write added in v1.2.5

func (ma MsgConnNetAdapter) Write(p []byte) (int, error)

type NetAddresser added in v1.2.0

type NetAddresser interface {
	LocalAddr() net.Addr
	RemoteAddr() net.Addr
}

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

type ReadWrapper struct {
	net.Conn
	OptionalReader    io.Reader
	RemainFirstBufLen int
}

选择性从 OptionalReader读取, 直到 RemainFirstBufLen 小于等于0 为止; 该结构 mimic utils.ReadWrapper

func (*ReadWrapper) Read

func (rw *ReadWrapper) Read(p []byte) (n int, err error)

type RejectConn added in v1.2.4

type RejectConn interface {
	RejectBehaviorDefined() bool //若为false,则只能直接Close
	Reject()
}

用于定义拒绝响应的行为;可参考 httpLayer.RejectConn

type RoutePolicy

type RoutePolicy struct {
	List []*RouteSet
}

一个完整的 所有RouteSet的列表,进行路由时,直接遍历即可。 所谓的路由实际上就是分流。

func NewRoutePolicy

func NewRoutePolicy() *RoutePolicy

func (*RoutePolicy) AddRouteSet

func (rp *RoutePolicy) AddRouteSet(rs *RouteSet)

func (*RoutePolicy) CalcuOutTag added in v1.2.4

func (rp *RoutePolicy) CalcuOutTag(td *TargetDescription) string

根据td 以及 RoutePolicy的配置 计算出 一个 对应的 proxy.Client 的 tag。 默认情况下,始终具有direct这个tag以及 proxy这个tag,无需用户额外在配置文件中指定。 默认如果不匹配任何值的话,就会流向 "proxy" tag,也就是客户设置的 remoteClient的值。

func (*RoutePolicy) LoadRulesForRoutePolicy added in v1.2.3

func (policy *RoutePolicy) LoadRulesForRoutePolicy(rules []*RuleConf)

type RouteSet

type RouteSet struct {
	//网络层
	NetRanger cidranger.Ranger    //一个范围
	IPs       map[netip.Addr]bool //一个确定值

	//Domains匹配子域名,当此域名是目标域名或其子域名时,该规则生效.
	Domains map[string]bool

	//Full只匹配完整域名;
	Full   map[string]bool
	InTags map[string]bool

	//Countries 使用 ISO 3166 字符串 作为key.
	Countries map[string]bool

	//Users 包含所有可匹配的 用户的 identityStr
	Users map[string]bool

	//Regex是正则匹配域名.
	Regex []*regexp.Regexp

	//Match 匹配任意字符串
	Match, Geosites []string

	//传输层
	AllowedTransportLayerProtocols uint16

	OutTag  string   //目标
	OutTags []string //目标列表

}

Set 是 “集合” 的意思, 是一组相同类型的数据放到一起。

这里的相同点,就是它们同属于 将发往一个方向, 即同属一个路由策略。

任意一个参数匹配后,都将发往相同的方向,由该方向OutTag 指定。 RouteSet 只负责把一些属性相同的 “网络层/传输层 特征” 放到一起。

这里主要通过 ip,域名 和 inTag 进行分流。域名的匹配又分多种方式。

func LoadRuleForRouteSet

func LoadRuleForRouteSet(rule *RuleConf) (rs *RouteSet)

func NewFullRouteSet

func NewFullRouteSet() *RouteSet

func NewRouteSetForMyCountry

func NewRouteSetForMyCountry(iso string) *RouteSet

对于我的country,直接直连

func (*RouteSet) IsAddrIn

func (rs *RouteSet) IsAddrIn(a Addr) bool

func (*RouteSet) IsAddrNetworkAllowed

func (rs *RouteSet) IsAddrNetworkAllowed(a Addr) bool

func (*RouteSet) IsIn

func (rs *RouteSet) IsIn(td *TargetDescription) bool

func (*RouteSet) IsNoLimitForNetworkLayer added in v1.2.1

func (rs *RouteSet) IsNoLimitForNetworkLayer() bool

func (*RouteSet) IsTCPAllowed

func (rs *RouteSet) IsTCPAllowed() bool

func (*RouteSet) IsTransportProtocolAllowed

func (rs *RouteSet) IsTransportProtocolAllowed(p uint16) bool

func (*RouteSet) IsUDPAllowed

func (rs *RouteSet) IsUDPAllowed() bool

type RuleConf

type RuleConf struct {
	DialTag any `toml:"toTag" json:"toTag"`

	InTags []string `toml:"fromTag" json:"fromTag"`
	Users  []string `toml:"user" json:"user"`

	Countries []string `toml:"country" json:"country"` // 如果类似 !CN, 则意味着专门匹配不为CN 的国家(目前还未实现)
	IPs       []string `toml:"ip" json:"ip"`
	Domains   []string `toml:"domain" json:"domain"`
	Network   []string `toml:"network" json:"network"`
}

type Sockopt

type Sockopt struct {
	TProxy bool   `toml:"tproxy"` //only linux
	Somark int    `toml:"mark"`   //only linux
	Device string `toml:"device"`
}

用于 listen和 dial 配置一些底层参数.

type SpecialDnsServerConf

type SpecialDnsServerConf struct {
	AddrUrlStr string   `toml:"addr"`   //必须为 udp://1.1.1.1:53 这种格式
	Domains    []string `toml:"domain"` //指定哪些域名需要通过 该dns服务器进行查询
}

type SpliceReader added in v1.2.5

type SpliceReader interface {
	EverPossibleToSpliceRead() bool
	CanSpliceRead() (bool, *net.TCPConn, *net.UnixConn) //若bool为true,则 TCPConn和UnixConn必须有且仅有一个不为nil
}

SpliceReader 标明是否 该接口最终能暴露出tcp/unix来用于 splice读

type Splicer

type Splicer interface {
	EverPossibleToSpliceWrite() bool      //是否有机会splice, 如果这个返回false,则永远无法splice; 主要审视自己能否向裸连接写入数据; 读不用splicer担心。
	CanSpliceWrite() (bool, *net.TCPConn) //当前状态是否可以splice写入,即是否会暴露出 net.TCPConn
}

Splicer 是一个 可以进行Write时使用splice的接口。

type TCPRequestInfo added in v1.2.5

type TCPRequestInfo struct {
	net.Conn
	Target Addr
}

type TCPUDPAddr added in v1.2.4

type TCPUDPAddr struct {
	*net.TCPAddr
	*net.UDPAddr
}

func (*TCPUDPAddr) Network added in v1.2.4

func (tu *TCPUDPAddr) Network() string

func (*TCPUDPAddr) String added in v1.2.4

func (tu *TCPUDPAddr) String() string

type TargetDescription

type TargetDescription struct {
	Addr  Addr
	InTag string

	UserIdentityStr string
}

TargetDescription 可以完整地描述一个网络层/传输层上的一个特定目标, 一般来说,一个具体的监听配置就会分配一个tag

type UDPAddrData

type UDPAddrData struct {
	Addr net.UDPAddr
	Data []byte
}

type UDPConn

type UDPConn struct {
	EasyDeadline
	// contains filtered or unexported fields
}

UDPConn 将一个udp连接包装成一个 向单一目标发送数据的 连接。 UDPConn 主要服务于 UDPListener。如果有udp客户端需求, 最好使用 UDPMsgConn, 以更好地支持 fullcone或symmetric.

UDPConn 也有能力接收来自其它目标的数据,以及向其它目标发送数据。然而, 本结构并没有记录链接端口, 所以无法实现 symmetric. 如果用 DialUDP 函数初始化的 UDPConn, 则无法使用 WriteMsg方法向其它地址发消息.

UDPConn 实现了 net.Conn , net.PacketConn , MsgConn.

func DialUDP

func DialUDP(raddr *net.UDPAddr) (*UDPConn, error)

DialUDP 对raddr拨号后调用 NewUDPConn

func NewUDPConn

func NewUDPConn(raddr *net.UDPAddr, conn *net.UDPConn, isClient bool) *UDPConn

如果isClient为true,则本函数返回后,必须要调用一次 Write,才能在Read读到数据. 这是udp的原理所决定的。 在客户端没有Write之前,该udp连接实际上根本没有被建立, Read也就不可能/不应该 读到任何东西.

我们这里为了保证udp连接不会一直滞留导致 too many open files的情况, 主动设置了 内层udp连接的 read的 timeout为 UDP_timeout。 你依然可以设置 DialUDP 所返回的 net.Conn 的 Deadline, 这属于外层的Deadline, 不会影响底层 udp所强制设置的 deadline.

func (*UDPConn) Close

func (uc *UDPConn) Close() error

func (*UDPConn) CloseConnWithRaddr

func (uc *UDPConn) CloseConnWithRaddr(_ Addr) error

func (*UDPConn) CloseMsgChan

func (uc *UDPConn) CloseMsgChan()

func (*UDPConn) GetReadChan

func (uc *UDPConn) GetReadChan() chan UDPAddrData

func (*UDPConn) LocalAddr

func (uc *UDPConn) LocalAddr() net.Addr

func (*UDPConn) Read

func (uc *UDPConn) Read(buf []byte) (n int, err error)

func (*UDPConn) ReadFrom

func (uc *UDPConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)

实现 net.PacketConn, 可以与 miekg/dns 配合。返回的 addr 只可能为 之前预先配置的远程目标地址

func (*UDPConn) ReadMsg

func (uc *UDPConn) ReadMsg() ([]byte, Addr, error)

func (*UDPConn) RemoteAddr

func (uc *UDPConn) RemoteAddr() net.Addr

func (*UDPConn) RemoteUDPAddr

func (uc *UDPConn) RemoteUDPAddr() *net.UDPAddr

func (*UDPConn) Write

func (uc *UDPConn) Write(buf []byte) (n int, err error)

func (*UDPConn) WriteMsg added in v1.2.5

func (uc *UDPConn) WriteMsg(buf []byte, addr Addr) error

func (*UDPConn) WriteTo

func (uc *UDPConn) WriteTo(p []byte, _ net.Addr) (n int, err error)

实现 net.PacketConn, 可以与 miekg/dns 配合。会无视传入的地址, 而使用 之前预先配置的远程目标地址

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) Accept

func (ul *UDPListener) Accept() (net.Conn, 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)

func (*UDPListener) NewConn

func (ul *UDPListener) NewConn(raddr *net.UDPAddr) *UDPConn

It can be used to dial a remote udp

type UDPMsgConn

type UDPMsgConn struct {
	*net.UDPConn
	IsServer bool
	// contains filtered or unexported fields
}

UDPMsgConn 实现 MsgConn 和 net.PacketConn。 可满足fullcone/symmetric. 在proxy/direct 被用到.

func NewUDPMsgConn

func NewUDPMsgConn(laddr *net.UDPAddr, fullcone bool, isserver bool, sockopt *Sockopt) (*UDPMsgConn, error)

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

func (uc *UDPMsgConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)

实现 net.PacketConn

func (*UDPMsgConn) ReadMsg added in v1.2.5

func (u *UDPMsgConn) ReadMsg() ([]byte, Addr, error)

func (*UDPMsgConn) WriteMsg added in v1.2.5

func (u *UDPMsgConn) WriteMsg(bs []byte, raddr Addr) error

func (*UDPMsgConn) WriteTo added in v1.2.4

func (uc *UDPMsgConn) WriteTo(p []byte, raddr net.Addr) (n int, err error)

实现 net.PacketConn

type UDPRequestInfo added in v1.2.5

type UDPRequestInfo struct {
	MsgConn
	Target Addr
}

type UniSourceMsgConnForPacketConn added in v1.2.5

type UniSourceMsgConnForPacketConn struct {
	net.PacketConn
	Source Addr
}

Wraps net.PacketConn and implements MsgConn

func (*UniSourceMsgConnForPacketConn) Close added in v1.2.5

func (*UniSourceMsgConnForPacketConn) CloseConnWithRaddr added in v1.2.5

func (mc *UniSourceMsgConnForPacketConn) CloseConnWithRaddr(raddr Addr) error

func (*UniSourceMsgConnForPacketConn) Fullcone added in v1.2.5

func (mc *UniSourceMsgConnForPacketConn) Fullcone() bool

func (*UniSourceMsgConnForPacketConn) ReadMsg added in v1.2.5

func (mc *UniSourceMsgConnForPacketConn) ReadMsg() ([]byte, Addr, error)

func (*UniSourceMsgConnForPacketConn) WriteMsg added in v1.2.5

func (mc *UniSourceMsgConnForPacketConn) WriteMsg(p []byte, a Addr) error

type UniTargetMsgConn

type UniTargetMsgConn struct {
	net.Conn
	Target Addr
}

symmetric, proxy/dokodemo 有用到. 实现 MsgConn 和 net.Conn

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) ReadMsg added in v1.2.5

func (u UniTargetMsgConn) ReadMsg() ([]byte, Addr, error)

func (UniTargetMsgConn) WriteMsg added in v1.2.5

func (u UniTargetMsgConn) WriteMsg(bs []byte, _ Addr) error

Directories

Path Synopsis
Package tproxy listens tproxy and setup corresponding iptables for linux.
Package tproxy listens tproxy and setup corresponding iptables for linux.
tun
Packages tun provides utilities for tun.
Packages tun provides utilities for tun.
device/iobased
Package iobased provides the implementation of io.ReadWriter based data-link layer endpoints.
Package iobased provides the implementation of io.ReadWriter based data-link layer endpoints.
device/tun
Package tun provides TUN which implemented device.Device interface.
Package tun provides TUN which implemented device.Device interface.

Jump to

Keyboard shortcuts

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