소스 검색

Accept RST on received packets

tags/v0.9.3
Michael Brown 18 년 전
부모
커밋
eea1167a85
1개의 변경된 파일49개의 추가작업 그리고 9개의 파일을 삭제
  1. 49
    9
      src/net/tcp.c

+ 49
- 9
src/net/tcp.c 파일 보기

@@ -559,7 +559,8 @@ static int tcp_rx_data ( struct tcp_connection *conn, uint32_t seq,
559 559
 	return 0;
560 560
 }
561 561
 
562
-/** Handle TCP received FIN
562
+/**
563
+ * Handle TCP received FIN
563 564
  *
564 565
  * @v conn		TCP connection
565 566
  * @v seq		SEQ value (in host-endian order)
@@ -587,6 +588,46 @@ static int tcp_rx_fin ( struct tcp_connection *conn, uint32_t seq ) {
587 588
 	return 0;
588 589
 }
589 590
 
591
+/**
592
+ * Handle TCP received RST
593
+ *
594
+ * @v conn		TCP connection
595
+ * @v seq		SEQ value (in host-endian order)
596
+ * @ret rc		Return status code
597
+ */
598
+static int tcp_rx_rst ( struct tcp_connection *conn, uint32_t seq ) {
599
+	struct tcp_application *app = conn->app;
600
+
601
+	/* Accept RST only if it falls within the window.  If we have
602
+	 * not yet received a SYN, then we have no window to test
603
+	 * against, so fall back to checking that our SYN has been
604
+	 * ACKed.
605
+	 */
606
+	if ( conn->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) {
607
+		if ( ( conn->rcv_ack - seq ) > 0 )
608
+			return 0;
609
+	} else {
610
+		if ( ! ( conn->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) )
611
+			return 0;
612
+	}
613
+
614
+	/* Transition to CLOSED */
615
+	conn->tcp_state = TCP_CLOSED;
616
+	tcp_dump_state ( conn );
617
+
618
+	/* Break association between application and connection */
619
+	tcp_disassociate ( conn );
620
+	
621
+	/* Free the connection */
622
+	free_tcp ( conn );
623
+	
624
+	/* Notify application */
625
+	if ( app && app->tcp_op->closed )
626
+		app->tcp_op->closed ( app, -ECONNRESET );
627
+
628
+	return -ECONNRESET;
629
+}
630
+
590 631
 /**
591 632
  * Process received packet
592 633
  *
@@ -668,13 +709,6 @@ static int tcp_rx ( struct pk_buff *pkb,
668 709
 		goto done;
669 710
 	}
670 711
 
671
-	/* Handle RST, if present */
672
-#warning "Handle RST"
673
-	if ( flags & TCP_RST ) {
674
-		rc = -ECONNRESET;
675
-		goto done;
676
-	}
677
-
678 712
 	/* Handle ACK, if present */
679 713
 	if ( flags & TCP_ACK )
680 714
 		tcp_rx_ack ( conn, ack, win );
@@ -685,6 +719,12 @@ static int tcp_rx ( struct pk_buff *pkb,
685 719
 		seq++;
686 720
 	}
687 721
 
722
+	/* Handle RST, if present */
723
+	if ( flags & TCP_RST ) {
724
+		if ( ( rc = tcp_rx_rst ( conn, seq ) ) != 0 )
725
+			goto done;
726
+	}
727
+
688 728
 	/* Handle new data, if any */
689 729
 	tcp_rx_data ( conn, seq, data, len );
690 730
 	seq += len;
@@ -695,7 +735,7 @@ static int tcp_rx ( struct pk_buff *pkb,
695 735
 		seq++;
696 736
 	}
697 737
 
698
-	/* Dump out any state change as a result of SYN, FIN or ACK */
738
+	/* Dump out any state change as a result of the received packet */
699 739
 	tcp_dump_state ( conn );
700 740
 
701 741
 	/* Send out any pending data.  If peer is expecting an ACK for

Loading…
취소
저장