mirror of
https://github.com/tailscale/tailscale.git
synced 2026-04-05 07:03:43 -04:00
test
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
This commit is contained in:
@@ -913,6 +913,12 @@ func (b *LocalBackend) setStateLocked(state ipn.State) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *LocalBackend) IPServiceMappings() netmap.IPServiceMappings {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.ipVIPServiceMap
|
||||
}
|
||||
|
||||
// setConfigLocked uses the provided config to update the backend's prefs
|
||||
// and other state.
|
||||
func (b *LocalBackend) setConfigLocked(conf *conffile.Config) error {
|
||||
@@ -5110,7 +5116,7 @@ func (b *LocalBackend) authReconfigLocked() {
|
||||
}
|
||||
|
||||
oneCGNATRoute := shouldUseOneCGNATRoute(b.logf, b.sys.NetMon.Get(), b.sys.ControlKnobs(), version.OS())
|
||||
rcfg := b.routerConfigLocked(cfg, prefs, oneCGNATRoute)
|
||||
rcfg := b.routerConfigLocked(cfg, prefs, nm, oneCGNATRoute)
|
||||
|
||||
err = b.e.Reconfig(cfg, rcfg, dcfg)
|
||||
if err == wgengine.ErrNoChanges {
|
||||
@@ -5426,7 +5432,7 @@ func peerRoutes(logf logger.Logf, peers []wgcfg.Peer, cgnatThreshold int) (route
|
||||
// routerConfig produces a router.Config from a wireguard config and IPN prefs.
|
||||
//
|
||||
// b.mu must be held.
|
||||
func (b *LocalBackend) routerConfigLocked(cfg *wgcfg.Config, prefs ipn.PrefsView, oneCGNATRoute bool) *router.Config {
|
||||
func (b *LocalBackend) routerConfigLocked(cfg *wgcfg.Config, prefs ipn.PrefsView, nm *netmap.NetworkMap, oneCGNATRoute bool) *router.Config {
|
||||
singleRouteThreshold := 10_000
|
||||
if oneCGNATRoute {
|
||||
singleRouteThreshold = 1
|
||||
@@ -5511,13 +5517,31 @@ func (b *LocalBackend) routerConfigLocked(cfg *wgcfg.Config, prefs ipn.PrefsView
|
||||
}
|
||||
}
|
||||
|
||||
// Get the VIPs for VIP services this node hosts. We will add all locally served VIPs to routes then
|
||||
// we terminate these connection locally in netstack instead of routing to peer.
|
||||
VIPServiceIPs := nm.GetIPVIPServiceMap()
|
||||
|
||||
if slices.ContainsFunc(rs.LocalAddrs, tsaddr.PrefixIs4) {
|
||||
rs.Routes = append(rs.Routes, netip.PrefixFrom(tsaddr.TailscaleServiceIP(), 32))
|
||||
for vip := range VIPServiceIPs {
|
||||
if vip.Is4() {
|
||||
rs.Routes = append(rs.Routes, netip.PrefixFrom(vip, 32))
|
||||
}
|
||||
}
|
||||
}
|
||||
if slices.ContainsFunc(rs.LocalAddrs, tsaddr.PrefixIs6) {
|
||||
rs.Routes = append(rs.Routes, netip.PrefixFrom(tsaddr.TailscaleServiceIPv6(), 128))
|
||||
for vip := range VIPServiceIPs {
|
||||
if vip.Is6() {
|
||||
rs.Routes = append(rs.Routes, netip.PrefixFrom(vip, 128))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("LocalAddrs are: ", rs.LocalAddrs)
|
||||
fmt.Println("SubnetRoutes are: ", rs.SubnetRoutes)
|
||||
fmt.Println("Routes are: ", rs.Routes)
|
||||
|
||||
return rs
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"github.com/tailscale/wireguard-go/device"
|
||||
"github.com/tailscale/wireguard-go/tun"
|
||||
"go4.org/mem"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"tailscale.com/disco"
|
||||
"tailscale.com/feature/buildfeatures"
|
||||
"tailscale.com/net/packet"
|
||||
@@ -828,6 +829,13 @@ func (t *Wrapper) SetWGConfig(wcfg *wgcfg.Config) {
|
||||
)
|
||||
|
||||
func (t *Wrapper) filterPacketOutboundToWireGuard(p *packet.Parsed, pc *peerConfigTable, gro *gro.GRO) (filter.Response, *gro.GRO) {
|
||||
if p.IPProto == ipproto.TCP {
|
||||
if p.TCPFlags&packet.TCPSyn != 0 {
|
||||
t.logf("Kevin_check: out->wg enter: SYN %v:%d -> %v:%d",
|
||||
p.Src.Addr(), p.Src.Port(),
|
||||
p.Dst.Addr(), p.Dst.Port())
|
||||
}
|
||||
}
|
||||
// Fake ICMP echo responses to MagicDNS (100.100.100.100).
|
||||
if p.IsEchoRequest() {
|
||||
switch p.Dst {
|
||||
@@ -862,11 +870,25 @@ func (t *Wrapper) filterPacketOutboundToWireGuard(p *packet.Parsed, pc *peerConf
|
||||
res, gro = t.PreFilterPacketOutboundToWireGuardNetstackIntercept(p, t, gro)
|
||||
if res.IsDrop() {
|
||||
// Handled by netstack.Impl.handleLocalPackets (quad-100 DNS primarily)
|
||||
if p.IPProto == ipproto.TCP {
|
||||
if p.TCPFlags&packet.TCPSyn != 0 {
|
||||
t.logf("Kevin_check: out->wg: SYN intercepted by netstack %v:%d -> %v:%d",
|
||||
p.Src.Addr(), p.Src.Port(),
|
||||
p.Dst.Addr(), p.Dst.Port())
|
||||
}
|
||||
}
|
||||
return res, gro
|
||||
}
|
||||
}
|
||||
if t.PreFilterPacketOutboundToWireGuardEngineIntercept != nil {
|
||||
if res := t.PreFilterPacketOutboundToWireGuardEngineIntercept(p, t); res.IsDrop() {
|
||||
if p.IPProto == ipproto.TCP {
|
||||
if p.TCPFlags&packet.TCPSyn != 0 {
|
||||
t.logf("Kevin_check: out->wg: SYN intercepted by engine %v:%d -> %v:%d",
|
||||
p.Src.Addr(), p.Src.Port(),
|
||||
p.Dst.Addr(), p.Dst.Port())
|
||||
}
|
||||
}
|
||||
// Handled by userspaceEngine.handleLocalPackets (primarily handles
|
||||
// quad-100 if netstack is not installed).
|
||||
return res, gro
|
||||
@@ -892,6 +914,13 @@ func (t *Wrapper) filterPacketOutboundToWireGuard(p *packet.Parsed, pc *peerConf
|
||||
Reason: reason,
|
||||
}, 1)
|
||||
}
|
||||
if p.IPProto == ipproto.TCP {
|
||||
if p.TCPFlags&packet.TCPSyn != 0 {
|
||||
t.logf("Kevin_check: out->wg: SYN dropped by filter %v:%d -> %v:%d reason=%q",
|
||||
p.Src.Addr(), p.Src.Port(),
|
||||
p.Dst.Addr(), p.Dst.Port())
|
||||
}
|
||||
}
|
||||
return filter.Drop, gro
|
||||
}
|
||||
|
||||
@@ -942,7 +971,12 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
if res.err != nil && len(res.data) == 0 {
|
||||
return 0, res.err
|
||||
}
|
||||
|
||||
if res.data == nil {
|
||||
// Kevin_check: confirm injected packets get dequeued by Read().
|
||||
if tlog := t.logf; tlog != nil {
|
||||
logInjectedSYN(tlog, res.injected) // helper below
|
||||
}
|
||||
return t.injectedRead(res.injected, buffs, sizes, offset)
|
||||
}
|
||||
|
||||
@@ -956,7 +990,13 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
var buffsGRO *gro.GRO
|
||||
for _, data := range res.data {
|
||||
p.Decode(data[res.dataOffset:])
|
||||
|
||||
if p.IPProto == ipproto.TCP {
|
||||
if p.TCPFlags&packet.TCPSyn != 0 {
|
||||
t.logf("Kevin_check: tun->ts: SYN %v:%d -> %v:%d",
|
||||
p.Src.Addr(), p.Src.Port(),
|
||||
p.Dst.Addr(), p.Dst.Port())
|
||||
}
|
||||
}
|
||||
if buildfeatures.HasLazyWG {
|
||||
if m := t.destIPActivity.Load(); m != nil {
|
||||
if fn := m[p.Dst.Addr()]; fn != nil {
|
||||
@@ -1007,6 +1047,60 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
return buffsPos, res.err
|
||||
}
|
||||
|
||||
func logInjectedSYN(logf func(string, ...any), inj tunInjectedRead) {
|
||||
// Prefer PacketBuffer if present (netstack-generated).
|
||||
if inj.packet != nil {
|
||||
// Assumption: PacketBuffer has NetworkHeader/TransportHeader accessors similar to gVisor stack.PacketBuffer.
|
||||
// If your netstack_PacketBuffer wrapper differs, paste its methods and I’ll adjust.
|
||||
nh := inj.packet.NetworkHeader().Slice()
|
||||
th := inj.packet.TransportHeader().Slice()
|
||||
|
||||
var src, dst netip.Addr
|
||||
var sp, dp uint16
|
||||
var syn bool
|
||||
|
||||
if len(nh) > 0 {
|
||||
switch inj.packet.NetworkProtocolNumber {
|
||||
case header.IPv4ProtocolNumber:
|
||||
ip := header.IPv4(nh)
|
||||
src = netip.AddrFrom4(ip.SourceAddress().As4())
|
||||
dst = netip.AddrFrom4(ip.DestinationAddress().As4())
|
||||
case header.IPv6ProtocolNumber:
|
||||
ip := header.IPv6(nh)
|
||||
src = netip.AddrFrom16(ip.SourceAddress().As16())
|
||||
dst = netip.AddrFrom16(ip.DestinationAddress().As16())
|
||||
}
|
||||
}
|
||||
|
||||
if inj.packet.TransportProtocolNumber == header.TCPProtocolNumber && len(th) >= header.TCPMinimumSize {
|
||||
tcp := header.TCP(th)
|
||||
sp = tcp.SourcePort()
|
||||
dp = tcp.DestinationPort()
|
||||
f := tcp.Flags()
|
||||
syn = f&header.TCPFlagSyn != 0
|
||||
}
|
||||
|
||||
if syn {
|
||||
logf("Kevin_check: Read(): dequeued injected(PacketBuffer) SYN %v:%d -> %v:%d", src, sp, dst, dp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Else parse raw bytes if present.
|
||||
if len(inj.data) > 0 {
|
||||
p := parsedPacketPool.Get().(*packet.Parsed)
|
||||
defer parsedPacketPool.Put(p)
|
||||
|
||||
p.Decode(inj.data)
|
||||
|
||||
if p.IPProto == ipproto.TCP && (p.TCPFlags&packet.TCPSyn) != 0 {
|
||||
logf("Kevin_check: Read(): dequeued injected(bytes) SYN %v:%d -> %v:%d",
|
||||
p.Src.Addr(), p.Src.Port(), p.Dst.Addr(), p.Dst.Port())
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
minTCPHeaderSize = 20
|
||||
)
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/netip"
|
||||
"sync"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
@@ -278,6 +280,7 @@ func (ep *linkEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Er
|
||||
// control MTU (and by effect TCP MSS in gVisor) we *shouldn't* expect to
|
||||
// ever overflow 128 slots (see wireguard-go/tun.ErrTooManySegments usage).
|
||||
for _, pkt := range pkts.AsSlice() {
|
||||
logLinkEPOut(pkt)
|
||||
if err := ep.q.Write(pkt); err != nil {
|
||||
if _, ok := err.(*tcpip.ErrNoBufferSpace); !ok && n == 0 {
|
||||
return 0, err
|
||||
@@ -290,6 +293,68 @@ func (ep *linkEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Er
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func logLinkEPOut(pkt *stack.PacketBuffer) {
|
||||
nh := pkt.NetworkHeader().Slice()
|
||||
th := pkt.TransportHeader().Slice()
|
||||
if len(nh) == 0 || len(th) == 0 {
|
||||
return
|
||||
}
|
||||
if pkt.TransportProtocolNumber != header.TCPProtocolNumber || len(th) < header.TCPMinimumSize {
|
||||
return
|
||||
}
|
||||
|
||||
tcp := header.TCP(th)
|
||||
flags := tcp.Flags()
|
||||
|
||||
// Only log SYN/SYN-ACK/RST (SYN=0x02, ACK=0x10, RST=0x04)
|
||||
syn := flags&header.TCPFlagSyn != 0
|
||||
rst := flags&header.TCPFlagRst != 0
|
||||
if !syn && !rst {
|
||||
return
|
||||
}
|
||||
|
||||
sp := tcp.SourcePort()
|
||||
dp := tcp.DestinationPort()
|
||||
|
||||
var srcIP, dstIP netip.Addr
|
||||
switch pkt.NetworkProtocolNumber {
|
||||
case header.IPv4ProtocolNumber:
|
||||
if len(nh) < header.IPv4MinimumSize {
|
||||
return
|
||||
}
|
||||
ip := header.IPv4(nh)
|
||||
srcIP = addrToNetip(ip.SourceAddress())
|
||||
dstIP = addrToNetip(ip.DestinationAddress())
|
||||
|
||||
case header.IPv6ProtocolNumber:
|
||||
if len(nh) < header.IPv6MinimumSize {
|
||||
return
|
||||
}
|
||||
ip := header.IPv6(nh)
|
||||
srcIP = addrToNetip(ip.SourceAddress())
|
||||
dstIP = addrToNetip(ip.DestinationAddress())
|
||||
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
// If parsing failed, don't log noisy junk.
|
||||
if !srcIP.IsValid() || !dstIP.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("linkEP out TCP flags=%#x %s:%d -> %s:%d seq=%d ack=%d",
|
||||
flags, srcIP, sp, dstIP, dp, tcp.SequenceNumber(), tcp.AckNumber())
|
||||
}
|
||||
|
||||
func addrToNetip(a tcpip.Address) netip.Addr {
|
||||
ip, ok := netip.AddrFromSlice(a.AsSlice())
|
||||
if !ok {
|
||||
return netip.Addr{}
|
||||
}
|
||||
return ip.Unmap()
|
||||
}
|
||||
|
||||
// Wait implements stack.LinkEndpoint.Wait.
|
||||
func (*linkEndpoint) Wait() {}
|
||||
|
||||
|
||||
@@ -771,6 +771,11 @@ func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper, gro *gro.
|
||||
|
||||
// Determine if we care about this local packet.
|
||||
dst := p.Dst.Addr()
|
||||
var IPServiceMappings netmap.IPServiceMappings
|
||||
if ns.lb != nil {
|
||||
IPServiceMappings = ns.lb.IPServiceMappings()
|
||||
}
|
||||
serviceName, hasIP := IPServiceMappings[dst]
|
||||
switch {
|
||||
case dst == serviceIP || dst == serviceIPv6:
|
||||
// We want to intercept some traffic to the "service IP" (e.g.
|
||||
@@ -787,6 +792,30 @@ func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper, gro *gro.
|
||||
return filter.Accept, gro
|
||||
}
|
||||
}
|
||||
case hasIP:
|
||||
if p.IPProto != ipproto.TCP {
|
||||
return filter.Accept, gro
|
||||
}
|
||||
// returns all configured VIP services, since the IPServiceMappings contains
|
||||
// inactive service IPs when node hosts the service, we need to check the
|
||||
// service is active or not before dropping the packet.
|
||||
VIPServices := ns.lb.VIPServices()
|
||||
serviceActive := false
|
||||
for _, svc := range VIPServices {
|
||||
// Even though control only send service IP down when there is a config
|
||||
// for the service, we want to still check that the config still exists
|
||||
// before passing the packet to netstack.
|
||||
if svc.Name == serviceName {
|
||||
serviceActive = svc.Active
|
||||
}
|
||||
}
|
||||
if !serviceActive {
|
||||
return filter.Accept, gro
|
||||
}
|
||||
if debugNetstack() {
|
||||
ns.logf("Kevin_check: netstack: intercepting local VIP service packet: proto=%v dst=%v src=%v",
|
||||
p.IPProto, p.Dst, p.Src)
|
||||
}
|
||||
case viaRange.Contains(dst):
|
||||
// We need to handle 4via6 packets leaving the host if the via
|
||||
// route is for this host; otherwise the packet will be dropped
|
||||
@@ -946,6 +975,55 @@ func (ns *Impl) inject() {
|
||||
inboundBuffs, inboundBuffsSizes := ns.getInjectInboundBuffsSizes()
|
||||
for {
|
||||
pkt := ns.linkEP.ReadContext(ns.ctx)
|
||||
nh := pkt.NetworkHeader().Slice()
|
||||
th := pkt.TransportHeader().Slice()
|
||||
|
||||
var src, dst netip.Addr
|
||||
var sp, dp uint16
|
||||
var syn, ack, rst bool
|
||||
|
||||
if len(nh) > 0 {
|
||||
switch pkt.NetworkProtocolNumber {
|
||||
case header.IPv4ProtocolNumber:
|
||||
ip := header.IPv4(nh)
|
||||
|
||||
sa := ip.SourceAddress()
|
||||
da := ip.DestinationAddress()
|
||||
|
||||
if s, ok := netip.AddrFromSlice(sa.AsSlice()); ok {
|
||||
src = s.Unmap()
|
||||
}
|
||||
if d, ok := netip.AddrFromSlice(da.AsSlice()); ok {
|
||||
dst = d.Unmap()
|
||||
}
|
||||
|
||||
case header.IPv6ProtocolNumber:
|
||||
ip := header.IPv6(nh)
|
||||
|
||||
sa := ip.SourceAddress()
|
||||
da := ip.DestinationAddress()
|
||||
|
||||
if s, ok := netip.AddrFromSlice(sa.AsSlice()); ok {
|
||||
src = s.Unmap()
|
||||
}
|
||||
if d, ok := netip.AddrFromSlice(da.AsSlice()); ok {
|
||||
dst = d.Unmap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if pkt.TransportProtocolNumber == header.TCPProtocolNumber && len(th) >= header.TCPMinimumSize {
|
||||
tcp := header.TCP(th)
|
||||
sp = tcp.SourcePort()
|
||||
dp = tcp.DestinationPort()
|
||||
f := tcp.Flags()
|
||||
syn = f&header.TCPFlagSyn != 0
|
||||
ack = f&header.TCPFlagAck != 0
|
||||
rst = f&header.TCPFlagRst != 0
|
||||
}
|
||||
|
||||
ns.logf("Kevin_check: inject: dequeued TCP syn=%v ack=%v rst=%v %v:%d -> %v:%d",
|
||||
syn, ack, rst, src, sp, dst, dp)
|
||||
if pkt == nil {
|
||||
if ns.ctx.Err() != nil {
|
||||
// Return without logging.
|
||||
@@ -965,15 +1043,18 @@ func (ns *Impl) inject() {
|
||||
// send traffic destined for the local device, hence must
|
||||
// be injected 'inbound'.
|
||||
sendToHost := ns.shouldSendToHost(pkt)
|
||||
ns.logf("Kevin_check: inject: shouldSendToHost=%v", sendToHost)
|
||||
|
||||
// pkt has a non-zero refcount, so injection methods takes
|
||||
// ownership of one count and will decrement on completion.
|
||||
if sendToHost {
|
||||
ns.logf("Kevin_check: inject: InjectInboundPacketBuffer")
|
||||
if err := ns.tundev.InjectInboundPacketBuffer(pkt, inboundBuffs, inboundBuffsSizes); err != nil {
|
||||
ns.logf("netstack inject inbound: %v", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ns.logf("Kevin_check: inject: InjectOutboundPacketBuffer")
|
||||
if err := ns.tundev.InjectOutboundPacketBuffer(pkt); err != nil {
|
||||
ns.logf("netstack inject outbound: %v", err)
|
||||
return
|
||||
@@ -998,12 +1079,28 @@ func (ns *Impl) shouldSendToHost(pkt *stack.PacketBuffer) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if ns.isVIPServiceIP(srcIP) {
|
||||
dstIP := netip.AddrFrom4(v.DestinationAddress().As4())
|
||||
if ns.isLocalIP(dstIP) {
|
||||
ns.logf("Kevin_check: netstack: sending VIP service packet to host: src=%v dst=%v", srcIP, dstIP)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
case header.IPv6:
|
||||
srcIP := netip.AddrFrom16(v.SourceAddress().As16())
|
||||
if srcIP == serviceIPv6 {
|
||||
return true
|
||||
}
|
||||
|
||||
if ns.isVIPServiceIP(srcIP) {
|
||||
dstIP := netip.AddrFrom16(v.DestinationAddress().As16())
|
||||
if ns.isLocalIP(dstIP) {
|
||||
ns.logf("Kevin_check: netstack: sending VIP service packet to host: src=%v dst=%v", srcIP, dstIP)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if viaRange.Contains(srcIP) {
|
||||
// Only send to the host if this 4via6 route is
|
||||
// something this node handles.
|
||||
@@ -1349,7 +1446,7 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
|
||||
getConnOrReset := func(opts ...tcpip.SettableSocketOption) *gonet.TCPConn {
|
||||
ep, err := r.CreateEndpoint(&wq)
|
||||
if err != nil {
|
||||
ns.logf("CreateEndpoint error for %s: %v", stringifyTEI(reqDetails), err)
|
||||
ns.logf("CreateEndpoint error for %s: (%T) %v", stringifyTEI(reqDetails), err, err)
|
||||
r.Complete(true) // sends a RST
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -596,6 +596,7 @@ func echoRespondToAll(p *packet.Parsed, t *tstun.Wrapper, gro *gro.GRO) (filter.
|
||||
// tailscaled directly. Other packets are allowed to proceed into the
|
||||
// main ACL filter.
|
||||
func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper) filter.Response {
|
||||
isTCPSYN := p.IPProto == ipproto.TCP && (p.TCPFlags&packet.TCPSyn) != 0
|
||||
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
|
||||
isLocalAddr, ok := e.isLocalAddr.LoadOk()
|
||||
if !ok {
|
||||
@@ -606,6 +607,9 @@ func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper)
|
||||
// looping back within the kernel network stack. We have to
|
||||
// notice that an outbound packet is actually destined for
|
||||
// ourselves, and loop it back into macOS.
|
||||
if isTCPSYN {
|
||||
e.logf("Kevin_check: e.handleLocalPackets: reflecting TCP SYN to local Tailscale IP %v back to OS", p.Dst.Addr())
|
||||
}
|
||||
t.InjectInboundCopy(p.Buffer())
|
||||
metricReflectToOS.Add(1)
|
||||
return filter.Drop
|
||||
@@ -622,7 +626,9 @@ func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isTCPSYN {
|
||||
e.logf("Kevin_check: e.handleLocalPackets: outbound TCP SYN to %v", p.Dst)
|
||||
}
|
||||
return filter.Accept
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user