diff options
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | src/core/gnunet-service-core.c | 2 | ||||
-rw-r--r-- | src/datastore/gnunet-service-datastore.c | 2 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs.c | 2 | ||||
-rw-r--r-- | src/include/gnunet_server_lib.h | 9 | ||||
-rw-r--r-- | src/peerinfo/gnunet-service-peerinfo.c | 259 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport.c | 2 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 2 | ||||
-rw-r--r-- | src/util/server.c | 1 | ||||
-rw-r--r-- | src/util/server_nc.c | 12 | ||||
-rw-r--r-- | src/util/test_server_disconnect.c | 2 | ||||
-rw-r--r-- | src/util/test_server_with_client.c | 2 |
12 files changed, 91 insertions, 211 deletions
@@ -18,8 +18,8 @@ Urgent items (before announcing ng.gnunet.org): | |||
18 | of having each service queue messages and "send when ready", | 18 | of having each service queue messages and "send when ready", |
19 | simply have a way to add a client to the notification set | 19 | simply have a way to add a client to the notification set |
20 | and to 'notify client' or 'notify all clients' | 20 | and to 'notify client' or 'notify all clients' |
21 | (useful for peerinfo (new hellos), transport (our hello; blacklist), | 21 | (transport (our hello), |
22 | core (misc monitoring features), statistics (change notifications) | 22 | core (misc monitoring features) |
23 | and likely others) | 23 | and likely others) |
24 | - server/service API change for ARM inetd'ing | 24 | - server/service API change for ARM inetd'ing |
25 | (listen as well as support for start with multiple, already | 25 | (listen as well as support for start with multiple, already |
@@ -66,7 +66,8 @@ Urgent items (before announcing ng.gnunet.org): | |||
66 | (async peerinfo would not be right) | 66 | (async peerinfo would not be right) |
67 | - OS: existing waitpid call is not nice (not integratable with scheduler! fix this!) | 67 | - OS: existing waitpid call is not nice (not integratable with scheduler! fix this!) |
68 | * STATISTICS: | 68 | * STATISTICS: |
69 | - synchronous/asynchronous API (& implementation) is not nice | 69 | - synchronous/asynchronous API (& implementation) is not nice; |
70 | => provide notification-based API | ||
70 | - does not seem to work with timeouts (especially if service is not running) | 71 | - does not seem to work with timeouts (especially if service is not running) |
71 | * ARM: | 72 | * ARM: |
72 | - need to get rid of synchronous API for service starts (cause all kinds of problems) | 73 | - need to get rid of synchronous API for service starts (cause all kinds of problems) |
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index 32b39fd7f..915217ea1 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c | |||
@@ -1034,6 +1034,8 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
1034 | struct Client *prev; | 1034 | struct Client *prev; |
1035 | struct Event *e; | 1035 | struct Event *e; |
1036 | 1036 | ||
1037 | if (client == NULL) | ||
1038 | return; | ||
1037 | #if DEBUG_CORE_CLIENT | 1039 | #if DEBUG_CORE_CLIENT |
1038 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1040 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1039 | "Client has disconnected from core service.\n"); | 1041 | "Client has disconnected from core service.\n"); |
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c index 1766ef96c..161fbc1d8 100644 --- a/src/datastore/gnunet-service-datastore.c +++ b/src/datastore/gnunet-service-datastore.c | |||
@@ -1233,6 +1233,8 @@ cleanup_reservations (void *cls, | |||
1233 | struct ReservationList *prev; | 1233 | struct ReservationList *prev; |
1234 | struct ReservationList *next; | 1234 | struct ReservationList *next; |
1235 | 1235 | ||
1236 | if (client == NULL) | ||
1237 | return; | ||
1236 | prev = NULL; | 1238 | prev = NULL; |
1237 | pos = reservations; | 1239 | pos = reservations; |
1238 | while (NULL != pos) | 1240 | while (NULL != pos) |
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index 541f656c6..b8855632c 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c | |||
@@ -2273,6 +2273,8 @@ handle_client_disconnect (void *cls, | |||
2273 | struct ClientList *cprev; | 2273 | struct ClientList *cprev; |
2274 | struct ClientRequestList *rl; | 2274 | struct ClientRequestList *rl; |
2275 | 2275 | ||
2276 | if (client == NULL) | ||
2277 | return; | ||
2276 | lgc = lgc_head; | 2278 | lgc = lgc_head; |
2277 | while ( (NULL != lgc) && | 2279 | while ( (NULL != lgc) && |
2278 | (lgc->client != client) ) | 2280 | (lgc->client != client) ) |
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h index 100dc9659..5609d7a9e 100644 --- a/src/include/gnunet_server_lib.h +++ b/src/include/gnunet_server_lib.h | |||
@@ -394,7 +394,8 @@ int GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, | |||
394 | * is disconnected on the network level. | 394 | * is disconnected on the network level. |
395 | * | 395 | * |
396 | * @param cls closure | 396 | * @param cls closure |
397 | * @param client identification of the client | 397 | * @param client identification of the client; NULL |
398 | * for the last call when the server is destroyed | ||
398 | */ | 399 | */ |
399 | typedef void (*GNUNET_SERVER_DisconnectCallback) (void *cls, | 400 | typedef void (*GNUNET_SERVER_DisconnectCallback) (void *cls, |
400 | struct GNUNET_SERVER_Client | 401 | struct GNUNET_SERVER_Client |
@@ -405,7 +406,11 @@ typedef void (*GNUNET_SERVER_DisconnectCallback) (void *cls, | |||
405 | * Ask the server to notify us whenever a client disconnects. | 406 | * Ask the server to notify us whenever a client disconnects. |
406 | * This function is called whenever the actual network connection | 407 | * This function is called whenever the actual network connection |
407 | * is closed; the reference count may be zero or larger than zero | 408 | * is closed; the reference count may be zero or larger than zero |
408 | * at this point. | 409 | * at this point. If the server is destroyed before this |
410 | * notification is explicitly cancelled, the 'callback' will | ||
411 | * once be called with a 'client' argument of NULL to indicate | ||
412 | * that the server itself is now gone (and that the callback | ||
413 | * won't be called anymore and also can no longer be cancelled). | ||
409 | * | 414 | * |
410 | * @param server the server manageing the clients | 415 | * @param server the server manageing the clients |
411 | * @param callback function to call on disconnect | 416 | * @param callback function to call on disconnect |
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c index 2f3e2c8e1..5b2b999d6 100644 --- a/src/peerinfo/gnunet-service-peerinfo.c +++ b/src/peerinfo/gnunet-service-peerinfo.c | |||
@@ -89,54 +89,6 @@ struct HostEntry | |||
89 | 89 | ||
90 | 90 | ||
91 | /** | 91 | /** |
92 | * Entries that we still need to tell the client about. | ||
93 | */ | ||
94 | struct PendingEntry | ||
95 | { | ||
96 | |||
97 | /** | ||
98 | * This is a linked list. | ||
99 | */ | ||
100 | struct PendingEntry *next; | ||
101 | |||
102 | /** | ||
103 | * Entry to tell the client about. | ||
104 | */ | ||
105 | struct HostEntry *he; | ||
106 | |||
107 | }; | ||
108 | |||
109 | |||
110 | /** | ||
111 | * Clients to notify of changes to the peer information. | ||
112 | */ | ||
113 | struct NotifyList | ||
114 | { | ||
115 | |||
116 | /** | ||
117 | * This is a linked list. | ||
118 | */ | ||
119 | struct NotifyList *next; | ||
120 | |||
121 | /** | ||
122 | * Client to notify. | ||
123 | */ | ||
124 | struct GNUNET_SERVER_Client *client; | ||
125 | |||
126 | /** | ||
127 | * Notifications pending for this entry. | ||
128 | */ | ||
129 | struct PendingEntry *pending; | ||
130 | |||
131 | /** | ||
132 | * Handle for a transmit ready request. | ||
133 | */ | ||
134 | struct GNUNET_CONNECTION_TransmitHandle *transmit_ctx; | ||
135 | |||
136 | }; | ||
137 | |||
138 | |||
139 | /** | ||
140 | * The in-memory list of known hosts. | 92 | * The in-memory list of known hosts. |
141 | */ | 93 | */ |
142 | static struct HostEntry *hosts; | 94 | static struct HostEntry *hosts; |
@@ -144,7 +96,7 @@ static struct HostEntry *hosts; | |||
144 | /** | 96 | /** |
145 | * Clients to immediately notify about all changes. | 97 | * Clients to immediately notify about all changes. |
146 | */ | 98 | */ |
147 | static struct NotifyList *notify_list; | 99 | static struct GNUNET_SERVER_NotificationContext *notify_list; |
148 | 100 | ||
149 | /** | 101 | /** |
150 | * Directory where the hellos are stored in (data/hosts) | 102 | * Directory where the hellos are stored in (data/hosts) |
@@ -158,116 +110,23 @@ static char *trustDirectory; | |||
158 | 110 | ||
159 | 111 | ||
160 | /** | 112 | /** |
161 | * Transmit peer information messages from the pending queue | ||
162 | * to the client. | ||
163 | * | ||
164 | * @param cls the 'struct NotifyList' that we are processing | ||
165 | * @param size number of bytes we can transmit | ||
166 | * @param vbuf where to write the messages | ||
167 | * @return number of bytes written to vbuf | ||
168 | */ | ||
169 | static size_t | ||
170 | transmit_pending_notification (void *cls, | ||
171 | size_t size, | ||
172 | void *vbuf) | ||
173 | { | ||
174 | struct NotifyList *nl = cls; | ||
175 | char *buf = vbuf; | ||
176 | struct PendingEntry *pos; | ||
177 | struct PendingEntry *next; | ||
178 | struct InfoMessage im; | ||
179 | uint16_t hs; | ||
180 | size_t left; | ||
181 | |||
182 | nl->transmit_ctx = NULL; | ||
183 | next = nl->pending; | ||
184 | pos = nl->pending; | ||
185 | left = size; | ||
186 | while (pos != NULL) | ||
187 | { | ||
188 | hs = (pos->he->hello == NULL) ? 0 : GNUNET_HELLO_size (pos->he->hello); | ||
189 | if (left < sizeof (struct InfoMessage) + hs) | ||
190 | break; | ||
191 | next = pos->next; | ||
192 | im.header.size = htons (hs + sizeof (struct InfoMessage)); | ||
193 | im.header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); | ||
194 | im.trust = htonl (pos->he->trust); | ||
195 | im.peer = pos->he->identity; | ||
196 | memcpy (&buf[size - left], &im, sizeof (struct InfoMessage)); | ||
197 | memcpy (&buf[size - left + sizeof (struct InfoMessage)], pos->he->hello, hs); | ||
198 | left -= hs + sizeof (struct InfoMessage); | ||
199 | GNUNET_free (pos); | ||
200 | pos = next; | ||
201 | } | ||
202 | nl->pending = next; | ||
203 | if (nl->pending != NULL) | ||
204 | { | ||
205 | nl->transmit_ctx | ||
206 | = GNUNET_SERVER_notify_transmit_ready (nl->client, | ||
207 | sizeof (struct InfoMessage) + hs, | ||
208 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
209 | &transmit_pending_notification, | ||
210 | nl); | ||
211 | } | ||
212 | return size - left; | ||
213 | } | ||
214 | |||
215 | |||
216 | |||
217 | /** | ||
218 | * Notify client about host change. Checks if the | ||
219 | * respective host entry is already in the list of things | ||
220 | * to send to the client, and if not, adds it. Also | ||
221 | * triggers a new request for transmission if the pending | ||
222 | * list was previously empty. | ||
223 | * | ||
224 | * @param nl client to notify | ||
225 | * @param he entry to notify about | ||
226 | */ | ||
227 | static void | ||
228 | do_notify (struct NotifyList *nl, | ||
229 | struct HostEntry *he) | ||
230 | { | ||
231 | struct PendingEntry *pe; | ||
232 | uint16_t hsize; | ||
233 | |||
234 | pe = nl->pending; | ||
235 | while (NULL != pe) | ||
236 | { | ||
237 | if (pe->he == he) | ||
238 | return; /* already in list */ | ||
239 | pe = pe->next; | ||
240 | } | ||
241 | pe = GNUNET_malloc (sizeof (struct PendingEntry)); | ||
242 | pe->next = nl->pending; | ||
243 | pe->he = he; | ||
244 | nl->pending = pe; | ||
245 | if (nl->transmit_ctx != NULL) | ||
246 | return; /* already trying to transmit */ | ||
247 | hsize = (he->hello == NULL) ? 0 : GNUNET_HELLO_size (he->hello); | ||
248 | nl->transmit_ctx = GNUNET_SERVER_notify_transmit_ready (nl->client, | ||
249 | sizeof (struct InfoMessage) + hsize, | ||
250 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
251 | &transmit_pending_notification, | ||
252 | nl); | ||
253 | } | ||
254 | |||
255 | |||
256 | /** | ||
257 | * Notify all clients in the notify list about the | 113 | * Notify all clients in the notify list about the |
258 | * given host entry changing. | 114 | * given host entry changing. |
259 | */ | 115 | */ |
260 | static void | 116 | static struct InfoMessage * |
261 | notify_all (struct HostEntry *he) | 117 | make_info_message (const struct HostEntry *he) |
262 | { | 118 | { |
263 | struct NotifyList *nl; | 119 | struct InfoMessage *im; |
264 | 120 | size_t hs; | |
265 | nl = notify_list; | 121 | |
266 | while (NULL != nl) | 122 | hs = (he->hello == NULL) ? 0 : GNUNET_HELLO_size (he->hello); |
267 | { | 123 | im = GNUNET_malloc (sizeof (struct InfoMessage) + hs); |
268 | do_notify (nl, he); | 124 | im->header.size = htons (hs + sizeof (struct InfoMessage)); |
269 | nl = nl->next; | 125 | im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); |
270 | } | 126 | im->trust = htonl (he->trust); |
127 | im->peer = he->identity; | ||
128 | memcpy (&im[1], he->hello, hs); | ||
129 | return im; | ||
271 | } | 130 | } |
272 | 131 | ||
273 | 132 | ||
@@ -328,6 +187,7 @@ get_trust_filename (const struct GNUNET_PeerIdentity *id) | |||
328 | return fn; | 187 | return fn; |
329 | } | 188 | } |
330 | 189 | ||
190 | |||
331 | /** | 191 | /** |
332 | * Find the host entry for the given peer. Call | 192 | * Find the host entry for the given peer. Call |
333 | * only when synchronized! | 193 | * only when synchronized! |
@@ -348,6 +208,25 @@ lookup_host_entry (const struct GNUNET_PeerIdentity *id) | |||
348 | 208 | ||
349 | 209 | ||
350 | /** | 210 | /** |
211 | * Broadcast information about the given entry to all | ||
212 | * clients that care. | ||
213 | * | ||
214 | * @param entry entry to broadcast about | ||
215 | */ | ||
216 | static void | ||
217 | notify_all (struct HostEntry *entry) | ||
218 | { | ||
219 | struct InfoMessage *msg; | ||
220 | |||
221 | msg = make_info_message (entry); | ||
222 | GNUNET_SERVER_notification_context_broadcast (notify_list, | ||
223 | &msg->header, | ||
224 | GNUNET_NO); | ||
225 | GNUNET_free (msg); | ||
226 | } | ||
227 | |||
228 | |||
229 | /** | ||
351 | * Add a host to the list. | 230 | * Add a host to the list. |
352 | * | 231 | * |
353 | * @param identity the identity of the host | 232 | * @param identity the identity of the host |
@@ -451,7 +330,7 @@ change_host_trust (const struct GNUNET_PeerIdentity *hostId, int value) | |||
451 | host->trust += value; | 330 | host->trust += value; |
452 | } | 331 | } |
453 | if (host->trust != old_trust) | 332 | if (host->trust != old_trust) |
454 | notify_all (host); | 333 | notify_all (host); |
455 | return value; | 334 | return value; |
456 | } | 335 | } |
457 | 336 | ||
@@ -834,18 +713,20 @@ handle_notify (void *cls, | |||
834 | struct GNUNET_SERVER_Client *client, | 713 | struct GNUNET_SERVER_Client *client, |
835 | const struct GNUNET_MessageHeader *message) | 714 | const struct GNUNET_MessageHeader *message) |
836 | { | 715 | { |
837 | struct NotifyList *nl; | 716 | struct InfoMessage *msg; |
838 | struct HostEntry *pos; | 717 | struct HostEntry *pos; |
839 | 718 | ||
840 | nl = GNUNET_malloc (sizeof (struct NotifyList)); | 719 | GNUNET_SERVER_notification_context_add (notify_list, |
841 | nl->next = notify_list; | 720 | client); |
842 | nl->client = client; | ||
843 | GNUNET_SERVER_client_keep (client); | ||
844 | notify_list = nl; | ||
845 | pos = hosts; | 721 | pos = hosts; |
846 | while (NULL != pos) | 722 | while (NULL != pos) |
847 | { | 723 | { |
848 | do_notify (nl, pos); | 724 | msg = make_info_message (pos); |
725 | GNUNET_SERVER_notification_context_unicast (notify_list, | ||
726 | client, | ||
727 | &msg->header, | ||
728 | GNUNET_NO); | ||
729 | GNUNET_free (msg); | ||
849 | pos = pos->next; | 730 | pos = pos->next; |
850 | } | 731 | } |
851 | } | 732 | } |
@@ -868,48 +749,17 @@ static struct GNUNET_SERVER_MessageHandler handlers[] = { | |||
868 | 749 | ||
869 | 750 | ||
870 | /** | 751 | /** |
871 | * Function that is called when a client disconnects. | 752 | * Clean up our state. Called during shutdown. |
753 | * | ||
754 | * @param cls unused | ||
755 | * @param tc scheduler task context, unused | ||
872 | */ | 756 | */ |
873 | static void | 757 | static void |
874 | notify_disconnect (void *cls, | 758 | shutdown_task (void *cls, |
875 | struct GNUNET_SERVER_Client *client) | 759 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
876 | { | 760 | { |
877 | struct NotifyList *pos; | 761 | GNUNET_SERVER_notification_context_destroy (notify_list); |
878 | struct NotifyList *prev; | 762 | notify_list = NULL; |
879 | struct NotifyList *next; | ||
880 | struct PendingEntry *p; | ||
881 | |||
882 | pos = notify_list; | ||
883 | prev = NULL; | ||
884 | while (pos != NULL) | ||
885 | { | ||
886 | next = pos->next; | ||
887 | if (pos->client == client) | ||
888 | { | ||
889 | while (NULL != (p = pos->pending)) | ||
890 | { | ||
891 | pos->pending = p->next; | ||
892 | GNUNET_free (p); | ||
893 | } | ||
894 | if (pos->transmit_ctx != NULL) | ||
895 | { | ||
896 | GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->transmit_ctx); | ||
897 | pos->transmit_ctx = NULL; | ||
898 | } | ||
899 | if (prev == NULL) | ||
900 | notify_list = next; | ||
901 | else | ||
902 | prev->next = next; | ||
903 | GNUNET_SERVER_client_drop (client); | ||
904 | GNUNET_free (pos); | ||
905 | } | ||
906 | else | ||
907 | { | ||
908 | prev = pos; | ||
909 | } | ||
910 | pos = next; | ||
911 | } | ||
912 | |||
913 | } | 763 | } |
914 | 764 | ||
915 | 765 | ||
@@ -927,6 +777,7 @@ run (void *cls, | |||
927 | struct GNUNET_SERVER_Handle *server, | 777 | struct GNUNET_SERVER_Handle *server, |
928 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 778 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
929 | { | 779 | { |
780 | notify_list = GNUNET_SERVER_notification_context_create (server, 0); | ||
930 | GNUNET_assert (GNUNET_OK == | 781 | GNUNET_assert (GNUNET_OK == |
931 | GNUNET_CONFIGURATION_get_value_filename (cfg, | 782 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
932 | "peerinfo", | 783 | "peerinfo", |
@@ -948,7 +799,9 @@ run (void *cls, | |||
948 | GNUNET_SCHEDULER_add_with_priority (sched, | 799 | GNUNET_SCHEDULER_add_with_priority (sched, |
949 | GNUNET_SCHEDULER_PRIORITY_IDLE, | 800 | GNUNET_SCHEDULER_PRIORITY_IDLE, |
950 | &cron_clean_data_hosts, NULL); | 801 | &cron_clean_data_hosts, NULL); |
951 | GNUNET_SERVER_disconnect_notify (server, ¬ify_disconnect, NULL); | 802 | GNUNET_SCHEDULER_add_delayed (sched, |
803 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
804 | &shutdown_task, NULL); | ||
952 | GNUNET_SERVER_add_handlers (server, handlers); | 805 | GNUNET_SERVER_add_handlers (server, handlers); |
953 | } | 806 | } |
954 | 807 | ||
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index b05e8360a..fe8b5043e 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -2743,6 +2743,8 @@ client_disconnect_notification (void *cls, | |||
2743 | struct TransportClient *prev; | 2743 | struct TransportClient *prev; |
2744 | struct ClientMessageQueueEntry *mqe; | 2744 | struct ClientMessageQueueEntry *mqe; |
2745 | 2745 | ||
2746 | if (client == NULL) | ||
2747 | return; | ||
2746 | #if DEBUG_TRANSPORT | 2748 | #if DEBUG_TRANSPORT |
2747 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | 2749 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, |
2748 | "Client disconnected, cleaning up.\n"); | 2750 | "Client disconnected, cleaning up.\n"); |
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 23ed867b7..51b1ce5e1 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -1146,6 +1146,8 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) | |||
1146 | struct Plugin *plugin = cls; | 1146 | struct Plugin *plugin = cls; |
1147 | struct Session *session; | 1147 | struct Session *session; |
1148 | 1148 | ||
1149 | if (client == NULL) | ||
1150 | return; | ||
1149 | session = find_session_by_client (plugin, client); | 1151 | session = find_session_by_client (plugin, client); |
1150 | if (session == NULL) | 1152 | if (session == NULL) |
1151 | return; /* unknown, nothing to do */ | 1153 | return; /* unknown, nothing to do */ |
diff --git a/src/util/server.c b/src/util/server.c index adc19ecb7..6f2ffe232 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -538,6 +538,7 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) | |||
538 | } | 538 | } |
539 | while (NULL != (npos = s->disconnect_notify_list)) | 539 | while (NULL != (npos = s->disconnect_notify_list)) |
540 | { | 540 | { |
541 | npos->callback (npos->callback_cls, NULL); | ||
541 | s->disconnect_notify_list = npos->next; | 542 | s->disconnect_notify_list = npos->next; |
542 | GNUNET_free (npos); | 543 | GNUNET_free (npos); |
543 | } | 544 | } |
diff --git a/src/util/server_nc.c b/src/util/server_nc.c index 9b6eefe1f..05a4913a8 100644 --- a/src/util/server_nc.c +++ b/src/util/server_nc.c | |||
@@ -146,6 +146,11 @@ handle_client_disconnect (void *cls, | |||
146 | struct ClientList *prev; | 146 | struct ClientList *prev; |
147 | struct PendingMessageList *pml; | 147 | struct PendingMessageList *pml; |
148 | 148 | ||
149 | if (client == NULL) | ||
150 | { | ||
151 | nc->server = NULL; | ||
152 | return; | ||
153 | } | ||
149 | prev = NULL; | 154 | prev = NULL; |
150 | pos = nc->clients; | 155 | pos = nc->clients; |
151 | while (NULL != pos) | 156 | while (NULL != pos) |
@@ -219,9 +224,10 @@ GNUNET_SERVER_notification_context_destroy (struct GNUNET_SERVER_NotificationCon | |||
219 | } | 224 | } |
220 | GNUNET_free (pos); | 225 | GNUNET_free (pos); |
221 | } | 226 | } |
222 | GNUNET_SERVER_disconnect_notify_cancel (nc->server, | 227 | if (nc->server != NULL) |
223 | &handle_client_disconnect, | 228 | GNUNET_SERVER_disconnect_notify_cancel (nc->server, |
224 | nc); | 229 | &handle_client_disconnect, |
230 | nc); | ||
225 | GNUNET_free (nc); | 231 | GNUNET_free (nc); |
226 | } | 232 | } |
227 | 233 | ||
diff --git a/src/util/test_server_disconnect.c b/src/util/test_server_disconnect.c index 76a73d348..b10719e73 100644 --- a/src/util/test_server_disconnect.c +++ b/src/util/test_server_disconnect.c | |||
@@ -138,6 +138,8 @@ disconnect_notify (void *cls, const struct GNUNET_MessageHeader *msg) | |||
138 | static void | 138 | static void |
139 | notify_disconnect (void *cls, struct GNUNET_SERVER_Client *clientarg) | 139 | notify_disconnect (void *cls, struct GNUNET_SERVER_Client *clientarg) |
140 | { | 140 | { |
141 | if (clientarg == NULL) | ||
142 | return; | ||
141 | GNUNET_assert (ok == 6); | 143 | GNUNET_assert (ok == 6); |
142 | ok++; | 144 | ok++; |
143 | GNUNET_CLIENT_receive (client, | 145 | GNUNET_CLIENT_receive (client, |
diff --git a/src/util/test_server_with_client.c b/src/util/test_server_with_client.c index 68b842ef8..adce0b432 100644 --- a/src/util/test_server_with_client.c +++ b/src/util/test_server_with_client.c | |||
@@ -123,6 +123,8 @@ clean_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
123 | static void | 123 | static void |
124 | notify_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | 124 | notify_disconnect (void *cls, struct GNUNET_SERVER_Client *client) |
125 | { | 125 | { |
126 | if (client == NULL) | ||
127 | return; | ||
126 | GNUNET_assert (ok == 5); | 128 | GNUNET_assert (ok == 5); |
127 | ok = 0; | 129 | ok = 0; |
128 | GNUNET_SCHEDULER_add_now (sched, | 130 | GNUNET_SCHEDULER_add_now (sched, |