github.com/yaling888/clash@v1.53.0/adapter/outbound/base.go (about) 1 package outbound 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "io" 8 "net" 9 10 "github.com/yaling888/clash/component/dialer" 11 C "github.com/yaling888/clash/constant" 12 ) 13 14 type Base struct { 15 name string 16 addr string 17 iface string 18 tp C.AdapterType 19 udp bool 20 dns bool 21 rmark int 22 } 23 24 // Name implements C.ProxyAdapter 25 func (b *Base) Name() string { 26 return b.name 27 } 28 29 // Type implements C.ProxyAdapter 30 func (b *Base) Type() C.AdapterType { 31 return b.tp 32 } 33 34 // StreamConn implements C.ProxyAdapter 35 func (b *Base) StreamConn(c net.Conn, _ *C.Metadata) (net.Conn, error) { 36 return c, errors.New("no support") 37 } 38 39 // StreamPacketConn implements C.ProxyAdapter 40 func (b *Base) StreamPacketConn(c net.Conn, _ *C.Metadata) (net.Conn, error) { 41 return c, errors.New("no support") 42 } 43 44 // ListenPacketContext implements C.ProxyAdapter 45 func (b *Base) ListenPacketContext(_ context.Context, _ *C.Metadata, _ ...dialer.Option) (C.PacketConn, error) { 46 return nil, errors.New("no support") 47 } 48 49 // SupportUDP implements C.ProxyAdapter 50 func (b *Base) SupportUDP() bool { 51 return b.udp 52 } 53 54 // DisableDnsResolve implements C.DisableDnsResolve 55 func (b *Base) DisableDnsResolve() bool { 56 return !b.dns 57 } 58 59 // MarshalJSON implements C.ProxyAdapter 60 func (b *Base) MarshalJSON() ([]byte, error) { 61 return json.Marshal(map[string]string{ 62 "type": b.Type().String(), 63 }) 64 } 65 66 // Addr implements C.ProxyAdapter 67 func (b *Base) Addr() string { 68 return b.addr 69 } 70 71 // Unwrap implements C.ProxyAdapter 72 func (b *Base) Unwrap(_ *C.Metadata) C.Proxy { 73 return nil 74 } 75 76 // Cleanup implements C.ProxyAdapter 77 func (b *Base) Cleanup() {} 78 79 // DialOptions return []dialer.Option from struct 80 func (b *Base) DialOptions(opts ...dialer.Option) []dialer.Option { 81 if b.iface != "" { 82 opts = append(opts, dialer.WithInterface(b.iface)) 83 } 84 85 if b.rmark != 0 { 86 opts = append(opts, dialer.WithRoutingMark(b.rmark)) 87 } 88 89 return opts 90 } 91 92 type BasicOption struct { 93 Interface string `proxy:"interface-name,omitempty" group:"interface-name,omitempty"` 94 RoutingMark int `proxy:"routing-mark,omitempty" group:"routing-mark,omitempty"` 95 } 96 97 type BaseOption struct { 98 Name string 99 Addr string 100 Type C.AdapterType 101 UDP bool 102 Interface string 103 RoutingMark int 104 } 105 106 func NewBase(opt BaseOption) *Base { 107 return &Base{ 108 name: opt.Name, 109 addr: opt.Addr, 110 tp: opt.Type, 111 udp: opt.UDP, 112 iface: opt.Interface, 113 rmark: opt.RoutingMark, 114 } 115 } 116 117 type conn struct { 118 net.Conn 119 chain C.Chain 120 } 121 122 // Chains implements C.Connection 123 func (c *conn) Chains() C.Chain { 124 return c.chain 125 } 126 127 // AppendToChains implements C.Connection 128 func (c *conn) AppendToChains(a C.ProxyAdapter) { 129 c.chain = append(c.chain, a.Name()) 130 } 131 132 // SetChains implements C.Connection 133 func (c *conn) SetChains(chains []string) { 134 c.chain = chains 135 } 136 137 func (c *conn) String() string { 138 return c.Chains().String() 139 } 140 141 func NewConn(c net.Conn, a C.ProxyAdapter) C.Conn { 142 return &conn{c, []string{a.Name()}} 143 } 144 145 type packetConn struct { 146 net.PacketConn 147 chain C.Chain 148 } 149 150 // Chains implements C.Connection 151 func (c *packetConn) Chains() C.Chain { 152 return c.chain 153 } 154 155 // AppendToChains implements C.Connection 156 func (c *packetConn) AppendToChains(a C.ProxyAdapter) { 157 c.chain = append(c.chain, a.Name()) 158 } 159 160 // SetChains implements C.Connection 161 func (c *packetConn) SetChains(chains []string) { 162 c.chain = chains 163 } 164 165 func (c *packetConn) String() string { 166 return c.Chains().String() 167 } 168 169 func NewPacketConn(pc net.PacketConn, a C.ProxyAdapter) C.PacketConn { 170 return &packetConn{pc, []string{a.Name()}} 171 } 172 173 type wrapConn struct { 174 net.PacketConn 175 } 176 177 func (*wrapConn) Read([]byte) (int, error) { 178 return 0, io.EOF 179 } 180 181 func (*wrapConn) Write([]byte) (int, error) { 182 return 0, io.EOF 183 } 184 185 func (*wrapConn) RemoteAddr() net.Addr { 186 return nil 187 } 188 189 func WrapConn(packetConn net.PacketConn) net.Conn { 190 return &wrapConn{ 191 PacketConn: packetConn, 192 } 193 } 194 195 func IsPacketConn(c net.Conn) bool { 196 if _, ok := c.(net.PacketConn); !ok { 197 return false 198 } 199 200 if ua, ok := c.LocalAddr().(*net.UnixAddr); ok { 201 return ua.Net == "unixgram" 202 } 203 204 return true 205 }