github.com/moqsien/xraycore@v1.8.5/common/singbridge/packet.go (about) 1 package singbridge 2 3 import ( 4 "context" 5 6 B "github.com/sagernet/sing/common/buf" 7 "github.com/sagernet/sing/common/bufio" 8 M "github.com/sagernet/sing/common/metadata" 9 "github.com/moqsien/xraycore/common/buf" 10 "github.com/moqsien/xraycore/common/net" 11 "github.com/moqsien/xraycore/transport" 12 ) 13 14 func CopyPacketConn(ctx context.Context, inboundConn net.Conn, link *transport.Link, destination net.Destination, serverConn net.PacketConn) error { 15 conn := &PacketConnWrapper{ 16 Reader: link.Reader, 17 Writer: link.Writer, 18 Dest: destination, 19 Conn: inboundConn, 20 } 21 return ReturnError(bufio.CopyPacketConn(ctx, conn, bufio.NewPacketConn(serverConn))) 22 } 23 24 type PacketConnWrapper struct { 25 buf.Reader 26 buf.Writer 27 net.Conn 28 Dest net.Destination 29 cached buf.MultiBuffer 30 } 31 32 func (w *PacketConnWrapper) ReadPacket(buffer *B.Buffer) (M.Socksaddr, error) { 33 if w.cached != nil { 34 mb, bb := buf.SplitFirst(w.cached) 35 if bb == nil { 36 w.cached = nil 37 } else { 38 buffer.Write(bb.Bytes()) 39 w.cached = mb 40 var destination net.Destination 41 if bb.UDP != nil { 42 destination = *bb.UDP 43 } else { 44 destination = w.Dest 45 } 46 bb.Release() 47 return ToSocksaddr(destination), nil 48 } 49 } 50 mb, err := w.ReadMultiBuffer() 51 if err != nil { 52 return M.Socksaddr{}, err 53 } 54 nb, bb := buf.SplitFirst(mb) 55 if bb == nil { 56 return M.Socksaddr{}, nil 57 } else { 58 buffer.Write(bb.Bytes()) 59 w.cached = nb 60 var destination net.Destination 61 if bb.UDP != nil { 62 destination = *bb.UDP 63 } else { 64 destination = w.Dest 65 } 66 bb.Release() 67 return ToSocksaddr(destination), nil 68 } 69 } 70 71 func (w *PacketConnWrapper) WritePacket(buffer *B.Buffer, destination M.Socksaddr) error { 72 vBuf := buf.New() 73 vBuf.Write(buffer.Bytes()) 74 endpoint := ToDestination(destination, net.Network_UDP) 75 vBuf.UDP = &endpoint 76 return w.Writer.WriteMultiBuffer(buf.MultiBuffer{vBuf}) 77 } 78 79 func (w *PacketConnWrapper) Close() error { 80 buf.ReleaseMulti(w.cached) 81 return nil 82 }