feat: wireguard add dialer-proxy
config to support chain forwarding
This commit is contained in:
78
component/proxydialer/proxydialer.go
Normal file
78
component/proxydialer/proxydialer.go
Normal file
@ -0,0 +1,78 @@
|
||||
package proxydialer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
N "github.com/Dreamacro/clash/common/net"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/tunnel"
|
||||
)
|
||||
|
||||
type proxyDialer struct {
|
||||
proxy C.Proxy
|
||||
dialer C.Dialer
|
||||
}
|
||||
|
||||
func New(proxy C.Proxy, dialer C.Dialer) C.Dialer {
|
||||
return proxyDialer{proxy: proxy, dialer: dialer}
|
||||
}
|
||||
|
||||
func NewByName(proxyName string, dialer C.Dialer) (C.Dialer, error) {
|
||||
proxies := tunnel.Proxies()
|
||||
if proxy, ok := proxies[proxyName]; ok {
|
||||
return New(proxy, dialer), nil
|
||||
}
|
||||
return nil, fmt.Errorf("proxyName[%s] not found", proxyName)
|
||||
}
|
||||
|
||||
func (p proxyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
currentMeta, err := addrToMetadata(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if strings.Contains(network, "udp") { // using in wireguard outbound
|
||||
currentMeta.NetWork = C.UDP
|
||||
pc, err := p.proxy.ListenPacketWithDialer(ctx, p.dialer, currentMeta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.NewBindPacketConn(pc, currentMeta.UDPAddr()), nil
|
||||
}
|
||||
return p.proxy.DialContextWithDialer(ctx, p.dialer, currentMeta)
|
||||
}
|
||||
|
||||
func (p proxyDialer) ListenPacket(ctx context.Context, network, address string, rAddrPort netip.AddrPort) (net.PacketConn, error) {
|
||||
currentMeta, err := addrToMetadata(rAddrPort.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentMeta.NetWork = C.UDP
|
||||
return p.proxy.ListenPacketWithDialer(ctx, p.dialer, currentMeta)
|
||||
}
|
||||
|
||||
func addrToMetadata(rawAddress string) (addr *C.Metadata, err error) {
|
||||
host, port, err := net.SplitHostPort(rawAddress)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("addrToMetadata failed: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
if ip, err := netip.ParseAddr(host); err != nil {
|
||||
addr = &C.Metadata{
|
||||
Host: host,
|
||||
DstPort: port,
|
||||
}
|
||||
} else {
|
||||
addr = &C.Metadata{
|
||||
Host: "",
|
||||
DstIP: ip.Unmap(),
|
||||
DstPort: port,
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user