github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/uot/protocol.go (about) 1 package uot 2 3 import ( 4 "encoding/binary" 5 "io" 6 7 "github.com/sagernet/sing/common" 8 "github.com/sagernet/sing/common/buf" 9 M "github.com/sagernet/sing/common/metadata" 10 ) 11 12 const ( 13 Version = 2 14 LegacyVersion = 1 15 MagicAddress = "sp.v2.udp-over-tcp.arpa" 16 LegacyMagicAddress = "sp.udp-over-tcp.arpa" 17 ) 18 19 var AddrParser = M.NewSerializer( 20 M.AddressFamilyByte(0x00, M.AddressFamilyIPv4), 21 M.AddressFamilyByte(0x01, M.AddressFamilyIPv6), 22 M.AddressFamilyByte(0x02, M.AddressFamilyFqdn), 23 ) 24 25 func RequestDestination(version uint8) M.Socksaddr { 26 switch version { 27 case 0, Version: 28 return M.Socksaddr{Fqdn: MagicAddress} 29 default: 30 fallthrough 31 case LegacyVersion: 32 return M.Socksaddr{Fqdn: LegacyMagicAddress} 33 } 34 } 35 36 type Request struct { 37 IsConnect bool 38 Destination M.Socksaddr 39 } 40 41 func ReadRequest(reader io.Reader) (*Request, error) { 42 var request Request 43 err := binary.Read(reader, binary.BigEndian, &request.IsConnect) 44 if err != nil { 45 return nil, err 46 } 47 request.Destination, err = M.SocksaddrSerializer.ReadAddrPort(reader) 48 if err != nil { 49 return nil, err 50 } 51 return &request, nil 52 } 53 54 func EncodeRequest(request Request) (*buf.Buffer, error) { 55 var bufferLen int 56 bufferLen += 1 // isConnect 57 bufferLen += M.SocksaddrSerializer.AddrPortLen(request.Destination) 58 buffer := buf.NewSize(bufferLen) 59 common.Must(binary.Write(buffer, binary.BigEndian, request.IsConnect)) 60 err := M.SocksaddrSerializer.WriteAddrPort(buffer, request.Destination) 61 if err != nil { 62 buffer.Release() 63 return nil, err 64 } 65 return buffer, nil 66 } 67 68 func WriteRequest(writer io.Writer, request Request) error { 69 buffer, err := EncodeRequest(request) 70 if err != nil { 71 return err 72 } 73 defer buffer.Release() 74 return common.Error(writer.Write(buffer.Bytes())) 75 }