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