Skip to content

Commit

Permalink
🦩 service: choose listen network for outgoing sockets automatically
Browse files Browse the repository at this point in the history
Manual configuration on systems without dual-stack sockets is no longer required.
  • Loading branch information
database64128 committed Oct 30, 2024
1 parent ef02f03 commit 26aed42
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 161 deletions.
13 changes: 13 additions & 0 deletions conn/sockaddr_notwindows.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ func AddrPortToSockaddr(addrPort netip.AddrPort) (name *byte, namelen uint32) {
return
}

func AddrPortToSockaddrWithAddressFamily(addrPort netip.AddrPort, is4 bool) (name *byte, namelen uint32) {
if is4 {
rsa4 := AddrPortToSockaddrInet4(addrPort)
name = (*byte)(unsafe.Pointer(&rsa4))
namelen = unix.SizeofSockaddrInet4
} else {
rsa6 := AddrPortToSockaddrInet6(addrPort)
name = (*byte)(unsafe.Pointer(&rsa6))
namelen = unix.SizeofSockaddrInet6
}
return
}

func SockaddrToAddrPort(name *byte, namelen uint32) (netip.AddrPort, error) {
switch namelen {
case unix.SizeofSockaddrInet4:
Expand Down
2 changes: 0 additions & 2 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"proxyTrafficClass": 0,
"wgEndpointNetwork": "",
"wgEndpoint": "[::1]:20221",
"wgConnListenNetwork": "",
"wgConnListenAddress": "",
"wgFwmark": 0,
"wgTrafficClass": 0,
Expand All @@ -32,7 +31,6 @@
"wgTrafficClass": 0,
"proxyEndpointNetwork": "",
"proxyEndpoint": "[2001:db8:1f74:3c86:aef9:a75:5d2a:425e]:20220",
"proxyConnListenNetwork": "",
"proxyConnListenAddress": "",
"proxyMode": "zero-overhead",
"proxyPSK": "sAe5RvzLJ3Q0Ll88QRM1N01dYk83Q4y0rXMP1i4rDmI=",
Expand Down
102 changes: 57 additions & 45 deletions service/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ type ClientConfig struct {
WgTrafficClass int `json:"wgTrafficClass"`
ProxyEndpointNetwork string `json:"proxyEndpointNetwork"`
ProxyEndpointAddress conn.Addr `json:"proxyEndpoint"`
ProxyConnListenNetwork string `json:"proxyConnListenNetwork"`
ProxyConnListenAddress string `json:"proxyConnListenAddress"`
ProxyMode string `json:"proxyMode"`
ProxyPSK []byte `json:"proxyPSK"`
Expand Down Expand Up @@ -55,31 +54,32 @@ type clientNatEntry struct {
}

type clientNatUplinkGeneric struct {
clientAddrPort netip.AddrPort
proxyAddrPort netip.AddrPort
proxyConn *net.UDPConn
proxyConnInfo conn.SocketInfo
proxyConnSendCh <-chan queuedPacket
handler packet.Handler
clientAddrPort netip.AddrPort
proxyConnListenAddrPort netip.AddrPort
proxyAddrPort netip.AddrPort
proxyConn *net.UDPConn
proxyConnInfo conn.SocketInfo
proxyConnSendCh <-chan queuedPacket
handler packet.Handler
}

type clientNatDownlinkGeneric struct {
clientAddrPort netip.AddrPort
clientPktinfop *pktinfo
clientPktinfo *atomic.Pointer[pktinfo]
proxyAddrPort netip.AddrPort
proxyConn *net.UDPConn
wgConn *net.UDPConn
wgConnInfo conn.SocketInfo
handler packet.Handler
maxProxyPacketSize int
clientAddrPort netip.AddrPort
clientPktinfop *pktinfo
clientPktinfo *atomic.Pointer[pktinfo]
proxyConnListenAddrPort netip.AddrPort
proxyAddrPort netip.AddrPort
proxyConn *net.UDPConn
wgConn *net.UDPConn
wgConnInfo conn.SocketInfo
handler packet.Handler
maxProxyPacketSize int
}

type client struct {
name string
wgListenNetwork string
wgListenAddress string
proxyConnListenNetwork string
proxyConnListenAddress string
relayBatchSize int
mainRecvBatchSize int
Expand Down Expand Up @@ -131,15 +131,6 @@ func (cc *ClientConfig) Client(logger *zap.Logger, listenConfigCache conn.Listen
return nil, fmt.Errorf("invalid proxyEndpointNetwork: %s", cc.ProxyEndpointNetwork)
}

// Check ProxyConnListenNetwork.
switch cc.ProxyConnListenNetwork {
case "":
cc.ProxyConnListenNetwork = "udp"
case "udp", "udp4", "udp6":
default:
return nil, fmt.Errorf("invalid proxyConnListenNetwork: %s", cc.ProxyConnListenNetwork)
}

// Check and apply PerfConfig defaults.
if err := cc.CheckAndApplyDefaults(); err != nil {
return nil, err
Expand Down Expand Up @@ -171,7 +162,6 @@ func (cc *ClientConfig) Client(logger *zap.Logger, listenConfigCache conn.Listen
name: cc.Name,
wgListenNetwork: cc.WgListenNetwork,
wgListenAddress: cc.WgListenAddress,
proxyConnListenNetwork: cc.ProxyConnListenNetwork,
proxyConnListenAddress: cc.ProxyConnListenAddress,
relayBatchSize: cc.RelayBatchSize,
mainRecvBatchSize: cc.MainRecvBatchSize,
Expand Down Expand Up @@ -230,6 +220,7 @@ func (c *client) startGeneric(ctx context.Context) error {
return err
}
c.wgConn = wgConn
c.wgListenAddress = wgConn.LocalAddr().String()

if wgConnInfo.UDPGenericReceiveOffload {
c.packetBufSize = 65535
Expand Down Expand Up @@ -405,23 +396,29 @@ func (c *client) recvFromWgConnGeneric(ctx context.Context, wgConn *net.UDPConn,
return
}

proxyConn, proxyConnInfo, err := c.proxyConnListenConfig.ListenUDP(ctx, c.proxyConnListenNetwork, c.proxyConnListenAddress)
proxyConnListenNetwork := listenUDPNetworkForRemoteAddr(proxyAddrPort.Addr())

proxyConn, proxyConnInfo, err := c.proxyConnListenConfig.ListenUDP(ctx, proxyConnListenNetwork, c.proxyConnListenAddress)
if err != nil {
c.logger.Warn("Failed to create UDP socket for new session",
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", clientAddrPort),
zap.String("proxyConnListenNetwork", proxyConnListenNetwork),
zap.String("proxyConnListenAddress", c.proxyConnListenAddress),
zap.Error(err),
)
return
}

err = proxyConn.SetReadDeadline(time.Now().Add(RejectAfterTime))
if err != nil {
proxyConnListenAddrPort := proxyConn.LocalAddr().(*net.UDPAddr).AddrPort()

if err = proxyConn.SetReadDeadline(time.Now().Add(RejectAfterTime)); err != nil {
c.logger.Warn("Failed to SetReadDeadline on proxyConn",
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", clientAddrPort),
zap.Stringer("proxyConnListenAddress", proxyConnListenAddrPort),
zap.Error(err),
)
proxyConn.Close()
Expand Down Expand Up @@ -457,6 +454,7 @@ func (c *client) recvFromWgConnGeneric(ctx context.Context, wgConn *net.UDPConn,
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", clientAddrPort),
zap.Stringer("proxyConnListenAddress", proxyConnListenAddrPort),
zap.Stringer("proxyAddress", proxyAddrPort),
zap.Int("wgTunnelMTU", wgTunnelMTU),
zap.Uint32("maxUDPGSOSegments", proxyConnInfo.MaxUDPGSOSegments),
Expand All @@ -467,27 +465,29 @@ func (c *client) recvFromWgConnGeneric(ctx context.Context, wgConn *net.UDPConn,

go func() {
c.relayWgToProxyGeneric(clientNatUplinkGeneric{
clientAddrPort: clientAddrPort,
proxyAddrPort: proxyAddrPort,
proxyConn: proxyConn,
proxyConnInfo: proxyConnInfo,
proxyConnSendCh: proxyConnSendCh,
handler: handler,
clientAddrPort: clientAddrPort,
proxyConnListenAddrPort: proxyConnListenAddrPort,
proxyAddrPort: proxyAddrPort,
proxyConn: proxyConn,
proxyConnInfo: proxyConnInfo,
proxyConnSendCh: proxyConnSendCh,
handler: handler,
})
proxyConn.Close()
c.wg.Done()
}()

c.relayProxyToWgGeneric(clientNatDownlinkGeneric{
clientAddrPort: clientAddrPort,
clientPktinfop: clientPktinfop,
clientPktinfo: &natEntry.clientPktinfo,
proxyAddrPort: proxyAddrPort,
proxyConn: proxyConn,
wgConn: wgConn,
wgConnInfo: wgConnInfo,
handler: handler,
maxProxyPacketSize: maxProxyPacketSize,
clientAddrPort: clientAddrPort,
clientPktinfop: clientPktinfop,
clientPktinfo: &natEntry.clientPktinfo,
proxyConnListenAddrPort: proxyConnListenAddrPort,
proxyAddrPort: proxyAddrPort,
proxyConn: proxyConn,
wgConn: wgConn,
wgConnInfo: wgConnInfo,
handler: handler,
maxProxyPacketSize: maxProxyPacketSize,
})
}()

Expand Down Expand Up @@ -567,6 +567,8 @@ func (c *client) relayWgToProxyGeneric(uplink clientNatUplinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", uplink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", uplink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", uplink.proxyAddrPort),
zap.Int("packetLength", wgPacketLength),
zap.Error(err),
)
Expand Down Expand Up @@ -655,6 +657,7 @@ func (c *client) relayWgToProxyGeneric(uplink clientNatUplinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", uplink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", uplink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", uplink.proxyAddrPort),
zap.Int("swgpPacketLength", sendBufSize),
zap.Uint32("segmentSize", sqp.segmentSize),
Expand All @@ -679,6 +682,7 @@ func (c *client) relayWgToProxyGeneric(uplink clientNatUplinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", uplink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", uplink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", uplink.proxyAddrPort),
zap.Error(err),
)
Expand All @@ -690,6 +694,7 @@ func (c *client) relayWgToProxyGeneric(uplink clientNatUplinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", uplink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", uplink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", uplink.proxyAddrPort),
zap.Uint64("sendmsgCount", sendmsgCount),
zap.Uint64("packetsSent", packetsSent),
Expand Down Expand Up @@ -731,6 +736,7 @@ func (c *client) relayProxyToWgGeneric(downlink clientNatDownlinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", downlink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", downlink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", downlink.proxyAddrPort),
zap.Stringer("packetSourceAddress", packetSourceAddrPort),
zap.Int("packetLength", n),
Expand All @@ -744,6 +750,7 @@ func (c *client) relayProxyToWgGeneric(downlink clientNatDownlinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", downlink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", downlink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", downlink.proxyAddrPort),
zap.Stringer("packetSourceAddress", packetSourceAddrPort),
zap.Int("packetLength", n),
Expand All @@ -758,6 +765,7 @@ func (c *client) relayProxyToWgGeneric(downlink clientNatDownlinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", downlink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", downlink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", downlink.proxyAddrPort),
zap.Stringer("packetSourceAddress", packetSourceAddrPort),
zap.Int("packetLength", n),
Expand All @@ -772,6 +780,7 @@ func (c *client) relayProxyToWgGeneric(downlink clientNatDownlinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", downlink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", downlink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", downlink.proxyAddrPort),
zap.Stringer("packetSourceAddress", packetSourceAddrPort),
zap.Int("cmsgLength", cmsgn),
Expand Down Expand Up @@ -809,6 +818,7 @@ func (c *client) relayProxyToWgGeneric(downlink clientNatDownlinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", downlink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", downlink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", downlink.proxyAddrPort),
zap.Int("packetLength", swgpPacketLength),
zap.Error(err),
Expand Down Expand Up @@ -905,6 +915,7 @@ func (c *client) relayProxyToWgGeneric(downlink clientNatDownlinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", downlink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", downlink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", downlink.proxyAddrPort),
zap.Int("wgPacketLength", sendBufSize),
zap.Uint32("segmentSize", qp.segmentSize),
Expand All @@ -929,6 +940,7 @@ func (c *client) relayProxyToWgGeneric(downlink clientNatDownlinkGeneric) {
zap.String("client", c.name),
zap.String("listenAddress", c.wgListenAddress),
zap.Stringer("clientAddress", downlink.clientAddrPort),
zap.Stringer("proxyConnListenAddress", downlink.proxyConnListenAddrPort),
zap.Stringer("proxyAddress", downlink.proxyAddrPort),
zap.Uint64("recvmsgCount", recvmsgCount),
zap.Uint64("packetsReceived", packetsReceived),
Expand Down
Loading

0 comments on commit 26aed42

Please sign in to comment.