aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/datastore/gnunet-service-datastore.c4
-rw-r--r--src/fs/gnunet-service-fs_lc.c4
-rw-r--r--src/include/gnunet_connection_lib.h7
-rw-r--r--src/include/gnunet_server_lib.h19
-rw-r--r--src/transport/plugin_transport_tcp.c4
-rw-r--r--src/util/connection.c187
-rw-r--r--src/util/server.c91
-rw-r--r--src/util/server_nc.c4
-rw-r--r--src/util/test_connection.c2
-rw-r--r--src/util/test_service.c14
10 files changed, 162 insertions, 174 deletions
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index 1d7e8cd2b..863cd3902 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -250,7 +250,7 @@ struct TransmitCallbackContext
250 /** 250 /**
251 * Handle for the transmission request. 251 * Handle for the transmission request.
252 */ 252 */
253 struct GNUNET_CONNECTION_TransmitHandle *th; 253 struct GNUNET_SERVER_TransmitHandle *th;
254 254
255 /** 255 /**
256 * Client that we are transmitting to. 256 * Client that we are transmitting to.
@@ -1409,7 +1409,7 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1409 GNUNET_CONTAINER_DLL_remove (tcc_head, tcc_tail, tcc); 1409 GNUNET_CONTAINER_DLL_remove (tcc_head, tcc_tail, tcc);
1410 if (tcc->th != NULL) 1410 if (tcc->th != NULL)
1411 { 1411 {
1412 GNUNET_CONNECTION_notify_transmit_ready_cancel (tcc->th); 1412 GNUNET_SERVER_notify_transmit_ready_cancel (tcc->th);
1413 GNUNET_SERVER_client_drop (tcc->client); 1413 GNUNET_SERVER_client_drop (tcc->client);
1414 } 1414 }
1415 GNUNET_free (tcc->msg); 1415 GNUNET_free (tcc->msg);
diff --git a/src/fs/gnunet-service-fs_lc.c b/src/fs/gnunet-service-fs_lc.c
index 36aafdde9..c2fbbecd7 100644
--- a/src/fs/gnunet-service-fs_lc.c
+++ b/src/fs/gnunet-service-fs_lc.c
@@ -140,7 +140,7 @@ struct GSF_LocalClient
140 /** 140 /**
141 * Context for sending replies. 141 * Context for sending replies.
142 */ 142 */
143 struct GNUNET_CONNECTION_TransmitHandle *th; 143 struct GNUNET_SERVER_TransmitHandle *th;
144 144
145}; 145};
146 146
@@ -498,7 +498,7 @@ GSF_client_disconnect_handler_ (void *cls, struct GNUNET_SERVER_Client *client)
498 } 498 }
499 if (pos->th != NULL) 499 if (pos->th != NULL)
500 { 500 {
501 GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->th); 501 GNUNET_SERVER_notify_transmit_ready_cancel (pos->th);
502 pos->th = NULL; 502 pos->th = NULL;
503 } 503 }
504 GSF_handle_local_client_disconnect_ (pos); 504 GSF_handle_local_client_disconnect_ (pos);
diff --git a/src/include/gnunet_connection_lib.h b/src/include/gnunet_connection_lib.h
index 5c9ead95e..0806ccaa3 100644
--- a/src/include/gnunet_connection_lib.h
+++ b/src/include/gnunet_connection_lib.h
@@ -230,10 +230,9 @@ GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
230 230
231 231
232/** 232/**
233 * Close the connection and free associated resources. A pending 233 * Close the connection and free associated resources. There must
234 * request for transmission is automatically cancelled (we might 234 * not be any pending requests for reading or writing to the
235 * want to change this in the future). We require that there 235 * connection at this time.
236 * are no active pending requests for reading from the connection.
237 * 236 *
238 * @param connection connection to destroy 237 * @param connection connection to destroy
239 */ 238 */
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
index 6fe9e79a7..2f939f18c 100644
--- a/src/include/gnunet_server_lib.h
+++ b/src/include/gnunet_server_lib.h
@@ -55,12 +55,16 @@ extern "C"
55 */ 55 */
56struct GNUNET_SERVER_Handle; 56struct GNUNET_SERVER_Handle;
57 57
58
59/** 58/**
60 * @brief opaque handle for a client of the server 59 * @brief opaque handle for a client of the server
61 */ 60 */
62struct GNUNET_SERVER_Client; 61struct GNUNET_SERVER_Client;
63 62
63/**
64 * @brief opaque handle server returns for aborting transmission to a client.
65 */
66struct GNUNET_SERVER_TransmitHandle;
67
64 68
65/** 69/**
66 * Functions with this signature are called whenever a message is 70 * Functions with this signature are called whenever a message is
@@ -190,10 +194,10 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
190 * @param callback_cls closure for callback 194 * @param callback_cls closure for callback
191 * @return non-NULL if the notify callback was queued; can be used 195 * @return non-NULL if the notify callback was queued; can be used
192 * to cancel the request using 196 * to cancel the request using
193 * GNUNET_CONNECTION_notify_transmit_ready_cancel. 197 * GNUNET_SERVER_notify_transmit_ready_cancel.
194 * NULL if we are already going to notify someone else (busy) 198 * NULL if we are already going to notify someone else (busy)
195 */ 199 */
196struct GNUNET_CONNECTION_TransmitHandle * 200struct GNUNET_SERVER_TransmitHandle *
197GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, 201GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
198 size_t size, 202 size_t size,
199 struct GNUNET_TIME_Relative timeout, 203 struct GNUNET_TIME_Relative timeout,
@@ -202,6 +206,15 @@ GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
202 206
203 207
204/** 208/**
209 * Abort transmission request.
210 *
211 * @param th request to abort
212 */
213void
214GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th);
215
216
217/**
205 * Set the persistent flag on this client, used to setup client connection 218 * Set the persistent flag on this client, used to setup client connection
206 * to only be killed when the service it's connected to is actually dead. 219 * to only be killed when the service it's connected to is actually dead.
207 * 220 *
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index ee94970e5..ea8b6ee08 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -267,7 +267,7 @@ struct Session
267 /** 267 /**
268 * Handle for pending transmission request. 268 * Handle for pending transmission request.
269 */ 269 */
270 struct GNUNET_CONNECTION_TransmitHandle *transmit_handle; 270 struct GNUNET_SERVER_TransmitHandle *transmit_handle;
271 271
272 /** 272 /**
273 * To whom are we talking to (set to our identity 273 * To whom are we talking to (set to our identity
@@ -919,7 +919,7 @@ disconnect_session (struct Session *session)
919 /* clean up state */ 919 /* clean up state */
920 if (session->transmit_handle != NULL) 920 if (session->transmit_handle != NULL)
921 { 921 {
922 GNUNET_CONNECTION_notify_transmit_ready_cancel (session->transmit_handle); 922 GNUNET_SERVER_notify_transmit_ready_cancel (session->transmit_handle);
923 session->transmit_handle = NULL; 923 session->transmit_handle = NULL;
924 } 924 }
925 session->plugin->env->session_end (session->plugin->env->cls, 925 session->plugin->env->session_end (session->plugin->env->cls,
diff --git a/src/util/connection.c b/src/util/connection.c
index 8d0042b7b..4473b7bb5 100644
--- a/src/util/connection.c
+++ b/src/util/connection.c
@@ -62,12 +62,8 @@ enum ConnectContinuations
62 /** 62 /**
63 * Call "transmit_ready". 63 * Call "transmit_ready".
64 */ 64 */
65 COCO_TRANSMIT_READY = 2, 65 COCO_TRANSMIT_READY = 2
66 66
67 /**
68 * Call "destroy_continuation".
69 */
70 COCO_DESTROY_CONTINUATION = 4
71}; 67};
72 68
73 69
@@ -243,11 +239,6 @@ struct GNUNET_CONNECTION_Handle
243 GNUNET_SCHEDULER_TaskIdentifier write_task; 239 GNUNET_SCHEDULER_TaskIdentifier write_task;
244 240
245 /** 241 /**
246 * Destroy task (if already scheduled).
247 */
248 GNUNET_SCHEDULER_TaskIdentifier destroy_task;
249
250 /**
251 * Handle to a pending DNS lookup request. 242 * Handle to a pending DNS lookup request.
252 */ 243 */
253 struct GNUNET_RESOLVER_RequestHandle *dns_active; 244 struct GNUNET_RESOLVER_RequestHandle *dns_active;
@@ -515,96 +506,6 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
515 506
516 507
517/** 508/**
518 * Scheduler let us know that the connect task is finished (or was
519 * cancelled due to shutdown). Now really clean up.
520 *
521 * @param cls our "struct GNUNET_CONNECTION_Handle *"
522 * @param tc unused
523 */
524static void
525destroy_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
526{
527 struct GNUNET_CONNECTION_Handle *connection = cls;
528 GNUNET_CONNECTION_TransmitReadyNotify notify;
529 struct AddressProbe *pos;
530
531 connection->destroy_task = GNUNET_SCHEDULER_NO_TASK;
532 GNUNET_assert (connection->dns_active == NULL);
533 if (0 != (connection->ccs & COCO_TRANSMIT_READY))
534 {
535 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy waits for CCS-TR to be done (%p)\n",
536 connection);
537 connection->ccs |= COCO_DESTROY_CONTINUATION;
538 return;
539 }
540 if (connection->write_task != GNUNET_SCHEDULER_NO_TASK)
541 {
542 LOG (GNUNET_ERROR_TYPE_DEBUG,
543 "Destroy waits for write_task to be done (%p)\n", connection);
544 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->destroy_task);
545 connection->destroy_task =
546 GNUNET_SCHEDULER_add_after (connection->write_task, &destroy_continuation,
547 connection);
548 return;
549 }
550 if (0 != (connection->ccs & COCO_RECEIVE_AGAIN))
551 {
552 connection->ccs |= COCO_DESTROY_CONTINUATION;
553 return;
554 }
555 if (connection->sock != NULL)
556 {
557 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection);
558 if (connection->persist != GNUNET_YES)
559 {
560 if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR))
561 && (errno != ENOTCONN) && (errno != ECONNRESET))
562 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown");
563 }
564 }
565 if (connection->read_task != GNUNET_SCHEDULER_NO_TASK)
566 {
567 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->destroy_task);
568 connection->destroy_task =
569 GNUNET_SCHEDULER_add_after (connection->read_task, &destroy_continuation,
570 connection);
571 return;
572 }
573 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy actually runs (%p)!\n", connection);
574 while (NULL != (pos = connection->ap_head))
575 {
576 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
577 GNUNET_SCHEDULER_cancel (pos->task);
578 GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, pos);
579 GNUNET_free (pos);
580 }
581 GNUNET_assert (connection->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK);
582 GNUNET_assert (connection->ccs == COCO_NONE);
583 if (NULL != (notify = connection->nth.notify_ready))
584 {
585 connection->nth.notify_ready = NULL;
586 notify (connection->nth.notify_ready_cls, 0, NULL);
587 }
588
589 if (connection->sock != NULL)
590 {
591 if (connection->persist != GNUNET_YES)
592 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock));
593 else
594 GNUNET_free (connection->sock); /* at least no memory leak (we deliberately
595 * leak the socket in this special case) ... */
596 }
597 GNUNET_free_non_null (connection->addr);
598 GNUNET_free_non_null (connection->hostname);
599 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->destroy_task);
600 LOG (GNUNET_ERROR_TYPE_DEBUG, "Freeing memory of connection %p.\n", connection);
601 GNUNET_free (connection->write_buffer);
602 GNUNET_free (connection);
603}
604
605
606
607/**
608 * See if we are now connected. If not, wait longer for 509 * See if we are now connected. If not, wait longer for
609 * connect to succeed. If connected, we should be able 510 * connect to succeed. If connected, we should be able
610 * to write now as well, unless we timed out. 511 * to write now as well, unless we timed out.
@@ -654,14 +555,6 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h)
654 GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); 555 GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK);
655 h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h); 556 h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h);
656 } 557 }
657 if (0 != (h->ccs & COCO_DESTROY_CONTINUATION))
658 {
659 LOG (GNUNET_ERROR_TYPE_DEBUG,
660 "connect_fail_continuation runs destroy_continuation (%p)\n", h);
661 h->ccs -= COCO_DESTROY_CONTINUATION;
662 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task);
663 h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h);
664 }
665} 558}
666 559
667 560
@@ -699,14 +592,6 @@ connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection)
699 (connection->nth.transmit_timeout), connection->sock, 592 (connection->nth.transmit_timeout), connection->sock,
700 &transmit_ready, connection); 593 &transmit_ready, connection);
701 } 594 }
702 if (0 != (connection->ccs & COCO_DESTROY_CONTINUATION))
703 {
704 LOG (GNUNET_ERROR_TYPE_DEBUG,
705 "connect_success_continuation runs destroy_continuation (%p)\n", connection);
706 connection->ccs -= COCO_DESTROY_CONTINUATION;
707 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->destroy_task);
708 connection->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, connection);
709 }
710} 595}
711 596
712 597
@@ -1012,16 +897,19 @@ GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *sock)
1012 897
1013 898
1014/** 899/**
1015 * Close the connection and free associated resources. A pending 900 * Close the connection and free associated resources. There must
1016 * request for transmission is automatically cancelled (we might 901 * not be any pending requests for reading or writing to the
1017 * want to change this in the future). We require that there 902 * connection at this time.
1018 * are no active pending requests for reading from the connection.
1019 * 903 *
1020 * @param connection connection to destroy 904 * @param connection connection to destroy
1021 */ 905 */
1022void 906void
1023GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection) 907GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
1024{ 908{
909 struct AddressProbe *pos;
910
911 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection);
912 GNUNET_assert (NULL == connection->nth.notify_ready);
1025 GNUNET_assert (NULL == connection->receiver); 913 GNUNET_assert (NULL == connection->receiver);
1026 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->read_task); 914 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->read_task);
1027 if (connection->write_task != GNUNET_SCHEDULER_NO_TASK) 915 if (connection->write_task != GNUNET_SCHEDULER_NO_TASK)
@@ -1030,14 +918,49 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
1030 connection->write_task = GNUNET_SCHEDULER_NO_TASK; 918 connection->write_task = GNUNET_SCHEDULER_NO_TASK;
1031 connection->write_buffer_off = 0; 919 connection->write_buffer_off = 0;
1032 } 920 }
921 if (connection->read_task != GNUNET_SCHEDULER_NO_TASK)
922 {
923 GNUNET_SCHEDULER_cancel (connection->read_task);
924 connection->read_task = GNUNET_SCHEDULER_NO_TASK;
925 }
926 if (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK)
927 {
928 GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
929 connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
930 }
1033 connection->nth.notify_ready = NULL; 931 connection->nth.notify_ready = NULL;
1034 if (connection->dns_active != NULL) 932 if (NULL != connection->dns_active)
1035 { 933 {
1036 GNUNET_RESOLVER_request_cancel (connection->dns_active); 934 GNUNET_RESOLVER_request_cancel (connection->dns_active);
1037 connection->dns_active = NULL; 935 connection->dns_active = NULL;
1038 } 936 }
1039 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->destroy_task); 937 while (NULL != (pos = connection->ap_head))
1040 connection->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, connection); 938 {
939 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
940 GNUNET_SCHEDULER_cancel (pos->task);
941 GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, pos);
942 GNUNET_free (pos);
943 }
944 if ( (NULL != connection->sock) &&
945 (connection->persist != GNUNET_YES) )
946 {
947 if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR)) &&
948 (errno != ENOTCONN) &&
949 (errno != ECONNRESET) )
950 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown");
951 }
952 if (connection->sock != NULL)
953 {
954 if (connection->persist != GNUNET_YES)
955 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock));
956 else
957 GNUNET_free (connection->sock); /* at least no memory leak (we deliberately
958 * leak the socket in this special case) ... */
959 }
960 GNUNET_free_non_null (connection->addr);
961 GNUNET_free_non_null (connection->hostname);
962 GNUNET_free (connection->write_buffer);
963 GNUNET_free (connection);
1041} 964}
1042 965
1043 966
@@ -1045,15 +968,15 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
1045 * Tell the receiver callback that a timeout was reached. 968 * Tell the receiver callback that a timeout was reached.
1046 */ 969 */
1047static void 970static void
1048signal_timeout (struct GNUNET_CONNECTION_Handle *sh) 971signal_timeout (struct GNUNET_CONNECTION_Handle *connection)
1049{ 972{
1050 GNUNET_CONNECTION_Receiver receiver; 973 GNUNET_CONNECTION_Receiver receiver;
1051 974
1052 LOG (GNUNET_ERROR_TYPE_DEBUG, "Network signals time out to receiver (%p)!\n", 975 LOG (GNUNET_ERROR_TYPE_DEBUG, "Network signals time out to receiver (%p)!\n",
1053 sh); 976 connection);
1054 GNUNET_assert (NULL != (receiver = sh->receiver)); 977 GNUNET_assert (NULL != (receiver = connection->receiver));
1055 sh->receiver = NULL; 978 connection->receiver = NULL;
1056 receiver (sh->receiver_cls, NULL, 0, NULL, 0, 0); 979 receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
1057} 980}
1058 981
1059 982
@@ -1061,13 +984,13 @@ signal_timeout (struct GNUNET_CONNECTION_Handle *sh)
1061 * Tell the receiver callback that we had an IO error. 984 * Tell the receiver callback that we had an IO error.
1062 */ 985 */
1063static void 986static void
1064signal_error (struct GNUNET_CONNECTION_Handle *sh, int errcode) 987signal_error (struct GNUNET_CONNECTION_Handle *connection, int errcode)
1065{ 988{
1066 GNUNET_CONNECTION_Receiver receiver; 989 GNUNET_CONNECTION_Receiver receiver;
1067 990
1068 GNUNET_assert (NULL != (receiver = sh->receiver)); 991 GNUNET_assert (NULL != (receiver = connection->receiver));
1069 sh->receiver = NULL; 992 connection->receiver = NULL;
1070 receiver (sh->receiver_cls, NULL, 0, sh->addr, sh->addrlen, errcode); 993 receiver (connection->receiver_cls, NULL, 0, connection->addr, connection->addrlen, errcode);
1071} 994}
1072 995
1073 996
diff --git a/src/util/server.c b/src/util/server.c
index a3f63490a..ede31b558 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -139,14 +139,52 @@ struct GNUNET_SERVER_Handle
139 */ 139 */
140 int clients_ignore_shutdown; 140 int clients_ignore_shutdown;
141 141
142 /**
143 * Alternative function to create a MST instance.
144 */
142 GNUNET_SERVER_MstCreateCallback mst_create; 145 GNUNET_SERVER_MstCreateCallback mst_create;
146
147 /**
148 * Alternative function to destroy a MST instance.
149 */
143 GNUNET_SERVER_MstDestroyCallback mst_destroy; 150 GNUNET_SERVER_MstDestroyCallback mst_destroy;
151
152 /**
153 * Alternative function to give data to a MST instance.
154 */
144 GNUNET_SERVER_MstReceiveCallback mst_receive; 155 GNUNET_SERVER_MstReceiveCallback mst_receive;
156
157 /**
158 * Closure for 'mst_'-callbacks.
159 */
145 void *mst_cls; 160 void *mst_cls;
146}; 161};
147 162
148 163
149/** 164/**
165 * Handle server returns for aborting transmission to a client.
166 */
167struct GNUNET_SERVER_TransmitHandle
168{
169 /**
170 * Function to call to get the message.
171 */
172 GNUNET_CONNECTION_TransmitReadyNotify callback;
173
174 /**
175 * Closure for 'callback'
176 */
177 void *callback_cls;
178
179 /**
180 * Active connection transmission handle.
181 */
182 struct GNUNET_CONNECTION_TransmitHandle *cth;
183
184};
185
186
187/**
150 * @brief handle for a client of the server 188 * @brief handle for a client of the server
151 */ 189 */
152struct GNUNET_SERVER_Client 190struct GNUNET_SERVER_Client
@@ -194,14 +232,10 @@ struct GNUNET_SERVER_Client
194 struct GNUNET_TIME_Absolute last_activity; 232 struct GNUNET_TIME_Absolute last_activity;
195 233
196 /** 234 /**
197 * 235 * Transmission handle we return for this client from
236 * GNUNET_SERVER_notify_transmit_ready.
198 */ 237 */
199 GNUNET_CONNECTION_TransmitReadyNotify callback; 238 struct GNUNET_SERVER_TransmitHandle th;
200
201 /**
202 * callback
203 */
204 void *callback_cls;
205 239
206 /** 240 /**
207 * After how long should an idle connection time 241 * After how long should an idle connection time
@@ -966,9 +1000,7 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
966 client->next = server->clients; 1000 client->next = server->clients;
967 client->idle_timeout = server->idle_timeout; 1001 client->idle_timeout = server->idle_timeout;
968 server->clients = client; 1002 server->clients = client;
969 client->callback = NULL; 1003 if (NULL != server->mst_create)
970 client->callback_cls = NULL;
971 if (server->mst_create != NULL)
972 client->mst = 1004 client->mst =
973 server->mst_create (server->mst_cls, client); 1005 server->mst_create (server->mst_cls, client);
974 else 1006 else
@@ -1231,9 +1263,13 @@ static size_t
1231transmit_ready_callback_wrapper (void *cls, size_t size, void *buf) 1263transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1232{ 1264{
1233 struct GNUNET_SERVER_Client *client = cls; 1265 struct GNUNET_SERVER_Client *client = cls;
1266 GNUNET_CONNECTION_TransmitReadyNotify callback;
1234 size_t ret; 1267 size_t ret;
1235 1268
1236 ret = client->callback (client->callback_cls, size, buf); 1269 client->th.cth = NULL;
1270 callback = client->th.callback;
1271 client->th.callback = NULL;
1272 ret = callback (client->th.callback_cls, size, buf);
1237 if (ret > 0) 1273 if (ret > 0)
1238 client->last_activity = GNUNET_TIME_absolute_get (); 1274 client->last_activity = GNUNET_TIME_absolute_get ();
1239 return ret; 1275 return ret;
@@ -1252,22 +1288,39 @@ transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1252 * @param callback_cls closure for callback 1288 * @param callback_cls closure for callback
1253 * @return non-NULL if the notify callback was queued; can be used 1289 * @return non-NULL if the notify callback was queued; can be used
1254 * to cancel the request using 1290 * to cancel the request using
1255 * GNUNET_CONNECTION_notify_transmit_ready_cancel. 1291 * GNUNET_SERVER_notify_transmit_ready_cancel.
1256 * NULL if we are already going to notify someone else (busy) 1292 * NULL if we are already going to notify someone else (busy)
1257 */ 1293 */
1258struct GNUNET_CONNECTION_TransmitHandle * 1294struct GNUNET_SERVER_TransmitHandle *
1259GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, 1295GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
1260 size_t size, 1296 size_t size,
1261 struct GNUNET_TIME_Relative timeout, 1297 struct GNUNET_TIME_Relative timeout,
1262 GNUNET_CONNECTION_TransmitReadyNotify 1298 GNUNET_CONNECTION_TransmitReadyNotify
1263 callback, void *callback_cls) 1299 callback, void *callback_cls)
1264{ 1300{
1265 client->callback_cls = callback_cls; 1301 if (NULL != client->th.callback)
1266 client->callback = callback; 1302 return NULL;
1267 return GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, 1303 client->th.callback_cls = callback_cls;
1268 timeout, 1304 client->th.callback = callback;
1269 &transmit_ready_callback_wrapper, 1305 client->th.cth = GNUNET_CONNECTION_notify_transmit_ready (client->connection, size,
1270 client); 1306 timeout,
1307 &transmit_ready_callback_wrapper,
1308 client);
1309 return &client->th;
1310}
1311
1312
1313/**
1314 * Abort transmission request.
1315 *
1316 * @param th request to abort
1317 */
1318void
1319GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th)
1320{
1321 GNUNET_CONNECTION_notify_transmit_ready_cancel (th->cth);
1322 th->cth = NULL;
1323 th->callback = NULL;
1271} 1324}
1272 1325
1273 1326
diff --git a/src/util/server_nc.c b/src/util/server_nc.c
index 08ffd4b0c..9717a4516 100644
--- a/src/util/server_nc.c
+++ b/src/util/server_nc.c
@@ -92,7 +92,7 @@ struct ClientList
92 /** 92 /**
93 * Handle for pending transmission request to the client (or NULL). 93 * Handle for pending transmission request to the client (or NULL).
94 */ 94 */
95 struct GNUNET_CONNECTION_TransmitHandle *th; 95 struct GNUNET_SERVER_TransmitHandle *th;
96 96
97 /** 97 /**
98 * Head of linked list of requests queued for transmission. 98 * Head of linked list of requests queued for transmission.
@@ -187,7 +187,7 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
187 } 187 }
188 if (pos->th != NULL) 188 if (pos->th != NULL)
189 { 189 {
190 GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->th); 190 GNUNET_SERVER_notify_transmit_ready_cancel (pos->th);
191 pos->th = NULL; 191 pos->th = NULL;
192 } 192 }
193 GNUNET_SERVER_client_drop (client); 193 GNUNET_SERVER_client_drop (client);
diff --git a/src/util/test_connection.c b/src/util/test_connection.c
index 8664ca16f..4568f8ecb 100644
--- a/src/util/test_connection.c
+++ b/src/util/test_connection.c
@@ -103,6 +103,7 @@ receive_check (void *cls, const void *buf, size_t available,
103#endif 103#endif
104 *ok = 0; 104 *ok = 0;
105 GNUNET_CONNECTION_destroy (asock); 105 GNUNET_CONNECTION_destroy (asock);
106 GNUNET_CONNECTION_destroy (csock);
106 } 107 }
107} 108}
108 109
@@ -142,7 +143,6 @@ make_hello (void *cls, size_t size, void *buf)
142#if VERBOSE 143#if VERBOSE
143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys client socket\n"); 144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys client socket\n");
144#endif 145#endif
145 GNUNET_CONNECTION_destroy (csock);
146 return 12; 146 return 12;
147} 147}
148 148
diff --git a/src/util/test_service.c b/src/util/test_service.c
index 716e90d78..83fbdec95 100644
--- a/src/util/test_service.c
+++ b/src/util/test_service.c
@@ -41,18 +41,18 @@ static struct GNUNET_SERVICE_Context *sctx;
41 41
42static int ok = 1; 42static int ok = 1;
43 43
44static struct GNUNET_CLIENT_Connection *client;
45
44 46
45static size_t 47static size_t
46build_msg (void *cls, size_t size, void *buf) 48build_msg (void *cls, size_t size, void *buf)
47{ 49{
48 struct GNUNET_CLIENT_Connection *client = cls;
49 struct GNUNET_MessageHeader *msg = buf; 50 struct GNUNET_MessageHeader *msg = buf;
50 51
51 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected, transmitting\n"); 52 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected, transmitting\n");
52 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); 53 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
53 msg->type = htons (MY_TYPE); 54 msg->type = htons (MY_TYPE);
54 msg->size = htons (sizeof (struct GNUNET_MessageHeader)); 55 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
55 GNUNET_CLIENT_disconnect (client);
56 return sizeof (struct GNUNET_MessageHeader); 56 return sizeof (struct GNUNET_MessageHeader);
57} 57}
58 58
@@ -72,23 +72,24 @@ ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
72 GNUNET_CLIENT_notify_transmit_ready (client, 72 GNUNET_CLIENT_notify_transmit_ready (client,
73 sizeof (struct GNUNET_MessageHeader), 73 sizeof (struct GNUNET_MessageHeader),
74 GNUNET_TIME_UNIT_SECONDS, GNUNET_NO, 74 GNUNET_TIME_UNIT_SECONDS, GNUNET_NO,
75 &build_msg, client); 75 &build_msg, NULL);
76} 76}
77 77
78 78
79static void 79static void
80do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 80do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
81{ 81{
82 GNUNET_CLIENT_disconnect (client);
82 GNUNET_SERVICE_stop (sctx); 83 GNUNET_SERVICE_stop (sctx);
83} 84}
84 85
85 86
86static void 87static void
87recv_cb (void *cls, struct GNUNET_SERVER_Client *client, 88recv_cb (void *cls, struct GNUNET_SERVER_Client *sc,
88 const struct GNUNET_MessageHeader *message) 89 const struct GNUNET_MessageHeader *message)
89{ 90{
90 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving client message...\n"); 91 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving client message...\n");
91 GNUNET_SERVER_receive_done (client, GNUNET_OK); 92 GNUNET_SERVER_receive_done (sc, GNUNET_OK);
92 if (sctx != NULL) 93 if (sctx != NULL)
93 GNUNET_SCHEDULER_add_now (&do_stop, NULL); 94 GNUNET_SCHEDULER_add_now (&do_stop, NULL);
94 else 95 else
@@ -146,7 +147,6 @@ static void
146ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 147ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
147{ 148{
148 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 149 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
149 struct GNUNET_CLIENT_Connection *client;
150 150
151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 ready\n"); 151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 ready\n");
152 GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); 152 GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE));
@@ -156,7 +156,7 @@ ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
156 GNUNET_CLIENT_notify_transmit_ready (client, 156 GNUNET_CLIENT_notify_transmit_ready (client,
157 sizeof (struct GNUNET_MessageHeader), 157 sizeof (struct GNUNET_MessageHeader),
158 GNUNET_TIME_UNIT_SECONDS, GNUNET_NO, 158 GNUNET_TIME_UNIT_SECONDS, GNUNET_NO,
159 &build_msg, client); 159 &build_msg, NULL);
160} 160}
161 161
162static void 162static void