github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/common/net/packetaddr/connection_adaptor.go (about) 1 package packetaddr 2 3 import ( 4 "context" 5 gonet "net" 6 "sync" 7 "time" 8 9 "github.com/v2fly/v2ray-core/v5/common" 10 "github.com/v2fly/v2ray-core/v5/common/buf" 11 "github.com/v2fly/v2ray-core/v5/common/errors" 12 "github.com/v2fly/v2ray-core/v5/common/net" 13 "github.com/v2fly/v2ray-core/v5/features/routing" 14 "github.com/v2fly/v2ray-core/v5/transport" 15 ) 16 17 var ( 18 errNotPacketConn = errors.New("not a packet connection") 19 errUnsupported = errors.New("unsupported action") 20 ) 21 22 func ToPacketAddrConn(link *transport.Link, dest net.Destination) (net.PacketConn, error) { 23 if !dest.Address.Family().IsDomain() { 24 return nil, errNotPacketConn 25 } 26 switch dest.Address.Domain() { 27 case seqPacketMagicAddress: 28 return &packetConnectionAdaptor{ 29 readerAccess: &sync.Mutex{}, 30 readerBuffer: nil, 31 link: link, 32 }, nil 33 default: 34 return nil, errNotPacketConn 35 } 36 } 37 38 func CreatePacketAddrConn(ctx context.Context, dispatcher routing.Dispatcher, isStream bool) (net.PacketConn, error) { 39 if isStream { 40 return nil, errUnsupported 41 } 42 packetDest := net.Destination{ 43 Address: net.DomainAddress(seqPacketMagicAddress), 44 Port: 0, 45 Network: net.Network_UDP, 46 } 47 link, err := dispatcher.Dispatch(ctx, packetDest) 48 if err != nil { 49 return nil, err 50 } 51 return &packetConnectionAdaptor{ 52 readerAccess: &sync.Mutex{}, 53 readerBuffer: nil, 54 link: link, 55 }, nil 56 } 57 58 type packetConnectionAdaptor struct { 59 readerAccess *sync.Mutex 60 readerBuffer buf.MultiBuffer 61 link *transport.Link 62 } 63 64 func (c *packetConnectionAdaptor) ReadFrom(p []byte) (n int, addr gonet.Addr, err error) { 65 c.readerAccess.Lock() 66 defer c.readerAccess.Unlock() 67 if c.readerBuffer.IsEmpty() { 68 c.readerBuffer, err = c.link.Reader.ReadMultiBuffer() 69 if err != nil { 70 return 0, nil, err 71 } 72 } 73 c.readerBuffer, n = buf.SplitFirstBytes(c.readerBuffer, p) 74 var w *buf.Buffer 75 w, addr, err = ExtractAddressFromPacket(buf.FromBytes(p[:n])) 76 n = copy(p, w.Bytes()) 77 w.Release() 78 return 79 } 80 81 func (c *packetConnectionAdaptor) WriteTo(p []byte, addr gonet.Addr) (n int, err error) { 82 payloadLen := len(p) 83 var buffer *buf.Buffer 84 buffer, err = AttachAddressToPacket(buf.FromBytes(p), addr) 85 if err != nil { 86 return 0, err 87 } 88 mb := buf.MultiBuffer{buffer} 89 err = c.link.Writer.WriteMultiBuffer(mb) 90 if err != nil { 91 return 0, err 92 } 93 return payloadLen, nil 94 } 95 96 func (c *packetConnectionAdaptor) Close() error { 97 c.readerAccess.Lock() 98 defer c.readerAccess.Unlock() 99 c.readerBuffer = buf.ReleaseMulti(c.readerBuffer) 100 return common.Interrupt(c.link) 101 } 102 103 func (c packetConnectionAdaptor) LocalAddr() gonet.Addr { 104 return &gonet.UnixAddr{Name: "unsupported"} 105 } 106 107 func (c packetConnectionAdaptor) SetDeadline(t time.Time) error { 108 return nil 109 } 110 111 func (c packetConnectionAdaptor) SetReadDeadline(t time.Time) error { 112 return nil 113 } 114 115 func (c packetConnectionAdaptor) SetWriteDeadline(t time.Time) error { 116 return nil 117 } 118 119 func ToPacketAddrConnWrapper(conn net.PacketConn, isStream bool) FusedConnection { 120 return &packetConnWrapper{conn} 121 } 122 123 type packetConnWrapper struct { 124 net.PacketConn 125 } 126 127 func (pc *packetConnWrapper) RemoteAddr() gonet.Addr { 128 return nil 129 } 130 131 type FusedConnection interface { 132 net.PacketConn 133 net.Conn 134 } 135 136 func (pc *packetConnWrapper) Read(p []byte) (n int, err error) { 137 recbuf := buf.StackNew() 138 recbuf.Extend(2048) 139 n, addr, err := pc.PacketConn.ReadFrom(recbuf.Bytes()) 140 if err != nil { 141 return 0, err 142 } 143 recbuf.Resize(0, int32(n)) 144 result, err := AttachAddressToPacket(&recbuf, addr) 145 if err != nil { 146 return 0, err 147 } 148 n = copy(p, result.Bytes()) 149 result.Release() 150 return n, nil 151 } 152 153 func (pc *packetConnWrapper) Write(p []byte) (n int, err error) { 154 data, addr, err := ExtractAddressFromPacket(buf.FromBytes(p)) 155 if err != nil { 156 return 0, err 157 } 158 _, err = pc.PacketConn.WriteTo(data.Bytes(), addr) 159 if err != nil { 160 return 0, err 161 } 162 data.Release() 163 return len(p), nil 164 } 165 166 func (pc *packetConnWrapper) Close() error { 167 return pc.PacketConn.Close() 168 } 169 170 func GetDestinationSubsetOf(dest net.Destination) (bool, error) { 171 if !dest.Address.Family().IsDomain() { 172 return false, errNotPacketConn 173 } 174 switch dest.Address.Domain() { 175 case seqPacketMagicAddress: 176 return false, nil 177 default: 178 return false, errNotPacketConn 179 } 180 }