github.com/xxf098/lite-proxy@v0.15.1-0.20230422081941-12c69f323218/tunnel/metadata.go (about)

     1  package tunnel
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"net"
     9  	"strconv"
    10  
    11  	"github.com/xxf098/lite-proxy/common"
    12  )
    13  
    14  type AddressType byte
    15  
    16  const (
    17  	IPv4       AddressType = 1
    18  	DomainName AddressType = 3
    19  	IPv6       AddressType = 4
    20  )
    21  
    22  type Address struct {
    23  	DomainName  string
    24  	Port        int
    25  	NetworkType string
    26  	net.IP
    27  	AddressType
    28  }
    29  
    30  func (a *Address) String() string {
    31  	switch a.AddressType {
    32  	case IPv4:
    33  		return fmt.Sprintf("%s:%d", a.IP.String(), a.Port)
    34  	case IPv6:
    35  		return fmt.Sprintf("[%s]:%d", a.IP.String(), a.Port)
    36  	case DomainName:
    37  		return fmt.Sprintf("%s:%d", a.DomainName, a.Port)
    38  	default:
    39  		return "INVALID_ADDRESS_TYPE"
    40  	}
    41  }
    42  
    43  func (a *Address) Network() string {
    44  	return a.NetworkType
    45  }
    46  
    47  func (a *Address) ResolveIP() (net.IP, error) {
    48  	if a.AddressType == IPv4 || a.AddressType == IPv6 {
    49  		return a.IP, nil
    50  	}
    51  	if a.IP != nil {
    52  		return a.IP, nil
    53  	}
    54  	addr, err := net.ResolveIPAddr("ip", a.DomainName)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	a.IP = addr.IP
    59  	return addr.IP, nil
    60  }
    61  
    62  func (a *Address) ReadFrom(r io.Reader) error {
    63  	byteBuf := [1]byte{}
    64  	_, err := io.ReadFull(r, byteBuf[:])
    65  	if err != nil {
    66  		return common.NewError("unable to read ATYP").Base(err)
    67  	}
    68  	a.AddressType = AddressType(byteBuf[0])
    69  	switch a.AddressType {
    70  	case IPv4:
    71  		var buf [6]byte
    72  		_, err := io.ReadFull(r, buf[:])
    73  		if err != nil {
    74  			return common.NewError("failed to read IPv4").Base(err)
    75  		}
    76  		a.IP = buf[0:4]
    77  		a.Port = int(binary.BigEndian.Uint16(buf[4:6]))
    78  	case IPv6:
    79  		var buf [18]byte
    80  		_, err := io.ReadFull(r, buf[:])
    81  		if err != nil {
    82  			return common.NewError("failed to read IPv6").Base(err)
    83  		}
    84  		a.IP = buf[0:16]
    85  		a.Port = int(binary.BigEndian.Uint16(buf[16:18]))
    86  	case DomainName:
    87  		_, err := io.ReadFull(r, byteBuf[:])
    88  		length := byteBuf[0]
    89  		if err != nil {
    90  			return common.NewError("failed to read domain name length")
    91  		}
    92  		buf := make([]byte, length+2)
    93  		_, err = io.ReadFull(r, buf)
    94  		if err != nil {
    95  			return common.NewError("failed to read domain name")
    96  		}
    97  		//the fucking browser uses IP as a domain name sometimes
    98  		host := buf[0:length]
    99  		if ip := net.ParseIP(string(host)); ip != nil {
   100  			a.IP = ip
   101  			if ip.To4() != nil {
   102  				a.AddressType = IPv4
   103  			} else {
   104  				a.AddressType = IPv6
   105  			}
   106  		} else {
   107  			a.DomainName = string(host)
   108  		}
   109  		a.Port = int(binary.BigEndian.Uint16(buf[length : length+2]))
   110  	default:
   111  		return common.NewError("invalid ATYP " + strconv.FormatInt(int64(a.AddressType), 10))
   112  	}
   113  	return nil
   114  }
   115  
   116  func (a *Address) WriteTo(w io.Writer) error {
   117  	_, err := w.Write([]byte{byte(a.AddressType)})
   118  	switch a.AddressType {
   119  	case DomainName:
   120  		w.Write([]byte{byte(len(a.DomainName))})
   121  		_, err = w.Write([]byte(a.DomainName))
   122  	case IPv4:
   123  		_, err = w.Write(a.IP.To4())
   124  	case IPv6:
   125  		_, err = w.Write(a.IP.To16())
   126  	default:
   127  		return common.NewError("invalid ATYP " + strconv.FormatInt(int64(a.AddressType), 10))
   128  	}
   129  	if err != nil {
   130  		return err
   131  	}
   132  	port := [2]byte{}
   133  	binary.BigEndian.PutUint16(port[:], uint16(a.Port))
   134  	_, err = w.Write(port[:])
   135  	return err
   136  }
   137  
   138  func NewAddressFromAddr(network string, addr string) (*Address, error) {
   139  	host, portStr, err := net.SplitHostPort(addr)
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  	port, err := strconv.ParseInt(portStr, 10, 32)
   144  	if err != nil {
   145  		log.Fatalln(err)
   146  	}
   147  	return NewAddressFromHostPort(network, host, int(port)), nil
   148  }
   149  
   150  func NewAddressFromHostPort(network string, host string, port int) *Address {
   151  	if ip := net.ParseIP(host); ip != nil {
   152  		if ip.To4() != nil {
   153  			return &Address{
   154  				IP:          ip,
   155  				Port:        int(port),
   156  				AddressType: IPv4,
   157  				NetworkType: network,
   158  			}
   159  		}
   160  		return &Address{
   161  			IP:          ip,
   162  			Port:        int(port),
   163  			AddressType: IPv6,
   164  			NetworkType: network,
   165  		}
   166  	}
   167  	return &Address{
   168  		DomainName:  host,
   169  		Port:        int(port),
   170  		AddressType: DomainName,
   171  		NetworkType: network,
   172  	}
   173  }
   174  
   175  type Command byte
   176  
   177  type Metadata struct {
   178  	Command
   179  	*Address
   180  }