github.com/igoogolx/clash@v1.19.8/constant/metadata.go (about)

     1  package constant
     2  
     3  import (
     4  	"encoding/json"
     5  	"net"
     6  	"net/netip"
     7  	"strconv"
     8  
     9  	"github.com/igoogolx/clash/transport/socks5"
    10  )
    11  
    12  // Socks addr type
    13  const (
    14  	TCP NetWork = iota
    15  	UDP
    16  
    17  	HTTP Type = iota
    18  	HTTPCONNECT
    19  	SOCKS4
    20  	SOCKS5
    21  	REDIR
    22  	TPROXY
    23  	TUNNEL
    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  	case TUNNEL:
    56  		return "Tunnel"
    57  	default:
    58  		return "Unknown"
    59  	}
    60  }
    61  
    62  func (t Type) MarshalJSON() ([]byte, error) {
    63  	return json.Marshal(t.String())
    64  }
    65  
    66  // Metadata is used to store connection address
    67  type Metadata struct {
    68  	NetWork      NetWork `json:"network"`
    69  	Type         Type    `json:"type"`
    70  	SrcIP        net.IP  `json:"sourceIP"`
    71  	DstIP        net.IP  `json:"destinationIP"`
    72  	SrcPort      Port    `json:"sourcePort"`
    73  	DstPort      Port    `json:"destinationPort"`
    74  	Host         string  `json:"host"`
    75  	DNSMode      DNSMode `json:"dnsMode"`
    76  	ProcessPath  string  `json:"processPath"`
    77  	SpecialProxy string  `json:"specialProxy"`
    78  
    79  	OriginDst netip.AddrPort `json:"-"`
    80  }
    81  
    82  func (m *Metadata) RemoteAddress() string {
    83  	return net.JoinHostPort(m.String(), m.DstPort.String())
    84  }
    85  
    86  func (m *Metadata) SourceAddress() string {
    87  	return net.JoinHostPort(m.SrcIP.String(), m.SrcPort.String())
    88  }
    89  
    90  func (m *Metadata) AddrType() int {
    91  	switch true {
    92  	case m.Host != "" || m.DstIP == nil:
    93  		return socks5.AtypDomainName
    94  	case m.DstIP.To4() != nil:
    95  		return socks5.AtypIPv4
    96  	default:
    97  		return socks5.AtypIPv6
    98  	}
    99  }
   100  
   101  func (m *Metadata) Resolved() bool {
   102  	return m.DstIP != nil
   103  }
   104  
   105  // Pure is used to solve unexpected behavior
   106  // when dialing proxy connection in DNSMapping mode.
   107  func (m *Metadata) Pure() *Metadata {
   108  	if m.DNSMode == DNSMapping && m.DstIP != nil {
   109  		copy := *m
   110  		copy.Host = ""
   111  		return &copy
   112  	}
   113  
   114  	return m
   115  }
   116  
   117  func (m *Metadata) UDPAddr() *net.UDPAddr {
   118  	if m.NetWork != UDP || m.DstIP == nil {
   119  		return nil
   120  	}
   121  	return &net.UDPAddr{
   122  		IP:   m.DstIP,
   123  		Port: int(m.DstPort),
   124  	}
   125  }
   126  
   127  func (m *Metadata) String() string {
   128  	if m.Host != "" {
   129  		return m.Host
   130  	} else if m.DstIP != nil {
   131  		return m.DstIP.String()
   132  	} else {
   133  		return "<nil>"
   134  	}
   135  }
   136  
   137  func (m *Metadata) Valid() bool {
   138  	return m.Host != "" || m.DstIP != nil
   139  }
   140  
   141  // Port is used to compatible with old version
   142  type Port uint16
   143  
   144  func (n Port) MarshalJSON() ([]byte, error) {
   145  	return json.Marshal(n.String())
   146  }
   147  
   148  func (n Port) String() string {
   149  	return strconv.FormatUint(uint64(n), 10)
   150  }