mirror of
https://github.com/netbirdio/netbird.git
synced 2025-03-15 23:28:28 +01:00
101 lines
2.0 KiB
Go
101 lines
2.0 KiB
Go
package netstack
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/netip"
|
|
"os"
|
|
"strconv"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"golang.zx2c4.com/wireguard/tun"
|
|
"golang.zx2c4.com/wireguard/tun/netstack"
|
|
)
|
|
|
|
const EnvSkipProxy = "NB_NETSTACK_SKIP_PROXY"
|
|
|
|
type NetStackTun struct { //nolint:revive
|
|
address net.IP
|
|
dnsAddress net.IP
|
|
mtu int
|
|
listenAddress string
|
|
|
|
proxy *Proxy
|
|
tundev tun.Device
|
|
}
|
|
|
|
func NewNetStackTun(listenAddress string, address net.IP, dnsAddress net.IP, mtu int) *NetStackTun {
|
|
return &NetStackTun{
|
|
address: address,
|
|
dnsAddress: dnsAddress,
|
|
mtu: mtu,
|
|
listenAddress: listenAddress,
|
|
}
|
|
}
|
|
|
|
func (t *NetStackTun) Create() (tun.Device, *netstack.Net, error) {
|
|
addr, ok := netip.AddrFromSlice(t.address)
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf("convert address to netip.Addr: %v", t.address)
|
|
}
|
|
|
|
dnsAddr, ok := netip.AddrFromSlice(t.dnsAddress)
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf("convert dns address to netip.Addr: %v", t.dnsAddress)
|
|
}
|
|
|
|
nsTunDev, tunNet, err := netstack.CreateNetTUN(
|
|
[]netip.Addr{addr.Unmap()},
|
|
[]netip.Addr{dnsAddr.Unmap()},
|
|
t.mtu)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
t.tundev = nsTunDev
|
|
|
|
skipProxy, err := strconv.ParseBool(os.Getenv(EnvSkipProxy))
|
|
if err != nil {
|
|
log.Errorf("failed to parse NB_ETSTACK_SKIP_PROXY: %s", err)
|
|
}
|
|
if skipProxy {
|
|
return nsTunDev, tunNet, nil
|
|
}
|
|
|
|
dialer := NewNSDialer(tunNet)
|
|
t.proxy, err = NewSocks5(dialer)
|
|
if err != nil {
|
|
_ = t.tundev.Close()
|
|
return nil, nil, err
|
|
}
|
|
|
|
go func() {
|
|
err := t.proxy.ListenAndServe(t.listenAddress)
|
|
if err != nil {
|
|
log.Errorf("error in socks5 proxy serving: %s", err)
|
|
}
|
|
}()
|
|
|
|
return nsTunDev, tunNet, nil
|
|
}
|
|
|
|
func (t *NetStackTun) Close() error {
|
|
var err error
|
|
if t.proxy != nil {
|
|
pErr := t.proxy.Close()
|
|
if pErr != nil {
|
|
log.Errorf("failed to close socks5 proxy: %s", pErr)
|
|
err = pErr
|
|
}
|
|
}
|
|
|
|
if t.tundev != nil {
|
|
dErr := t.tundev.Close()
|
|
if dErr != nil {
|
|
log.Errorf("failed to close netstack tun device: %s", dErr)
|
|
err = dErr
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|