diff options
-rw-r--r-- | TODO | 44 | ||||
-rw-r--r-- | src/include/gnunet_server_lib.h | 91 | ||||
-rw-r--r-- | src/peerinfo/gnunet-service-peerinfo.c | 2 | ||||
-rw-r--r-- | src/util/Makefile.am | 1 | ||||
-rw-r--r-- | src/util/server.c | 39 | ||||
-rw-r--r-- | src/util/server_nc.c | 218 |
6 files changed, 381 insertions, 14 deletions
@@ -12,24 +12,40 @@ away), in order in which they will likely be done: | |||
12 | * UPNP [Milan] | 12 | * UPNP [Milan] |
13 | 13 | ||
14 | Urgent items (before announcing ng.gnunet.org): | 14 | Urgent items (before announcing ng.gnunet.org): |
15 | * UTIL: | ||
16 | - provide higher-level convenience API for servers/services that | ||
17 | need to send a stream of notifications to clients; instead | ||
18 | of having each service queue messages and "send when ready", | ||
19 | simply have a way to add a client to the notification set | ||
20 | and to 'notify client' or 'notify all clients' | ||
21 | (useful for peerinfo (new hellos), transport (our hello; blacklist), | ||
22 | core (misc monitoring features), statistics (change notifications) | ||
23 | and likely others) | ||
24 | - server/service API change for ARM inetd'ing | ||
25 | (listen as well as support for start with multiple, already | ||
26 | bound & listening sockets!) | ||
27 | * TRANSPORT: | ||
28 | - main service not implemented [Nate] | ||
29 | - blacklist not implemented [Christian] | ||
30 | - testcases crash & burn (no surprise) | ||
15 | * CORE: | 31 | * CORE: |
16 | - test currently fails spectacularly | 32 | - request disconnect not implemented [Christian] |
17 | - request disconnect not implemented | 33 | - various notification options not implemented [Christian] |
18 | - request connect not working | 34 | - test currently fails spectacularly [segv of transport service] |
19 | - various notification options not implemented | 35 | => need transport to work first! |
20 | * topology | 36 | - request connect not working [Christian, need transport first] |
21 | - (forced) disconnect does not work as implemented (still?) | 37 | * PEERINFO: |
22 | - needs testing (not sure the current testcase does much...) | 38 | - make sue we also trigger notifications whenever HELLOs expire |
23 | * testing: | 39 | * TOPOLOGY: |
24 | - timeout_hello_task is not used but should be (so we can fail | 40 | - needs testing [need transport first] |
25 | properly) | 41 | * TESTING: |
26 | - check that 'GNUNET_TRANSPORT_get_hello' is associated with | 42 | - check that 'GNUNET_TRANSPORT_get_hello' is associated with |
27 | a TIMEOUT task wherever else appropriate (other testcases | 43 | a cancel request wherever appropriate (other testcases |
28 | in particular!) | 44 | in particular!) [Christian] |
29 | * hostlist | 45 | * HOSTLIST: |
30 | - test fails (looks like it works, but that's because of a bad | 46 | - test fails (looks like it works, but that's because of a bad |
31 | connectivity notification; somehow core is unable to send | 47 | connectivity notification; somehow core is unable to send |
32 | messages successfully via transport) | 48 | messages successfully via transport) [need transport first] |
33 | * FS (basic anonymous FS only) | 49 | * FS (basic anonymous FS only) |
34 | - implement FS service (P2P operations) | 50 | - implement FS service (P2P operations) |
35 | + how to send queries (soliciting is not there in core; do we | 51 | + how to send queries (soliciting is not there in core; do we |
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h index ecfead5ab..100dc9659 100644 --- a/src/include/gnunet_server_lib.h +++ b/src/include/gnunet_server_lib.h | |||
@@ -138,6 +138,8 @@ struct GNUNET_SERVER_Handle *GNUNET_SERVER_create (struct | |||
138 | 138 | ||
139 | /** | 139 | /** |
140 | * Free resources held by this server. | 140 | * Free resources held by this server. |
141 | * | ||
142 | * @param s server to destroy | ||
141 | */ | 143 | */ |
142 | void GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s); | 144 | void GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s); |
143 | 145 | ||
@@ -192,6 +194,7 @@ struct GNUNET_CONNECTION_TransmitHandle | |||
192 | * @param client client we were processing a message of | 194 | * @param client client we were processing a message of |
193 | * @param success GNUNET_OK to keep the connection open and | 195 | * @param success GNUNET_OK to keep the connection open and |
194 | * continue to receive | 196 | * continue to receive |
197 | * GNUNET_NO to close the connection (normal behavior) | ||
195 | * GNUNET_SYSERR to close the connection (signal | 198 | * GNUNET_SYSERR to close the connection (signal |
196 | * serious error) | 199 | * serious error) |
197 | */ | 200 | */ |
@@ -414,6 +417,18 @@ void GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, | |||
414 | 417 | ||
415 | 418 | ||
416 | /** | 419 | /** |
420 | * Ask the server to stop notifying us whenever a client disconnects. | ||
421 | * | ||
422 | * @param server the server manageing the clients | ||
423 | * @param callback function to call on disconnect | ||
424 | * @param callback_cls closure for callback | ||
425 | */ | ||
426 | void GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, | ||
427 | GNUNET_SERVER_DisconnectCallback | ||
428 | callback, void *callback_cls); | ||
429 | |||
430 | |||
431 | /** | ||
417 | * Ask the server to disconnect from the given client. | 432 | * Ask the server to disconnect from the given client. |
418 | * This is the same as returning GNUNET_SYSERR from a message | 433 | * This is the same as returning GNUNET_SYSERR from a message |
419 | * handler, except that it allows dropping of a client even | 434 | * handler, except that it allows dropping of a client even |
@@ -440,6 +455,7 @@ GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, | |||
440 | int do_ignore); | 455 | int do_ignore); |
441 | 456 | ||
442 | 457 | ||
458 | |||
443 | /** | 459 | /** |
444 | * The tansmit context is the key datastructure for a conveniance API | 460 | * The tansmit context is the key datastructure for a conveniance API |
445 | * used for transmission of complex results to the client followed | 461 | * used for transmission of complex results to the client followed |
@@ -490,6 +506,81 @@ GNUNET_SERVER_transmit_context_run (struct GNUNET_SERVER_TransmitContext *tc, | |||
490 | 506 | ||
491 | 507 | ||
492 | 508 | ||
509 | /** | ||
510 | * The notification context is the key datastructure for a conveniance | ||
511 | * API used for transmission of notifications to the client until the | ||
512 | * client disconnects (or the notification context is destroyed, in | ||
513 | * which case we disconnect these clients). Essentially, all | ||
514 | * (notification) messages are queued up until the client is able to | ||
515 | * read them. | ||
516 | */ | ||
517 | struct GNUNET_SERVER_NotificationContext; | ||
518 | |||
519 | |||
520 | /** | ||
521 | * Create a new notification context. | ||
522 | * | ||
523 | * @param server server for which this function creates the context | ||
524 | * @param queue_length maximum number of messages to keep in | ||
525 | * the notification queue; optional messages are dropped | ||
526 | * it the queue gets longer than this number of messages | ||
527 | * @return handle to the notification context | ||
528 | */ | ||
529 | struct GNUNET_SERVER_NotificationContext * | ||
530 | GNUNET_SERVER_notification_context_create (struct GNUNET_SERVER_Handle *server, | ||
531 | unsigned int queue_length); | ||
532 | |||
533 | |||
534 | /** | ||
535 | * Destroy the context, force disconnect for all clients. | ||
536 | * | ||
537 | * @param nc context to destroy. | ||
538 | */ | ||
539 | void | ||
540 | GNUNET_SERVER_notification_context_destroy (struct GNUNET_SERVER_NotificationContext *nc); | ||
541 | |||
542 | |||
543 | /** | ||
544 | * Add a client to the notification context. | ||
545 | * | ||
546 | * @param nc context to modify | ||
547 | * @param client client to add | ||
548 | */ | ||
549 | void | ||
550 | GNUNET_SERVER_notification_context_add (struct GNUNET_SERVER_NotificationContext *nc, | ||
551 | struct GNUNET_SERVER_Client *client); | ||
552 | |||
553 | |||
554 | /** | ||
555 | * Send a message to a particular client; must have | ||
556 | * already been added to the notification context. | ||
557 | * | ||
558 | * @param nc context to modify | ||
559 | * @param client client to transmit to | ||
560 | * @param msg message to send | ||
561 | * @param can_drop can this message be dropped due to queue length limitations | ||
562 | */ | ||
563 | void | ||
564 | GNUNET_SERVER_notification_context_unicast (struct GNUNET_SERVER_NotificationContext *nc, | ||
565 | struct GNUNET_SERVER_Client *client, | ||
566 | const struct GNUNET_MessageHeader *msg, | ||
567 | int can_drop); | ||
568 | |||
569 | |||
570 | /** | ||
571 | * Send a message to all clients of this context. | ||
572 | * | ||
573 | * @param nc context to modify | ||
574 | * @param msg message to send | ||
575 | * @param can_drop can this message be dropped due to queue length limitations | ||
576 | */ | ||
577 | void | ||
578 | GNUNET_SERVER_notification_context_broadcast (struct GNUNET_SERVER_NotificationContext *nc, | ||
579 | const struct GNUNET_MessageHeader *msg, | ||
580 | int can_drop); | ||
581 | |||
582 | |||
583 | |||
493 | #if 0 /* keep Emacsens' auto-indent happy */ | 584 | #if 0 /* keep Emacsens' auto-indent happy */ |
494 | { | 585 | { |
495 | #endif | 586 | #endif |
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c index f0d8b0606..2f3e2c8e1 100644 --- a/src/peerinfo/gnunet-service-peerinfo.c +++ b/src/peerinfo/gnunet-service-peerinfo.c | |||
@@ -103,6 +103,7 @@ struct PendingEntry | |||
103 | * Entry to tell the client about. | 103 | * Entry to tell the client about. |
104 | */ | 104 | */ |
105 | struct HostEntry *he; | 105 | struct HostEntry *he; |
106 | |||
106 | }; | 107 | }; |
107 | 108 | ||
108 | 109 | ||
@@ -131,6 +132,7 @@ struct NotifyList | |||
131 | * Handle for a transmit ready request. | 132 | * Handle for a transmit ready request. |
132 | */ | 133 | */ |
133 | struct GNUNET_CONNECTION_TransmitHandle *transmit_ctx; | 134 | struct GNUNET_CONNECTION_TransmitHandle *transmit_ctx; |
135 | |||
134 | }; | 136 | }; |
135 | 137 | ||
136 | 138 | ||
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index d4c35ccdb..037ab64b2 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -59,6 +59,7 @@ libgnunetutil_la_SOURCES = \ | |||
59 | resolver_api.c \ | 59 | resolver_api.c \ |
60 | scheduler.c \ | 60 | scheduler.c \ |
61 | server.c \ | 61 | server.c \ |
62 | server_nc.c \ | ||
62 | server_tc.c \ | 63 | server_tc.c \ |
63 | service.c \ | 64 | service.c \ |
64 | signal.c \ | 65 | signal.c \ |
diff --git a/src/util/server.c b/src/util/server.c index 036c8a441..adc19ecb7 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -1118,6 +1118,44 @@ GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, | |||
1118 | 1118 | ||
1119 | 1119 | ||
1120 | /** | 1120 | /** |
1121 | * Ask the server to stop notifying us whenever a client disconnects. | ||
1122 | * | ||
1123 | * @param server the server manageing the clients | ||
1124 | * @param callback function to call on disconnect | ||
1125 | * @param callback_cls closure for callback | ||
1126 | */ | ||
1127 | void | ||
1128 | GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, | ||
1129 | GNUNET_SERVER_DisconnectCallback callback, | ||
1130 | void *callback_cls) | ||
1131 | { | ||
1132 | struct NotifyList *pos; | ||
1133 | struct NotifyList *prev; | ||
1134 | |||
1135 | prev = NULL; | ||
1136 | pos = server->disconnect_notify_list; | ||
1137 | while (pos != NULL) | ||
1138 | { | ||
1139 | if ( (pos->callback == callback) && | ||
1140 | (pos->callback_cls == callback_cls ) ) | ||
1141 | break; | ||
1142 | prev = pos; | ||
1143 | pos = pos->next; | ||
1144 | } | ||
1145 | if (pos == NULL) | ||
1146 | { | ||
1147 | GNUNET_break (0); | ||
1148 | return; | ||
1149 | } | ||
1150 | if (prev == NULL) | ||
1151 | server->disconnect_notify_list = pos->next; | ||
1152 | else | ||
1153 | prev->next = pos->next; | ||
1154 | GNUNET_free (pos); | ||
1155 | } | ||
1156 | |||
1157 | |||
1158 | /** | ||
1121 | * Ask the server to disconnect from the given client. | 1159 | * Ask the server to disconnect from the given client. |
1122 | * This is the same as returning GNUNET_SYSERR from a message | 1160 | * This is the same as returning GNUNET_SYSERR from a message |
1123 | * handler, except that it allows dropping of a client even | 1161 | * handler, except that it allows dropping of a client even |
@@ -1171,6 +1209,7 @@ GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, | |||
1171 | * @param client client we were processing a message of | 1209 | * @param client client we were processing a message of |
1172 | * @param success GNUNET_OK to keep the connection open and | 1210 | * @param success GNUNET_OK to keep the connection open and |
1173 | * continue to receive | 1211 | * continue to receive |
1212 | * GNUNET_NO to close the connection (normal behavior) | ||
1174 | * GNUNET_SYSERR to close the connection (signal | 1213 | * GNUNET_SYSERR to close the connection (signal |
1175 | * serious error) | 1214 | * serious error) |
1176 | */ | 1215 | */ |
diff --git a/src/util/server_nc.c b/src/util/server_nc.c new file mode 100644 index 000000000..89e59b799 --- /dev/null +++ b/src/util/server_nc.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file util/server_nc.c | ||
23 | * @brief convenience functions for transmission of | ||
24 | * a notification stream | ||
25 | * @author Christian Grothoff | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_common.h" | ||
30 | #include "gnunet_connection_lib.h" | ||
31 | #include "gnunet_scheduler_lib.h" | ||
32 | #include "gnunet_server_lib.h" | ||
33 | #include "gnunet_time_lib.h" | ||
34 | |||
35 | |||
36 | struct PendingMessageList | ||
37 | { | ||
38 | |||
39 | struct PendingMessageList *next; | ||
40 | |||
41 | const struct GNUNET_MessageHeader *msg; | ||
42 | |||
43 | int can_drop; | ||
44 | |||
45 | }; | ||
46 | |||
47 | |||
48 | struct ClientList | ||
49 | { | ||
50 | |||
51 | struct ClientList *next; | ||
52 | |||
53 | struct GNUNET_SERVER_Client *client; | ||
54 | |||
55 | struct GNUNET_CONNECTION_TransmitHandle *th; | ||
56 | |||
57 | struct PendingMessageList *pending; | ||
58 | |||
59 | unsigned int num_pending; | ||
60 | |||
61 | }; | ||
62 | |||
63 | |||
64 | /** | ||
65 | * The notification context is the key datastructure for a conveniance | ||
66 | * API used for transmission of notifications to the client until the | ||
67 | * client disconnects (or the notification context is destroyed, in | ||
68 | * which case we disconnect these clients). Essentially, all | ||
69 | * (notification) messages are queued up until the client is able to | ||
70 | * read them. | ||
71 | */ | ||
72 | struct GNUNET_SERVER_NotificationContext | ||
73 | { | ||
74 | |||
75 | struct GNUNET_SERVER_Handle *server; | ||
76 | |||
77 | struct ClientList *clients; | ||
78 | |||
79 | unsigned int queue_length; | ||
80 | |||
81 | }; | ||
82 | |||
83 | |||
84 | static void | ||
85 | handle_client_disconnect (void *cls, | ||
86 | struct GNUNET_SERVER_Client *client) | ||
87 | { | ||
88 | struct GNUNET_SERVER_NotificationContext *nc = cls; | ||
89 | struct ClientList *pos; | ||
90 | struct ClientList *prev; | ||
91 | struct PendingMessageList *pml; | ||
92 | |||
93 | prev = NULL; | ||
94 | pos = nc->clients; | ||
95 | while (NULL != pos) | ||
96 | { | ||
97 | if (pos->client == client) | ||
98 | break; | ||
99 | prev = pos; | ||
100 | pos = pos->next; | ||
101 | } | ||
102 | if (pos == NULL) | ||
103 | return; | ||
104 | if (prev == NULL) | ||
105 | nc->clients = pos->next; | ||
106 | else | ||
107 | prev->next = pos->next; | ||
108 | while (NULL != (pml = pos->pending)) | ||
109 | { | ||
110 | pos->pending = pml->next; | ||
111 | GNUNET_free (pml); | ||
112 | } | ||
113 | GNUNET_free (pos); | ||
114 | } | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Create a new notification context. | ||
119 | * | ||
120 | * @param server server for which this function creates the context | ||
121 | * @param queue_length maximum number of messages to keep in | ||
122 | * the notification queue; optional messages are dropped | ||
123 | * it the queue gets longer than this number of messages | ||
124 | * @return handle to the notification context | ||
125 | */ | ||
126 | struct GNUNET_SERVER_NotificationContext * | ||
127 | GNUNET_SERVER_notification_context_create (struct GNUNET_SERVER_Handle *server, | ||
128 | unsigned int queue_length) | ||
129 | { | ||
130 | struct GNUNET_SERVER_NotificationContext *ret; | ||
131 | |||
132 | ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_NotificationContext)); | ||
133 | ret->server = server; | ||
134 | ret->queue_length = queue_length; | ||
135 | GNUNET_SERVER_disconnect_notify (server, | ||
136 | &handle_client_disconnect, | ||
137 | ret); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | |||
142 | /** | ||
143 | * Destroy the context, force disconnect for all clients. | ||
144 | * | ||
145 | * @param nc context to destroy. | ||
146 | */ | ||
147 | void | ||
148 | GNUNET_SERVER_notification_context_destroy (struct GNUNET_SERVER_NotificationContext *nc) | ||
149 | { | ||
150 | struct ClientList *pos; | ||
151 | struct PendingMessageList *pml; | ||
152 | |||
153 | while (NULL != (pos = nc->clients)) | ||
154 | { | ||
155 | nc->clients = pos->next; | ||
156 | GNUNET_SERVER_receive_done (pos->client, GNUNET_NO); | ||
157 | GNUNET_SERVER_client_drop (pos->client); | ||
158 | while (NULL != (pml = pos->pending)) | ||
159 | { | ||
160 | pos->pending = pml->next; | ||
161 | GNUNET_free (pml); | ||
162 | } | ||
163 | GNUNET_free (pos); | ||
164 | } | ||
165 | GNUNET_SERVER_disconnect_notify_cancel (nc->server, | ||
166 | &handle_client_disconnect, | ||
167 | nc); | ||
168 | GNUNET_free (nc); | ||
169 | } | ||
170 | |||
171 | |||
172 | /** | ||
173 | * Add a client to the notification context. | ||
174 | * | ||
175 | * @param nc context to modify | ||
176 | * @param client client to add | ||
177 | */ | ||
178 | void | ||
179 | GNUNET_SERVER_notification_context_add (struct GNUNET_SERVER_NotificationContext *nc, | ||
180 | struct GNUNET_SERVER_Client *client) | ||
181 | { | ||
182 | } | ||
183 | |||
184 | |||
185 | /** | ||
186 | * Send a message to a particular client; must have | ||
187 | * already been added to the notification context. | ||
188 | * | ||
189 | * @param nc context to modify | ||
190 | * @param client client to transmit to | ||
191 | * @param msg message to send | ||
192 | * @param can_drop can this message be dropped due to queue length limitations | ||
193 | */ | ||
194 | void | ||
195 | GNUNET_SERVER_notification_context_unicast (struct GNUNET_SERVER_NotificationContext *nc, | ||
196 | struct GNUNET_SERVER_Client *client, | ||
197 | const struct GNUNET_MessageHeader *msg, | ||
198 | int can_drop) | ||
199 | { | ||
200 | } | ||
201 | |||
202 | |||
203 | /** | ||
204 | * Send a message to all clients of this context. | ||
205 | * | ||
206 | * @param nc context to modify | ||
207 | * @param msg message to send | ||
208 | * @param can_drop can this message be dropped due to queue length limitations | ||
209 | */ | ||
210 | void | ||
211 | GNUNET_SERVER_notification_context_broadcast (struct GNUNET_SERVER_NotificationContext *nc, | ||
212 | const struct GNUNET_MessageHeader *msg, | ||
213 | int can_drop) | ||
214 | { | ||
215 | } | ||
216 | |||
217 | |||
218 | /* end of server_nc.c */ | ||