Add L3 routing support

This commit is contained in:
世界
2023-03-21 21:36:17 +08:00
parent 9b762e3c2e
commit afcc8b204f
61 changed files with 2043 additions and 965 deletions

View File

@@ -8,7 +8,9 @@ import (
"encoding/hex"
"fmt"
"net"
"os"
"strings"
"syscall"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
@@ -26,7 +28,7 @@ import (
)
var (
_ adapter.Outbound = (*WireGuard)(nil)
_ adapter.IPOutbound = (*WireGuard)(nil)
_ adapter.InterfaceUpdateListener = (*WireGuard)(nil)
)
@@ -34,6 +36,7 @@ type WireGuard struct {
myOutboundAdapter
bind *wireguard.ClientBind
device *device.Device
natDevice wireguard.NatDevice
tunDevice wireguard.Device
}
@@ -106,17 +109,25 @@ func NewWireGuard(ctx context.Context, router adapter.Router, logger log.Context
if mtu == 0 {
mtu = 1408
}
var wireTunDevice wireguard.Device
var tunDevice wireguard.Device
var err error
if !options.SystemInterface && tun.WithGVisor {
wireTunDevice, err = wireguard.NewStackDevice(localPrefixes, mtu)
tunDevice, err = wireguard.NewStackDevice(localPrefixes, mtu, options.IPRewrite)
} else {
wireTunDevice, err = wireguard.NewSystemDevice(router, options.InterfaceName, localPrefixes, mtu)
tunDevice, err = wireguard.NewSystemDevice(router, options.InterfaceName, localPrefixes, mtu)
}
if err != nil {
return nil, E.Cause(err, "create WireGuard device")
}
wgDevice := device.NewDevice(wireTunDevice, outbound.bind, &device.Logger{
natDevice, isNatDevice := tunDevice.(wireguard.NatDevice)
if !isNatDevice && router.NatRequired(tag) {
natDevice = wireguard.NewNATDevice(tunDevice, options.IPRewrite)
}
deviceInput := tunDevice
if natDevice != nil {
deviceInput = natDevice
}
wgDevice := device.NewDevice(deviceInput, outbound.bind, &device.Logger{
Verbosef: func(format string, args ...interface{}) {
logger.Debug(fmt.Sprintf(strings.ToLower(format), args...))
},
@@ -132,7 +143,8 @@ func NewWireGuard(ctx context.Context, router adapter.Router, logger log.Context
return nil, E.Cause(err, "setup wireguard")
}
outbound.device = wgDevice
outbound.tunDevice = wireTunDevice
outbound.natDevice = natDevice
outbound.tunDevice = tunDevice
return outbound, nil
}
@@ -171,6 +183,27 @@ func (w *WireGuard) NewPacketConnection(ctx context.Context, conn N.PacketConn,
return NewPacketConnection(ctx, w, conn, metadata)
}
func (w *WireGuard) NewIPConnection(ctx context.Context, conn tun.RouteContext, metadata adapter.InboundContext) (tun.DirectDestination, error) {
if w.natDevice == nil {
return nil, os.ErrInvalid
}
session := tun.RouteSession{
IPVersion: metadata.IPVersion,
Network: tun.NetworkFromName(metadata.Network),
Source: metadata.Source.AddrPort(),
Destination: metadata.Destination.AddrPort(),
}
switch session.Network {
case syscall.IPPROTO_TCP:
w.logger.InfoContext(ctx, "linked connection to ", metadata.Destination)
case syscall.IPPROTO_UDP:
w.logger.InfoContext(ctx, "linked packet connection to ", metadata.Destination)
default:
w.logger.InfoContext(ctx, "linked ", metadata.Network, " connection to ", metadata.Destination.AddrString())
}
return w.natDevice.CreateDestination(session, conn), nil
}
func (w *WireGuard) Start() error {
return w.tunDevice.Start()
}