Files
v2ray_simple/netLayer/netlayer.go
2023-02-12 11:38:03 +08:00

219 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
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 文件;默认不内嵌。
*/
package netLayer
import (
"errors"
"io"
"net"
"reflect"
"sync"
"syscall"
"time"
"github.com/e1732a364fed/v2ray_simple/utils"
"go.uber.org/zap"
)
var (
ErrTimeout = errors.New("timeout")
ErrDoNotClose = errors.New("do not close")
)
// c.SetDeadline(time.Time{})
func PersistConn(c net.Conn) {
c.SetDeadline(time.Time{})
}
func PersistRead(c net.Conn) {
c.SetReadDeadline(time.Time{})
}
func PersistWrite(c net.Conn) {
c.SetWriteDeadline(time.Time{})
}
// default recommended handshake read timeout
const DefaultCommonReadTimeout = time.Second * 4
var CommonReadTimeout = DefaultCommonReadTimeout
// set read timeout after CommonReadTimeout
func SetCommonReadTimeout(c net.Conn) error {
return c.SetReadDeadline(time.Now().Add(CommonReadTimeout))
}
// 暂时也使用 CommonReadTimeout
func SetCommonWriteTimeout(c net.Conn) error {
return c.SetWriteDeadline(time.Now().Add(CommonReadTimeout))
}
func IsTCP(r any) *net.TCPConn {
if tc, ok := r.(*net.TCPConn); ok {
return tc
}
return nil
}
func IsUnix(r any) *net.UnixConn {
if uc, ok := r.(*net.UnixConn); ok {
return uc
}
return nil
}
// net.IPConn, net.TCPConn, net.UDPConn, net.UnixConn
func IsBasicConn(r interface{}) bool {
if _, ok := r.(syscall.Conn); ok {
return true
}
return false
}
func GetRawConn(reader io.Reader) syscall.RawConn {
if sc, ok := reader.(syscall.Conn); ok {
rawConn, err := sc.SyscallConn()
if err != nil {
if ce := utils.CanLogDebug("can't convert syscall.Conn to syscall.RawConn"); ce != nil {
ce.Write(zap.Any("reader", reader), zap.String("type", reflect.TypeOf(reader).String()), zap.Error(err))
}
return nil
}
return rawConn
}
return nil
}
// "udp", "udp4", "udp6"
func IsStrUDP_network(s string) bool {
switch s {
case "udp", "udp4", "udp6":
return true
}
return false
}
// 返回它所包装前的 那一层 net.Conn, 不一定是 基本连接,
// 所以仍然可以继续 被识别为 ConnWrapper 并继续解包.
type ConnWrapper interface {
Upstream() net.Conn
}
// part of net.Conn
type NetAddresser interface {
LocalAddr() net.Addr
RemoteAddr() net.Addr
}
// part of net.Conn
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
}
// 实现 NetAddresser
type EasyNetAddresser struct {
LA, RA net.Addr
}
func (iw *EasyNetAddresser) LocalAddr() net.Addr { return iw.LA }
func (iw *EasyNetAddresser) RemoteAddr() net.Addr { return iw.RA }
// 用于定义拒绝响应的行为;可参考 httpLayer.RejectConn
type RejectConn interface {
RejectBehaviorDefined() bool //若为false则只能直接Close
Reject()
}
type TCPRequestInfo struct {
net.Conn
Target Addr
}
type UDPRequestInfo struct {
MsgConn
Target Addr
}
type ChanCloseConn struct {
net.Conn
CChan chan struct{}
}
func (c *ChanCloseConn) Close() error {
close(c.CChan)
return nil
}
// ConnList 是一个 多线程安全 的用于保存Conn的列表
type ConnList struct {
sync.Mutex
list []net.Conn
}
func (cl *ConnList) Insert(c net.Conn) {
cl.Lock()
cl.list = append(cl.list, c)
cl.Unlock()
}
func (cl *ConnList) CloseDelete(c net.Conn) {
c.Close()
cl.Delete(c)
}
func (cl *ConnList) Delete(c net.Conn) {
cl.Lock()
index := -1
for i, v := range cl.list {
if v == c {
index = i
}
}
if index == -1 {
cl.Unlock()
return
}
utils.Splice(&cl.list, index, 1)
cl.Unlock()
}
func (cl *ConnList) CloseDeleteAll() {
cl.Lock()
for _, conn := range cl.list {
conn.Close()
}
cl.list = nil
cl.Unlock()
}