63
63
* Mutex to guard access to the handler array.
65
static struct MUTEX *handlerlock;
65
static struct GNUNET_Mutex *handlerlock;
68
68
* The thread that waits for new connections.
70
static struct SelectHandle *selector;
72
static struct GE_Context *ectx;
74
static struct GC_Configuration *cfg;
70
static struct GNUNET_SelectHandle *selector;
72
static struct GNUNET_GE_Context *ectx;
74
static struct GNUNET_GC_Configuration *cfg;
77
77
* Per-client data structure.
79
typedef struct ClientHandle
79
typedef struct GNUNET_ClientHandle
82
struct SocketHandle *sock;
82
struct GNUNET_SocketHandle *sock;
89
static struct CIDRNetwork *trustedNetworks_ = NULL;
89
static struct GNUNET_IPv4NetworkSet *trustedNetworks_ = NULL;
92
92
* Is this IP labeled as trusted for CS connections?
95
isWhitelisted (IPaddr ip)
95
isWhitelisted (GNUNET_IPv4Address ip)
97
return check_ipv4_listed (trustedNetworks_, ip);
97
return GNUNET_check_ipv4_listed (trustedNetworks_, ip);
101
shutdownHandler (struct ClientHandle *client, const MESSAGE_HEADER * msg)
101
shutdownHandler (struct GNUNET_ClientHandle *client,
102
const GNUNET_MessageHeader * msg)
105
if (ntohs (msg->size) != sizeof (MESSAGE_HEADER))
106
if (ntohs (msg->size) != sizeof (GNUNET_MessageHeader))
108
GE_WARNING | GE_USER | GE_BULK,
109
_("The `%s' request received from client is malformed.\n"),
109
GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK,
111
("The `%s' request received from client is malformed.\n"),
113
return GNUNET_SYSERR;
114
GE_INFO | GE_USER | GE_REQUEST,
115
"shutdown request accepted from client\n");
116
ret = sendTCPResultToClient (client, OK);
117
shutdown_gnunetd (cfg, 0);
116
GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST,
117
"shutdown request accepted from client\n");
118
ret = GNUNET_CORE_cs_send_result_to_client (client, GNUNET_OK);
119
GNUNET_CORE_shutdown (cfg, 0);
122
registerClientExitHandler (ClientExitHandler callback)
124
GNUNET_CORE_cs_register_exit_handler (GNUNET_ClientExitHandler callback)
124
MUTEX_LOCK (handlerlock);
125
GROW (exitHandlers, exitHandlerCount, exitHandlerCount + 1);
126
GNUNET_mutex_lock (handlerlock);
127
GNUNET_array_grow (exitHandlers, exitHandlerCount, exitHandlerCount + 1);
126
128
exitHandlers[exitHandlerCount - 1] = callback;
127
MUTEX_UNLOCK (handlerlock);
129
GNUNET_mutex_unlock (handlerlock);
132
unregisterClientExitHandler (ClientExitHandler callback)
134
GNUNET_CORE_cs_exit_handler_unregister (GNUNET_ClientExitHandler callback)
136
MUTEX_LOCK (handlerlock);
138
GNUNET_mutex_lock (handlerlock);
137
139
for (i = 0; i < exitHandlerCount; i++)
139
141
if (exitHandlers[i] == callback)
141
143
exitHandlers[i] = exitHandlers[exitHandlerCount - 1];
142
GROW (exitHandlers, exitHandlerCount, exitHandlerCount - 1);
143
MUTEX_UNLOCK (handlerlock);
144
GNUNET_array_grow (exitHandlers, exitHandlerCount,
145
exitHandlerCount - 1);
146
GNUNET_mutex_unlock (handlerlock);
147
MUTEX_UNLOCK (handlerlock);
150
GNUNET_mutex_unlock (handlerlock);
151
return GNUNET_SYSERR;
152
155
select_accept_handler (void *ah_cls,
153
struct SelectHandle *sh,
154
struct SocketHandle *sock,
156
struct GNUNET_SelectHandle *sh,
157
struct GNUNET_SocketHandle *sock,
155
158
const void *addr, unsigned int addr_len)
157
struct ClientHandle *session;
160
struct GNUNET_ClientHandle *session;
161
GNUNET_IPv4Address ip;
159
162
struct sockaddr_in *a;
161
164
if (addr_len != sizeof (struct sockaddr_in))
163
166
a = (struct sockaddr_in *) addr;
164
memcpy (&ip, &a->sin_addr, sizeof (IPaddr));
167
memcpy (&ip, &a->sin_addr, sizeof (GNUNET_IPv4Address));
165
168
if (!isWhitelisted (ip))
167
session = MALLOC (sizeof (ClientHandle));
170
session = GNUNET_malloc (sizeof (ClientHandle));
168
171
session->sock = sock;
173
176
select_close_handler (void *ch_cls,
174
struct SelectHandle *sh,
175
struct SocketHandle *sock, void *sock_ctx)
177
struct GNUNET_SelectHandle *sh,
178
struct GNUNET_SocketHandle *sock, void *sock_ctx)
177
180
ClientHandle *session = sock_ctx;
180
MUTEX_LOCK (handlerlock);
183
GNUNET_mutex_lock (handlerlock);
181
184
for (i = 0; i < exitHandlerCount; i++)
182
185
exitHandlers[i] (session);
183
MUTEX_UNLOCK (handlerlock);
186
GNUNET_mutex_unlock (handlerlock);
187
GNUNET_free (session);
188
191
* Send a message to the client identified by the handle. Note that
189
192
* the core will typically buffer these messages as much as possible
190
* and only return errors if it runs out of buffers. Returning OK
193
* and only return errors if it runs out of buffers. Returning GNUNET_OK
191
194
* on the other hand does NOT confirm delivery since the actual
192
195
* transfer happens asynchronously.
194
* @param force YES if this message MUST be queued
197
* @param force GNUNET_YES if this message MUST be queued
197
sendToClient (struct ClientHandle *handle, const MESSAGE_HEADER * message,
200
GNUNET_CORE_cs_send_to_client (struct GNUNET_ClientHandle *handle,
201
const GNUNET_MessageHeader * message,
200
204
#if DEBUG_TCPHANDLER
202
GE_DEBUG | GE_DEVELOPER | GE_REQUEST,
203
"%s: sending reply to client\n", __FUNCTION__);
206
GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST,
207
"%s: sending reply to client\n", __FUNCTION__);
205
return select_write (selector, handle->sock, message, YES, force);
209
return GNUNET_select_write (selector, handle->sock, message, GNUNET_YES,
209
terminateClientConnection (struct ClientHandle *sock)
214
GNUNET_CORE_cs_terminate_client_connection (struct GNUNET_ClientHandle *sock)
211
select_disconnect (selector, sock->sock);
216
GNUNET_select_disconnect (selector, sock->sock);
215
220
select_message_handler (void *mh_cls,
216
struct SelectHandle *sh,
217
struct SocketHandle *sock,
218
void *sock_ctx, const MESSAGE_HEADER * msg)
221
struct GNUNET_SelectHandle *sh,
222
struct GNUNET_SocketHandle *sock,
223
void *sock_ctx, const GNUNET_MessageHeader * msg)
220
struct ClientHandle *sender = sock_ctx;
225
struct GNUNET_ClientHandle *sender = sock_ctx;
221
226
unsigned short ptyp;
227
GNUNET_ClientRequestHandler callback;
223
228
#if TIME_HANDLERS
229
GNUNET_CronTime start;
227
232
ptyp = htons (msg->type);
228
MUTEX_LOCK (handlerlock);
233
GNUNET_mutex_lock (handlerlock);
229
234
if (ptyp >= max_registeredType)
232
GE_INFO | GE_USER | GE_BULK,
233
"%s: Message of type %d not understood: no handler registered\n",
234
__FUNCTION__, ptyp, max_registeredType);
235
MUTEX_UNLOCK (handlerlock);
237
GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,
238
"%s: Message of type %d not understood: no handler registered\n",
239
__FUNCTION__, ptyp, max_registeredType);
240
GNUNET_mutex_unlock (handlerlock);
241
return GNUNET_SYSERR;
238
243
callback = handlers[ptyp];
239
244
if (callback == NULL)
242
GE_INFO | GE_USER | GE_BULK,
243
"%s: Message of type %d not understood: no handler registered\n",
245
MUTEX_UNLOCK (handlerlock);
247
GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,
248
"%s: Message of type %d not understood: no handler registered\n",
250
GNUNET_mutex_unlock (handlerlock);
251
return GNUNET_SYSERR;
250
255
#if TIME_HANDLERS
256
start = GNUNET_get_time ();
253
if (OK != callback (sender, msg))
258
if (GNUNET_OK != callback (sender, msg))
257
GE_INFO | GE_USER | GE_BULK,
258
"%s: Message of type %d caused error in handler\n",
262
GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,
263
"%s: Message of type %d caused error in handler\n",
261
MUTEX_UNLOCK (handlerlock);
266
GNUNET_mutex_unlock (handlerlock);
267
return GNUNET_SYSERR;
264
269
#if TIME_HANDLERS
265
if (get_time () - start > cronSECONDS)
267
GE_INFO | GE_DEVELOPER | GE_IMMEDIATE,
268
"Handling message of type %u took %llu s\n",
269
ptyp, (get_time () - start) / cronSECONDS);
270
if (GNUNET_get_time () - start > GNUNET_CRON_SECONDS)
272
GNUNET_GE_INFO | GNUNET_GE_DEVELOPER |
274
"Handling message of type %u took %llu s\n", ptyp,
275
(GNUNET_get_time () - start) / GNUNET_CRON_SECONDS);
272
MUTEX_UNLOCK (handlerlock);
278
GNUNET_mutex_unlock (handlerlock);
313
320
serverAddr.sin_addr.s_addr = htonl (INADDR_ANY);
314
321
serverAddr.sin_port = htons (listenerPort);
315
322
if (SETSOCKOPT (listenerFD, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
316
GE_LOG_STRERROR (ectx, GE_ERROR | GE_ADMIN | GE_BULK, "setsockopt");
323
GNUNET_GE_LOG_STRERROR (ectx,
324
GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
325
GNUNET_GE_BULK, "setsockopt");
317
326
/* bind the socket */
318
327
if (BIND (listenerFD,
319
328
(struct sockaddr *) &serverAddr, sizeof (serverAddr)) < 0)
321
GE_LOG_STRERROR (ectx, GE_ERROR | GE_ADMIN | GE_IMMEDIATE, "bind");
323
GE_FATAL | GE_ADMIN | GE_USER | GE_IMMEDIATE,
324
_("`%s' failed for port %d. Is gnunetd already running?\n"),
325
"bind", listenerPort);
330
GNUNET_GE_LOG_STRERROR (ectx,
331
GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
332
GNUNET_GE_IMMEDIATE, "bind");
334
GNUNET_GE_FATAL | GNUNET_GE_ADMIN | GNUNET_GE_USER |
337
("`%s' failed for port %d. Is gnunetd already running?\n"),
338
"bind", listenerPort);
326
339
CLOSE (listenerFD);
340
return GNUNET_SYSERR;
329
selector = select_create ("tcpserver", NO, ectx, NULL, listenerFD, sizeof (struct sockaddr_in), 0, /* no timeout */
330
&select_message_handler,
332
&select_accept_handler,
334
&select_close_handler,
335
NULL, 0 /* no memory quota */ ,
336
256 /* max sockets */ );
342
selector = GNUNET_select_create ("tcpserver", GNUNET_NO, ectx, NULL, listenerFD, sizeof (struct sockaddr_in), 0, /* no timeout */
343
&select_message_handler,
345
&select_accept_handler,
347
&select_close_handler,
348
NULL, 0 /* no memory quota */ ,
349
256 /* max sockets */ );
337
350
if (selector == NULL)
339
352
CLOSE (listenerFD); /* maybe closed already
340
depending on how select_create
353
depending on how GNUNET_select_create
355
return GNUNET_SYSERR;
361
GNUNET_CORE_cs_done ()
350
363
if (selector != NULL)
351
stopTCPServer (); /* just to be sure; used mostly
352
for the benefit of gnunet-update
353
and other gnunet-tools that are
355
unregisterCSHandler (CS_PROTO_SHUTDOWN_REQUEST, &shutdownHandler);
356
GROW (handlers, max_registeredType, 0);
357
GROW (exitHandlers, exitHandlerCount, 0);
358
FREE (trustedNetworks_);
362
void __attribute__ ((constructor)) gnunet_tcpserver_ltdl_init ()
364
handlerlock = MUTEX_CREATE (YES);
367
void __attribute__ ((destructor)) gnunet_tcpserver_ltdl_fini ()
369
MUTEX_DESTROY (handlerlock);
364
GNUNET_CORE_stop_cs_server (); /* just to be sure; used mostly
365
for the benefit of gnunet-update
366
and other gnunet-tools that are
368
GNUNET_CORE_unregister_handler (GNUNET_CS_PROTO_SHUTDOWN_REQUEST,
370
GNUNET_array_grow (handlers, max_registeredType, 0);
371
GNUNET_array_grow (exitHandlers, exitHandlerCount, 0);
372
GNUNET_free (trustedNetworks_);
376
void __attribute__ ((constructor)) GNUNET_CORE_cs_ltdl_init ()
378
handlerlock = GNUNET_mutex_create (GNUNET_YES);
381
void __attribute__ ((destructor)) GNUNET_CORE_cs_ltdl_fini ()
383
GNUNET_mutex_destroy (handlerlock);
370
384
handlerlock = NULL;