aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_stream_lib.h8
-rw-r--r--src/stream/stream_api.c184
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 */
154struct GNUNET_STREAM_ShutdownHandle * 154struct GNUNET_STREAM_ShutdownHandle *
155GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket, 155GNUNET_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 */
166void 166void
167GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle); 167GNUNET_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 */
1237static void
1238set_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 */
1257static void
1258set_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 */
1553static int
1554handle_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 */
1621static int
1622handle_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 */
2397void 2565void
2398GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle) 2566GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle)