Browse Source

[tcp] Attempt to catch all possible error cases with debug messages

All TCP errors or unusual events should now generate a debugging
message at DBGLVL_LOG, with enough information (SEQ and ACK numbers)
to be able to identify the corresponding packet (or missing packet) in
a network trace from the remote end.
tags/v0.9.8
Michael Brown 15 years ago
parent
commit
99e64f5806
1 changed files with 36 additions and 11 deletions
  1. 36
    11
      src/net/tcp.c

+ 36
- 11
src/net/tcp.c View File

402
 	size_t seq_len;
402
 	size_t seq_len;
403
 	size_t app_win;
403
 	size_t app_win;
404
 	size_t max_rcv_win;
404
 	size_t max_rcv_win;
405
+	int rc;
405
 
406
 
406
 	/* If retransmission timer is already running, do nothing */
407
 	/* If retransmission timer is already running, do nothing */
407
 	if ( timer_running ( &tcp->timer ) )
408
 	if ( timer_running ( &tcp->timer ) )
438
 	/* Allocate I/O buffer */
439
 	/* Allocate I/O buffer */
439
 	iobuf = alloc_iob ( len + MAX_HDR_LEN );
440
 	iobuf = alloc_iob ( len + MAX_HDR_LEN );
440
 	if ( ! iobuf ) {
441
 	if ( ! iobuf ) {
441
-		DBGC ( tcp, "TCP %p could not allocate data buffer\n", tcp );
442
+		DBGC ( tcp, "TCP %p could not allocate iobuf for %08x..%08x "
443
+		       "%08x\n", tcp, tcp->snd_seq, ( tcp->snd_seq + seq_len ),
444
+		       tcp->rcv_ack );
442
 		return -ENOMEM;
445
 		return -ENOMEM;
443
 	}
446
 	}
444
 	iob_reserve ( iobuf, MAX_HDR_LEN );
447
 	iob_reserve ( iobuf, MAX_HDR_LEN );
495
 	DBGC2 ( tcp, "\n" );
498
 	DBGC2 ( tcp, "\n" );
496
 
499
 
497
 	/* Transmit packet */
500
 	/* Transmit packet */
498
-	return tcpip_tx ( iobuf, &tcp_protocol, NULL, &tcp->peer, NULL,
499
-			  &tcphdr->csum );
501
+	if ( ( rc = tcpip_tx ( iobuf, &tcp_protocol, NULL, &tcp->peer, NULL,
502
+			       &tcphdr->csum ) ) != 0 ) {
503
+		DBGC ( tcp, "TCP %p could not transmit %08x..%08x %08x: %s\n",
504
+		       tcp, tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ),
505
+		       tcp->rcv_ack, strerror ( rc ) );
506
+		return rc;
507
+	}
508
+
509
+	return 0;
500
 }
510
 }
501
 
511
 
502
 /**
512
 /**
510
 		container_of ( timer, struct tcp_connection, timer );
520
 		container_of ( timer, struct tcp_connection, timer );
511
 	int graceful_close = TCP_CLOSED_GRACEFULLY ( tcp->tcp_state );
521
 	int graceful_close = TCP_CLOSED_GRACEFULLY ( tcp->tcp_state );
512
 
522
 
513
-	DBGC ( tcp, "TCP %p timer %s in %s for [%08x,%08x)\n", tcp,
523
+	DBGC ( tcp, "TCP %p timer %s in %s for %08x..%08x %08x\n", tcp,
514
 	       ( over ? "expired" : "fired" ), tcp_state ( tcp->tcp_state ),
524
 	       ( over ? "expired" : "fired" ), tcp_state ( tcp->tcp_state ),
515
-	       tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ) );
525
+	       tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ), tcp->rcv_ack );
516
 
526
 
517
 	assert ( ( tcp->tcp_state == TCP_SYN_SENT ) ||
527
 	assert ( ( tcp->tcp_state == TCP_SYN_SENT ) ||
518
 		 ( tcp->tcp_state == TCP_SYN_RCVD ) ||
528
 		 ( tcp->tcp_state == TCP_SYN_RCVD ) ||
547
 			    struct tcp_header *in_tcphdr ) {
557
 			    struct tcp_header *in_tcphdr ) {
548
 	struct io_buffer *iobuf;
558
 	struct io_buffer *iobuf;
549
 	struct tcp_header *tcphdr;
559
 	struct tcp_header *tcphdr;
560
+	int rc;
550
 
561
 
551
 	/* Allocate space for dataless TX buffer */
562
 	/* Allocate space for dataless TX buffer */
552
 	iobuf = alloc_iob ( MAX_HDR_LEN );
563
 	iobuf = alloc_iob ( MAX_HDR_LEN );
553
 	if ( ! iobuf ) {
564
 	if ( ! iobuf ) {
554
-		DBGC ( tcp, "TCP %p could not allocate data buffer\n", tcp );
565
+		DBGC ( tcp, "TCP %p could not allocate iobuf for RST "
566
+		       "%08x..%08x %08x\n", tcp, ntohl ( in_tcphdr->ack ),
567
+		       ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->seq ) );
555
 		return -ENOMEM;
568
 		return -ENOMEM;
556
 	}
569
 	}
557
 	iob_reserve ( iobuf, MAX_HDR_LEN );
570
 	iob_reserve ( iobuf, MAX_HDR_LEN );
577
 	DBGC2 ( tcp, "\n" );
590
 	DBGC2 ( tcp, "\n" );
578
 
591
 
579
 	/* Transmit packet */
592
 	/* Transmit packet */
580
-	return tcpip_tx ( iobuf, &tcp_protocol, NULL, st_dest,
581
-			  NULL, &tcphdr->csum );
593
+	if ( ( rc = tcpip_tx ( iobuf, &tcp_protocol, NULL, st_dest,
594
+			       NULL, &tcphdr->csum ) ) != 0 ) {
595
+		DBGC ( tcp, "TCP %p could not transmit RST %08x..%08x %08x: "
596
+		       "%s\n", tcp, ntohl ( in_tcphdr->ack ),
597
+		       ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->seq ),
598
+		       strerror ( rc ) );
599
+		return rc;
600
+	}
601
+
602
+	return 0;
582
 }
603
 }
583
 
604
 
584
 /***************************************************************************
605
 /***************************************************************************
728
 		 * timer running, as for the ack_len==0 case, to
749
 		 * timer running, as for the ack_len==0 case, to
729
 		 * handle old duplicate ACKs.
750
 		 * handle old duplicate ACKs.
730
 		 */
751
 		 */
731
-		DBGC ( tcp, "TCP %p received ACK for [%08x,%08zx), "
732
-		       "sent only [%08x,%08x)\n", tcp, tcp->snd_seq,
752
+		DBGC ( tcp, "TCP %p received ACK for %08x..%08zx, "
753
+		       "sent only %08x..%08x\n", tcp, tcp->snd_seq,
733
 		       ( tcp->snd_seq + ack_len ), tcp->snd_seq,
754
 		       ( tcp->snd_seq + ack_len ), tcp->snd_seq,
734
 		       ( tcp->snd_seq + tcp->snd_sent ) );
755
 		       ( tcp->snd_seq + tcp->snd_sent ) );
735
 		/* Send RST if an out-of-range ACK is received on a
756
 		/* Send RST if an out-of-range ACK is received on a
785
 	len -= already_rcvd;
806
 	len -= already_rcvd;
786
 
807
 
787
 	/* Deliver data to application */
808
 	/* Deliver data to application */
788
-	if ( ( rc = xfer_deliver_iob ( &tcp->xfer, iobuf ) ) != 0 )
809
+	if ( ( rc = xfer_deliver_iob ( &tcp->xfer, iobuf ) ) != 0 ) {
810
+		DBGC ( tcp, "TCP %p could not deliver %08x..%08x: %s\n",
811
+		       tcp, seq, ( seq + len ), strerror ( rc ) );
789
 		return rc;
812
 		return rc;
813
+	}
790
 
814
 
791
 	/* Acknowledge new data */
815
 	/* Acknowledge new data */
792
 	tcp_rx_seq ( tcp, len );
816
 	tcp_rx_seq ( tcp, len );
844
 	tcp_dump_state ( tcp );
868
 	tcp_dump_state ( tcp );
845
 	tcp_close ( tcp, -ECONNRESET );
869
 	tcp_close ( tcp, -ECONNRESET );
846
 
870
 
871
+	DBGC ( tcp, "TCP %p connection reset by peer\n", tcp );
847
 	return -ECONNRESET;
872
 	return -ECONNRESET;
848
 }
873
 }
849
 
874
 

Loading…
Cancel
Save