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  }