mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2025-10-09 02:30:05 +08:00
97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
package adapter
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net"
|
|
"strconv"
|
|
|
|
"github.com/xjasonlyu/clash/component/socks5"
|
|
)
|
|
|
|
const (
|
|
TCP Network = iota
|
|
UDP
|
|
)
|
|
|
|
type Network int
|
|
|
|
func (n Network) String() string {
|
|
if n == TCP {
|
|
return "tcp"
|
|
}
|
|
return "udp"
|
|
}
|
|
|
|
func (n Network) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(n.String())
|
|
}
|
|
|
|
// Metadata implements the net.Addr interface.
|
|
type Metadata struct {
|
|
Net Network `json:"network"`
|
|
SrcIP net.IP `json:"sourceIP"`
|
|
MidIP net.IP `json:"dialerIP"`
|
|
DstIP net.IP `json:"destinationIP"`
|
|
SrcPort uint16 `json:"sourcePort"`
|
|
MidPort uint16 `json:"dialerPort"`
|
|
DstPort uint16 `json:"destinationPort"`
|
|
Host string `json:"host"`
|
|
}
|
|
|
|
func (m *Metadata) DestinationAddress() string {
|
|
if m.Host != "" {
|
|
return net.JoinHostPort(m.Host, strconv.FormatUint(uint64(m.DstPort), 10))
|
|
} else if m.DstIP != nil {
|
|
return net.JoinHostPort(m.DstIP.String(), strconv.FormatUint(uint64(m.DstPort), 10))
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (m *Metadata) SourceAddress() string {
|
|
return net.JoinHostPort(m.SrcIP.String(), strconv.FormatUint(uint64(m.SrcPort), 10))
|
|
}
|
|
|
|
func (m *Metadata) UDPAddr() *net.UDPAddr {
|
|
if m.Net != UDP || m.DstIP == nil {
|
|
return nil
|
|
}
|
|
return &net.UDPAddr{
|
|
IP: m.DstIP,
|
|
Port: int(m.DstPort),
|
|
}
|
|
}
|
|
|
|
func (m *Metadata) SerializesSocksAddr() socks5.Addr {
|
|
var buf [][]byte
|
|
port := []byte{uint8(m.DstPort >> 8), uint8(m.DstPort & 0xff)}
|
|
switch {
|
|
case m.Host != "": /* Domain */
|
|
aType := socks5.AtypDomainName
|
|
length := uint8(len(m.Host))
|
|
host := []byte(m.Host)
|
|
buf = [][]byte{{uint8(aType), length}, host, port}
|
|
case m.DstIP.To4() != nil: /* IPv4 */
|
|
aType := socks5.AtypIPv4
|
|
host := m.DstIP.To4()
|
|
buf = [][]byte{{uint8(aType)}, host, port}
|
|
default: /* IPv6 */
|
|
aType := socks5.AtypIPv6
|
|
host := m.DstIP.To16()
|
|
buf = [][]byte{{uint8(aType)}, host, port}
|
|
}
|
|
return bytes.Join(buf, nil)
|
|
}
|
|
|
|
func (m *Metadata) Network() string {
|
|
return m.Net.String()
|
|
}
|
|
|
|
func (m *Metadata) String() string {
|
|
return m.DestinationAddress()
|
|
}
|
|
|
|
func (m *Metadata) Valid() bool {
|
|
return m.Host != "" || m.DstIP != nil
|
|
}
|