github.com/sagernet/sing@v0.2.6/common/metadata/serializer.go (about) 1 package metadata 2 3 import ( 4 "encoding/binary" 5 "io" 6 "net/netip" 7 8 "github.com/sagernet/sing/common" 9 "github.com/sagernet/sing/common/buf" 10 E "github.com/sagernet/sing/common/exceptions" 11 "github.com/sagernet/sing/common/rw" 12 ) 13 14 const ( 15 MaxSocksaddrLength = 2 + 255 + 2 16 MaxIPSocksaddrLength = 1 + 16 + 2 17 ) 18 19 type SerializerOption func(*Serializer) 20 21 func AddressFamilyByte(b byte, f Family) SerializerOption { 22 return func(s *Serializer) { 23 s.familyMap[b] = f 24 s.familyByteMap[f] = b 25 } 26 } 27 28 func PortThenAddress() SerializerOption { 29 return func(s *Serializer) { 30 s.portFirst = true 31 } 32 } 33 34 type Serializer struct { 35 familyMap map[byte]Family 36 familyByteMap map[Family]byte 37 portFirst bool 38 } 39 40 func NewSerializer(options ...SerializerOption) *Serializer { 41 s := &Serializer{ 42 familyMap: make(map[byte]Family), 43 familyByteMap: make(map[Family]byte), 44 } 45 for _, option := range options { 46 option(s) 47 } 48 return s 49 } 50 51 func (s *Serializer) WriteAddress(buffer *buf.Buffer, addr Socksaddr) error { 52 var af Family 53 if addr.IsIPv4() { 54 af = AddressFamilyIPv4 55 } else if addr.IsIPv6() { 56 af = AddressFamilyIPv6 57 } else { 58 af = AddressFamilyFqdn 59 } 60 err := buffer.WriteByte(s.familyByteMap[af]) 61 if err != nil { 62 return err 63 } 64 if addr.Addr.IsValid() { 65 _, err = buffer.Write(addr.Addr.AsSlice()) 66 } else { 67 err = WriteSocksString(buffer, addr.Fqdn) 68 } 69 return err 70 } 71 72 func (s *Serializer) AddressLen(addr Socksaddr) int { 73 if addr.IsIPv4() { 74 return 5 75 } else if addr.IsIPv6() { 76 return 17 77 } else { 78 return 2 + len(addr.Fqdn) 79 } 80 } 81 82 func (s *Serializer) WritePort(writer io.Writer, port uint16) error { 83 return binary.Write(writer, binary.BigEndian, port) 84 } 85 86 func (s *Serializer) WriteAddrPort(writer io.Writer, destination Socksaddr) error { 87 buffer, isBuffer := writer.(*buf.Buffer) 88 if !isBuffer { 89 buffer = buf.NewSize(s.AddrPortLen(destination)) 90 defer buffer.Release() 91 } 92 var err error 93 if !s.portFirst { 94 err = s.WriteAddress(buffer, destination) 95 } else { 96 err = s.WritePort(buffer, destination.Port) 97 } 98 if err != nil { 99 return err 100 } 101 if s.portFirst { 102 err = s.WriteAddress(buffer, destination) 103 } else { 104 err = s.WritePort(buffer, destination.Port) 105 } 106 if err != nil { 107 return err 108 } 109 if !isBuffer { 110 err = rw.WriteBytes(writer, buffer.Bytes()) 111 } 112 return err 113 } 114 115 func (s *Serializer) AddrPortLen(destination Socksaddr) int { 116 return s.AddressLen(destination) + 2 117 } 118 119 func (s *Serializer) ReadAddress(reader io.Reader) (Socksaddr, error) { 120 af, err := rw.ReadByte(reader) 121 if err != nil { 122 return Socksaddr{}, err 123 } 124 family := s.familyMap[af] 125 switch family { 126 case AddressFamilyFqdn: 127 fqdn, err := ReadSockString(reader) 128 if err != nil { 129 return Socksaddr{}, E.Cause(err, "read fqdn") 130 } 131 return ParseSocksaddrHostPort(fqdn, 0), nil 132 default: 133 switch family { 134 case AddressFamilyIPv4: 135 var addr [4]byte 136 err = common.Error(reader.Read(addr[:])) 137 if err != nil { 138 return Socksaddr{}, E.Cause(err, "read ipv4 address") 139 } 140 return Socksaddr{Addr: netip.AddrFrom4(addr)}, nil 141 case AddressFamilyIPv6: 142 var addr [16]byte 143 err = common.Error(reader.Read(addr[:])) 144 if err != nil { 145 return Socksaddr{}, E.Cause(err, "read ipv6 address") 146 } 147 148 return Socksaddr{Addr: netip.AddrFrom16(addr)}.Unwrap(), nil 149 default: 150 return Socksaddr{}, E.New("unknown address family: ", af) 151 } 152 } 153 } 154 155 func (s *Serializer) ReadPort(reader io.Reader) (uint16, error) { 156 port, err := rw.ReadBytes(reader, 2) 157 if err != nil { 158 return 0, E.Cause(err, "read port") 159 } 160 return binary.BigEndian.Uint16(port), nil 161 } 162 163 func (s *Serializer) ReadAddrPort(reader io.Reader) (destination Socksaddr, err error) { 164 var addr Socksaddr 165 var port uint16 166 if !s.portFirst { 167 addr, err = s.ReadAddress(reader) 168 } else { 169 port, err = s.ReadPort(reader) 170 } 171 if err != nil { 172 return 173 } 174 if s.portFirst { 175 addr, err = s.ReadAddress(reader) 176 } else { 177 port, err = s.ReadPort(reader) 178 } 179 if err != nil { 180 return 181 } 182 addr.Port = port 183 return addr, nil 184 } 185 186 func ReadSockString(reader io.Reader) (string, error) { 187 strLen, err := rw.ReadByte(reader) 188 if err != nil { 189 return "", err 190 } 191 return rw.ReadString(reader, int(strLen)) 192 } 193 194 func WriteSocksString(buffer *buf.Buffer, str string) error { 195 strLen := len(str) 196 if strLen > 255 { 197 return E.New("fqdn too long") 198 } 199 err := buffer.WriteByte(byte(strLen)) 200 if err != nil { 201 return err 202 } 203 return common.Error(buffer.WriteString(str)) 204 }