summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--tun/netstack/tun.go51
1 files changed, 30 insertions, 21 deletions
diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go
index c5f8326..7a3f4f6 100644
--- a/tun/netstack/tun.go
+++ b/tun/netstack/tun.go
@@ -34,6 +34,7 @@ import (
type netTun struct {
stack *stack.Stack
+ nicID tcpip.NICID
dispatcher stack.NetworkDispatcher
events chan tun.Event
incomingPacket chan buffer.VectorisedView
@@ -96,38 +97,28 @@ func CreateNetTUN(localAddresses []net.IP, dnsServers []net.IP, mtu int) (tun.De
TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol},
HandleLocal: true,
}
+ return CreateNetTUNWithStack(stack.New(opts), 1, localAddresses, dnsServers, mtu)
+}
+
+func CreateNetTUNWithStack(stack *stack.Stack, nicID tcpip.NICID, localAddresses []net.IP, dnsServers []net.IP, mtu int) (tun.Device, *Net, error) {
dev := &netTun{
- stack: stack.New(opts),
+ stack: stack,
+ nicID: nicID,
events: make(chan tun.Event, 10),
incomingPacket: make(chan buffer.VectorisedView),
dnsServers: dnsServers,
mtu: mtu,
}
- tcpipErr := dev.stack.CreateNIC(1, (*endpoint)(dev))
+ tcpipErr := dev.stack.CreateNIC(nicID, (*endpoint)(dev))
if tcpipErr != nil {
return nil, nil, fmt.Errorf("CreateNIC: %v", tcpipErr)
}
for _, ip := range localAddresses {
- if ip4 := ip.To4(); ip4 != nil {
- tcpipErr = dev.stack.AddAddress(1, ipv4.ProtocolNumber, tcpip.Address(ip4))
- if tcpipErr != nil {
- return nil, nil, fmt.Errorf("AddAddress(%v): %v", ip4, tcpipErr)
- }
- dev.hasV4 = true
- } else {
- tcpipErr = dev.stack.AddAddress(1, ipv6.ProtocolNumber, tcpip.Address(ip))
- if tcpipErr != nil {
- return nil, nil, fmt.Errorf("AddAddress(%v): %v", ip4, tcpipErr)
- }
- dev.hasV6 = true
+ tcpipErr := (*Net)(dev).AddAddress(ip)
+ if tcpipErr != nil {
+ return nil, nil, fmt.Errorf("AddAddress(%v): %w", ip, tcpipErr)
}
}
- if dev.hasV4 {
- dev.stack.AddRoute(tcpip.Route{Destination: header.IPv4EmptySubnet, NIC: 1})
- }
- if dev.hasV6 {
- dev.stack.AddRoute(tcpip.Route{Destination: header.IPv6EmptySubnet, NIC: 1})
- }
dev.events <- tun.EventUp
return dev, (*Net)(dev), nil
@@ -175,7 +166,7 @@ func (tun *netTun) Flush() error {
}
func (tun *netTun) Close() error {
- tun.stack.RemoveNIC(1)
+ tun.stack.RemoveNIC(tun.nicID)
if tun.events != nil {
close(tun.events)
@@ -206,6 +197,24 @@ func convertToFullAddr(ip net.IP, port int) (tcpip.FullAddress, tcpip.NetworkPro
}
}
+func (net *Net) AddAddress(ip net.IP) *tcpip.Error {
+ if ip4 := ip.To4(); ip4 != nil {
+ tcpipErr := net.stack.AddAddress(net.nicID, ipv4.ProtocolNumber, tcpip.Address(ip4))
+ if tcpipErr == nil && !net.hasV4 {
+ net.hasV4 = true
+ net.stack.AddRoute(tcpip.Route{Destination: header.IPv4EmptySubnet, NIC: net.nicID})
+ }
+ return tcpipErr
+ } else {
+ tcpipErr := net.stack.AddAddress(net.nicID, ipv6.ProtocolNumber, tcpip.Address(ip))
+ if tcpipErr == nil && !net.hasV6{
+ net.hasV6 = true
+ net.stack.AddRoute(tcpip.Route{Destination: header.IPv6EmptySubnet, NIC: net.nicID})
+ }
+ return tcpipErr
+ }
+}
+
func (net *Net) DialContextTCP(ctx context.Context, addr *net.TCPAddr) (*gonet.TCPConn, error) {
if addr == nil {
panic("todo: deal with auto addr semantics for nil addr")