aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO44
-rw-r--r--src/include/gnunet_server_lib.h91
-rw-r--r--src/peerinfo/gnunet-service-peerinfo.c2
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/server.c39
-rw-r--r--src/util/server_nc.c218
6 files changed, 381 insertions, 14 deletions
diff --git a/TODO b/TODO
index 1d975e95a..992f61f80 100644
--- a/TODO
+++ b/TODO
@@ -12,24 +12,40 @@ away), in order in which they will likely be done:
12* UPNP [Milan] 12* UPNP [Milan]
13 13
14Urgent items (before announcing ng.gnunet.org): 14Urgent 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 */
142void GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s); 144void 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 */
426void 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 */
517struct 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 */
529struct GNUNET_SERVER_NotificationContext *
530GNUNET_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 */
539void
540GNUNET_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 */
549void
550GNUNET_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 */
563void
564GNUNET_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 */
577void
578GNUNET_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 */
1127void
1128GNUNET_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
36struct PendingMessageList
37{
38
39 struct PendingMessageList *next;
40
41 const struct GNUNET_MessageHeader *msg;
42
43 int can_drop;
44
45};
46
47
48struct 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 */
72struct 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
84static void
85handle_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 */
126struct GNUNET_SERVER_NotificationContext *
127GNUNET_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 */
147void
148GNUNET_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 */
178void
179GNUNET_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 */
194void
195GNUNET_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 */
210void
211GNUNET_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 */