aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/stream/stream_api.c50
-rw-r--r--src/stream/test_stream_local.c49
2 files changed, 92 insertions, 7 deletions
diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c
index 92c1093f7..535850de2 100644
--- a/src/stream/stream_api.c
+++ b/src/stream/stream_api.c
@@ -232,6 +232,11 @@ struct GNUNET_STREAM_Socket
232 struct GNUNET_STREAM_IOReadHandle *read_handle; 232 struct GNUNET_STREAM_IOReadHandle *read_handle;
233 233
234 /** 234 /**
235 * The shutdown handle associated with this socket
236 */
237 struct GNUNET_STREAM_ShutdownHandle *shutdown_handle;
238
239 /**
235 * Buffer for storing received messages 240 * Buffer for storing received messages
236 */ 241 */
237 void *receive_buffer; 242 void *receive_buffer;
@@ -443,6 +448,16 @@ struct GNUNET_STREAM_ShutdownHandle
443 * Which operation to shutdown? SHUT_RD, SHUT_WR or SHUT_RDWR 448 * Which operation to shutdown? SHUT_RD, SHUT_WR or SHUT_RDWR
444 */ 449 */
445 int operation; 450 int operation;
451
452 /**
453 * Shutdown completion callback
454 */
455 GNUNET_STREAM_ShutdownCompletion completion_cb;
456
457 /**
458 * Closure for completion callback
459 */
460 void *completion_cls;
446}; 461};
447 462
448 463
@@ -1559,6 +1574,10 @@ handle_close (struct GNUNET_STREAM_Socket *socket,
1559{ 1574{
1560 struct GNUNET_STREAM_MessageHeader *close_ack; 1575 struct GNUNET_STREAM_MessageHeader *close_ack;
1561 1576
1577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1578 "%x: Received CLOSE from %x\n",
1579 socket->our_id,
1580 socket->other_peer);
1562 close_ack = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); 1581 close_ack = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader));
1563 close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); 1582 close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader));
1564 close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK); 1583 close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK);
@@ -1625,10 +1644,30 @@ handle_close_ack (struct GNUNET_STREAM_Socket *socket,
1625 const struct GNUNET_STREAM_MessageHeader *message, 1644 const struct GNUNET_STREAM_MessageHeader *message,
1626 const struct GNUNET_ATS_Information*atsi) 1645 const struct GNUNET_ATS_Information*atsi)
1627{ 1646{
1647 struct GNUNET_STREAM_ShutdownHandle *shutdown_handle;
1648
1649 shutdown_handle = socket->shutdown_handle;
1628 switch (socket->state) 1650 switch (socket->state)
1629 { 1651 {
1630 case STATE_CLOSE_WAIT: 1652 case STATE_CLOSE_WAIT:
1631 socket->state = STATE_CLOSED; 1653 socket->state = STATE_CLOSED;
1654 if ( (NULL == shutdown_handle) ||
1655 (SHUT_RDWR != shutdown_handle->operation) )
1656 {
1657 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1658 "%x: Received CLOSE_ACK when shutdown handle is NULL or "
1659 "not for SHUT_RDWR\n",
1660 socket->our_id);
1661 return GNUNET_OK;
1662 }
1663 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1664 "%x: Received CLOSE_ACK from %x\n",
1665 socket->our_id,
1666 socket->other_peer);
1667 if (NULL != shutdown_handle->completion_cb) /* Shutdown completion */
1668 shutdown_handle->completion_cb(shutdown_handle->completion_cls,
1669 SHUT_RDWR);
1670 GNUNET_free (shutdown_handle); /* Free shutdown handle */
1632 break; 1671 break;
1633 default: 1672 default:
1634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1673 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2515,16 +2554,25 @@ GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket,
2515{ 2554{
2516 struct GNUNET_STREAM_ShutdownHandle *handle; 2555 struct GNUNET_STREAM_ShutdownHandle *handle;
2517 struct GNUNET_STREAM_MessageHeader *msg; 2556 struct GNUNET_STREAM_MessageHeader *msg;
2557
2558 GNUNET_assert (NULL == socket->shutdown_handle);
2518 2559
2519 handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ShutdownHandle)); 2560 handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ShutdownHandle));
2520 handle->socket = socket; 2561 handle->socket = socket;
2562 handle->completion_cb = completion_cb;
2563 handle->completion_cls = completion_cls;
2564 socket->shutdown_handle = handle;
2565
2521 msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); 2566 msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader));
2522 msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); 2567 msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader));
2523 switch (operation) 2568 switch (operation)
2524 { 2569 {
2525 case SHUT_RD: 2570 case SHUT_RD:
2526 handle->operation = SHUT_RD; 2571 handle->operation = SHUT_RD;
2527 2572 if (NULL != socket->read_handle)
2573 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2574 "Existing read handle should be cancelled before shutting"
2575 " down reading\n");
2528 break; 2576 break;
2529 case SHUT_WR: 2577 case SHUT_WR:
2530 handle->operation = SHUT_WR; 2578 handle->operation = SHUT_WR;
diff --git a/src/stream/test_stream_local.c b/src/stream/test_stream_local.c
index c3fcc6492..125873acf 100644
--- a/src/stream/test_stream_local.c
+++ b/src/stream/test_stream_local.c
@@ -60,6 +60,11 @@ struct PeerData
60 struct GNUNET_STREAM_IOReadHandle *io_read_handle; 60 struct GNUNET_STREAM_IOReadHandle *io_read_handle;
61 61
62 /** 62 /**
63 * Peer's shutdown handle
64 */
65 struct GNUNET_STREAM_ShutdownHandle *shutdown_handle;
66
67 /**
63 * Our Peer id 68 * Our Peer id
64 */ 69 */
65 struct GNUNET_PeerIdentity our_id; 70 struct GNUNET_PeerIdentity our_id;
@@ -109,7 +114,7 @@ static int reading_success;
109 * Check whether peers successfully shut down. 114 * Check whether peers successfully shut down.
110 */ 115 */
111static void 116static void
112shutdown_callback (void *cls, const char *emsg) 117peergroup_shutdown_callback (void *cls, const char *emsg)
113{ 118{
114 if (emsg != NULL) 119 if (emsg != NULL)
115 { 120 {
@@ -126,10 +131,10 @@ shutdown_callback (void *cls, const char *emsg)
126 131
127 132
128/** 133/**
129 * Shutdown nicely 134 * Close sockets and stop testing deamons nicely
130 */ 135 */
131static void 136static void
132do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 137do_close (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
133{ 138{
134 if (NULL != peer1.socket) 139 if (NULL != peer1.socket)
135 GNUNET_STREAM_close (peer1.socket); 140 GNUNET_STREAM_close (peer1.socket);
@@ -149,12 +154,44 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
149 GNUNET_TESTING_daemons_stop (pg, 154 GNUNET_TESTING_daemons_stop (pg,
150 GNUNET_TIME_relative_multiply 155 GNUNET_TIME_relative_multiply
151 (GNUNET_TIME_UNIT_SECONDS, 5), 156 (GNUNET_TIME_UNIT_SECONDS, 5),
152 &shutdown_callback, 157 &peergroup_shutdown_callback,
153 NULL); 158 NULL);
154} 159}
155 160
156 161
157/** 162/**
163 * Completion callback for shutdown
164 *
165 * @param cls the closure from GNUNET_STREAM_shutdown call
166 * @param operation the operation that was shutdown (SHUT_RD, SHUT_WR,
167 * SHUT_RDWR)
168 */
169static void
170shutdown_completion (void *cls,
171 int operation)
172{
173 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
174 "STREAM shutdown successful\n");
175 GNUNET_SCHEDULER_add_now (&do_close,
176 cls);
177}
178
179
180
181/**
182 * Shutdown sockets gracefully
183 */
184static void
185do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
186{
187 peer1.shutdown_handle = GNUNET_STREAM_shutdown (peer1.socket,
188 SHUT_RDWR,
189 &shutdown_completion,
190 cls);
191}
192
193
194/**
158 * Something went wrong and timed out. Kill everything and set error flag 195 * Something went wrong and timed out. Kill everything and set error flag
159 */ 196 */
160static void 197static void
@@ -167,7 +204,7 @@ do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
167 } 204 }
168 result = GNUNET_SYSERR; 205 result = GNUNET_SYSERR;
169 abort_task = 0; 206 abort_task = 0;
170 do_shutdown (cls, tc); 207 do_close (cls, tc);
171} 208}
172 209
173/** 210/**
@@ -237,7 +274,7 @@ write_completion (void *cls,
237 else 274 else
238 { 275 {
239 writing_success = GNUNET_YES; 276 writing_success = GNUNET_YES;
240 if (GNUNET_YES == reading_success) 277 if (GNUNET_YES == reading_success)
241 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 278 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
242 } 279 }
243 } 280 }