MCPcopy
hub / github.com/monasticacademy/httptap / handlePacket

Method handlePacket

tcp.go:410–505  ·  view source on GitHub ↗
(ipv4 *layers.IPv4, tcp *layers.TCP, payload []byte)

Source from the content-addressed store, hash-verified

408}
409
410func (s *tcpStack) handlePacket(ipv4 *layers.IPv4, tcp *layers.TCP, payload []byte) {
411 // it happens that a process will connect to the same remote service multiple times in from
412 // different source ports so we must key by a descriptor that includes both endpoints
413 dst := AddrPort{Addr: ipv4.DstIP, Port: uint16(tcp.DstPort)}
414 src := AddrPort{Addr: ipv4.SrcIP, Port: uint16(tcp.SrcPort)}
415
416 // put source address, source port, destination address, and destination port into a human-readable string
417 srcdst := src.String() + " => " + dst.String()
418 stream, found := s.streamsBySrcDst[srcdst]
419 if !found {
420 // create a new stream no matter what kind of packet this is
421 // later we will reject everything other than SYN packets sent to a fresh stream
422 stream = newTCPStream(dst, src, s.toSubprocess)
423 stream.ack = tcp.Seq
424 s.streamsBySrcDst[srcdst] = stream
425 }
426
427 // handle connection establishment
428 if tcp.SYN && stream.state == StateInit {
429 stream.state = StateSynReceived
430 atomic.StoreUint32(&stream.ack, tcp.Seq+1)
431 verbosef("got SYN to %v:%v, now state is %v", ipv4.DstIP, tcp.DstPort, stream.state)
432 s.app.notifyTCP(stream)
433 }
434
435 // handle connection teardown
436 if tcp.FIN && stream.state != StateInit {
437 // according to the tcp spec we are always allowed to ack the other side's FIN, even if we have
438 // already sent our own FIN
439 stream.state = StateOtherSideFinished
440 seq := atomic.AddUint32(&stream.seq, 1) - 1
441 atomic.StoreUint32(&stream.ack, tcp.Seq+1)
442 verbosef("got FIN to %v:%v, now state is %v", ipv4.DstIP, tcp.DstPort, stream.state)
443
444 // make a FIN+ACK reply to send to the subprocess
445 replytcp := layers.TCP{
446 SrcPort: tcp.DstPort,
447 DstPort: tcp.SrcPort,
448 FIN: true,
449 ACK: true,
450 Seq: seq,
451 Ack: tcp.Seq + 1,
452 Window: 64240, // number of bytes we are willing to receive (copied from sender)
453 }
454
455 replyipv4 := layers.IPv4{
456 Version: 4, // indicates IPv4
457 TTL: ttl,
458 Protocol: layers.IPProtocolTCP,
459 SrcIP: ipv4.DstIP,
460 DstIP: ipv4.SrcIP,
461 }
462
463 replytcp.SetNetworkLayerForChecksum(&replyipv4)
464
465 // log
466 verbosef("sending FIN+ACK to subprocess: %s", summarizeTCP(&replyipv4, &replytcp, nil))
467

Callers

nothing calls this directly

Calls 8

StringMethod · 0.95
newTCPStreamFunction · 0.85
summarizeTCPFunction · 0.85
serializeTCPFunction · 0.85
notifyTCPMethod · 0.80
deliverToApplicationMethod · 0.80
verbosefFunction · 0.70
errorfFunction · 0.70

Tested by

no test coverage detected