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

Method wrapTCPProtocolHandler

wgengine/netstack/netstack.go:515–603  ·  view source on GitHub ↗

wrapTCPProtocolHandler wraps the protocol handler we pass to netstack for TCP.

(h protocolHandlerFunc)

Source from the content-addressed store, hash-verified

513
514// wrapTCPProtocolHandler wraps the protocol handler we pass to netstack for TCP.
515func (ns *Impl) wrapTCPProtocolHandler(h protocolHandlerFunc) protocolHandlerFunc {
516 // 'handled' is whether the packet should be accepted by netstack; if
517 // true, then the TCP connection is accepted by the transport layer and
518 // passes through our acceptTCP handler/etc. If false, then the packet
519 // is dropped and the TCP connection is rejected (typically with an
520 // ICMP Port Unreachable or ICMP Protocol Unreachable message).
521 return func(tei stack.TransportEndpointID, pb *stack.PacketBuffer) (handled bool) {
522 localIP, ok := netip.AddrFromSlice(tei.LocalAddress.AsSlice())
523 if !ok {
524 ns.logf("netstack: could not parse local address for incoming connection")
525 return false
526 }
527 localIP = localIP.Unmap()
528
529 remoteIP, ok := netip.AddrFromSlice(tei.RemoteAddress.AsSlice())
530 if !ok {
531 ns.logf("netstack: could not parse remote address for incoming connection")
532 return false
533 }
534
535 // If we have too many in-flight connections for this client, abort
536 // early and don't open a new one.
537 //
538 // NOTE: the counter is decremented in
539 // decrementInFlightTCPForward, called from the acceptTCP
540 // function, below.
541
542 ns.mu.Lock()
543 if _, ok := ns.packetsInFlight[tei]; ok {
544 // We're already handling this packet; just bail early
545 // (this is also what would happen in the TCP
546 // forwarder).
547 ns.mu.Unlock()
548 return true
549 }
550
551 // Check the per-client limit.
552 inFlight := ns.connsInFlightByClient[remoteIP]
553 tooManyInFlight := inFlight >= maxInFlightConnectionAttemptsPerClient()
554 if !tooManyInFlight {
555 ns.connsInFlightByClient[remoteIP]++
556 }
557
558 // We're handling this packet now; see the comment on the
559 // packetsInFlight field for more details.
560 ns.packetsInFlight[tei] = struct{}{}
561 ns.mu.Unlock()
562
563 if debugNetstack() {
564 ns.logf("[v2] netstack: in-flight connections for client %v: %d", remoteIP, inFlight)
565 }
566 if tooManyInFlight {
567 ns.logf("netstack: ignoring a new TCP connection from %v to %v because the client already has %d in-flight connections", localIP, remoteIP, inFlight)
568 metricPerClientForwardLimit.Add(1)
569 ns.forwardInFlightPerClientDropped.Add(1)
570 return false // unhandled
571 }
572

Callers 1

StartMethod · 0.95

Calls 9

isLocalIPMethod · 0.95
isVIPServiceIPMethod · 0.95
addSubnetAddressMethod · 0.95
LockMethod · 0.65
UnlockMethod · 0.65
AddMethod · 0.65
AsSliceMethod · 0.45
logfMethod · 0.45

Tested by

no test coverage detected