Files
v2ray_simple/netLayer/netlayer.go
hahahrfool 447bd8749a 重构所有udp部分的代码! 摒弃了过去非常复杂的upd转发机制;
不再使用 UDP_Putter 等机制去转发udp,而是用一个 netLayer.MsgConn 结构

proxy.Server 和 proxy.Client 接口改动,

Client在握手udp时不再使用handshake方法, 而是用新的 EstablishUDPChannel 方法

Server 在 Handshake时会选择性返回两种接口,io.ReadWriteCloser 用于tcp, netLayer.MsgConn 用于 udp

此时vless、socks5、direct 的udp转发都已经成功经过了 go test 验证, 但是 main.go 还未修改。
2022-04-08 13:49:56 +08:00

138 lines
3.0 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, readv, relay, route, udp, splice 等相关功能。
以后如果要添加 kcp 或 raw socket 等底层协议时或者要控制tcp/udp拨号的细节时也要在此包里实现.
*/
package netLayer
import (
"io"
"log"
"net"
"syscall"
"github.com/hahahrfool/v2ray_simple/utils"
"go.uber.org/zap"
)
var (
// 如果机器没有ipv6地址, 就无法联通ipv6, 此时可以在dial时更快拒绝ipv6地址,
// 避免打印过多错误输出
machineCanConnectToIpv6 bool
ErrMachineCantConnectToIpv6 = utils.NumErr{Prefix: "ErrMachineCanConnectToIpv6"}
)
//做一些网络层的资料准备工作, 可以优化本包其它函数的调用。
func Prepare() {
machineCanConnectToIpv6 = HasIpv6Interface()
}
func HasIpv6Interface() bool {
if utils.LogLevel == utils.Log_debug {
log.Println("HasIpv6Interface called")
}
addrs, err := net.InterfaceAddrs()
if err != nil {
if utils.ZapLogger != nil {
if ce := utils.CanLogErr("call net.InterfaceAddrs failed"); ce != nil {
ce.Write(zap.Error(err))
}
} else {
log.Println("call net.InterfaceAddrs failed", err)
}
return false
}
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && !ipnet.IP.IsPrivate() && !ipnet.IP.IsLinkLocalUnicast() {
// IsLinkLocalUnicast: something starts with fe80:
// According to godoc, If ip is not an IPv4 address, To4 returns nil.
// This means it's ipv6
if ipnet.IP.To4() == nil {
return true
}
}
}
return false
}
//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.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
}
//使用Addr是因为有可能申请的是域名而不是ip
type MsgConn interface {
ReadFrom() ([]byte, Addr, error)
WriteTo([]byte, Addr) error
}
type UDPMsgConnWrapper struct {
*net.UDPConn
IsClient bool
FirstAddr Addr
}
func (u *UDPMsgConnWrapper) ReadFrom() ([]byte, Addr, error) {
bs := utils.GetPacket()
n, ad, err := u.UDPConn.ReadFromUDP(bs)
if err != nil {
return nil, Addr{}, err
}
return bs[:n], NewAddrFromUDPAddr(ad), err
}
func (u *UDPMsgConnWrapper) WriteTo(bs []byte, ad Addr) error {
if u.IsClient {
if ad.GetHashable() == u.FirstAddr.GetHashable() {
_, err := u.UDPConn.Write(bs)
return err
} else {
return utils.ErrNotImplemented
}
} else {
_, err := u.UDPConn.WriteTo(bs, ad.ToUDPAddr())
return err
}
}