You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tcp.c 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  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. /** @file
  13. *
  14. * TCP protocol
  15. *
  16. */
  17. static void tcp_expired ( struct retry_timer *timer, int over );
  18. /**
  19. * A TCP connection
  20. *
  21. * This data structure represents the internal state of a TCP
  22. * connection. It is kept separate from @c struct @c tcp_application
  23. * because the internal state is still required for some time after
  24. * the application closes the connection.
  25. */
  26. struct tcp_connection {
  27. /** List of TCP connections */
  28. struct list_head list;
  29. /** The associated TCP application, if any */
  30. struct tcp_application *app;
  31. /** Remote socket address */
  32. struct sockaddr_tcpip peer;
  33. /** Local port, in network byte order */
  34. uint16_t local_port;
  35. /** Current TCP state */
  36. unsigned int tcp_state;
  37. /** Previous TCP state
  38. *
  39. * Maintained only for debug messages
  40. */
  41. unsigned int prev_tcp_state;
  42. /** Current sequence number
  43. *
  44. * Equivalent to SND.UNA in RFC 793 terminology.
  45. */
  46. uint32_t snd_seq;
  47. /** Unacknowledged sequence count
  48. *
  49. * Equivalent to (SND.NXT-SND.UNA) in RFC 793 terminology.
  50. */
  51. uint32_t snd_sent;
  52. /** Send window
  53. *
  54. * Equivalent to SND.WND in RFC 793 terminology
  55. */
  56. uint32_t snd_win;
  57. /** Current acknowledgement number
  58. *
  59. * Equivalent to RCV.NXT in RFC 793 terminology.
  60. */
  61. uint32_t rcv_ack;
  62. /** Transmit packet buffer
  63. *
  64. * This buffer is allocated prior to calling the application's
  65. * senddata() method, to provide temporary storage space.
  66. */
  67. struct pk_buff *tx_pkb;
  68. /** Retransmission timer */
  69. struct retry_timer timer;
  70. };
  71. /**
  72. * List of registered TCP connections
  73. */
  74. static LIST_HEAD ( tcp_conns );
  75. /**
  76. * Name TCP state
  77. *
  78. * @v state TCP state
  79. * @ret name Name of TCP state
  80. */
  81. static inline __attribute__ (( always_inline )) const char *
  82. tcp_state ( int state ) {
  83. switch ( state ) {
  84. case TCP_CLOSED: return "CLOSED";
  85. case TCP_LISTEN: return "LISTEN";
  86. case TCP_SYN_SENT: return "SYN_SENT";
  87. case TCP_SYN_RCVD: return "SYN_RCVD";
  88. case TCP_ESTABLISHED: return "ESTABLISHED";
  89. case TCP_FIN_WAIT_1: return "FIN_WAIT_1";
  90. case TCP_FIN_WAIT_2: return "FIN_WAIT_2";
  91. case TCP_CLOSING_OR_LAST_ACK: return "CLOSING/LAST_ACK";
  92. case TCP_TIME_WAIT: return "TIME_WAIT";
  93. case TCP_CLOSE_WAIT: return "CLOSE_WAIT";
  94. default: return "INVALID";
  95. }
  96. }
  97. /**
  98. * Dump TCP state transition
  99. *
  100. * @v conn TCP connection
  101. */
  102. static inline __attribute__ (( always_inline )) void
  103. tcp_dump_state ( struct tcp_connection *conn ) {
  104. if ( conn->tcp_state != conn->prev_tcp_state ) {
  105. DBG ( "TCP %p transitioned from %s to %s\n", conn,
  106. tcp_state ( conn->prev_tcp_state ),
  107. tcp_state ( conn->tcp_state ) );
  108. }
  109. conn->prev_tcp_state = conn->tcp_state;
  110. }
  111. /**
  112. * Dump TCP flags
  113. *
  114. * @v flags TCP flags
  115. */
  116. static inline __attribute__ (( always_inline )) void
  117. tcp_dump_flags ( unsigned int flags ) {
  118. if ( flags & TCP_RST )
  119. DBG ( " RST" );
  120. if ( flags & TCP_SYN )
  121. DBG ( " SYN" );
  122. if ( flags & TCP_PSH )
  123. DBG ( " PSH" );
  124. if ( flags & TCP_FIN )
  125. DBG ( " FIN" );
  126. if ( flags & TCP_ACK )
  127. DBG ( " ACK" );
  128. }
  129. /**
  130. * Allocate TCP connection
  131. *
  132. * @ret conn TCP connection, or NULL
  133. *
  134. * Allocates TCP connection and adds it to the TCP connection list.
  135. */
  136. static struct tcp_connection * alloc_tcp ( void ) {
  137. struct tcp_connection *conn;
  138. conn = calloc ( 1, sizeof ( *conn ) );
  139. if ( conn ) {
  140. DBG ( "TCP %p allocated\n", conn );
  141. conn->tcp_state = conn->prev_tcp_state = TCP_CLOSED;
  142. conn->snd_seq = random();
  143. conn->timer.expired = tcp_expired;
  144. list_add ( &conn->list, &tcp_conns );
  145. }
  146. return conn;
  147. }
  148. /**
  149. * Free TCP connection
  150. *
  151. * @v conn TCP connection
  152. *
  153. * Removes connection from TCP connection list and frees the data
  154. * structure.
  155. */
  156. static void free_tcp ( struct tcp_connection *conn ) {
  157. assert ( conn );
  158. assert ( conn->tcp_state == TCP_CLOSED );
  159. assert ( conn->app == NULL );
  160. stop_timer ( &conn->timer );
  161. list_del ( &conn->list );
  162. free ( conn );
  163. DBG ( "TCP %p freed\n", conn );
  164. }
  165. /**
  166. * Associate TCP connection with application
  167. *
  168. * @v conn TCP connection
  169. * @v app TCP application
  170. */
  171. static void tcp_associate ( struct tcp_connection *conn,
  172. struct tcp_application *app ) {
  173. assert ( conn->app == NULL );
  174. assert ( app->conn == NULL );
  175. conn->app = app;
  176. app->conn = conn;
  177. DBG ( "TCP %p associated with application %p\n", conn, app );
  178. }
  179. /**
  180. * Disassociate TCP connection from application
  181. *
  182. * @v conn TCP connection
  183. */
  184. static void tcp_disassociate ( struct tcp_connection *conn ) {
  185. struct tcp_application *app = conn->app;
  186. if ( app ) {
  187. assert ( app->conn == conn );
  188. conn->app = NULL;
  189. app->conn = NULL;
  190. DBG ( "TCP %p disassociated from application %p\n",
  191. conn, app );
  192. }
  193. }
  194. /**
  195. * Transmit any outstanding data
  196. *
  197. * @v conn TCP connection
  198. * @v force_send Force sending of packet
  199. *
  200. * Transmits any outstanding data on the connection. If the
  201. * connection is in a connected state, the application's senddata()
  202. * method will be called to generate the data payload, if any.
  203. *
  204. * Note that even if an error is returned, the retransmission timer
  205. * will have been started if necessary, and so the stack will
  206. * eventually attempt to retransmit the failed packet.
  207. */
  208. static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send ) {
  209. struct tcp_application *app = conn->app;
  210. struct pk_buff *pkb;
  211. struct tcp_header *tcphdr;
  212. unsigned int flags;
  213. size_t len;
  214. size_t seq_len;
  215. /* Allocate space to the TX buffer */
  216. pkb = alloc_pkb ( MAX_PKB_LEN );
  217. if ( ! pkb ) {
  218. DBG ( "TCP %p could not allocate senddata buffer\n", conn );
  219. /* Start the retry timer so that we attempt to
  220. * retransmit this packet later. (Start it
  221. * unconditionally, since without a packet buffer we
  222. * can't can the senddata() callback, and so may not
  223. * be able to tell whether or not we have something
  224. * that actually needs to be retransmitted).
  225. */
  226. start_timer ( &conn->timer );
  227. return -ENOMEM;
  228. }
  229. pkb_reserve ( pkb, MAX_HDR_LEN );
  230. /* If we are connected, call the senddata() method, which may
  231. * call tcp_send() to queue up a data payload.
  232. */
  233. if ( TCP_CAN_SEND_DATA ( conn->tcp_state ) &&
  234. app && app->tcp_op->senddata ) {
  235. conn->tx_pkb = pkb;
  236. app->tcp_op->senddata ( app, pkb->data, pkb_available ( pkb ));
  237. conn->tx_pkb = NULL;
  238. }
  239. /* Calculate amount of sequence space that this transmission
  240. * consumes. (SYN or FIN consume one byte, and we can never
  241. * send both at once).
  242. */
  243. len = pkb_len ( pkb );
  244. seq_len = len;
  245. flags = TCP_FLAGS_SENDING ( conn->tcp_state );
  246. assert ( ! ( ( flags & TCP_SYN ) && ( flags & TCP_FIN ) ) );
  247. if ( flags & ( TCP_SYN | TCP_FIN ) )
  248. seq_len++;
  249. conn->snd_sent = seq_len;
  250. /* If we have nothing to transmit, drop the packet */
  251. if ( ( seq_len == 0 ) && ! force_send ) {
  252. free_pkb ( pkb );
  253. return 0;
  254. }
  255. /* If we are transmitting anything that requires
  256. * acknowledgement (i.e. consumes sequence space), start the
  257. * retransmission timer.
  258. */
  259. if ( seq_len )
  260. start_timer ( &conn->timer );
  261. /* Fill up the TCP header */
  262. tcphdr = pkb_push ( pkb, sizeof ( *tcphdr ) );
  263. memset ( tcphdr, 0, sizeof ( *tcphdr ) );
  264. tcphdr->src = conn->local_port;
  265. tcphdr->dest = conn->peer.st_port;
  266. tcphdr->seq = htonl ( conn->snd_seq );
  267. tcphdr->ack = htonl ( conn->rcv_ack );
  268. tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 );
  269. tcphdr->flags = flags;
  270. tcphdr->win = htons ( TCP_WINDOW_SIZE );
  271. tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
  272. /* Dump header */
  273. DBG ( "TCP %p TX %d->%d %08lx..%08lx %08lx %4zd", conn,
  274. ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ),
  275. ntohl ( tcphdr->seq ), ( ntohl ( tcphdr->seq ) + seq_len ),
  276. ntohl ( tcphdr->ack ), len );
  277. tcp_dump_flags ( tcphdr->flags );
  278. DBG ( "\n" );
  279. /* Transmit packet */
  280. return tcpip_tx ( pkb, &tcp_protocol, &conn->peer );
  281. }
  282. /**
  283. * Transmit any outstanding data
  284. *
  285. * @v conn TCP connection
  286. *
  287. * This function allocates space to the transmit buffer and invokes
  288. * the senddata() callback function, to allow the application to
  289. * transmit new data.
  290. */
  291. int tcp_senddata ( struct tcp_application *app ) {
  292. struct tcp_connection *conn = app->conn;
  293. /* Check connection actually exists */
  294. if ( ! conn ) {
  295. DBG ( "TCP app %p has no connection\n", app );
  296. return -ENOTCONN;
  297. }
  298. return tcp_senddata_conn ( conn, 0 );
  299. }
  300. /**
  301. * Transmit data
  302. *
  303. * @v app TCP application
  304. * @v data Data to be sent
  305. * @v len Length of the data
  306. * @ret rc Return status code
  307. *
  308. * This function queues data to be sent via the TCP connection. It
  309. * can be called only in the context of an application's senddata()
  310. * method.
  311. */
  312. int tcp_send ( struct tcp_application *app, const void *data, size_t len ) {
  313. struct tcp_connection *conn = app->conn;
  314. struct pk_buff *pkb;
  315. /* Check connection actually exists */
  316. if ( ! conn ) {
  317. DBG ( "TCP app %p has no connection\n", app );
  318. return -ENOTCONN;
  319. }
  320. /* Check that we have a packet buffer to fill */
  321. pkb = conn->tx_pkb;
  322. if ( ! pkb ) {
  323. DBG ( "TCP app %p tried to send data outside of the "
  324. "senddata() method\n", app );
  325. return -EINVAL;
  326. }
  327. /* Truncate length to fit transmit window */
  328. if ( len > conn->snd_win )
  329. len = conn->snd_win;
  330. /* Truncate length to fit packet buffer */
  331. if ( len > pkb_available ( pkb ) )
  332. len = pkb_available ( pkb );
  333. /* Copy payload */
  334. memmove ( pkb_put ( pkb, len ), data, len );
  335. return 0;
  336. }
  337. /**
  338. * Retransmission timer expired
  339. *
  340. * @v timer Retry timer
  341. * @v over Failure indicator
  342. */
  343. static void tcp_expired ( struct retry_timer *timer, int over ) {
  344. struct tcp_connection *conn =
  345. container_of ( timer, struct tcp_connection, timer );
  346. struct tcp_application *app = conn->app;
  347. int graceful_close = TCP_CLOSED_GRACEFULLY ( conn->tcp_state );
  348. DBG ( "TCP %p timer %s in %s\n", conn,
  349. ( over ? "expired" : "fired" ), tcp_state ( conn->tcp_state ) );
  350. assert ( ( conn->tcp_state == TCP_SYN_SENT ) ||
  351. ( conn->tcp_state == TCP_SYN_RCVD ) ||
  352. ( conn->tcp_state == TCP_ESTABLISHED ) ||
  353. ( conn->tcp_state == TCP_FIN_WAIT_1 ) ||
  354. ( conn->tcp_state == TCP_TIME_WAIT ) ||
  355. ( conn->tcp_state == TCP_CLOSE_WAIT ) ||
  356. ( conn->tcp_state == TCP_CLOSING_OR_LAST_ACK ) );
  357. /* If we have finally timed out and given up, or if this is
  358. * the result of a graceful close, terminate the connection
  359. */
  360. if ( over || graceful_close ) {
  361. /* Transition to CLOSED */
  362. conn->tcp_state = TCP_CLOSED;
  363. tcp_dump_state ( conn );
  364. /* If we haven't closed gracefully, send a RST */
  365. if ( ! graceful_close )
  366. tcp_senddata_conn ( conn, 1 );
  367. /* Break association between application and connection */
  368. tcp_disassociate ( conn );
  369. /* Free the connection */
  370. free_tcp ( conn );
  371. /* Notify application */
  372. if ( app && app->tcp_op->closed )
  373. app->tcp_op->closed ( app, -ETIMEDOUT );
  374. } else {
  375. /* Otherwise, retransmit the packet */
  376. tcp_senddata_conn ( conn, 0 );
  377. }
  378. }
  379. /**
  380. * Identify TCP connection by local port number
  381. *
  382. * @v local_port Local port (in network-endian order)
  383. * @ret conn TCP connection, or NULL
  384. */
  385. static struct tcp_connection * tcp_demux ( uint16_t local_port ) {
  386. struct tcp_connection *conn;
  387. list_for_each_entry ( conn, &tcp_conns, list ) {
  388. if ( conn->local_port == local_port )
  389. return conn;
  390. }
  391. return NULL;
  392. }
  393. /**
  394. * Handle TCP received SYN
  395. *
  396. * @v conn TCP connection
  397. * @v seq SEQ value (in host-endian order)
  398. * @ret rc Return status code
  399. */
  400. static int tcp_rx_syn ( struct tcp_connection *conn, uint32_t seq ) {
  401. /* Synchronise sequence numbers on first SYN */
  402. if ( ! ( conn->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) )
  403. conn->rcv_ack = seq;
  404. /* Ignore duplicate SYN */
  405. if ( ( conn->rcv_ack - seq ) > 0 )
  406. return 0;
  407. /* Mark SYN as received and start sending ACKs with each packet */
  408. conn->tcp_state |= ( TCP_STATE_SENT ( TCP_ACK ) |
  409. TCP_STATE_RCVD ( TCP_SYN ) );
  410. /* Acknowledge SYN */
  411. conn->rcv_ack++;
  412. return 0;
  413. }
  414. /**
  415. * Handle TCP received ACK
  416. *
  417. * @v conn TCP connection
  418. * @v ack ACK value (in host-endian order)
  419. * @v win WIN value (in host-endian order)
  420. * @ret rc Return status code
  421. */
  422. static int tcp_rx_ack ( struct tcp_connection *conn, uint32_t ack,
  423. uint32_t win ) {
  424. struct tcp_application *app = conn->app;
  425. size_t ack_len = ( ack - conn->snd_seq );
  426. size_t len;
  427. unsigned int acked_flags = 0;
  428. /* Ignore duplicate or out-of-range ACK */
  429. if ( ack_len > conn->snd_sent ) {
  430. DBG ( "TCP %p received ACK for [%08lx,%08lx), sent only "
  431. "[%08lx,%08lx)\n", conn, conn->snd_seq,
  432. ( conn->snd_seq + ack_len ), conn->snd_seq,
  433. ( conn->snd_seq + conn->snd_sent ) );
  434. return -EINVAL;
  435. }
  436. /* If we are sending flags and this ACK acknowledges all
  437. * outstanding sequence points, then it acknowledges the
  438. * flags. (This works since both SYN and FIN will always be
  439. * the last outstanding sequence point.)
  440. */
  441. len = ack_len;
  442. if ( ack_len == conn->snd_sent ) {
  443. acked_flags = ( TCP_FLAGS_SENDING ( conn->tcp_state ) &
  444. ( TCP_SYN | TCP_FIN ) );
  445. if ( acked_flags )
  446. len--;
  447. }
  448. /* Update SEQ and sent counters, and window size */
  449. conn->snd_seq = ack;
  450. conn->snd_sent = 0;
  451. conn->snd_win = win;
  452. /* Stop the retransmission timer */
  453. stop_timer ( &conn->timer );
  454. /* Notify application of acknowledged data, if any */
  455. if ( len && app && app->tcp_op->acked )
  456. app->tcp_op->acked ( app, len );
  457. /* Mark SYN/FIN as acknowledged if applicable. */
  458. if ( acked_flags )
  459. conn->tcp_state |= TCP_STATE_ACKED ( acked_flags );
  460. /* Notify application of established connection, if applicable */
  461. if ( ( acked_flags & TCP_SYN ) && app && app->tcp_op->connected )
  462. app->tcp_op->connected ( app );
  463. return 0;
  464. }
  465. /**
  466. * Handle TCP received data
  467. *
  468. * @v conn TCP connection
  469. * @v seq SEQ value (in host-endian order)
  470. * @v data Data buffer
  471. * @v len Length of data buffer
  472. * @ret rc Return status code
  473. */
  474. static int tcp_rx_data ( struct tcp_connection *conn, uint32_t seq,
  475. void *data, size_t len ) {
  476. struct tcp_application *app = conn->app;
  477. size_t already_rcvd;
  478. /* Ignore duplicate data */
  479. already_rcvd = ( conn->rcv_ack - seq );
  480. if ( already_rcvd >= len )
  481. return 0;
  482. data += already_rcvd;
  483. len -= already_rcvd;
  484. /* Acknowledge new data */
  485. conn->rcv_ack += len;
  486. /* Notify application */
  487. if ( app && app->tcp_op->newdata )
  488. app->tcp_op->newdata ( app, data, len );
  489. return 0;
  490. }
  491. /** Handle TCP received FIN
  492. *
  493. * @v conn TCP connection
  494. * @v seq SEQ value (in host-endian order)
  495. * @ret rc Return status code
  496. */
  497. static int tcp_rx_fin ( struct tcp_connection *conn, uint32_t seq ) {
  498. struct tcp_application *app = conn->app;
  499. /* Ignore duplicate FIN */
  500. if ( ( conn->rcv_ack - seq ) > 0 )
  501. return 0;
  502. /* Mark FIN as received, acknowledge it, and send our own FIN */
  503. conn->tcp_state |= ( TCP_STATE_RCVD ( TCP_FIN ) |
  504. TCP_STATE_SENT ( TCP_FIN ) );
  505. conn->rcv_ack++;
  506. /* Break association with application */
  507. tcp_disassociate ( conn );
  508. /* Notify application */
  509. if ( app && app->tcp_op->closed )
  510. app->tcp_op->closed ( app, 0 );
  511. return 0;
  512. }
  513. /**
  514. * Process received packet
  515. *
  516. * @v pkb Packet buffer
  517. * @v partial Partial checksum
  518. */
  519. static int tcp_rx ( struct pk_buff *pkb,
  520. struct sockaddr_tcpip *st_src __unused,
  521. struct sockaddr_tcpip *st_dest __unused ) {
  522. struct tcp_header *tcphdr;
  523. struct tcp_connection *conn;
  524. unsigned int hlen;
  525. uint32_t start_seq;
  526. uint32_t seq;
  527. uint32_t ack;
  528. uint32_t win;
  529. unsigned int flags;
  530. void *data;
  531. size_t len;
  532. int rc = 0;
  533. /* Sanity check packet and strip TCP header */
  534. if ( pkb_len ( pkb ) < sizeof ( *tcphdr ) ) {
  535. DBG ( "TCP packet too short at %d bytes (min %d bytes)\n",
  536. pkb_len ( pkb ), sizeof ( *tcphdr ) );
  537. rc = -EINVAL;
  538. goto err;
  539. }
  540. tcphdr = pkb->data;
  541. hlen = ( ( tcphdr->hlen & TCP_MASK_HLEN ) / 16 ) * 4;
  542. if ( hlen < sizeof ( *tcphdr ) ) {
  543. DBG ( "TCP header too short at %d bytes (min %d bytes)\n",
  544. hlen, sizeof ( *tcphdr ) );
  545. rc = -EINVAL;
  546. goto err;
  547. }
  548. if ( hlen > pkb_len ( pkb ) ) {
  549. DBG ( "TCP header too long at %d bytes (max %d bytes)\n",
  550. hlen, pkb_len ( pkb ) );
  551. rc = -EINVAL;
  552. goto err;
  553. }
  554. /* TODO: Verify checksum */
  555. #warning "Verify checksum"
  556. /* Parse parameters from header and strip header */
  557. conn = tcp_demux ( tcphdr->dest );
  558. start_seq = seq = ntohl ( tcphdr->seq );
  559. ack = ntohl ( tcphdr->ack );
  560. win = ntohs ( tcphdr->win );
  561. flags = tcphdr->flags;
  562. data = pkb_pull ( pkb, hlen );
  563. len = pkb_len ( pkb );
  564. /* Dump header */
  565. DBG ( "TCP %p RX %d<-%d %08lx %08lx..%08lx %4zd", conn,
  566. ntohs ( tcphdr->dest ), ntohs ( tcphdr->src ),
  567. ntohl ( tcphdr->ack ), ntohl ( tcphdr->seq ),
  568. ( ntohl ( tcphdr->seq ) + len +
  569. ( ( tcphdr->flags & ( TCP_SYN | TCP_FIN ) ) ? 1 : 0 ) ), len );
  570. tcp_dump_flags ( tcphdr->flags );
  571. DBG ( "\n" );
  572. /* If no connection was found, create dummy connection for
  573. * sending RST
  574. */
  575. #warning "Handle non-matched connections"
  576. if ( ! conn )
  577. goto err;
  578. /* Handle RST, if present */
  579. #warning "Handle RST"
  580. if ( flags & TCP_RST )
  581. goto err;
  582. /* Handle ACK, if present */
  583. if ( flags & TCP_ACK )
  584. tcp_rx_ack ( conn, ack, win );
  585. /* Handle SYN, if present */
  586. if ( flags & TCP_SYN ) {
  587. tcp_rx_syn ( conn, seq );
  588. seq++;
  589. }
  590. /* Handle new data, if any */
  591. tcp_rx_data ( conn, seq, data, len );
  592. seq += len;
  593. /* Handle FIN, if present */
  594. if ( flags & TCP_FIN ) {
  595. tcp_rx_fin ( conn, seq );
  596. seq++;
  597. }
  598. /* Dump out any state change as a result of SYN, FIN or ACK */
  599. tcp_dump_state ( conn );
  600. /* Send out any pending data. If peer is expecting an ACK for
  601. * this packet then force sending a reply.
  602. */
  603. tcp_senddata_conn ( conn, ( start_seq != seq ) );
  604. /* If this packet was the last we expect to receive, set up
  605. * timer to expire and cause the connection to be freed.
  606. */
  607. if ( TCP_CLOSED_GRACEFULLY ( conn->tcp_state ) ) {
  608. conn->timer.timeout = ( 2 * TCP_MSL );
  609. start_timer ( &conn->timer );
  610. }
  611. err:
  612. /* Free received packet */
  613. free_pkb ( pkb );
  614. return rc;
  615. }
  616. /**
  617. * Bind TCP connection to local port
  618. *
  619. * @v conn TCP connection
  620. * @v local_port Local port (in network byte order), or 0
  621. * @ret rc Return status code
  622. *
  623. * This function adds the connection to the list of registered TCP
  624. * connections. If the local port is 0, the connection is assigned an
  625. * available port between 1024 and 65535.
  626. */
  627. static int tcp_bind ( struct tcp_connection *conn, uint16_t local_port ) {
  628. struct tcp_connection *existing;
  629. static uint16_t try_port = 1024;
  630. #warning "Fix the port re-use bug"
  631. try_port = random();
  632. /* If no port specified, find the first available port */
  633. if ( ! local_port ) {
  634. for ( ; try_port ; try_port++ ) {
  635. if ( try_port < 1024 )
  636. continue;
  637. if ( tcp_bind ( conn, htons ( try_port ) ) == 0 )
  638. return 0;
  639. }
  640. DBG ( "TCP %p could not bind: no free ports remaining\n",
  641. conn );
  642. return -EADDRINUSE;
  643. }
  644. /* Attempt bind to local port */
  645. list_for_each_entry ( existing, &tcp_conns, list ) {
  646. if ( existing->local_port == local_port ) {
  647. DBG ( "TCP %p could not bind: port %d in use\n",
  648. conn, ntohs ( local_port ) );
  649. return -EADDRINUSE;
  650. }
  651. }
  652. conn->local_port = local_port;
  653. DBG ( "TCP %p bound to port %d\n", conn, ntohs ( local_port ) );
  654. return 0;
  655. }
  656. /**
  657. * Connect to a remote server
  658. *
  659. * @v app TCP application
  660. * @v peer Remote socket address
  661. * @v local_port Local port number (in network byte order), or 0
  662. * @ret rc Return status code
  663. *
  664. * This function initiates a TCP connection to the socket address specified in
  665. * peer. It sends a SYN packet to peer. When the connection is established, the
  666. * TCP stack calls the connected() callback function.
  667. */
  668. int tcp_connect ( struct tcp_application *app, struct sockaddr_tcpip *peer,
  669. uint16_t local_port ) {
  670. struct tcp_connection *conn;
  671. int rc;
  672. /* Application must not already have an open connection */
  673. if ( app->conn ) {
  674. DBG ( "TCP app %p already open on %p\n", app, app->conn );
  675. return -EISCONN;
  676. }
  677. /* Allocate connection state storage and add to connection list */
  678. conn = alloc_tcp();
  679. if ( ! conn ) {
  680. DBG ( "TCP app %p could not allocate connection\n", app );
  681. return -ENOMEM;
  682. }
  683. /* Bind to peer and to local port */
  684. memcpy ( &conn->peer, peer, sizeof ( conn->peer ) );
  685. if ( ( rc = tcp_bind ( conn, local_port ) ) != 0 ) {
  686. free_tcp ( conn );
  687. return rc;
  688. }
  689. /* Associate with application */
  690. tcp_associate ( conn, app );
  691. /* Transition to TCP_SYN_SENT and send the SYN */
  692. conn->tcp_state = TCP_SYN_SENT;
  693. tcp_dump_state ( conn );
  694. tcp_senddata_conn ( conn, 0 );
  695. return 0;
  696. }
  697. /**
  698. * Close the connection
  699. *
  700. * @v app TCP application
  701. *
  702. * The association between the application and the TCP connection is
  703. * immediately severed, and the TCP application data structure can be
  704. * reused or freed immediately. The TCP connection will persist until
  705. * the state machine has returned to the TCP_CLOSED state.
  706. */
  707. void tcp_close ( struct tcp_application *app ) {
  708. struct tcp_connection *conn = app->conn;
  709. /* If no connection exists, do nothing */
  710. if ( ! conn )
  711. return;
  712. /* Break association between application and connection */
  713. tcp_disassociate ( conn );
  714. /* If we have not yet received a SYN (i.e. we are in CLOSED,
  715. * LISTEN or SYN_SENT), just delete the connection
  716. */
  717. if ( ! ( conn->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) ) {
  718. conn->tcp_state = TCP_CLOSED;
  719. tcp_dump_state ( conn );
  720. free_tcp ( conn );
  721. return;
  722. }
  723. /* If we have not had our SYN acknowledged (i.e. we are in
  724. * SYN_RCVD), pretend that it has been acknowledged so that we
  725. * can send a FIN without breaking things.
  726. */
  727. if ( ! ( conn->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) )
  728. tcp_rx_ack ( conn, ( conn->snd_seq + 1 ), 0 );
  729. /* Send a FIN to initiate the close */
  730. conn->tcp_state |= TCP_STATE_SENT ( TCP_FIN );
  731. tcp_dump_state ( conn );
  732. tcp_senddata_conn ( conn, 0 );
  733. }
  734. /** TCP protocol */
  735. struct tcpip_protocol tcp_protocol __tcpip_protocol = {
  736. .name = "TCP",
  737. .rx = tcp_rx,
  738. .tcpip_proto = IP_TCP,
  739. .csum_offset = 16,
  740. };