wrapTCPProtocolHandler wraps the protocol handler we pass to netstack for TCP.
(h protocolHandlerFunc)
| 513 | |
| 514 | // wrapTCPProtocolHandler wraps the protocol handler we pass to netstack for TCP. |
| 515 | func (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 |
no test coverage detected