Use total free memory as advertised window. This seems to be sufficient
[people/xl0/gpxe.git] / src / net / tcp.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <errno.h>
5 #include <byteswap.h>
6 #include <timer.h>
7 #include <vsprintf.h>
8 #include <gpxe/pkbuff.h>
9 #include <gpxe/malloc.h>
10 #include <gpxe/retry.h>
11 #include <gpxe/tcpip.h>
12 #include <gpxe/tcp.h>
13
14 /** @file
15  *
16  * TCP protocol
17  *
18  */
19
20 static void tcp_expired ( struct retry_timer *timer, int over );
21 static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send );
22
23 /**
24  * A TCP connection
25  *
26  * This data structure represents the internal state of a TCP
27  * connection.  It is kept separate from @c struct @c tcp_application
28  * because the internal state is still required for some time after
29  * the application closes the connection.
30  */
31 struct tcp_connection {
32         /** List of TCP connections */
33         struct list_head list;
34         /** The associated TCP application, if any */
35         struct tcp_application *app;
36
37         /** Remote socket address */
38         struct sockaddr_tcpip peer;
39         /** Local port, in network byte order */
40         uint16_t local_port;
41
42         /** Current TCP state */
43         unsigned int tcp_state;
44         /** Previous TCP state
45          *
46          * Maintained only for debug messages
47          */
48         unsigned int prev_tcp_state;
49         /** Current sequence number
50          *
51          * Equivalent to SND.UNA in RFC 793 terminology.
52          */
53         uint32_t snd_seq;
54         /** Unacknowledged sequence count
55          *
56          * Equivalent to (SND.NXT-SND.UNA) in RFC 793 terminology.
57          */
58         uint32_t snd_sent;
59         /** Send window
60          *
61          * Equivalent to SND.WND in RFC 793 terminology
62          */
63         uint32_t snd_win;
64         /** Current acknowledgement number
65          *
66          * Equivalent to RCV.NXT in RFC 793 terminology.
67          */
68         uint32_t rcv_ack;
69
70         /** Transmit packet buffer
71          *
72          * This buffer is allocated prior to calling the application's
73          * senddata() method, to provide temporary storage space.
74          */
75         struct pk_buff *tx_pkb;
76         /** Retransmission timer */
77         struct retry_timer timer;
78 };
79
80 /**
81  * List of registered TCP connections
82  */
83 static LIST_HEAD ( tcp_conns );
84
85 /**
86  * Name TCP state
87  *
88  * @v state             TCP state
89  * @ret name            Name of TCP state
90  */
91 static inline __attribute__ (( always_inline )) const char *
92 tcp_state ( int state ) {
93         switch ( state ) {
94         case TCP_CLOSED:                return "CLOSED";
95         case TCP_LISTEN:                return "LISTEN";
96         case TCP_SYN_SENT:              return "SYN_SENT";
97         case TCP_SYN_RCVD:              return "SYN_RCVD";
98         case TCP_ESTABLISHED:           return "ESTABLISHED";
99         case TCP_FIN_WAIT_1:            return "FIN_WAIT_1";
100         case TCP_FIN_WAIT_2:            return "FIN_WAIT_2";
101         case TCP_CLOSING_OR_LAST_ACK:   return "CLOSING/LAST_ACK";
102         case TCP_TIME_WAIT:             return "TIME_WAIT";
103         case TCP_CLOSE_WAIT:            return "CLOSE_WAIT";
104         default:                        return "INVALID";
105         }
106 }
107
108 /**
109  * Dump TCP state transition
110  *
111  * @v conn              TCP connection
112  */
113 static inline __attribute__ (( always_inline )) void
114 tcp_dump_state ( struct tcp_connection *conn ) {
115
116         if ( conn->tcp_state != conn->prev_tcp_state ) {
117                 DBGC ( conn, "TCP %p transitioned from %s to %s\n", conn,
118                        tcp_state ( conn->prev_tcp_state ),
119                        tcp_state ( conn->tcp_state ) );
120         }
121         conn->prev_tcp_state = conn->tcp_state;
122 }
123
124 /**
125  * Dump TCP flags
126  *
127  * @v flags             TCP flags
128  */
129 static inline __attribute__ (( always_inline )) void
130 tcp_dump_flags ( struct tcp_connection *conn, unsigned int flags ) {
131         if ( flags & TCP_RST )
132                 DBGC ( conn, " RST" );
133         if ( flags & TCP_SYN )
134                 DBGC ( conn, " SYN" );
135         if ( flags & TCP_PSH )
136                 DBGC ( conn, " PSH" );
137         if ( flags & TCP_FIN )
138                 DBGC ( conn, " FIN" );
139         if ( flags & TCP_ACK )
140                 DBGC ( conn, " ACK" );
141 }
142
143 /**
144  * Allocate TCP connection
145  *
146  * @ret conn            TCP connection, or NULL
147  *
148  * Allocates TCP connection and adds it to the TCP connection list.
149  */
150 static struct tcp_connection * alloc_tcp ( void ) {
151         struct tcp_connection *conn;
152
153         conn = malloc ( sizeof ( *conn ) );
154         if ( conn ) {
155                 DBGC ( conn, "TCP %p allocated\n", conn );
156                 memset ( conn, 0, sizeof ( *conn ) );
157                 conn->tcp_state = conn->prev_tcp_state = TCP_CLOSED;
158                 conn->snd_seq = random();
159                 conn->timer.expired = tcp_expired;
160                 list_add ( &conn->list, &tcp_conns );
161         }
162         return conn;
163 }
164
165 /**
166  * Free TCP connection
167  *
168  * @v conn              TCP connection
169  *
170  * Removes connection from TCP connection list and frees the data
171  * structure.
172  */
173 static void free_tcp ( struct tcp_connection *conn ) {
174
175         assert ( conn );
176         assert ( conn->tcp_state == TCP_CLOSED );
177         assert ( conn->app == NULL );
178
179         stop_timer ( &conn->timer );
180         list_del ( &conn->list );
181         free ( conn );
182         DBGC ( conn, "TCP %p freed\n", conn );
183 }
184
185 /**
186  * Associate TCP connection with application
187  *
188  * @v conn              TCP connection
189  * @v app               TCP application
190  */
191 static void tcp_associate ( struct tcp_connection *conn,
192                             struct tcp_application *app ) {
193         assert ( conn->app == NULL );
194         assert ( app->conn == NULL );
195         conn->app = app;
196         app->conn = conn;
197         DBGC ( conn, "TCP %p associated with application %p\n", conn, app );
198 }
199
200 /**
201  * Disassociate TCP connection from application
202  *
203  * @v conn              TCP connection
204  */
205 static void tcp_disassociate ( struct tcp_connection *conn ) {
206         struct tcp_application *app = conn->app;
207
208         if ( app ) {
209                 assert ( app->conn == conn );
210                 conn->app = NULL;
211                 app->conn = NULL;
212                 DBGC ( conn, "TCP %p disassociated from application %p\n",
213                        conn, app );
214         }
215 }
216
217 /**
218  * Abort TCP connection
219  *
220  * @v conn              TCP connection
221  * @v send_rst          Send a RST after closing
222  * @v rc                Reason code
223  */
224 static void tcp_abort ( struct tcp_connection *conn, int send_rst, int rc ) {
225         struct tcp_application *app = conn->app;
226
227         /* Transition to CLOSED */
228         conn->tcp_state = TCP_CLOSED;
229         tcp_dump_state ( conn );
230
231         /* Send RST if requested to do so */
232         if ( send_rst )
233                 tcp_senddata_conn ( conn, 1 );
234
235         /* Break association between application and connection */
236         tcp_disassociate ( conn );
237
238         /* Free the connection */
239         free_tcp ( conn );
240
241         /* Notify application */
242         if ( app && app->tcp_op->closed )
243                 app->tcp_op->closed ( app, rc );
244 }
245
246 /**
247  * Transmit any outstanding data
248  *
249  * @v conn              TCP connection
250  * @v force_send        Force sending of packet
251  * 
252  * Transmits any outstanding data on the connection.  If the
253  * connection is in a connected state, the application's senddata()
254  * method will be called to generate the data payload, if any.
255  *
256  * Note that even if an error is returned, the retransmission timer
257  * will have been started if necessary, and so the stack will
258  * eventually attempt to retransmit the failed packet.
259  */
260 static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send ) {
261         struct tcp_application *app = conn->app;
262         struct pk_buff *pkb;
263         struct tcp_header *tcphdr;
264         struct tcp_mss_option *mssopt;
265         void *payload;
266         unsigned int flags;
267         size_t len;
268         size_t seq_len;
269         size_t window;
270         int rc;
271
272         /* Allocate space to the TX buffer */
273         pkb = alloc_pkb ( MAX_PKB_LEN );
274         if ( ! pkb ) {
275                 DBGC ( conn, "TCP %p could not allocate data buffer\n", conn );
276                 /* Start the retry timer so that we attempt to
277                  * retransmit this packet later.  (Start it
278                  * unconditionally, since without a packet buffer we
279                  * can't call the senddata() callback, and so may not
280                  * be able to tell whether or not we have something
281                  * that actually needs to be retransmitted).
282                  */
283                 start_timer ( &conn->timer );
284                 return -ENOMEM;
285         }
286         pkb_reserve ( pkb, MAX_HDR_LEN );
287
288         /* If we are connected, call the senddata() method, which may
289          * call tcp_send() to queue up a data payload.
290          */
291         if ( TCP_CAN_SEND_DATA ( conn->tcp_state ) &&
292              app && app->tcp_op->senddata ) {
293                 conn->tx_pkb = pkb;
294                 app->tcp_op->senddata ( app, pkb->data, pkb_tailroom ( pkb ) );
295                 conn->tx_pkb = NULL;
296         }
297
298         /* Truncate payload length to fit transmit window */
299         len = pkb_len ( pkb );
300         if ( len > conn->snd_win )
301                 len = conn->snd_win;
302
303         /* Calculate amount of sequence space that this transmission
304          * consumes.  (SYN or FIN consume one byte, and we can never
305          * send both at once).
306          */
307         seq_len = len;
308         flags = TCP_FLAGS_SENDING ( conn->tcp_state );
309         assert ( ! ( ( flags & TCP_SYN ) && ( flags & TCP_FIN ) ) );
310         if ( flags & ( TCP_SYN | TCP_FIN ) )
311                 seq_len++;
312         conn->snd_sent = seq_len;
313
314         /* If we have nothing to transmit, drop the packet */
315         if ( ( seq_len == 0 ) && ! force_send ) {
316                 free_pkb ( pkb );
317                 return 0;
318         }
319
320         /* If we are transmitting anything that requires
321          * acknowledgement (i.e. consumes sequence space), start the
322          * retransmission timer.
323          */
324         if ( seq_len )
325                 start_timer ( &conn->timer );
326
327         /* Estimate window size */
328         window = freemem;
329         if ( window > TCP_MAX_WINDOW_SIZE )
330                 window = TCP_MAX_WINDOW_SIZE;
331         window &= ~0x03; /* Keep everything dword-aligned */
332
333         /* Fill up the TCP header */
334         payload = pkb->data;
335         if ( flags & TCP_SYN ) {
336                 mssopt = pkb_push ( pkb, sizeof ( *mssopt ) );
337                 mssopt->kind = TCP_OPTION_MSS;
338                 mssopt->length = sizeof ( *mssopt );
339                 mssopt->mss = htons ( TCP_MSS );
340         }
341         tcphdr = pkb_push ( pkb, sizeof ( *tcphdr ) );
342         memset ( tcphdr, 0, sizeof ( *tcphdr ) );
343         tcphdr->src = conn->local_port;
344         tcphdr->dest = conn->peer.st_port;
345         tcphdr->seq = htonl ( conn->snd_seq );
346         tcphdr->ack = htonl ( conn->rcv_ack );
347         tcphdr->hlen = ( ( payload - pkb->data ) << 2 );
348         tcphdr->flags = flags;
349         tcphdr->win = htons ( window );
350         tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
351
352         /* Dump header */
353         DBGC ( conn, "TCP %p TX %d->%d %08lx..%08lx           %08lx %4zd",
354                conn, ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ),
355                ntohl ( tcphdr->seq ), ( ntohl ( tcphdr->seq ) + seq_len ),
356                ntohl ( tcphdr->ack ), len );
357         tcp_dump_flags ( conn, tcphdr->flags );
358         DBGC ( conn, "\n" );
359
360         /* Transmit packet */
361         rc = tcpip_tx ( pkb, &tcp_protocol, &conn->peer, NULL, &tcphdr->csum );
362
363         /* If we got -ENETUNREACH, kill the connection immediately
364          * because there is no point retrying.  This isn't strictly
365          * necessary (since we will eventually time out anyway), but
366          * it avoids irritating needless delays.  Don't do this for
367          * RST packets transmitted on connection abort, to avoid a
368          * potential infinite loop.
369          */
370         if ( ( ! ( conn->tcp_state & TCP_STATE_SENT ( TCP_RST ) ) ) &&
371              ( rc == -ENETUNREACH ) ) {
372                 DBGC ( conn, "TCP %p aborting after TX failed: %s\n",
373                        conn, strerror ( rc ) );
374                 tcp_abort ( conn, 0, rc );
375         }
376
377         return rc;
378 }
379
380 /**
381  * Transmit any outstanding data
382  *
383  * @v conn      TCP connection
384  * 
385  * This function allocates space to the transmit buffer and invokes
386  * the senddata() callback function, to allow the application to
387  * transmit new data.
388  */
389 int tcp_senddata ( struct tcp_application *app ) {
390         struct tcp_connection *conn = app->conn;
391
392         /* Check connection actually exists */
393         if ( ! conn ) {
394                 DBG ( "TCP app %p has no connection\n", app );
395                 return -ENOTCONN;
396         }
397
398         return tcp_senddata_conn ( conn, 0 );
399 }
400
401 /**
402  * Transmit data
403  *
404  * @v app               TCP application
405  * @v data              Data to be sent
406  * @v len               Length of the data
407  * @ret rc              Return status code
408  *
409  * This function queues data to be sent via the TCP connection.  It
410  * can be called only in the context of an application's senddata()
411  * method.
412  */
413 int tcp_send ( struct tcp_application *app, const void *data, size_t len ) {
414         struct tcp_connection *conn = app->conn;
415         struct pk_buff *pkb;
416
417         /* Check connection actually exists */
418         if ( ! conn ) {
419                 DBG ( "TCP app %p has no connection\n", app );
420                 return -ENOTCONN;
421         }
422
423         /* Check that we have a packet buffer to fill */
424         pkb = conn->tx_pkb;
425         if ( ! pkb ) {
426                 DBG ( "TCP app %p tried to send data outside of the "
427                       "senddata() method\n", app );
428                 return -EINVAL;
429         }
430
431         /* Truncate length to fit packet buffer */
432         if ( len > pkb_tailroom ( pkb ) )
433                 len = pkb_tailroom ( pkb );
434
435         /* Copy payload */
436         memmove ( pkb_put ( pkb, len ), data, len );
437
438         return 0;
439 }
440
441 /**
442  * Retransmission timer expired
443  *
444  * @v timer     Retry timer
445  * @v over      Failure indicator
446  */
447 static void tcp_expired ( struct retry_timer *timer, int over ) {
448         struct tcp_connection *conn =
449                 container_of ( timer, struct tcp_connection, timer );
450         int graceful_close = TCP_CLOSED_GRACEFULLY ( conn->tcp_state );
451
452         DBGC ( conn, "TCP %p timer %s in %s\n", conn,
453                ( over ? "expired" : "fired" ), tcp_state ( conn->tcp_state ) );
454
455         assert ( ( conn->tcp_state == TCP_SYN_SENT ) ||
456                  ( conn->tcp_state == TCP_SYN_RCVD ) ||
457                  ( conn->tcp_state == TCP_ESTABLISHED ) ||
458                  ( conn->tcp_state == TCP_FIN_WAIT_1 ) ||
459                  ( conn->tcp_state == TCP_TIME_WAIT ) ||
460                  ( conn->tcp_state == TCP_CLOSE_WAIT ) ||
461                  ( conn->tcp_state == TCP_CLOSING_OR_LAST_ACK ) );
462
463         if ( over || graceful_close ) {
464                 /* If we have finally timed out and given up, or if
465                  * this is the result of a graceful close, terminate
466                  * the connection
467                  */
468                 tcp_abort ( conn, 1, -ETIMEDOUT );
469         } else {
470                 /* Otherwise, retransmit the packet */
471                 tcp_senddata_conn ( conn, 0 );
472         }
473 }
474
475 /**
476  * Send RST response to incoming packet
477  *
478  * @v in_tcphdr         TCP header of incoming packet
479  * @ret rc              Return status code
480  */
481 static int tcp_send_reset ( struct tcp_connection *conn,
482                             struct tcp_header *in_tcphdr ) {
483         struct pk_buff *pkb;
484         struct tcp_header *tcphdr;
485
486         /* Allocate space for dataless TX buffer */
487         pkb = alloc_pkb ( MAX_HDR_LEN );
488         if ( ! pkb ) {
489                 DBGC ( conn, "TCP %p could not allocate data buffer\n", conn );
490                 return -ENOMEM;
491         }
492         pkb_reserve ( pkb, MAX_HDR_LEN );
493
494         /* Construct RST response */
495         tcphdr = pkb_push ( pkb, sizeof ( *tcphdr ) );
496         memset ( tcphdr, 0, sizeof ( *tcphdr ) );
497         tcphdr->src = in_tcphdr->dest;
498         tcphdr->dest = in_tcphdr->src;
499         tcphdr->seq = in_tcphdr->ack;
500         tcphdr->ack = in_tcphdr->seq;
501         tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 );
502         tcphdr->flags = ( TCP_RST | TCP_ACK );
503         tcphdr->win = htons ( TCP_MAX_WINDOW_SIZE );
504         tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
505
506         /* Dump header */
507         DBGC ( conn, "TCP %p TX %d->%d %08lx..%08lx           %08lx %4zd",
508                conn, ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ),
509                ntohl ( tcphdr->seq ), ( ntohl ( tcphdr->seq ) ),
510                ntohl ( tcphdr->ack ), 0 );
511         tcp_dump_flags ( conn, tcphdr->flags );
512         DBGC ( conn, "\n" );
513
514         /* Transmit packet */
515         return tcpip_tx ( pkb, &tcp_protocol, &conn->peer,
516                           NULL, &tcphdr->csum );
517 }
518
519 /**
520  * Identify TCP connection by local port number
521  *
522  * @v local_port        Local port (in network-endian order)
523  * @ret conn            TCP connection, or NULL
524  */
525 static struct tcp_connection * tcp_demux ( uint16_t local_port ) {
526         struct tcp_connection *conn;
527
528         list_for_each_entry ( conn, &tcp_conns, list ) {
529                 if ( conn->local_port == local_port )
530                         return conn;
531         }
532         return NULL;
533 }
534
535 /**
536  * Handle TCP received SYN
537  *
538  * @v conn              TCP connection
539  * @v seq               SEQ value (in host-endian order)
540  * @ret rc              Return status code
541  */
542 static int tcp_rx_syn ( struct tcp_connection *conn, uint32_t seq ) {
543         struct tcp_application *app = conn->app;
544
545         /* Synchronise sequence numbers on first SYN */
546         if ( ! ( conn->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) )
547                 conn->rcv_ack = seq;
548
549         /* Ignore duplicate SYN */
550         if ( ( conn->rcv_ack - seq ) > 0 )
551                 return 0;
552
553         /* Mark SYN as received and start sending ACKs with each packet */
554         conn->tcp_state |= ( TCP_STATE_SENT ( TCP_ACK ) |
555                              TCP_STATE_RCVD ( TCP_SYN ) );
556
557         /* Acknowledge SYN */
558         conn->rcv_ack++;
559
560         /* Notify application of established connection, if applicable */
561         if ( ( conn->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) &&
562              app && app->tcp_op->connected )
563                 app->tcp_op->connected ( app );
564
565         return 0;
566 }
567
568 /**
569  * Handle TCP received ACK
570  *
571  * @v conn              TCP connection
572  * @v ack               ACK value (in host-endian order)
573  * @v win               WIN value (in host-endian order)
574  * @ret rc              Return status code
575  */
576 static int tcp_rx_ack ( struct tcp_connection *conn, uint32_t ack,
577                         uint32_t win ) {
578         struct tcp_application *app = conn->app;
579         size_t ack_len = ( ack - conn->snd_seq );
580         size_t len;
581         unsigned int acked_flags = 0;
582
583         /* Ignore duplicate or out-of-range ACK */
584         if ( ack_len > conn->snd_sent ) {
585                 DBGC ( conn, "TCP %p received ACK for [%08lx,%08lx), "
586                        "sent only [%08lx,%08lx)\n", conn, conn->snd_seq,
587                        ( conn->snd_seq + ack_len ), conn->snd_seq,
588                        ( conn->snd_seq + conn->snd_sent ) );
589                 return -EINVAL;
590         }
591
592         /* If we are sending flags and this ACK acknowledges all
593          * outstanding sequence points, then it acknowledges the
594          * flags.  (This works since both SYN and FIN will always be
595          * the last outstanding sequence point.)
596          */
597         len = ack_len;
598         if ( ack_len == conn->snd_sent ) {
599                 acked_flags = ( TCP_FLAGS_SENDING ( conn->tcp_state ) &
600                                 ( TCP_SYN | TCP_FIN ) );
601                 if ( acked_flags )
602                         len--;
603         }
604
605         /* Update SEQ and sent counters, and window size */
606         conn->snd_seq = ack;
607         conn->snd_sent = 0;
608         conn->snd_win = win;
609
610         /* Stop the retransmission timer */
611         stop_timer ( &conn->timer );
612
613         /* Notify application of acknowledged data, if any */
614         if ( len && app && app->tcp_op->acked )
615                 app->tcp_op->acked ( app, len );
616
617         /* Mark SYN/FIN as acknowledged if applicable. */
618         if ( acked_flags )
619                 conn->tcp_state |= TCP_STATE_ACKED ( acked_flags );
620
621         /* Notify application of established connection, if applicable */
622         if ( ( acked_flags & TCP_SYN ) &&
623              ( conn->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) &&
624              app && app->tcp_op->connected )
625                 app->tcp_op->connected ( app );
626
627         return 0;
628 }
629
630 /**
631  * Handle TCP received data
632  *
633  * @v conn              TCP connection
634  * @v seq               SEQ value (in host-endian order)
635  * @v data              Data buffer
636  * @v len               Length of data buffer
637  * @ret rc              Return status code
638  */
639 static int tcp_rx_data ( struct tcp_connection *conn, uint32_t seq,
640                          void *data, size_t len ) {
641         struct tcp_application *app = conn->app;
642         size_t already_rcvd;
643
644         /* Ignore duplicate data */
645         already_rcvd = ( conn->rcv_ack - seq );
646         if ( already_rcvd >= len )
647                 return 0;
648         data += already_rcvd;
649         len -= already_rcvd;
650
651         /* Acknowledge new data */
652         conn->rcv_ack += len;
653
654         /* Notify application */
655         if ( app && app->tcp_op->newdata )
656                 app->tcp_op->newdata ( app, data, len );
657
658         return 0;
659 }
660
661 /**
662  * Handle TCP received FIN
663  *
664  * @v conn              TCP connection
665  * @v seq               SEQ value (in host-endian order)
666  * @ret rc              Return status code
667  */
668 static int tcp_rx_fin ( struct tcp_connection *conn, uint32_t seq ) {
669         struct tcp_application *app = conn->app;
670
671         /* Ignore duplicate FIN */
672         if ( ( conn->rcv_ack - seq ) > 0 )
673                 return 0;
674
675         /* Mark FIN as received, acknowledge it, and send our own FIN */
676         conn->tcp_state |= ( TCP_STATE_RCVD ( TCP_FIN ) |
677                              TCP_STATE_SENT ( TCP_FIN ) );
678         conn->rcv_ack++;
679
680         /* Break association with application */
681         tcp_disassociate ( conn );
682
683         /* Notify application */
684         if ( app && app->tcp_op->closed )
685                 app->tcp_op->closed ( app, 0 );
686
687         return 0;
688 }
689
690 /**
691  * Handle TCP received RST
692  *
693  * @v conn              TCP connection
694  * @v seq               SEQ value (in host-endian order)
695  * @ret rc              Return status code
696  */
697 static int tcp_rx_rst ( struct tcp_connection *conn, uint32_t seq ) {
698
699         /* Accept RST only if it falls within the window.  If we have
700          * not yet received a SYN, then we have no window to test
701          * against, so fall back to checking that our SYN has been
702          * ACKed.
703          */
704         if ( conn->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) {
705                 if ( ( conn->rcv_ack - seq ) > 0 )
706                         return 0;
707         } else {
708                 if ( ! ( conn->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) )
709                         return 0;
710         }
711
712         /* Abort connection without sending a RST */
713         tcp_abort ( conn, 0, -ECONNRESET );
714
715         return -ECONNRESET;
716 }
717
718 /**
719  * Process received packet
720  *
721  * @v pkb               Packet buffer
722  * @v st_src            Partially-filled source address
723  * @v st_dest           Partially-filled destination address
724  * @v pshdr_csum        Pseudo-header checksum
725  * @ret rc              Return status code
726   */
727 static int tcp_rx ( struct pk_buff *pkb,
728                     struct sockaddr_tcpip *st_src __unused,
729                     struct sockaddr_tcpip *st_dest __unused,
730                     uint16_t pshdr_csum ) {
731         struct tcp_header *tcphdr = pkb->data;
732         struct tcp_connection *conn;
733         unsigned int hlen;
734         uint16_t csum;
735         uint32_t start_seq;
736         uint32_t seq;
737         uint32_t ack;
738         uint32_t win;
739         unsigned int flags;
740         void *data;
741         size_t len;
742         int rc;
743
744         /* Sanity check packet */
745         if ( pkb_len ( pkb ) < sizeof ( *tcphdr ) ) {
746                 DBG ( "TCP packet too short at %d bytes (min %d bytes)\n",
747                       pkb_len ( pkb ), sizeof ( *tcphdr ) );
748                 rc = -EINVAL;
749                 goto done;
750         }
751         hlen = ( ( tcphdr->hlen & TCP_MASK_HLEN ) / 16 ) * 4;
752         if ( hlen < sizeof ( *tcphdr ) ) {
753                 DBG ( "TCP header too short at %d bytes (min %d bytes)\n",
754                       hlen, sizeof ( *tcphdr ) );
755                 rc = -EINVAL;
756                 goto done;
757         }
758         if ( hlen > pkb_len ( pkb ) ) {
759                 DBG ( "TCP header too long at %d bytes (max %d bytes)\n",
760                       hlen, pkb_len ( pkb ) );
761                 rc = -EINVAL;
762                 goto done;
763         }
764         csum = tcpip_continue_chksum ( pshdr_csum, pkb->data, pkb_len ( pkb ));
765         if ( csum != 0 ) {
766                 DBG ( "TCP checksum incorrect (is %04x including checksum "
767                       "field, should be 0000)\n", csum );
768                 rc = -EINVAL;
769                 goto done;
770         }
771         
772         /* Parse parameters from header and strip header */
773         conn = tcp_demux ( tcphdr->dest );
774         start_seq = seq = ntohl ( tcphdr->seq );
775         ack = ntohl ( tcphdr->ack );
776         win = ntohs ( tcphdr->win );
777         flags = tcphdr->flags;
778         data = pkb_pull ( pkb, hlen );
779         len = pkb_len ( pkb );
780
781         /* Dump header */
782         DBGC ( conn, "TCP %p RX %d<-%d           %08lx %08lx..%08lx %4zd",
783                conn, ntohs ( tcphdr->dest ), ntohs ( tcphdr->src ),
784                ntohl ( tcphdr->ack ), ntohl ( tcphdr->seq ),
785                ( ntohl ( tcphdr->seq ) + len +
786                  ( ( tcphdr->flags & ( TCP_SYN | TCP_FIN ) ) ? 1 : 0 ) ), len);
787         tcp_dump_flags ( conn, tcphdr->flags );
788         DBGC ( conn, "\n" );
789
790         /* If no connection was found, send RST */
791         if ( ! conn ) {
792                 tcp_send_reset ( conn, tcphdr );
793                 rc = -ENOTCONN;
794                 goto done;
795         }
796
797         /* Handle ACK, if present */
798         if ( flags & TCP_ACK ) {
799                 if ( ( rc = tcp_rx_ack ( conn, ack, win ) ) != 0 ) {
800                         tcp_send_reset ( conn, tcphdr );
801                         goto done;
802                 }
803         }
804
805         /* Handle SYN, if present */
806         if ( flags & TCP_SYN ) {
807                 tcp_rx_syn ( conn, seq );
808                 seq++;
809         }
810
811         /* Handle RST, if present */
812         if ( flags & TCP_RST ) {
813                 if ( ( rc = tcp_rx_rst ( conn, seq ) ) != 0 )
814                         goto done;
815         }
816
817         /* Handle new data, if any */
818         tcp_rx_data ( conn, seq, data, len );
819         seq += len;
820
821         /* Handle FIN, if present */
822         if ( flags & TCP_FIN ) {
823                 tcp_rx_fin ( conn, seq );
824                 seq++;
825         }
826
827         /* Dump out any state change as a result of the received packet */
828         tcp_dump_state ( conn );
829
830         /* Send out any pending data.  If peer is expecting an ACK for
831          * this packet then force sending a reply.
832          */
833         tcp_senddata_conn ( conn, ( start_seq != seq ) );
834
835         /* If this packet was the last we expect to receive, set up
836          * timer to expire and cause the connection to be freed.
837          */
838         if ( TCP_CLOSED_GRACEFULLY ( conn->tcp_state ) ) {
839                 conn->timer.timeout = ( 2 * TCP_MSL );
840                 start_timer ( &conn->timer );
841         }
842
843         rc = 0;
844  done:
845         /* Free received packet */
846         free_pkb ( pkb );
847         return rc;
848 }
849
850 /**
851  * Bind TCP connection to local port
852  *
853  * @v conn              TCP connection
854  * @v local_port        Local port (in network byte order), or 0
855  * @ret rc              Return status code
856  *
857  * This function adds the connection to the list of registered TCP
858  * connections.  If the local port is 0, the connection is assigned an
859  * available port between 1024 and 65535.
860  */
861 static int tcp_bind ( struct tcp_connection *conn, uint16_t local_port ) {
862         struct tcp_connection *existing;
863         static uint16_t try_port = 1024;
864
865         /* If no port specified, find the first available port */
866         if ( ! local_port ) {
867                 for ( ; try_port ; try_port++ ) {
868                         if ( try_port < 1024 )
869                                 continue;
870                         if ( tcp_bind ( conn, htons ( try_port ) ) == 0 )
871                                 return 0;
872                 }
873                 DBGC ( conn, "TCP %p could not bind: no free ports\n", conn );
874                 return -EADDRINUSE;
875         }
876
877         /* Attempt bind to local port */
878         list_for_each_entry ( existing, &tcp_conns, list ) {
879                 if ( existing->local_port == local_port ) {
880                         DBGC ( conn, "TCP %p could not bind: port %d in use\n",
881                                conn, ntohs ( local_port ) );
882                         return -EADDRINUSE;
883                 }
884         }
885         conn->local_port = local_port;
886
887         DBGC ( conn, "TCP %p bound to port %d\n", conn, ntohs ( local_port ) );
888         return 0;
889 }
890
891 /**
892  * Connect to a remote server
893  *
894  * @v app               TCP application
895  * @v peer              Remote socket address
896  * @v local_port        Local port number (in network byte order), or 0
897  * @ret rc              Return status code
898  *
899  * This function initiates a TCP connection to the socket address specified in
900  * peer. It sends a SYN packet to peer. When the connection is established, the
901  * TCP stack calls the connected() callback function.
902  */
903 int tcp_connect ( struct tcp_application *app, struct sockaddr_tcpip *peer,
904                   uint16_t local_port ) {
905         struct tcp_connection *conn;
906         int rc;
907
908         /* Application must not already have an open connection */
909         if ( app->conn ) {
910                 DBG ( "TCP app %p already open on %p\n", app, app->conn );
911                 return -EISCONN;
912         }
913
914         /* Allocate connection state storage and add to connection list */
915         conn = alloc_tcp();
916         if ( ! conn ) {
917                 DBG ( "TCP app %p could not allocate connection\n", app );
918                 return -ENOMEM;
919         }
920
921         /* Bind to peer and to local port */
922         memcpy ( &conn->peer, peer, sizeof ( conn->peer ) );
923         if ( ( rc = tcp_bind ( conn, local_port ) ) != 0 ) {
924                 free_tcp ( conn );
925                 return rc;
926         }
927
928         /* Associate with application */
929         tcp_associate ( conn, app );
930
931         /* Transition to TCP_SYN_SENT and send the SYN */
932         conn->tcp_state = TCP_SYN_SENT;
933         tcp_dump_state ( conn );
934         tcp_senddata_conn ( conn, 0 );
935
936         return 0;
937 }
938
939 /**
940  * Close the connection
941  *
942  * @v app               TCP application
943  *
944  * The association between the application and the TCP connection is
945  * immediately severed, and the TCP application data structure can be
946  * reused or freed immediately.  The TCP connection will persist until
947  * the state machine has returned to the TCP_CLOSED state.
948  */
949 void tcp_close ( struct tcp_application *app ) {
950         struct tcp_connection *conn = app->conn;
951
952         /* If no connection exists, do nothing */
953         if ( ! conn )
954                 return;
955
956         /* Break association between application and connection */
957         tcp_disassociate ( conn );
958
959         /* If we have not yet received a SYN (i.e. we are in CLOSED,
960          * LISTEN or SYN_SENT), just delete the connection
961          */
962         if ( ! ( conn->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) ) {
963                 conn->tcp_state = TCP_CLOSED;
964                 tcp_dump_state ( conn );
965                 free_tcp ( conn );
966                 return;
967         }
968
969         /* If we have not had our SYN acknowledged (i.e. we are in
970          * SYN_RCVD), pretend that it has been acknowledged so that we
971          * can send a FIN without breaking things.
972          */
973         if ( ! ( conn->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) )
974                 tcp_rx_ack ( conn, ( conn->snd_seq + 1 ), 0 );
975
976         /* Send a FIN to initiate the close */
977         conn->tcp_state |= TCP_STATE_SENT ( TCP_FIN );
978         tcp_dump_state ( conn );
979         tcp_senddata_conn ( conn, 0 );
980 }
981
982 /** TCP protocol */
983 struct tcpip_protocol tcp_protocol __tcpip_protocol = {
984         .name = "TCP",
985         .rx = tcp_rx,
986         .tcpip_proto = IP_TCP,
987 };