github.com/chwjbn/xclash@v0.2.0/constant/metadata.go (about)

     1  package constant
     2  
     3  import (
     4  	"encoding/json"
     5  	"net"
     6  	"strconv"
     7  )
     8  
     9  // Socks addr type
    10  const (
    11  	AtypIPv4       = 1
    12  	AtypDomainName = 3
    13  	AtypIPv6       = 4
    14  
    15  	TCP NetWork = iota
    16  	UDP
    17  
    18  	HTTP Type = iota
    19  	HTTPCONNECT
    20  	SOCKS4
    21  	SOCKS5
    22  	REDIR
    23  	TPROXY
    24  )
    25  
    26  type NetWork int
    27  
    28  func (n NetWork) String() string {
    29  	if n == TCP {
    30  		return "tcp"
    31  	}
    32  	return "udp"
    33  }
    34  
    35  func (n NetWork) MarshalJSON() ([]byte, error) {
    36  	return json.Marshal(n.String())
    37  }
    38  
    39  type Type int
    40  
    41  func (t Type) String() string {
    42  	switch t {
    43  	case HTTP:
    44  		return "HTTP"
    45  	case HTTPCONNECT:
    46  		return "HTTP Connect"
    47  	case SOCKS4:
    48  		return "Socks4"
    49  	case SOCKS5:
    50  		return "Socks5"
    51  	case REDIR:
    52  		return "Redir"
    53  	case TPROXY:
    54  		return "TProxy"
    55  	default:
    56  		return "Unknown"
    57  	}
    58  }
    59  
    60  func (t Type) MarshalJSON() ([]byte, error) {
    61  	return json.Marshal(t.String())
    62  }
    63  
    64  // Metadata is used to store connection address
    65  type Metadata struct {
    66  	NetWork  NetWork `json:"network"`
    67  	Type     Type    `json:"type"`
    68  	SrcIP    net.IP  `json:"sourceIP"`
    69  	DstIP    net.IP  `json:"destinationIP"`
    70  	SrcPort  string  `json:"sourcePort"`
    71  	DstPort  string  `json:"destinationPort"`
    72  	AddrType int     `json:"-"`
    73  	Host     string  `json:"host"`
    74  	DNSMode  DNSMode `json:"dnsMode"`
    75  }
    76  
    77  func (m *Metadata) RemoteAddress() string {
    78  	return net.JoinHostPort(m.String(), m.DstPort)
    79  }
    80  
    81  func (m *Metadata) SourceAddress() string {
    82  	return net.JoinHostPort(m.SrcIP.String(), m.SrcPort)
    83  }
    84  
    85  func (m *Metadata) Resolved() bool {
    86  	return m.DstIP != nil
    87  }
    88  
    89  // Pure is used to solve unexpected behavior
    90  // when dialing proxy connection in DNSMapping mode.
    91  func (m *Metadata) Pure() *Metadata {
    92  	if m.DNSMode == DNSMapping && m.DstIP != nil {
    93  		copy := *m
    94  		copy.Host = ""
    95  		if copy.DstIP.To4() != nil {
    96  			copy.AddrType = AtypIPv4
    97  		} else {
    98  			copy.AddrType = AtypIPv6
    99  		}
   100  		return &copy
   101  	}
   102  
   103  	return m
   104  }
   105  
   106  func (m *Metadata) UDPAddr() *net.UDPAddr {
   107  	if m.NetWork != UDP || m.DstIP == nil {
   108  		return nil
   109  	}
   110  	port, _ := strconv.ParseUint(m.DstPort, 10, 16)
   111  	return &net.UDPAddr{
   112  		IP:   m.DstIP,
   113  		Port: int(port),
   114  	}
   115  }
   116  
   117  func (m *Metadata) String() string {
   118  	if m.Host != "" {
   119  		return m.Host
   120  	} else if m.DstIP != nil {
   121  		return m.DstIP.String()
   122  	} else {
   123  		return "<nil>"
   124  	}
   125  }
   126  
   127  func (m *Metadata) Valid() bool {
   128  	return m.Host != "" || m.DstIP != nil
   129  }