Browse Source

Removed some bugs in TCP

tags/v0.9.3
Nikhil Chandru Rao 18 years ago
parent
commit
d2bdf81505
4 changed files with 106 additions and 57 deletions
  1. 2
    1
      src/include/gpxe/ip6.h
  2. 2
    3
      src/include/gpxe/tcp.h
  3. 6
    0
      src/net/ipv4.c
  4. 96
    53
      src/net/tcp.c

+ 2
- 1
src/include/gpxe/ip6.h View File

11
 
11
 
12
 /* IP6 constants */
12
 /* IP6 constants */
13
 
13
 
14
-#define IP6_VER		6
14
+#define IP6_VERSION	0x6
15
+#define IP6_HOP_LIMIT	64
15
 
16
 
16
 /* IP6 header */
17
 /* IP6 header */
17
 
18
 

+ 2
- 3
src/include/gpxe/tcp.h View File

159
 	struct list_head list;		/* List of TCP connections */
159
 	struct list_head list;		/* List of TCP connections */
160
 	struct pk_buff *tx_pkb;		/* Transmit packet buffer */
160
 	struct pk_buff *tx_pkb;		/* Transmit packet buffer */
161
 	struct retry_timer timer;	/* Retransmission timer */
161
 	struct retry_timer timer;	/* Retransmission timer */
162
-	int retransmits;		/* Number of retransmits */
163
 	struct tcp_operations *tcp_op;	/* Operations table for connection */
162
 	struct tcp_operations *tcp_op;	/* Operations table for connection */
164
 };
163
 };
165
 
164
 
198
 /**
197
 /**
199
  * TCP flags
198
  * TCP flags
200
  */
199
  */
201
-#define TCP_RST		0x20
200
+#define TCP_URG		0x20
202
 #define TCP_ACK		0x10
201
 #define TCP_ACK		0x10
203
 #define TCP_PSH		0x08
202
 #define TCP_PSH		0x08
204
-#define TCP_URG		0x04
203
+#define TCP_RST		0x04
205
 #define TCP_SYN		0x02
204
 #define TCP_SYN		0x02
206
 #define TCP_FIN		0x01
205
 #define TCP_FIN		0x01
207
 
206
 

+ 6
- 0
src/net/ipv4.c View File

107
  */
107
  */
108
 static void ipv4_dump ( struct iphdr *iphdr __unused ) {
108
 static void ipv4_dump ( struct iphdr *iphdr __unused ) {
109
 
109
 
110
+/*
110
 	DBG ( "IP4 header at %p+%#zx\n", iphdr, sizeof ( *iphdr ) );
111
 	DBG ( "IP4 header at %p+%#zx\n", iphdr, sizeof ( *iphdr ) );
111
 	DBG ( "\tVersion = %d\n", ( iphdr->verhdrlen & IP_MASK_VER ) / 16 );
112
 	DBG ( "\tVersion = %d\n", ( iphdr->verhdrlen & IP_MASK_VER ) / 16 );
112
 	DBG ( "\tHeader length = %d\n", iphdr->verhdrlen & IP_MASK_HLEN );
113
 	DBG ( "\tHeader length = %d\n", iphdr->verhdrlen & IP_MASK_HLEN );
120
 				ntohs ( iphdr->chksum ) );
121
 				ntohs ( iphdr->chksum ) );
121
 	DBG ( "\tSource = %s\n", inet_ntoa ( iphdr->src ) );
122
 	DBG ( "\tSource = %s\n", inet_ntoa ( iphdr->src ) );
122
 	DBG ( "\tDestination = %s\n", inet_ntoa ( iphdr->dest ) );
123
 	DBG ( "\tDestination = %s\n", inet_ntoa ( iphdr->dest ) );
124
+*/
125
+	DBG ( "IP4 %p transmitting %p+%d ident %d protocol %d header-csum %x\n",
126
+		&ipv4_protocol, iphdr, ntohs ( iphdr->len ), ntohs ( iphdr->ident ),
127
+		iphdr->protocol, ntohs ( iphdr->chksum ) );
128
+	DBG ( "src %s, dest %s\n", inet_ntoa ( iphdr->src ), inet_ntoa ( iphdr->dest ) );
123
 }
129
 }
124
 
130
 
125
 /**
131
 /**

+ 96
- 53
src/net/tcp.c View File

258
  * @v conn	TCP connection
258
  * @v conn	TCP connection
259
  * @v nxt_state Next TCP state
259
  * @v nxt_state Next TCP state
260
  */
260
  */
261
-void tcp_trans ( struct tcp_connection *conn, int nxt_state ) {
261
+void tcp_set_flags ( struct tcp_connection *conn ) {
262
-	/* Remember the last state */
263
-	conn->tcp_lstate = conn->tcp_state;
264
-	conn->tcp_state = nxt_state;
265
-
266
-	/* TODO: Check if this check is required */
267
-	if ( conn->tcp_lstate == conn->tcp_state || 
268
-	     conn->tcp_state == TCP_INVALID ) {
269
-		conn->tcp_flags = 0;
270
-		return;
271
-	}
272
 
262
 
273
 	/* Set the TCP flags */
263
 	/* Set the TCP flags */
274
 	switch ( conn->tcp_state ) {
264
 	switch ( conn->tcp_state ) {
331
 	}
321
 	}
332
 }
322
 }
333
 
323
 
324
+void tcp_trans ( struct tcp_connection *conn, int nxt_state ) {
325
+	/* Remember the last state */
326
+	conn->tcp_lstate = conn->tcp_state;
327
+	conn->tcp_state = nxt_state;
328
+
329
+	printf ( "Transition from %s to %s\n", tcp_states[conn->tcp_lstate], tcp_states[conn->tcp_state] );
330
+
331
+	/* TODO: Check if this check is required */
332
+	if ( conn->tcp_lstate == conn->tcp_state || 
333
+	     conn->tcp_state == TCP_INVALID ) {
334
+		conn->tcp_flags = 0;
335
+		return;
336
+	}
337
+	tcp_set_flags ( conn );
338
+}
339
+
334
 /**
340
 /**
335
  * Dump TCP header
341
  * Dump TCP header
336
  *
342
  *
337
  * @v tcphdr	TCP header
343
  * @v tcphdr	TCP header
338
  */
344
  */
339
 void tcp_dump ( struct tcp_header *tcphdr ) {
345
 void tcp_dump ( struct tcp_header *tcphdr ) {
346
+/*
340
 	DBG ( "TCP header at %p+%d\n", tcphdr, sizeof ( *tcphdr ) );
347
 	DBG ( "TCP header at %p+%d\n", tcphdr, sizeof ( *tcphdr ) );
341
 	DBG ( "\tSource port = %d, Destination port = %d\n",
348
 	DBG ( "\tSource port = %d, Destination port = %d\n",
342
 		ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ) );
349
 		ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ) );
347
 		( tcphdr->flags & TCP_MASK_FLAGS ) );
354
 		( tcphdr->flags & TCP_MASK_FLAGS ) );
348
 	DBG ( "\tAdvertised window = %ld, Checksum = %x, Urgent Pointer = %d\n",
355
 	DBG ( "\tAdvertised window = %ld, Checksum = %x, Urgent Pointer = %d\n",
349
 		ntohs ( tcphdr->win ), tcphdr->csum, ntohs ( tcphdr->urg ) );
356
 		ntohs ( tcphdr->win ), tcphdr->csum, ntohs ( tcphdr->urg ) );
357
+*/
358
+	DBG ( "TCP %p at %p src:%d dest:%d seq:%lld ack:%lld hlen:%hd flags:%#hx\n",
359
+		&tcp_protocol, tcphdr, ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ), ntohl ( tcphdr->seq ),
360
+		ntohl ( tcphdr->ack ), ( ( tcphdr->hlen & TCP_MASK_HLEN ) / 16 ), ( tcphdr->flags & TCP_MASK_FLAGS ) );
350
 }
361
 }
351
 
362
 
352
 /**
363
 /**
377
  */
388
  */
378
 void tcp_expired ( struct retry_timer *timer, int over ) {
389
 void tcp_expired ( struct retry_timer *timer, int over ) {
379
 	struct tcp_connection *conn;
390
 	struct tcp_connection *conn;
380
-	if ( over ) {
391
+	conn = ( struct tcp_connection * ) container_of ( timer, 
381
-		conn = ( struct tcp_connection * ) container_of ( timer, 
392
+					struct tcp_connection, timer );
382
-						struct tcp_connection, timer );
393
+	DBG ( "Timer expired in %s\n", tcp_states[conn->tcp_state] );
383
-		switch ( conn->tcp_state ) {
394
+	switch ( conn->tcp_state ) {
384
-		case TCP_SYN_SENT:
395
+	case TCP_SYN_SENT:
385
-			if ( conn->retransmits > MAX_RETRANSMITS ) {
396
+		if ( over ) {
386
-				tcp_trans ( conn, TCP_CLOSED );
387
-				return;
388
-			}
389
-			if ( conn->tcp_lstate == TCP_CLOSED ||
390
-			     conn->tcp_lstate == TCP_LISTEN ) {
391
-				goto send_tcp_nomsg;
392
-			}
393
-			return;
394
-		case TCP_SYN_RCVD:
395
 			tcp_trans ( conn, TCP_CLOSED );
397
 			tcp_trans ( conn, TCP_CLOSED );
396
-			if ( conn->tcp_lstate == TCP_LISTEN ||
398
+			stop_timer ( &conn->timer );
397
-			     conn->tcp_lstate == TCP_SYN_SENT ) {
399
+			DBG ( "Timeout! Connection closed\n" );
398
-				goto send_tcp_nomsg;
399
-			}
400
-			return;
401
-		case TCP_ESTABLISHED:
402
-			break;
403
-		case TCP_FIN_WAIT_1:
404
-		case TCP_FIN_WAIT_2:
405
-		case TCP_CLOSE_WAIT:
406
-			goto send_tcp_nomsg;
407
-		case TCP_CLOSING:
408
-		case TCP_LAST_ACK:
409
 			return;
400
 			return;
410
-		case TCP_TIME_WAIT:
401
+		}
402
+		goto send_tcp_nomsg;
403
+	case TCP_SYN_RCVD:
404
+		if ( over ) {
411
 			tcp_trans ( conn, TCP_CLOSED );
405
 			tcp_trans ( conn, TCP_CLOSED );
412
-			return;
406
+			stop_timer ( &conn->timer );
407
+			goto send_tcp_nomsg;
408
+		}
409
+		goto send_tcp_nomsg;
410
+	case TCP_ESTABLISHED:
411
+		if ( conn->tcp_lstate == TCP_SYN_SENT ) {
412
+			goto send_tcp_nomsg;
413
+		}
414
+		break;
415
+	case TCP_CLOSE_WAIT:
416
+		if ( conn->tcp_lstate == TCP_ESTABLISHED ) {
417
+			goto send_tcp_nomsg;
418
+		}
419
+		break;
420
+	case TCP_FIN_WAIT_1:
421
+	case TCP_FIN_WAIT_2:
422
+		goto send_tcp_nomsg;
423
+	case TCP_CLOSING:
424
+	case TCP_LAST_ACK:
425
+		if ( conn->tcp_lstate == TCP_CLOSE_WAIT ) {
426
+			goto send_tcp_nomsg;
413
 		}
427
 		}
414
-		/* Retransmit the data */
415
-		tcp_senddata ( conn );
416
-		conn->retransmits++;
417
 		return;
428
 		return;
429
+	case TCP_TIME_WAIT:
430
+		tcp_trans ( conn, TCP_CLOSED );
431
+		stop_timer ( &conn->timer );
432
+		return;
433
+	}
434
+	/* Retransmit the data */
435
+	tcp_set_flags ( conn );
436
+	tcp_senddata ( conn );
437
+	return;
418
 
438
 
419
   send_tcp_nomsg:
439
   send_tcp_nomsg:
420
-		tcp_send ( conn, TCP_NOMSG, TCP_NOMSG_LEN );
440
+//	free_pkb ( conn->tx_pkb );
421
-		return;
441
+	conn->tx_pkb = alloc_pkb ( MIN_PKB_LEN );
442
+	pkb_reserve ( conn->tx_pkb, MAX_HDR_LEN );
443
+	tcp_set_flags ( conn );
444
+	int rc;
445
+	if ( ( rc = tcp_send ( conn, TCP_NOMSG, TCP_NOMSG_LEN ) ) != 0 ) {
446
+		DBG ( "Error sending TCP message (rc = %d)\n", rc );
422
 	}
447
 	}
448
+	return;
423
 }
449
 }
424
 
450
 
425
 /**
451
 /**
634
 	tcp_dump ( tcphdr );
660
 	tcp_dump ( tcphdr );
635
 
661
 
636
 	/* Start the timer */
662
 	/* Start the timer */
637
-	start_timer ( &conn->timer );
663
+	if ( ( conn->tcp_state == TCP_ESTABLISHED && conn->tcp_lstate == TCP_SYN_SENT ) ||
664
+	     ( conn->tcp_state == TCP_LISTEN && conn->tcp_lstate == TCP_SYN_RCVD ) ||
665
+	     ( conn->tcp_state == TCP_CLOSED && conn->tcp_lstate == TCP_SYN_RCVD ) ) {
666
+		// Don't start the timer
667
+	} else {
668
+		start_timer ( &conn->timer );
669
+	}
638
 
670
 
639
 	/* Transmit packet */
671
 	/* Transmit packet */
640
 	return tcpip_tx ( pkb, &tcp_protocol, peer );
672
 	return tcpip_tx ( pkb, &tcp_protocol, peer );
653
 	struct tcp_header *tcphdr;
685
 	struct tcp_header *tcphdr;
654
 	uint32_t acked, toack;
686
 	uint32_t acked, toack;
655
 	int hlen;
687
 	int hlen;
688
+	int add = 0;
656
 
689
 
657
 	/* Sanity check */
690
 	/* Sanity check */
658
 	if ( pkb_len ( pkb ) < sizeof ( *tcphdr ) ) {
691
 	if ( pkb_len ( pkb ) < sizeof ( *tcphdr ) ) {
660
 		return -EINVAL;
693
 		return -EINVAL;
661
 	}
694
 	}
662
 
695
 
696
+
663
 	/* Process TCP header */
697
 	/* Process TCP header */
664
 	tcphdr = pkb->data;
698
 	tcphdr = pkb->data;
699
+	tcp_dump ( tcphdr );
665
 
700
 
666
 	/* Verify header length */
701
 	/* Verify header length */
667
 	hlen = ( ( tcphdr->hlen & TCP_MASK_HLEN ) / 16 ) * 4;
702
 	hlen = ( ( tcphdr->hlen & TCP_MASK_HLEN ) / 16 ) * 4;
668
 	if ( hlen != sizeof ( *tcphdr ) ) {
703
 	if ( hlen != sizeof ( *tcphdr ) ) {
669
-		DBG ( "Bad header length (%d bytes)\n", hlen );
704
+		if ( hlen == sizeof ( *tcphdr ) + 4 ) {
670
-		return -EINVAL;
705
+			DBG ( "TCP options sent\n" );
706
+			add = 4;
707
+		} else {
708
+			DBG ( "Bad header length (%d bytes)\n", hlen );
709
+			return -EINVAL;
710
+		}
671
 	}
711
 	}
672
 	
712
 	
673
 	/* TODO: Verify checksum */
713
 	/* TODO: Verify checksum */
685
   found_conn:
725
   found_conn:
686
 	/* Stop the timer */
726
 	/* Stop the timer */
687
 	stop_timer ( &conn->timer );
727
 	stop_timer ( &conn->timer );
688
-	conn->retransmits = 0;
689
 
728
 
690
 	/* Set the advertised window */
729
 	/* Set the advertised window */
691
 	conn->snd_win = tcphdr->win;
730
 	conn->snd_win = tcphdr->win;
729
 				 */
768
 				 */
730
 				conn->snd_una = ntohl ( tcphdr->ack );
769
 				conn->snd_una = ntohl ( tcphdr->ack );
731
 				conn->tcp_op->connected ( conn );
770
 				conn->tcp_op->connected ( conn );
771
+				tcp_senddata ( conn );
732
 			} else {
772
 			} else {
733
 				tcp_trans ( conn, TCP_SYN_RCVD );
773
 				tcp_trans ( conn, TCP_SYN_RCVD );
734
 				out_flags |= TCP_SYN;
774
 				out_flags |= TCP_SYN;
752
 			 */
792
 			 */
753
 			conn->snd_una = tcphdr->ack - 1;
793
 			conn->snd_una = tcphdr->ack - 1;
754
 			conn->tcp_op->connected ( conn );
794
 			conn->tcp_op->connected ( conn );
795
+			tcp_senddata ( conn );
755
 			return 0;
796
 			return 0;
756
 		}
797
 		}
757
 		/* Unexpected packet */
798
 		/* Unexpected packet */
799
 	case TCP_CLOSING:
840
 	case TCP_CLOSING:
800
 		if ( tcphdr->flags & TCP_ACK ) {
841
 		if ( tcphdr->flags & TCP_ACK ) {
801
 			tcp_trans ( conn, TCP_TIME_WAIT );
842
 			tcp_trans ( conn, TCP_TIME_WAIT );
843
+			start_timer ( &conn->timer );
802
 			return 0;
844
 			return 0;
803
 		}
845
 		}
804
 		/* Unexpected packet */
846
 		/* Unexpected packet */
831
 		/* Check if expected sequence number */
873
 		/* Check if expected sequence number */
832
 		if ( conn->rcv_nxt == ntohl ( tcphdr->seq ) ) {
874
 		if ( conn->rcv_nxt == ntohl ( tcphdr->seq ) ) {
833
 			conn->rcv_nxt += toack;
875
 			conn->rcv_nxt += toack;
834
-			conn->tcp_op->newdata ( conn, pkb->data + sizeof ( *tcphdr ), toack );
876
+			conn->tcp_op->newdata ( conn, pkb->data + sizeof ( *tcphdr ) + add, toack );
835
 		}
877
 		}
836
 
878
 
837
 		/* Acknowledge new data */
879
 		/* Acknowledge new data */
870
 	return 0;
912
 	return 0;
871
 
913
 
872
   unexpected:
914
   unexpected:
873
-	DBG ( "Unexpected packet received in %d state with flags = %hd\n",
915
+	DBG ( "Unexpected packet received in %s with flags = %#hx\n",
874
-			conn->tcp_state, tcphdr->flags & TCP_MASK_FLAGS );
916
+			tcp_states[conn->tcp_state], tcphdr->flags & TCP_MASK_FLAGS );
917
+	tcp_close ( conn );
875
 	free_pkb ( conn->tx_pkb );
918
 	free_pkb ( conn->tx_pkb );
876
 	return -EINVAL;
919
 	return -EINVAL;
877
 }
920
 }

Loading…
Cancel
Save