github.com/yaling888/clash@v1.53.0/constant/metadata.go (about)

     1  package constant
     2  
     3  import (
     4  	"encoding/json"
     5  	"net"
     6  	"net/netip"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/phuslu/log"
    11  
    12  	"github.com/yaling888/clash/transport/socks5"
    13  )
    14  
    15  var MetadataTypeMapping = map[string]Type{
    16  	strings.ToLower(HTTP.String()):        HTTP,
    17  	strings.ToLower(HTTPCONNECT.String()): HTTPCONNECT,
    18  	strings.ToLower(SOCKS4.String()):      SOCKS4,
    19  	strings.ToLower(SOCKS5.String()):      SOCKS5,
    20  	strings.ToLower(REDIR.String()):       REDIR,
    21  	strings.ToLower(TPROXY.String()):      TPROXY,
    22  	strings.ToLower(TUN.String()):         TUN,
    23  	strings.ToLower(MITM.String()):        MITM,
    24  	strings.ToLower(TUNNEL.String()):      TUNNEL,
    25  }
    26  
    27  // Socks addr type
    28  const (
    29  	TCP NetWork = iota
    30  	UDP
    31  	ALLNet
    32  )
    33  
    34  const (
    35  	HTTP Type = iota
    36  	HTTPCONNECT
    37  	SOCKS4
    38  	SOCKS5
    39  	REDIR
    40  	TPROXY
    41  	TUN
    42  	MITM
    43  	TUNNEL
    44  )
    45  
    46  type NetWork int
    47  
    48  func (n NetWork) String() string {
    49  	if n == TCP {
    50  		return "tcp"
    51  	} else if n == UDP {
    52  		return "udp"
    53  	}
    54  	return "all"
    55  }
    56  
    57  func (n NetWork) MarshalJSON() ([]byte, error) {
    58  	return json.Marshal(n.String())
    59  }
    60  
    61  type Type int
    62  
    63  func (t Type) String() string {
    64  	switch t {
    65  	case HTTP:
    66  		return "HTTP"
    67  	case HTTPCONNECT:
    68  		return "HTTP Connect"
    69  	case SOCKS4:
    70  		return "Socks4"
    71  	case SOCKS5:
    72  		return "Socks5"
    73  	case REDIR:
    74  		return "Redir"
    75  	case TPROXY:
    76  		return "TProxy"
    77  	case TUN:
    78  		return "TUN"
    79  	case MITM:
    80  		return "MITM"
    81  	case TUNNEL:
    82  		return "Tunnel"
    83  	default:
    84  		return "Unknown"
    85  	}
    86  }
    87  
    88  func (t Type) MarshalJSON() ([]byte, error) {
    89  	return json.Marshal(t.String())
    90  }
    91  
    92  // Metadata is used to store connection address
    93  type Metadata struct {
    94  	NetWork      NetWork    `json:"network"`
    95  	Type         Type       `json:"type"`
    96  	SrcIP        netip.Addr `json:"sourceIP"`
    97  	DstIP        netip.Addr `json:"destinationIP"`
    98  	SrcPort      Port       `json:"sourcePort"`
    99  	DstPort      Port       `json:"destinationPort"`
   100  	Host         string     `json:"host"`
   101  	DNSMode      DNSMode    `json:"dnsMode"`
   102  	Process      string     `json:"process"`
   103  	ProcessPath  string     `json:"processPath"`
   104  	UserAgent    string     `json:"userAgent"`
   105  	SpecialProxy string     `json:"specialProxy"`
   106  
   107  	OriginDst netip.AddrPort `json:"-"`
   108  }
   109  
   110  func (m *Metadata) RemoteAddress() string {
   111  	return net.JoinHostPort(m.String(), m.DstPort.String())
   112  }
   113  
   114  func (m *Metadata) SourceAddress() string {
   115  	return net.JoinHostPort(m.SrcIP.String(), m.SrcPort.String())
   116  }
   117  
   118  func (m *Metadata) AddrType() int {
   119  	switch true {
   120  	case m.DstIP.Is4():
   121  		return socks5.AtypIPv4
   122  	case m.DstIP.Is6():
   123  		return socks5.AtypIPv6
   124  	default:
   125  		return socks5.AtypDomainName
   126  	}
   127  }
   128  
   129  func (m *Metadata) Resolved() bool {
   130  	return m.DstIP.IsValid()
   131  }
   132  
   133  func (m *Metadata) UDPAddr() *net.UDPAddr {
   134  	if m.NetWork != UDP || !m.DstIP.IsValid() {
   135  		return nil
   136  	}
   137  	return &net.UDPAddr{
   138  		IP:   m.DstIP.AsSlice(),
   139  		Port: int(m.DstPort),
   140  	}
   141  }
   142  
   143  func (m *Metadata) String() string {
   144  	if m.Host != "" {
   145  		return m.Host
   146  	} else if m.DstIP.IsValid() {
   147  		return m.DstIP.String()
   148  	} else {
   149  		return "<nil>"
   150  	}
   151  }
   152  
   153  func (m *Metadata) Valid() bool {
   154  	return m.Host != "" || m.DstIP.IsValid()
   155  }
   156  
   157  func (m *Metadata) TypeFromString(s string) {
   158  	if _type, ok := MetadataTypeMapping[strings.ToLower(s)]; ok {
   159  		m.Type = _type
   160  	} else {
   161  		m.Type = -1
   162  	}
   163  }
   164  
   165  func (m *Metadata) NetworkFromString(s string) {
   166  	switch strings.ToLower(s) {
   167  	case "tcp":
   168  		m.NetWork = TCP
   169  	case "udp":
   170  		m.NetWork = UDP
   171  	default:
   172  		m.NetWork = ALLNet
   173  	}
   174  }
   175  
   176  func (m *Metadata) MarshalObject(e *log.Entry) {
   177  	e.Str("lAddr", m.SourceAddress()).Str("rAddr", m.RemoteAddress())
   178  
   179  	if m.Process != "" {
   180  		e.Str("process", m.Process)
   181  	}
   182  
   183  	if m.UserAgent != "" {
   184  		e.Str("userAgent", m.UserAgent)
   185  	}
   186  }
   187  
   188  // Port is used to compatible with old version
   189  type Port uint16
   190  
   191  func (n Port) MarshalJSON() ([]byte, error) {
   192  	return json.Marshal(n.String())
   193  }
   194  
   195  func (n Port) String() string {
   196  	return strconv.FormatUint(uint64(n), 10)
   197  }
   198  
   199  type LogAddr struct {
   200  	M        Metadata
   201  	Src      bool
   202  	HostOnly bool
   203  }
   204  
   205  func (l LogAddr) String() string {
   206  	if l.HostOnly {
   207  		return l.M.String()
   208  	}
   209  	if !l.Src {
   210  		return l.M.RemoteAddress()
   211  	}
   212  	return l.M.SourceAddress()
   213  }