|
|
|
@ -17,12 +17,11 @@ import (
|
|
|
|
|
"os/exec"
|
|
|
|
|
"runtime"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
|
"sync/atomic"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"gvisor.dev/gvisor/pkg/bufferv2"
|
|
|
|
|
"gvisor.dev/gvisor/pkg/buffer"
|
|
|
|
|
"gvisor.dev/gvisor/pkg/refs"
|
|
|
|
|
"gvisor.dev/gvisor/pkg/tcpip"
|
|
|
|
|
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
|
|
|
@ -197,8 +196,8 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi
|
|
|
|
|
ipstack.SetPromiscuousMode(nicID, true)
|
|
|
|
|
// Add IPv4 and IPv6 default routes, so all incoming packets from the Tailscale side
|
|
|
|
|
// are handled by the one fake NIC we use.
|
|
|
|
|
ipv4Subnet, _ := tcpip.NewSubnet(tcpip.Address(strings.Repeat("\x00", 4)), tcpip.AddressMask(strings.Repeat("\x00", 4)))
|
|
|
|
|
ipv6Subnet, _ := tcpip.NewSubnet(tcpip.Address(strings.Repeat("\x00", 16)), tcpip.AddressMask(strings.Repeat("\x00", 16)))
|
|
|
|
|
ipv4Subnet, _ := tcpip.NewSubnet(tcpip.AddrFromSlice(bytes.Repeat([]byte{0x00}, 4)), tcpip.MaskFromBytes(bytes.Repeat([]byte{0x00}, 4)))
|
|
|
|
|
ipv6Subnet, _ := tcpip.NewSubnet(tcpip.AddrFromSlice(bytes.Repeat([]byte{0x00}, 16)), tcpip.MaskFromBytes(bytes.Repeat([]byte{0x00}, 16)))
|
|
|
|
|
ipstack.SetRouteTable([]tcpip.Route{
|
|
|
|
|
{
|
|
|
|
|
Destination: ipv4Subnet,
|
|
|
|
@ -241,7 +240,7 @@ func (ns *Impl) Close() error {
|
|
|
|
|
func (ns *Impl) wrapProtoHandler(h func(stack.TransportEndpointID, stack.PacketBufferPtr) bool) func(stack.TransportEndpointID, stack.PacketBufferPtr) bool {
|
|
|
|
|
return func(tei stack.TransportEndpointID, pb stack.PacketBufferPtr) bool {
|
|
|
|
|
addr := tei.LocalAddress
|
|
|
|
|
ip, ok := netip.AddrFromSlice(net.IP(addr))
|
|
|
|
|
ip, ok := netip.AddrFromSlice(net.IP(addr.AsSlice()))
|
|
|
|
|
if !ok {
|
|
|
|
|
ns.logf("netstack: could not parse local address for incoming connection")
|
|
|
|
|
return false
|
|
|
|
@ -280,10 +279,7 @@ func (ns *Impl) addSubnetAddress(ip netip.Addr) {
|
|
|
|
|
// Only register address into netstack for first concurrent connection.
|
|
|
|
|
if needAdd {
|
|
|
|
|
pa := tcpip.ProtocolAddress{
|
|
|
|
|
AddressWithPrefix: tcpip.AddressWithPrefix{
|
|
|
|
|
Address: tcpip.Address(ip.AsSlice()),
|
|
|
|
|
PrefixLen: int(ip.BitLen()),
|
|
|
|
|
},
|
|
|
|
|
AddressWithPrefix: tcpip.AddrFromSlice(ip.AsSlice()).WithPrefix(),
|
|
|
|
|
}
|
|
|
|
|
if ip.Is4() {
|
|
|
|
|
pa.Protocol = ipv4.ProtocolNumber
|
|
|
|
@ -303,14 +299,14 @@ func (ns *Impl) removeSubnetAddress(ip netip.Addr) {
|
|
|
|
|
ns.connsOpenBySubnetIP[ip]--
|
|
|
|
|
// Only unregister address from netstack after last concurrent connection.
|
|
|
|
|
if ns.connsOpenBySubnetIP[ip] == 0 {
|
|
|
|
|
ns.ipstack.RemoveAddress(nicID, tcpip.Address(ip.AsSlice()))
|
|
|
|
|
ns.ipstack.RemoveAddress(nicID, tcpip.AddrFromSlice(ip.AsSlice()))
|
|
|
|
|
delete(ns.connsOpenBySubnetIP, ip)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ipPrefixToAddressWithPrefix(ipp netip.Prefix) tcpip.AddressWithPrefix {
|
|
|
|
|
return tcpip.AddressWithPrefix{
|
|
|
|
|
Address: tcpip.Address(ipp.Addr().AsSlice()),
|
|
|
|
|
Address: tcpip.AddrFromSlice(ipp.Addr().AsSlice()),
|
|
|
|
|
PrefixLen: int(ipp.Bits()),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -374,7 +370,7 @@ func (ns *Impl) UpdateNetstackIPs(nm *netmap.NetworkMap) {
|
|
|
|
|
}
|
|
|
|
|
ns.mu.Lock()
|
|
|
|
|
for ip := range ns.connsOpenBySubnetIP {
|
|
|
|
|
ipp := tcpip.Address(ip.AsSlice()).WithPrefix()
|
|
|
|
|
ipp := tcpip.AddrFromSlice(ip.AsSlice()).WithPrefix()
|
|
|
|
|
delete(ipsToBeRemoved, ipp)
|
|
|
|
|
}
|
|
|
|
|
ns.mu.Unlock()
|
|
|
|
@ -391,7 +387,7 @@ func (ns *Impl) UpdateNetstackIPs(nm *netmap.NetworkMap) {
|
|
|
|
|
pa := tcpip.ProtocolAddress{
|
|
|
|
|
AddressWithPrefix: ipp,
|
|
|
|
|
}
|
|
|
|
|
if ipp.Address.To4() == "" {
|
|
|
|
|
if ipp.Address.Unspecified() || ipp.Address.Len() == 16 {
|
|
|
|
|
pa.Protocol = ipv6.ProtocolNumber
|
|
|
|
|
} else {
|
|
|
|
|
pa.Protocol = ipv4.ProtocolNumber
|
|
|
|
@ -447,7 +443,7 @@ func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper) filter.Re
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
packetBuf := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
|
|
|
|
Payload: bufferv2.MakeWithData(bytes.Clone(p.Buffer())),
|
|
|
|
|
Payload: buffer.MakeWithData(bytes.Clone(p.Buffer())),
|
|
|
|
|
})
|
|
|
|
|
ns.linkEP.InjectInbound(pn, packetBuf)
|
|
|
|
|
packetBuf.DecRef()
|
|
|
|
@ -457,7 +453,7 @@ func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper) filter.Re
|
|
|
|
|
func (ns *Impl) DialContextTCP(ctx context.Context, ipp netip.AddrPort) (*gonet.TCPConn, error) {
|
|
|
|
|
remoteAddress := tcpip.FullAddress{
|
|
|
|
|
NIC: nicID,
|
|
|
|
|
Addr: tcpip.Address(ipp.Addr().AsSlice()),
|
|
|
|
|
Addr: tcpip.AddrFromSlice(ipp.Addr().AsSlice()),
|
|
|
|
|
Port: ipp.Port(),
|
|
|
|
|
}
|
|
|
|
|
var ipType tcpip.NetworkProtocolNumber
|
|
|
|
@ -473,7 +469,7 @@ func (ns *Impl) DialContextTCP(ctx context.Context, ipp netip.AddrPort) (*gonet.
|
|
|
|
|
func (ns *Impl) DialContextUDP(ctx context.Context, ipp netip.AddrPort) (*gonet.UDPConn, error) {
|
|
|
|
|
remoteAddress := &tcpip.FullAddress{
|
|
|
|
|
NIC: nicID,
|
|
|
|
|
Addr: tcpip.Address(ipp.Addr().AsSlice()),
|
|
|
|
|
Addr: tcpip.AddrFromSlice(ipp.Addr().AsSlice()),
|
|
|
|
|
Port: ipp.Port(),
|
|
|
|
|
}
|
|
|
|
|
var ipType tcpip.NetworkProtocolNumber
|
|
|
|
@ -739,7 +735,7 @@ func (ns *Impl) injectInbound(p *packet.Parsed, t *tstun.Wrapper) filter.Respons
|
|
|
|
|
ns.logf("[v2] packet in (from %v): % x", p.Src, p.Buffer())
|
|
|
|
|
}
|
|
|
|
|
packetBuf := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
|
|
|
|
Payload: bufferv2.MakeWithData(bytes.Clone(p.Buffer())),
|
|
|
|
|
Payload: buffer.MakeWithData(bytes.Clone(p.Buffer())),
|
|
|
|
|
})
|
|
|
|
|
ns.linkEP.InjectInbound(pn, packetBuf)
|
|
|
|
|
packetBuf.DecRef()
|
|
|
|
@ -807,12 +803,13 @@ func (ns *Impl) shouldHandlePing(p *packet.Parsed) (_ netip.Addr, ok bool) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func netaddrIPFromNetstackIP(s tcpip.Address) netip.Addr {
|
|
|
|
|
switch len(s) {
|
|
|
|
|
switch s.Len() {
|
|
|
|
|
case 4:
|
|
|
|
|
s := s.As4()
|
|
|
|
|
return netaddr.IPv4(s[0], s[1], s[2], s[3])
|
|
|
|
|
case 16:
|
|
|
|
|
var a [16]byte
|
|
|
|
|
copy(a[:], s)
|
|
|
|
|
copy(a[:], s.AsSlice())
|
|
|
|
|
return netip.AddrFrom16(a).Unmap()
|
|
|
|
|
}
|
|
|
|
|
return netip.Addr{}
|
|
|
|
@ -1235,8 +1232,8 @@ func stringifyTEI(tei stack.TransportEndpointID) string {
|
|
|
|
|
|
|
|
|
|
func ipPortOfNetstackAddr(a tcpip.Address, port uint16) (ipp netip.AddrPort, ok bool) {
|
|
|
|
|
var a16 [16]byte
|
|
|
|
|
copy(a16[:], a)
|
|
|
|
|
switch len(a) {
|
|
|
|
|
copy(a16[:], a.AsSlice())
|
|
|
|
|
switch a.Len() {
|
|
|
|
|
case 4:
|
|
|
|
|
return netip.AddrPortFrom(
|
|
|
|
|
netip.AddrFrom4(*(*[4]byte)(a16[:4])).Unmap(),
|
|
|
|
|