Browse Source

Added retransmissions to TCP

tags/v0.9.3
Nikhil Chandru Rao 18 years ago
parent
commit
cb42e573a0
2 changed files with 69 additions and 0 deletions
  1. 6
    0
      src/include/gpxe/tcp.h
  2. 63
    0
      src/net/tcp.c

+ 6
- 0
src/include/gpxe/tcp.h View File

13
 #include <gpxe/list.h>
13
 #include <gpxe/list.h>
14
 #include <gpxe/tcpip.h>
14
 #include <gpxe/tcpip.h>
15
 #include <gpxe/pkbuff.h>
15
 #include <gpxe/pkbuff.h>
16
+#include <gpxe/retry.h>
16
 
17
 
17
 struct tcp_connection;
18
 struct tcp_connection;
18
 
19
 
157
 	uint8_t tcp_flags;		/* TCP header flags */
158
 	uint8_t tcp_flags;		/* TCP header flags */
158
 	struct list_head list;		/* List of TCP connections */
159
 	struct list_head list;		/* List of TCP connections */
159
 	struct pk_buff *tx_pkb;		/* Transmit packet buffer */
160
 	struct pk_buff *tx_pkb;		/* Transmit packet buffer */
161
+	struct retry_timer timer;	/* Retransmission timer */
162
+	int retransmits;		/* Number of retransmits */
160
 	struct tcp_operations *tcp_op;	/* Operations table for connection */
163
 	struct tcp_operations *tcp_op;	/* Operations table for connection */
161
 };
164
 };
162
 
165
 
166
+/** Retry timer values */
167
+#define MAX_RETRANSMITS	3
168
+
163
 /**
169
 /**
164
  * Connection closed status codes
170
  * Connection closed status codes
165
  */
171
  */

+ 63
- 0
src/net/tcp.c View File

11
 #include <gpxe/ip.h>
11
 #include <gpxe/ip.h>
12
 #include <gpxe/tcp.h>
12
 #include <gpxe/tcp.h>
13
 #include <gpxe/tcpip.h>
13
 #include <gpxe/tcpip.h>
14
+#include <gpxe/retry.h>
14
 #include "uip/uip.h"
15
 #include "uip/uip.h"
15
 
16
 
16
 /** @file
17
 /** @file
369
 	conn->tcp_op = NULL;
370
 	conn->tcp_op = NULL;
370
 }
371
 }
371
 
372
 
373
+/** Retry timer
374
+ *
375
+ * @v timer	Retry timer
376
+ * @v over	Failure indicator
377
+ */
378
+void tcp_expired ( struct retry_timer *timer, int over ) {
379
+	struct tcp_connection *conn;
380
+	if ( over ) {
381
+		conn = ( struct tcp_connection * ) container_of ( timer, 
382
+						struct tcp_connection, timer );
383
+		switch ( conn->tcp_state ) {
384
+		case TCP_SYN_SENT:
385
+			if ( conn->retransmits > MAX_RETRANSMITS ) {
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 );
396
+			if ( conn->tcp_lstate == TCP_LISTEN ||
397
+			     conn->tcp_lstate == TCP_SYN_SENT ) {
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;
410
+		case TCP_TIME_WAIT:
411
+			tcp_trans ( conn, TCP_CLOSED );
412
+			return;
413
+		}
414
+		/* Retransmit the data */
415
+		tcp_senddata ( conn );
416
+		conn->retransmits++;
417
+		return;
418
+
419
+  send_tcp_nomsg:
420
+		tcp_send ( conn, TCP_NOMSG, TCP_NOMSG_LEN );
421
+		return;
422
+	}
423
+}
424
+
372
 /**
425
 /**
373
  * Connect to a remote server
426
  * Connect to a remote server
374
  *
427
  *
396
 	}
449
 	}
397
 	memcpy ( &conn->peer, peer, sizeof ( conn->peer ) );
450
 	memcpy ( &conn->peer, peer, sizeof ( conn->peer ) );
398
 
451
 
452
+	/* Initialize the TCP timer */
453
+	conn->timer.expired = tcp_expired;
454
+
399
 	/* Send a SYN packet and transition to TCP_SYN_SENT */
455
 	/* Send a SYN packet and transition to TCP_SYN_SENT */
400
 	conn->snd_una = ( ( ( uint32_t ) random() ) << 16 ) & random();
456
 	conn->snd_una = ( ( ( uint32_t ) random() ) << 16 ) & random();
401
 	tcp_trans ( conn, TCP_SYN_SENT );
457
 	tcp_trans ( conn, TCP_SYN_SENT );
577
 	/* Dump the TCP header */
633
 	/* Dump the TCP header */
578
 	tcp_dump ( tcphdr );
634
 	tcp_dump ( tcphdr );
579
 
635
 
636
+	/* Start the timer */
637
+	start_timer ( &conn->timer );
638
+
580
 	/* Transmit packet */
639
 	/* Transmit packet */
581
 	return tcpip_tx ( pkb, &tcp_protocol, peer );
640
 	return tcpip_tx ( pkb, &tcp_protocol, peer );
582
 }
641
 }
624
 	return 0;
683
 	return 0;
625
 
684
 
626
   found_conn:
685
   found_conn:
686
+	/* Stop the timer */
687
+	stop_timer ( &conn->timer );
688
+	conn->retransmits = 0;
689
+
627
 	/* Set the advertised window */
690
 	/* Set the advertised window */
628
 	conn->snd_win = tcphdr->win;
691
 	conn->snd_win = tcphdr->win;
629
 
692
 

Loading…
Cancel
Save