diff options
-rw-r--r-- | src/include/gnunet_stream_lib.h | 8 | ||||
-rw-r--r-- | src/stream/stream_api.c | 184 |
2 files changed, 180 insertions, 12 deletions
diff --git a/src/include/gnunet_stream_lib.h b/src/include/gnunet_stream_lib.h index 4a574dfe4..ac2ce0854 100644 --- a/src/include/gnunet_stream_lib.h +++ b/src/include/gnunet_stream_lib.h | |||
@@ -142,14 +142,14 @@ typedef void (*GNUNET_STREAM_ShutdownCompletion) (void *cls, | |||
142 | 142 | ||
143 | 143 | ||
144 | /** | 144 | /** |
145 | * Shutdown the stream for reading or writing (man 2 shutdown). | 145 | * Shutdown the stream for reading or writing (similar to man 2 shutdown). |
146 | * | 146 | * |
147 | * @param socket the stream socket | 147 | * @param socket the stream socket |
148 | * @param opertion SHUT_RD, SHUT_WR or SHUT_RDWR | 148 | * @param operation SHUT_RD, SHUT_WR or SHUT_RDWR |
149 | * @param completion_cb the callback that will be called upon successful | 149 | * @param completion_cb the callback that will be called upon successful |
150 | * shutdown of given operation | 150 | * shutdown of given operation |
151 | * @param completion_cls the closure for the completion callback | 151 | * @param completion_cls the closure for the completion callback |
152 | * @return the shutdown handle | 152 | * @return the shutdown handle; NULL in case of any error |
153 | */ | 153 | */ |
154 | struct GNUNET_STREAM_ShutdownHandle * | 154 | struct GNUNET_STREAM_ShutdownHandle * |
155 | GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket, | 155 | GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket, |
@@ -161,7 +161,7 @@ GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket, | |||
161 | /** | 161 | /** |
162 | * Cancels a pending shutdown | 162 | * Cancels a pending shutdown |
163 | * | 163 | * |
164 | * @param the shutdown handle returned from GNUNET_STREAM_shutdown | 164 | * @param handle the shutdown handle returned from GNUNET_STREAM_shutdown |
165 | */ | 165 | */ |
166 | void | 166 | void |
167 | GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle); | 167 | GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle); |
diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c index 93d9c9fe2..92c1093f7 100644 --- a/src/stream/stream_api.c +++ b/src/stream/stream_api.c | |||
@@ -27,6 +27,8 @@ | |||
27 | * memory used for PEER interning | 27 | * memory used for PEER interning |
28 | * | 28 | * |
29 | * Add code for write io timeout | 29 | * Add code for write io timeout |
30 | * | ||
31 | * Include retransmission for control messages | ||
30 | **/ | 32 | **/ |
31 | 33 | ||
32 | /** | 34 | /** |
@@ -826,6 +828,9 @@ call_read_processor (void *cls, | |||
826 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 828 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
827 | return; | 829 | return; |
828 | 830 | ||
831 | if (NULL == socket->receive_buffer) | ||
832 | return; | ||
833 | |||
829 | GNUNET_assert (NULL != socket->read_handle); | 834 | GNUNET_assert (NULL != socket->read_handle); |
830 | GNUNET_assert (NULL != socket->read_handle->proc); | 835 | GNUNET_assert (NULL != socket->read_handle->proc); |
831 | 836 | ||
@@ -1224,6 +1229,39 @@ set_state_hello_wait (void *cls, | |||
1224 | 1229 | ||
1225 | 1230 | ||
1226 | /** | 1231 | /** |
1232 | * Callback to set state to CLOSE_WAIT | ||
1233 | * | ||
1234 | * @param cls the closure from queue_message | ||
1235 | * @param socket the socket requiring state change | ||
1236 | */ | ||
1237 | static void | ||
1238 | set_state_close_wait (void *cls, | ||
1239 | struct GNUNET_STREAM_Socket *socket) | ||
1240 | { | ||
1241 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1242 | "%x: Attaing CLOSE_WAIT state\n", | ||
1243 | socket->our_id); | ||
1244 | socket->state = STATE_CLOSE_WAIT; | ||
1245 | GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */ | ||
1246 | socket->receive_buffer = NULL; | ||
1247 | socket->receive_buffer_size = 0; | ||
1248 | } | ||
1249 | |||
1250 | |||
1251 | /** | ||
1252 | * Callback to set state to CLOSED | ||
1253 | * | ||
1254 | * @param cls the closure from queue_message | ||
1255 | * @param socket the socket requiring state change | ||
1256 | */ | ||
1257 | static void | ||
1258 | set_state_closed (void *cls, | ||
1259 | struct GNUNET_STREAM_Socket *socket) | ||
1260 | { | ||
1261 | socket->state = STATE_CLOSED; | ||
1262 | } | ||
1263 | |||
1264 | /** | ||
1227 | * Returns a new HelloAckMessage. Also sets the write sequence number for the | 1265 | * Returns a new HelloAckMessage. Also sets the write sequence number for the |
1228 | * socket | 1266 | * socket |
1229 | * | 1267 | * |
@@ -1501,6 +1539,44 @@ client_handle_receive_close_ack (void *cls, | |||
1501 | 1539 | ||
1502 | 1540 | ||
1503 | /** | 1541 | /** |
1542 | * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE | ||
1543 | * | ||
1544 | * @param socket the socket | ||
1545 | * @param tunnel connection to the other end | ||
1546 | * @param tunnel_ctx this is NULL | ||
1547 | * @param sender who sent the message | ||
1548 | * @param message the actual message | ||
1549 | * @param atsi performance data for the connection | ||
1550 | * @return GNUNET_OK to keep the connection open, | ||
1551 | * GNUNET_SYSERR to close it (signal serious error) | ||
1552 | */ | ||
1553 | static int | ||
1554 | handle_close (struct GNUNET_STREAM_Socket *socket, | ||
1555 | struct GNUNET_MESH_Tunnel *tunnel, | ||
1556 | const struct GNUNET_PeerIdentity *sender, | ||
1557 | const struct GNUNET_STREAM_MessageHeader *message, | ||
1558 | const struct GNUNET_ATS_Information*atsi) | ||
1559 | { | ||
1560 | struct GNUNET_STREAM_MessageHeader *close_ack; | ||
1561 | |||
1562 | close_ack = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); | ||
1563 | close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); | ||
1564 | close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK); | ||
1565 | queue_message (socket, | ||
1566 | close_ack, | ||
1567 | &set_state_closed, | ||
1568 | NULL); | ||
1569 | if (socket->state == STATE_CLOSED) | ||
1570 | return GNUNET_OK; | ||
1571 | |||
1572 | GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */ | ||
1573 | socket->receive_buffer = NULL; | ||
1574 | socket->receive_buffer_size = 0; | ||
1575 | return GNUNET_OK; | ||
1576 | } | ||
1577 | |||
1578 | |||
1579 | /** | ||
1504 | * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE | 1580 | * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE |
1505 | * | 1581 | * |
1506 | * @param cls the socket (set from GNUNET_MESH_connect) | 1582 | * @param cls the socket (set from GNUNET_MESH_connect) |
@@ -1522,6 +1598,44 @@ client_handle_close (void *cls, | |||
1522 | { | 1598 | { |
1523 | struct GNUNET_STREAM_Socket *socket = cls; | 1599 | struct GNUNET_STREAM_Socket *socket = cls; |
1524 | 1600 | ||
1601 | return handle_close (socket, | ||
1602 | tunnel, | ||
1603 | sender, | ||
1604 | (const struct GNUNET_STREAM_MessageHeader *) message, | ||
1605 | atsi); | ||
1606 | } | ||
1607 | |||
1608 | |||
1609 | /** | ||
1610 | * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK | ||
1611 | * | ||
1612 | * @param socket the socket | ||
1613 | * @param tunnel connection to the other end | ||
1614 | * @param tunnel_ctx this is NULL | ||
1615 | * @param sender who sent the message | ||
1616 | * @param message the actual message | ||
1617 | * @param atsi performance data for the connection | ||
1618 | * @return GNUNET_OK to keep the connection open, | ||
1619 | * GNUNET_SYSERR to close it (signal serious error) | ||
1620 | */ | ||
1621 | static int | ||
1622 | handle_close_ack (struct GNUNET_STREAM_Socket *socket, | ||
1623 | struct GNUNET_MESH_Tunnel *tunnel, | ||
1624 | const struct GNUNET_PeerIdentity *sender, | ||
1625 | const struct GNUNET_STREAM_MessageHeader *message, | ||
1626 | const struct GNUNET_ATS_Information*atsi) | ||
1627 | { | ||
1628 | switch (socket->state) | ||
1629 | { | ||
1630 | case STATE_CLOSE_WAIT: | ||
1631 | socket->state = STATE_CLOSED; | ||
1632 | break; | ||
1633 | default: | ||
1634 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1635 | "%x: Received CLOSE_ACK when in it not expected\n", | ||
1636 | socket->our_id); | ||
1637 | break; | ||
1638 | } | ||
1525 | return GNUNET_OK; | 1639 | return GNUNET_OK; |
1526 | } | 1640 | } |
1527 | 1641 | ||
@@ -1548,7 +1662,12 @@ client_handle_close_ack (void *cls, | |||
1548 | { | 1662 | { |
1549 | struct GNUNET_STREAM_Socket *socket = cls; | 1663 | struct GNUNET_STREAM_Socket *socket = cls; |
1550 | 1664 | ||
1551 | return GNUNET_OK; | 1665 | return handle_close_ack (socket, |
1666 | tunnel, | ||
1667 | sender, | ||
1668 | (const struct GNUNET_STREAM_MessageHeader *) | ||
1669 | message, | ||
1670 | atsi); | ||
1552 | } | 1671 | } |
1553 | 1672 | ||
1554 | /*****************************/ | 1673 | /*****************************/ |
@@ -1834,7 +1953,8 @@ server_handle_receive_close_ack (void *cls, | |||
1834 | /** | 1953 | /** |
1835 | * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE | 1954 | * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE |
1836 | * | 1955 | * |
1837 | * @param cls the closure | 1956 | * @param cls the listen socket (from GNUNET_MESH_connect in |
1957 | * GNUNET_STREAM_listen) | ||
1838 | * @param tunnel connection to the other end | 1958 | * @param tunnel connection to the other end |
1839 | * @param tunnel_ctx the socket | 1959 | * @param tunnel_ctx the socket |
1840 | * @param sender who sent the message | 1960 | * @param sender who sent the message |
@@ -1852,8 +1972,12 @@ server_handle_close (void *cls, | |||
1852 | const struct GNUNET_ATS_Information*atsi) | 1972 | const struct GNUNET_ATS_Information*atsi) |
1853 | { | 1973 | { |
1854 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; | 1974 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; |
1855 | 1975 | ||
1856 | return GNUNET_OK; | 1976 | return handle_close (socket, |
1977 | tunnel, | ||
1978 | sender, | ||
1979 | (const struct GNUNET_STREAM_MessageHeader *) message, | ||
1980 | atsi); | ||
1857 | } | 1981 | } |
1858 | 1982 | ||
1859 | 1983 | ||
@@ -1879,7 +2003,11 @@ server_handle_close_ack (void *cls, | |||
1879 | { | 2003 | { |
1880 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; | 2004 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; |
1881 | 2005 | ||
1882 | return GNUNET_OK; | 2006 | return handle_close_ack (socket, |
2007 | tunnel, | ||
2008 | sender, | ||
2009 | (const struct GNUNET_STREAM_MessageHeader *) message, | ||
2010 | atsi); | ||
1883 | } | 2011 | } |
1884 | 2012 | ||
1885 | 2013 | ||
@@ -2373,7 +2501,7 @@ GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
2373 | * Shutdown the stream for reading or writing (similar to man 2 shutdown). | 2501 | * Shutdown the stream for reading or writing (similar to man 2 shutdown). |
2374 | * | 2502 | * |
2375 | * @param socket the stream socket | 2503 | * @param socket the stream socket |
2376 | * @param opertion SHUT_RD, SHUT_WR or SHUT_RDWR | 2504 | * @param operation SHUT_RD, SHUT_WR or SHUT_RDWR |
2377 | * @param completion_cb the callback that will be called upon successful | 2505 | * @param completion_cb the callback that will be called upon successful |
2378 | * shutdown of given operation | 2506 | * shutdown of given operation |
2379 | * @param completion_cls the closure for the completion callback | 2507 | * @param completion_cls the closure for the completion callback |
@@ -2385,14 +2513,54 @@ GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket, | |||
2385 | GNUNET_STREAM_ShutdownCompletion completion_cb, | 2513 | GNUNET_STREAM_ShutdownCompletion completion_cb, |
2386 | void *completion_cls) | 2514 | void *completion_cls) |
2387 | { | 2515 | { |
2388 | return NULL; | 2516 | struct GNUNET_STREAM_ShutdownHandle *handle; |
2517 | struct GNUNET_STREAM_MessageHeader *msg; | ||
2518 | |||
2519 | handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ShutdownHandle)); | ||
2520 | handle->socket = socket; | ||
2521 | msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); | ||
2522 | msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); | ||
2523 | switch (operation) | ||
2524 | { | ||
2525 | case SHUT_RD: | ||
2526 | handle->operation = SHUT_RD; | ||
2527 | |||
2528 | break; | ||
2529 | case SHUT_WR: | ||
2530 | handle->operation = SHUT_WR; | ||
2531 | |||
2532 | break; | ||
2533 | case SHUT_RDWR: | ||
2534 | handle->operation = SHUT_RDWR; | ||
2535 | if (NULL != socket->write_handle) | ||
2536 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2537 | "Existing write handle should be cancelled before shutting" | ||
2538 | " down writing\n"); | ||
2539 | if (NULL != socket->read_handle) | ||
2540 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2541 | "Existing read handle should be cancelled before shutting" | ||
2542 | " down reading\n"); | ||
2543 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE); | ||
2544 | queue_message (socket, | ||
2545 | msg, | ||
2546 | &set_state_close_wait, | ||
2547 | NULL); | ||
2548 | break; | ||
2549 | default: | ||
2550 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2551 | "GNUNET_STREAM_shutdown called with invalid value for " | ||
2552 | "parameter operation -- Ignoring\n"); | ||
2553 | GNUNET_free (handle); | ||
2554 | return NULL; | ||
2555 | } | ||
2556 | return handle; | ||
2389 | } | 2557 | } |
2390 | 2558 | ||
2391 | 2559 | ||
2392 | /** | 2560 | /** |
2393 | * Cancels a pending shutdown | 2561 | * Cancels a pending shutdown |
2394 | * | 2562 | * |
2395 | * @param the shutdown handle returned from GNUNET_STREAM_shutdown | 2563 | * @param handle the shutdown handle returned from GNUNET_STREAM_shutdown |
2396 | */ | 2564 | */ |
2397 | void | 2565 | void |
2398 | GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle) | 2566 | GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle) |