github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/uot/server.go (about) 1 package uot 2 3 import ( 4 "encoding/binary" 5 "io" 6 "net" 7 8 "github.com/sagernet/sing/common/buf" 9 M "github.com/sagernet/sing/common/metadata" 10 ) 11 12 type ServerConn struct { 13 net.PacketConn 14 version int 15 isConnect bool 16 destination M.Socksaddr 17 inputReader, outputReader *io.PipeReader 18 inputWriter, outputWriter *io.PipeWriter 19 } 20 21 func NewServerConn(packetConn net.PacketConn, version int) net.Conn { 22 c := &ServerConn{ 23 PacketConn: packetConn, 24 version: version, 25 } 26 c.inputReader, c.inputWriter = io.Pipe() 27 c.outputReader, c.outputWriter = io.Pipe() 28 go c.loopInput() 29 go c.loopOutput() 30 return c 31 } 32 33 func (c *ServerConn) Read(b []byte) (n int, err error) { 34 return c.outputReader.Read(b) 35 } 36 37 func (c *ServerConn) Write(b []byte) (n int, err error) { 38 return c.inputWriter.Write(b) 39 } 40 41 func (c *ServerConn) RemoteAddr() net.Addr { 42 return M.Socksaddr{Fqdn: "pipe"} 43 } 44 45 //warn:unsafe 46 func (c *ServerConn) loopInput() { 47 if c.version == Version { 48 request, err := ReadRequest(c.inputReader) 49 if err != nil { 50 return 51 } 52 c.isConnect = request.IsConnect 53 c.destination = request.Destination 54 } 55 buffer := buf.NewPacket() 56 defer buffer.Release() 57 for { 58 var destination M.Socksaddr 59 var err error 60 if c.isConnect { 61 destination = c.destination 62 } else { 63 destination, err = AddrParser.ReadAddrPort(c.inputReader) 64 if err != nil { 65 break 66 } 67 } 68 if destination.IsFqdn() { 69 addr, err := net.ResolveUDPAddr("udp", destination.String()) 70 if err != nil { 71 continue 72 } 73 destination = M.SocksaddrFromNet(addr) 74 } 75 var length uint16 76 err = binary.Read(c.inputReader, binary.BigEndian, &length) 77 if err != nil { 78 break 79 } 80 buffer.Reset() 81 _, err = buffer.ReadFullFrom(c.inputReader, int(length)) 82 if err != nil { 83 break 84 } 85 _, err = c.WriteTo(buffer.Bytes(), destination.UDPAddr()) 86 if err != nil { 87 break 88 } 89 } 90 c.Close() 91 } 92 93 //warn:unsafe 94 func (c *ServerConn) loopOutput() { 95 buffer := buf.NewPacket() 96 defer buffer.Release() 97 for { 98 buffer.Reset() 99 n, addr, err := buffer.ReadPacketFrom(c) 100 if err != nil { 101 break 102 } 103 if !c.isConnect { 104 err = AddrParser.WriteAddrPort(c.outputWriter, M.SocksaddrFromNet(addr)) 105 if err != nil { 106 break 107 } 108 } 109 err = binary.Write(c.outputWriter, binary.BigEndian, uint16(n)) 110 if err != nil { 111 break 112 } 113 _, err = buffer.WriteTo(c.outputWriter) 114 if err != nil { 115 break 116 } 117 } 118 c.Close() 119 } 120 121 func (c *ServerConn) Close() error { 122 c.inputReader.Close() 123 c.inputWriter.Close() 124 c.outputReader.Close() 125 c.outputWriter.Close() 126 c.PacketConn.Close() 127 return nil 128 }