Browse Source

Correct some packet ownership and freeing bugs.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
09688cb3b5
1 changed files with 36 additions and 15 deletions
  1. 36
    15
      src/net/tcp.c

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

@@ -636,9 +636,13 @@ int tcp_senddata ( struct tcp_connection *conn ) {
636 636
  */
637 637
 int tcp_send ( struct tcp_connection *conn, const void *data, size_t len ) {
638 638
 	struct sockaddr_tcpip *peer = &conn->peer;
639
-	struct pk_buff *pkb = conn->tx_pkb;
639
+	struct pk_buff *pkb;
640 640
 	int slen;
641 641
 
642
+	/* Take ownership of the TX buffer from the connection */
643
+	pkb = conn->tx_pkb;
644
+	conn->tx_pkb = NULL;
645
+
642 646
 	/* Determine the amount of data to be sent */
643 647
 	slen = len < conn->snd_win ? len : conn->snd_win;
644 648
 	/* Copy payload */
@@ -694,11 +698,13 @@ static int tcp_rx ( struct pk_buff *pkb,
694 698
 	struct tcp_header *tcphdr;
695 699
 	uint32_t acked, toack;
696 700
 	int hlen;
701
+	int rc;
697 702
 
698 703
 	/* Sanity check */
699 704
 	if ( pkb_len ( pkb ) < sizeof ( *tcphdr ) ) {
700 705
 		DBG ( "Packet too short (%d bytes)\n", pkb_len ( pkb ) );
701
-		return -EINVAL;
706
+		rc = -EINVAL;
707
+		goto done;
702 708
 	}
703 709
 
704 710
 
@@ -713,7 +719,8 @@ static int tcp_rx ( struct pk_buff *pkb,
713 719
 			DBG ( "TCP options sent\n" );
714 720
 		} else {
715 721
 			DBG ( "Bad header length (%d bytes)\n", hlen );
716
-			return -EINVAL;
722
+			rc = -EINVAL;
723
+			goto done;
717 724
 		}
718 725
 	}
719 726
 
@@ -728,7 +735,8 @@ static int tcp_rx ( struct pk_buff *pkb,
728 735
 	}
729 736
 	
730 737
 	DBG ( "No connection found on port %d\n", ntohs ( tcphdr->dest ) );
731
-	return 0;
738
+	rc = 0;
739
+	goto done;
732 740
 
733 741
   found_conn:
734 742
 	/* Stop the timer */
@@ -743,7 +751,8 @@ static int tcp_rx ( struct pk_buff *pkb,
743 751
 	case TCP_CLOSED:
744 752
 		DBG ( "tcp_rx(): Invalid state %s\n",
745 753
 				tcp_states[conn->tcp_state] );
746
-		return -EINVAL;
754
+		rc = -EINVAL;
755
+		goto done;
747 756
 	case TCP_LISTEN:
748 757
 		if ( tcphdr->flags & TCP_SYN ) {
749 758
 			tcp_trans ( conn, TCP_SYN_RCVD );
@@ -776,7 +785,8 @@ static int tcp_rx ( struct pk_buff *pkb,
776 785
 				conn->tcp_op->connected ( conn );
777 786
 				conn->tcp_flags |= TCP_ACK;
778 787
 				tcp_senddata ( conn );
779
-				return;
788
+				rc = 0;
789
+				goto done;
780 790
 			} else {
781 791
 				tcp_trans ( conn, TCP_SYN_RCVD );
782 792
 				conn->tcp_flags |= TCP_SYN;
@@ -789,7 +799,8 @@ static int tcp_rx ( struct pk_buff *pkb,
789 799
 		if ( tcphdr->flags & TCP_RST ) {
790 800
 			tcp_trans ( conn, TCP_LISTEN );
791 801
 			conn->tcp_op->closed ( conn, CONN_RESTART );
792
-			return 0;
802
+			rc = 0;
803
+			goto done;
793 804
 		}
794 805
 		if ( tcphdr->flags & TCP_ACK ) {
795 806
 			tcp_trans ( conn, TCP_ESTABLISHED );
@@ -799,7 +810,8 @@ static int tcp_rx ( struct pk_buff *pkb,
799 810
 			 */
800 811
 			conn->snd_una = tcphdr->ack - 1;
801 812
 			conn->tcp_op->connected ( conn );
802
-			return 0;
813
+			rc = 0;
814
+			goto done;
803 815
 		}
804 816
 		/* Unexpected packet */
805 817
 		goto unexpected;
@@ -849,7 +861,8 @@ static int tcp_rx ( struct pk_buff *pkb,
849 861
 		if ( tcphdr->flags & TCP_ACK ) {
850 862
 			tcp_trans ( conn, TCP_TIME_WAIT );
851 863
 			start_timer ( &conn->timer );
852
-			return 0;
864
+			rc = 0;
865
+			goto done;
853 866
 		}
854 867
 		/* Unexpected packet */
855 868
 		goto unexpected;
@@ -862,7 +875,8 @@ static int tcp_rx ( struct pk_buff *pkb,
862 875
 	case TCP_LAST_ACK:
863 876
 		if ( tcphdr->flags & TCP_ACK ) {
864 877
 			tcp_trans ( conn, TCP_CLOSED );
865
-			return 0;
878
+			rc = 0;
879
+			goto done;
866 880
 		}
867 881
 		/* Unexpected packet */
868 882
 		goto unexpected;
@@ -900,7 +914,8 @@ static int tcp_rx ( struct pk_buff *pkb,
900 914
 		acked = ntohl ( tcphdr->ack ) - conn->snd_una;
901 915
 		if ( acked < 0 ) { /* TODO: Replace all uint32_t arith */
902 916
 			DBG ( "Previously ACKed (%d)\n", tcphdr->ack );
903
-			return 0;
917
+			rc = 0;
918
+			goto done;
904 919
 		}
905 920
 		/* Advance snd stream */
906 921
 		conn->snd_una += acked;
@@ -922,24 +937,30 @@ static int tcp_rx ( struct pk_buff *pkb,
922 937
 		}
923 938
 		/* Otherwise, the packet has been ACKed already */
924 939
 	}
925
-	return 0;
940
+	rc = 0;
941
+	goto done;
926 942
 
927 943
   send_tcp_nomsg:
928 944
 	free_pkb ( conn->tx_pkb );
929 945
 	conn->tx_pkb = alloc_pkb ( MIN_PKB_LEN );
930 946
 	pkb_reserve ( conn->tx_pkb, MAX_HDR_LEN );
931
-	int rc;
932 947
 	if ( ( rc = tcp_send ( conn, TCP_NOMSG, TCP_NOMSG_LEN ) ) != 0 ) {
933 948
 		DBG ( "Error sending TCP message (rc = %d)\n", rc );
934 949
 	}
935
-	return 0;
950
+	goto done;
936 951
 
937 952
   unexpected:
938 953
 	DBG ( "Unexpected packet received in %s with flags = %#hx\n",
939 954
 			tcp_states[conn->tcp_state], tcphdr->flags & TCP_MASK_FLAGS );
940 955
 	tcp_close ( conn );
941 956
 	free_pkb ( conn->tx_pkb );
942
-	return -EINVAL;
957
+	conn->tx_pkb = NULL;
958
+	rc = -EINVAL;
959
+	goto done;
960
+
961
+ done:
962
+	free_pkb ( pkb );
963
+	return rc;
943 964
 }
944 965
 
945 966
 /** TCP protocol */

Loading…
Cancel
Save