MCPcopy Index your code
hub / github.com/tailscale/tailscale / handleLocalPackets

Method handleLocalPackets

wgengine/netstack/netstack.go:842–946  ·  view source on GitHub ↗

handleLocalPackets is hooked into the tun datapath for packets leaving the host and arriving at tailscaled. This method returns filter.DropSilently to intercept a packet for handling, for instance traffic to quad-100. Caution: can be called before Start

(p *packet.Parsed, t *tstun.Wrapper, gro *gro.GRO)

Source from the content-addressed store, hash-verified

840// to intercept a packet for handling, for instance traffic to quad-100.
841// Caution: can be called before Start
842func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper, gro *gro.GRO) (filter.Response, *gro.GRO) {
843 if !ns.ready.Load() || ns.ctx.Err() != nil {
844 return filter.DropSilently, gro
845 }
846
847 // Determine if we care about this local packet.
848 dst := p.Dst.Addr()
849 serviceName, isVIPServiceIP := ns.atomicIPVIPServiceMap.Load()[dst]
850 switch {
851 case dst == serviceIP || dst == serviceIPv6:
852 // Traffic to the Tailscale service IP (100.100.100.100 /
853 // fd7a:115c:a1e0::53) is always terminated locally on this
854 // node; it must never be forwarded out over WireGuard to a
855 // peer. Netstack's TCP/UDP acceptors handle the ports we
856 // actually serve (UDP 53 MagicDNS, TCP 53/80/8080 for DNS,
857 // the web client, and Taildrive, plus any debug loopback
858 // port). Other ports are rejected cleanly by netstack: UDP
859 // closes the endpoint in acceptUDP, and TCP is RST'd by
860 // acceptTCP's hittingServiceIP guard.
861 //
862 // Previously we returned filter.Accept for TCP/UDP on any
863 // other port, which let the packet fall through to the ACL
864 // filter and ultimately wireguard-go, where no peer owns the
865 // quad-100 AllowedIP. That produced noisy "open-conn-track:
866 // timeout opening ...; no associated peer node" log lines
867 // (e.g. for stray traffic to 100.100.100.100:853 / DoT) and
868 // leaked quad-100 packets onto the tailnet.
869 //
870 // We now unconditionally absorb quad-100 into netstack here,
871 // regardless of IP protocol or port, so such traffic never
872 // reaches the conntrack / peer-routing layers.
873 case isVIPServiceIP:
874 // returns all active VIP services in a set, since the IPVIPServiceMap
875 // contains inactive service IPs when node hosts the service, we need to
876 // check the service is active or not before dropping the packet.
877 activeServices := ns.atomicActiveVIPServices.Load()
878 if !activeServices.Contains(serviceName) {
879 // Other host might have the service active, so we let the packet go through.
880 return filter.Accept, gro
881 }
882 if p.IPProto != ipproto.TCP {
883 // We currenly only support VIP services over TCP. If service is in Tun mode,
884 // it's up to the service host to set up local packet handling which shouldn't
885 // arrive here.
886 return filter.DropSilently, gro
887 }
888 if debugNetstack() {
889 ns.logf("netstack: intercepting local VIP service packet: proto=%v dst=%v src=%v",
890 p.IPProto, p.Dst, p.Src)
891 }
892 case viaRange.Contains(dst):
893 // We need to handle 4via6 packets leaving the host if the via
894 // route is for this host; otherwise the packet will be dropped
895 // because nothing will translate it.
896 var shouldHandle bool
897 if p.IPVersion == 6 && !ns.isLocalIP(dst) {
898 shouldHandle = ns.lb != nil && ns.lb.ShouldHandleViaIP(dst)
899 }

Calls 15

isLocalIPMethod · 0.95
shouldHandlePingMethod · 0.95
userPingMethod · 0.95
GenerateFunction · 0.92
ShouldHandleViaIPMethod · 0.80
ICMP4HeaderMethod · 0.80
ICMP6HeaderMethod · 0.80
BufferMethod · 0.80
groMethod · 0.80
LoadMethod · 0.65
ToResponseMethod · 0.65
ErrMethod · 0.45

Tested by 2

TestHandleLocalPacketsFunction · 0.36