Browse Source

Send RST packets when we get a non-matching connection, or receive an

out-of-range ACK.
tags/v0.9.3
Michael Brown 17 years ago
parent
commit
b0daa99dce
1 changed files with 51 additions and 9 deletions
  1. 51
    9
      src/net/tcp.c

+ 51
- 9
src/net/tcp.c View File

425
 	}
425
 	}
426
 }
426
 }
427
 
427
 
428
+/**
429
+ * Send RST response to incoming packet
430
+ *
431
+ * @v in_tcphdr		TCP header of incoming packet
432
+ * @ret rc		Return status code
433
+ */
434
+static int tcp_send_reset ( struct tcp_connection *conn,
435
+			    struct tcp_header *in_tcphdr ) {
436
+	struct pk_buff *pkb;
437
+	struct tcp_header *tcphdr;
438
+
439
+	/* Allocate space for dataless TX buffer */
440
+	pkb = alloc_pkb ( MAX_HDR_LEN );
441
+	if ( ! pkb ) {
442
+		DBGC ( conn, "TCP %p could not allocate data buffer\n", conn );
443
+		return -ENOMEM;
444
+	}
445
+	pkb_reserve ( pkb, MAX_HDR_LEN );
446
+
447
+	/* Construct RST response */
448
+	tcphdr = pkb_push ( pkb, sizeof ( *tcphdr ) );
449
+	memset ( tcphdr, 0, sizeof ( *tcphdr ) );
450
+	tcphdr->src = in_tcphdr->dest;
451
+	tcphdr->dest = in_tcphdr->src;
452
+	tcphdr->seq = in_tcphdr->ack;
453
+	tcphdr->ack = in_tcphdr->seq;
454
+	tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 );
455
+	tcphdr->flags = ( TCP_RST | TCP_ACK );
456
+	tcphdr->win = htons ( TCP_WINDOW_SIZE );
457
+	tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
458
+
459
+	/* Dump header */
460
+	DBGC ( conn, "TCP %p TX %d->%d %08lx..%08lx           %08lx %4zd",
461
+	       conn, ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ),
462
+	       ntohl ( tcphdr->seq ), ( ntohl ( tcphdr->seq ) ),
463
+	       ntohl ( tcphdr->ack ), 0 );
464
+	tcp_dump_flags ( conn, tcphdr->flags );
465
+	DBGC ( conn, "\n" );
466
+
467
+	/* Transmit packet */
468
+	return tcpip_tx ( pkb, &tcp_protocol, &conn->peer, &tcphdr->csum );
469
+}
470
+
428
 /**
471
 /**
429
  * Identify TCP connection by local port number
472
  * Identify TCP connection by local port number
430
  *
473
  *
700
 	tcp_dump_flags ( conn, tcphdr->flags );
743
 	tcp_dump_flags ( conn, tcphdr->flags );
701
 	DBGC ( conn, "\n" );
744
 	DBGC ( conn, "\n" );
702
 
745
 
703
-	/* If no connection was found, create dummy connection for
704
-	 * sending RST
705
-	 */
706
-#warning "Handle non-matched connections"
746
+	/* If no connection was found, send RST */
707
 	if ( ! conn ) {
747
 	if ( ! conn ) {
748
+		tcp_send_reset ( conn, tcphdr );
708
 		rc = -ENOTCONN;
749
 		rc = -ENOTCONN;
709
 		goto done;
750
 		goto done;
710
 	}
751
 	}
711
 
752
 
712
 	/* Handle ACK, if present */
753
 	/* Handle ACK, if present */
713
-	if ( flags & TCP_ACK )
714
-		tcp_rx_ack ( conn, ack, win );
754
+	if ( flags & TCP_ACK ) {
755
+		if ( ( rc = tcp_rx_ack ( conn, ack, win ) ) != 0 ) {
756
+			tcp_send_reset ( conn, tcphdr );
757
+			goto done;
758
+		}
759
+	}
715
 
760
 
716
 	/* Handle SYN, if present */
761
 	/* Handle SYN, if present */
717
 	if ( flags & TCP_SYN ) {
762
 	if ( flags & TCP_SYN ) {
773
 	struct tcp_connection *existing;
818
 	struct tcp_connection *existing;
774
 	static uint16_t try_port = 1024;
819
 	static uint16_t try_port = 1024;
775
 
820
 
776
-#warning "Fix the port re-use bug"
777
-	try_port = random();
778
-
779
 	/* If no port specified, find the first available port */
821
 	/* If no port specified, find the first available port */
780
 	if ( ! local_port ) {
822
 	if ( ! local_port ) {
781
 		for ( ; try_port ; try_port++ ) {
823
 		for ( ; try_port ; try_port++ ) {

Loading…
Cancel
Save