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