~ubuntu-branches/ubuntu/intrepid/gnunet/intrepid

« back to all changes in this revision

Viewing changes to src/server/tcpserver.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2008-01-31 17:40:18 UTC
  • mfrom: (1.2.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20080131174018-sfnbb8wv7p4nmut1
Tags: 0.7.3-2ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/rules:
    = Make use of code from cdbs' clean-la.mk file to clear the
      dependency_libs field in all .la files in the gnunet-dev package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include "handler.h"
35
35
#include "startup.h"
36
36
 
37
 
#define DEBUG_TCPHANDLER NO
 
37
#define DEBUG_TCPHANDLER GNUNET_NO
38
38
 
39
 
#define TIME_HANDLERS NO
 
39
#define TIME_HANDLERS GNUNET_NO
40
40
 
41
41
/**
42
42
 * Array of the message handlers.
43
43
 */
44
 
static CSHandler *handlers = NULL;
 
44
static GNUNET_ClientRequestHandler *handlers = NULL;
45
45
 
46
46
/**
47
47
 * Number of handlers in the array (max, there
52
52
/**
53
53
 * Handlers to call if client exits.
54
54
 */
55
 
static ClientExitHandler *exitHandlers;
 
55
static GNUNET_ClientExitHandler *exitHandlers;
56
56
 
57
57
/**
58
58
 * How many entries are in exitHandlers?
62
62
/**
63
63
 * Mutex to guard access to the handler array.
64
64
 */
65
 
static struct MUTEX *handlerlock;
 
65
static struct GNUNET_Mutex *handlerlock;
66
66
 
67
67
/**
68
68
 * The thread that waits for new connections.
69
69
 */
70
 
static struct SelectHandle *selector;
71
 
 
72
 
static struct GE_Context *ectx;
73
 
 
74
 
static struct GC_Configuration *cfg;
 
70
static struct GNUNET_SelectHandle *selector;
 
71
 
 
72
static struct GNUNET_GE_Context *ectx;
 
73
 
 
74
static struct GNUNET_GC_Configuration *cfg;
75
75
 
76
76
/**
77
77
 * Per-client data structure.
78
78
 */
79
 
typedef struct ClientHandle
 
79
typedef struct GNUNET_ClientHandle
80
80
{
81
81
 
82
 
  struct SocketHandle *sock;
 
82
  struct GNUNET_SocketHandle *sock;
83
83
 
84
84
} ClientHandle;
85
85
 
86
86
/**
87
87
 * Configuration...
88
88
 */
89
 
static struct CIDRNetwork *trustedNetworks_ = NULL;
 
89
static struct GNUNET_IPv4NetworkSet *trustedNetworks_ = NULL;
90
90
 
91
91
/**
92
92
 * Is this IP labeled as trusted for CS connections?
93
93
 */
94
94
static int
95
 
isWhitelisted (IPaddr ip)
 
95
isWhitelisted (GNUNET_IPv4Address ip)
96
96
{
97
 
  return check_ipv4_listed (trustedNetworks_, ip);
 
97
  return GNUNET_check_ipv4_listed (trustedNetworks_, ip);
98
98
}
99
99
 
100
100
static int
101
 
shutdownHandler (struct ClientHandle *client, const MESSAGE_HEADER * msg)
 
101
shutdownHandler (struct GNUNET_ClientHandle *client,
 
102
                 const GNUNET_MessageHeader * msg)
102
103
{
103
104
  int ret;
104
105
 
105
 
  if (ntohs (msg->size) != sizeof (MESSAGE_HEADER))
 
106
  if (ntohs (msg->size) != sizeof (GNUNET_MessageHeader))
106
107
    {
107
 
      GE_LOG (NULL,
108
 
              GE_WARNING | GE_USER | GE_BULK,
109
 
              _("The `%s' request received from client is malformed.\n"),
110
 
              "shutdown");
111
 
      return SYSERR;
 
108
      GNUNET_GE_LOG (NULL,
 
109
                     GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK,
 
110
                     _
 
111
                     ("The `%s' request received from client is malformed.\n"),
 
112
                     "shutdown");
 
113
      return GNUNET_SYSERR;
112
114
    }
113
 
  GE_LOG (NULL,
114
 
          GE_INFO | GE_USER | GE_REQUEST,
115
 
          "shutdown request accepted from client\n");
116
 
  ret = sendTCPResultToClient (client, OK);
117
 
  shutdown_gnunetd (cfg, 0);
 
115
  GNUNET_GE_LOG (NULL,
 
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);
118
120
  return ret;
119
121
}
120
122
 
121
123
int
122
 
registerClientExitHandler (ClientExitHandler callback)
 
124
GNUNET_CORE_cs_register_exit_handler (GNUNET_ClientExitHandler callback)
123
125
{
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);
128
 
  return OK;
 
129
  GNUNET_mutex_unlock (handlerlock);
 
130
  return GNUNET_OK;
129
131
}
130
132
 
131
133
int
132
 
unregisterClientExitHandler (ClientExitHandler callback)
 
134
GNUNET_CORE_cs_exit_handler_unregister (GNUNET_ClientExitHandler callback)
133
135
{
134
136
  int i;
135
137
 
136
 
  MUTEX_LOCK (handlerlock);
 
138
  GNUNET_mutex_lock (handlerlock);
137
139
  for (i = 0; i < exitHandlerCount; i++)
138
140
    {
139
141
      if (exitHandlers[i] == callback)
140
142
        {
141
143
          exitHandlers[i] = exitHandlers[exitHandlerCount - 1];
142
 
          GROW (exitHandlers, exitHandlerCount, exitHandlerCount - 1);
143
 
          MUTEX_UNLOCK (handlerlock);
144
 
          return OK;
 
144
          GNUNET_array_grow (exitHandlers, exitHandlerCount,
 
145
                             exitHandlerCount - 1);
 
146
          GNUNET_mutex_unlock (handlerlock);
 
147
          return GNUNET_OK;
145
148
        }
146
149
    }
147
 
  MUTEX_UNLOCK (handlerlock);
148
 
  return SYSERR;
 
150
  GNUNET_mutex_unlock (handlerlock);
 
151
  return GNUNET_SYSERR;
149
152
}
150
153
 
151
154
static void *
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)
156
159
{
157
 
  struct ClientHandle *session;
158
 
  IPaddr ip;
 
160
  struct GNUNET_ClientHandle *session;
 
161
  GNUNET_IPv4Address ip;
159
162
  struct sockaddr_in *a;
160
163
 
161
164
  if (addr_len != sizeof (struct sockaddr_in))
162
165
    return NULL;
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))
166
169
    return NULL;
167
 
  session = MALLOC (sizeof (ClientHandle));
 
170
  session = GNUNET_malloc (sizeof (ClientHandle));
168
171
  session->sock = sock;
169
172
  return session;
170
173
}
171
174
 
172
175
static void
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)
176
179
{
177
180
  ClientHandle *session = sock_ctx;
178
181
  int i;
179
182
 
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);
184
 
  FREE (session);
 
186
  GNUNET_mutex_unlock (handlerlock);
 
187
  GNUNET_free (session);
185
188
}
186
189
 
187
190
/**
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.
193
196
 *
194
 
 * @param force YES if this message MUST be queued
 
197
 * @param force GNUNET_YES if this message MUST be queued
195
198
 */
196
199
int
197
 
sendToClient (struct ClientHandle *handle, const MESSAGE_HEADER * message,
198
 
              int force)
 
200
GNUNET_CORE_cs_send_to_client (struct GNUNET_ClientHandle *handle,
 
201
                               const GNUNET_MessageHeader * message,
 
202
                               int force)
199
203
{
200
204
#if DEBUG_TCPHANDLER
201
 
  GE_LOG (ectx,
202
 
          GE_DEBUG | GE_DEVELOPER | GE_REQUEST,
203
 
          "%s: sending reply to client\n", __FUNCTION__);
 
205
  GNUNET_GE_LOG (ectx,
 
206
                 GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST,
 
207
                 "%s: sending reply to client\n", __FUNCTION__);
204
208
#endif
205
 
  return select_write (selector, handle->sock, message, YES, force);
 
209
  return GNUNET_select_write (selector, handle->sock, message, GNUNET_YES,
 
210
                              force);
206
211
}
207
212
 
208
213
void
209
 
terminateClientConnection (struct ClientHandle *sock)
 
214
GNUNET_CORE_cs_terminate_client_connection (struct GNUNET_ClientHandle *sock)
210
215
{
211
 
  select_disconnect (selector, sock->sock);
 
216
  GNUNET_select_disconnect (selector, sock->sock);
212
217
}
213
218
 
214
219
static int
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)
219
224
{
220
 
  struct ClientHandle *sender = sock_ctx;
 
225
  struct GNUNET_ClientHandle *sender = sock_ctx;
221
226
  unsigned short ptyp;
222
 
  CSHandler callback;
 
227
  GNUNET_ClientRequestHandler callback;
223
228
#if TIME_HANDLERS
224
 
  cron_t start;
 
229
  GNUNET_CronTime start;
225
230
#endif
226
231
 
227
232
  ptyp = htons (msg->type);
228
 
  MUTEX_LOCK (handlerlock);
 
233
  GNUNET_mutex_lock (handlerlock);
229
234
  if (ptyp >= max_registeredType)
230
235
    {
231
 
      GE_LOG (ectx,
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);
236
 
      return SYSERR;
 
236
      GNUNET_GE_LOG (ectx,
 
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;
237
242
    }
238
243
  callback = handlers[ptyp];
239
244
  if (callback == NULL)
240
245
    {
241
 
      GE_LOG (ectx,
242
 
              GE_INFO | GE_USER | GE_BULK,
243
 
              "%s: Message of type %d not understood: no handler registered\n",
244
 
              __FUNCTION__, ptyp);
245
 
      MUTEX_UNLOCK (handlerlock);
246
 
      return SYSERR;
 
246
      GNUNET_GE_LOG (ectx,
 
247
                     GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,
 
248
                     "%s: Message of type %d not understood: no handler registered\n",
 
249
                     __FUNCTION__, ptyp);
 
250
      GNUNET_mutex_unlock (handlerlock);
 
251
      return GNUNET_SYSERR;
247
252
    }
248
253
  else
249
254
    {
250
255
#if TIME_HANDLERS
251
 
      start = get_time ();
 
256
      start = GNUNET_get_time ();
252
257
#endif
253
 
      if (OK != callback (sender, msg))
 
258
      if (GNUNET_OK != callback (sender, msg))
254
259
        {
255
260
#if 0
256
 
          GE_LOG (ectx,
257
 
                  GE_INFO | GE_USER | GE_BULK,
258
 
                  "%s: Message of type %d caused error in handler\n",
259
 
                  __FUNCTION__, ptyp);
 
261
          GNUNET_GE_LOG (ectx,
 
262
                         GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK,
 
263
                         "%s: Message of type %d caused error in handler\n",
 
264
                         __FUNCTION__, ptyp);
260
265
#endif
261
 
          MUTEX_UNLOCK (handlerlock);
262
 
          return SYSERR;
 
266
          GNUNET_mutex_unlock (handlerlock);
 
267
          return GNUNET_SYSERR;
263
268
        }
264
269
#if TIME_HANDLERS
265
 
      if (get_time () - start > cronSECONDS)
266
 
        GE_LOG (ectx,
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)
 
271
        GNUNET_GE_LOG (ectx,
 
272
                       GNUNET_GE_INFO | GNUNET_GE_DEVELOPER |
 
273
                       GNUNET_GE_IMMEDIATE,
 
274
                       "Handling message of type %u took %llu s\n", ptyp,
 
275
                       (GNUNET_get_time () - start) / GNUNET_CRON_SECONDS);
270
276
#endif
271
277
    }
272
 
  MUTEX_UNLOCK (handlerlock);
273
 
  return OK;
 
278
  GNUNET_mutex_unlock (handlerlock);
 
279
  return GNUNET_OK;
274
280
}
275
281
 
276
282
/**
281
287
{
282
288
  unsigned long long port;
283
289
 
284
 
  if (-1 == GC_get_configuration_value_number (cfg,
285
 
                                               "NETWORK",
286
 
                                               "PORT", 1, 65535, 2087, &port))
 
290
  if (-1 == GNUNET_GC_get_configuration_value_number (cfg,
 
291
                                                      "NETWORK",
 
292
                                                      "PORT", 1, 65535, 2087,
 
293
                                                      &port))
287
294
    port = 0;
288
295
  return (unsigned short) port;
289
296
}
298
305
 
299
306
  listenerPort = getGNUnetPort ();
300
307
  if (listenerPort == 0)
301
 
    return SYSERR;
 
308
    return GNUNET_SYSERR;
302
309
  listenerFD = SOCKET (PF_INET, SOCK_STREAM, 0);
303
310
  if (listenerFD < 0)
304
311
    {
305
 
      GE_LOG_STRERROR (ectx,
306
 
                       GE_FATAL | GE_ADMIN | GE_USER | GE_IMMEDIATE,
307
 
                       "socket");
308
 
      return SYSERR;
 
312
      GNUNET_GE_LOG_STRERROR (ectx,
 
313
                              GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
 
314
                              GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, "socket");
 
315
      return GNUNET_SYSERR;
309
316
    }
310
317
  /* fill in the inet address structure */
311
318
  memset (&serverAddr, 0, sizeof (serverAddr));
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)
320
329
    {
321
 
      GE_LOG_STRERROR (ectx, GE_ERROR | GE_ADMIN | GE_IMMEDIATE, "bind");
322
 
      GE_LOG (ectx,
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");
 
333
      GNUNET_GE_LOG (ectx,
 
334
                     GNUNET_GE_FATAL | GNUNET_GE_ADMIN | GNUNET_GE_USER |
 
335
                     GNUNET_GE_IMMEDIATE,
 
336
                     _
 
337
                     ("`%s' failed for port %d. Is gnunetd already running?\n"),
 
338
                     "bind", listenerPort);
326
339
      CLOSE (listenerFD);
327
 
      return SYSERR;
 
340
      return GNUNET_SYSERR;
328
341
    }
329
 
  selector = select_create ("tcpserver", NO, ectx, NULL, listenerFD, sizeof (struct sockaddr_in), 0,    /* no timeout */
330
 
                            &select_message_handler,
331
 
                            NULL,
332
 
                            &select_accept_handler,
333
 
                            NULL,
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,
 
344
                                   NULL,
 
345
                                   &select_accept_handler,
 
346
                                   NULL,
 
347
                                   &select_close_handler,
 
348
                                   NULL, 0 /* no memory quota */ ,
 
349
                                   256 /* max sockets */ );
337
350
  if (selector == NULL)
338
351
    {
339
352
      CLOSE (listenerFD);       /* maybe closed already
340
 
                                   depending on how select_create
 
353
                                   depending on how GNUNET_select_create
341
354
                                   failed... */
342
 
      return SYSERR;
 
355
      return GNUNET_SYSERR;
343
356
    }
344
 
  return OK;
 
357
  return GNUNET_OK;
345
358
}
346
359
 
347
360
int
348
 
doneTCPServer ()
 
361
GNUNET_CORE_cs_done ()
349
362
{
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
354
 
                                   not gnunetd */
355
 
  unregisterCSHandler (CS_PROTO_SHUTDOWN_REQUEST, &shutdownHandler);
356
 
  GROW (handlers, max_registeredType, 0);
357
 
  GROW (exitHandlers, exitHandlerCount, 0);
358
 
  FREE (trustedNetworks_);
359
 
  return OK;
360
 
}
361
 
 
362
 
void __attribute__ ((constructor)) gnunet_tcpserver_ltdl_init ()
363
 
{
364
 
  handlerlock = MUTEX_CREATE (YES);
365
 
}
366
 
 
367
 
void __attribute__ ((destructor)) gnunet_tcpserver_ltdl_fini ()
368
 
{
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
 
367
                                           not gnunetd */
 
368
  GNUNET_CORE_unregister_handler (GNUNET_CS_PROTO_SHUTDOWN_REQUEST,
 
369
                                  &shutdownHandler);
 
370
  GNUNET_array_grow (handlers, max_registeredType, 0);
 
371
  GNUNET_array_grow (exitHandlers, exitHandlerCount, 0);
 
372
  GNUNET_free (trustedNetworks_);
 
373
  return GNUNET_OK;
 
374
}
 
375
 
 
376
void __attribute__ ((constructor)) GNUNET_CORE_cs_ltdl_init ()
 
377
{
 
378
  handlerlock = GNUNET_mutex_create (GNUNET_YES);
 
379
}
 
380
 
 
381
void __attribute__ ((destructor)) GNUNET_CORE_cs_ltdl_fini ()
 
382
{
 
383
  GNUNET_mutex_destroy (handlerlock);
370
384
  handlerlock = NULL;
371
385
}
372
386
 
374
388
 * Initialize the TCP port and listen for incoming client connections.
375
389
 */
376
390
int
377
 
initTCPServer (struct GE_Context *e, struct GC_Configuration *c)
 
391
GNUNET_CORE_cs_init (struct GNUNET_GE_Context *e,
 
392
                     struct GNUNET_GC_Configuration *c)
378
393
{
379
394
  char *ch;
380
395
 
383
398
 
384
399
  /* move to reload-configuration method! */
385
400
  ch = NULL;
386
 
  if (-1 == GC_get_configuration_value_string (cfg,
387
 
                                               "NETWORK",
388
 
                                               "TRUSTED",
389
 
                                               "127.0.0.0/8;", &ch))
390
 
    return SYSERR;
391
 
  GE_ASSERT (ectx, ch != NULL);
392
 
  trustedNetworks_ = parse_ipv4_network_specification (ectx, ch);
 
401
  if (-1 == GNUNET_GC_get_configuration_value_string (cfg,
 
402
                                                      "NETWORK",
 
403
                                                      "TRUSTED",
 
404
                                                      "127.0.0.0/8;", &ch))
 
405
    return GNUNET_SYSERR;
 
406
  GNUNET_GE_ASSERT (ectx, ch != NULL);
 
407
  trustedNetworks_ = GNUNET_parse_ipv4_network_specification (ectx, ch);
393
408
  if (trustedNetworks_ == NULL)
394
409
    {
395
 
      GE_LOG (ectx,
396
 
              GE_FATAL | GE_USER | GE_ADMIN | GE_IMMEDIATE,
397
 
              _
398
 
              ("Malformed network specification in the configuration in section `%s' for entry `%s': %s\n"),
399
 
              "NETWORK", "TRUSTED", ch);
400
 
      FREE (ch);
401
 
      return SYSERR;
 
410
      GNUNET_GE_LOG (ectx,
 
411
                     GNUNET_GE_FATAL | GNUNET_GE_USER | GNUNET_GE_ADMIN |
 
412
                     GNUNET_GE_IMMEDIATE,
 
413
                     _
 
414
                     ("Malformed network specification in the configuration in section `%s' for entry `%s': %s\n"),
 
415
                     "NETWORK", "TRUSTED", ch);
 
416
      GNUNET_free (ch);
 
417
      return GNUNET_SYSERR;
402
418
    }
403
 
  FREE (ch);
 
419
  GNUNET_free (ch);
404
420
 
405
 
  registerCSHandler (CS_PROTO_SHUTDOWN_REQUEST, &shutdownHandler);
406
 
  if ((NO == GC_get_configuration_value_yesno (cfg,
407
 
                                               "TCPSERVER",
408
 
                                               "DISABLE",
409
 
                                               NO)) &&
410
 
      (OK != startTCPServer ()))
 
421
  GNUNET_CORE_register_handler (GNUNET_CS_PROTO_SHUTDOWN_REQUEST,
 
422
                                &shutdownHandler);
 
423
  if ((GNUNET_NO ==
 
424
       GNUNET_GC_get_configuration_value_yesno (cfg, "TCPSERVER", "DISABLE",
 
425
                                                GNUNET_NO))
 
426
      && (GNUNET_OK != startTCPServer ()))
411
427
    {
412
 
      doneTCPServer ();
413
 
      return SYSERR;
 
428
      GNUNET_CORE_cs_done ();
 
429
      return GNUNET_SYSERR;
414
430
    }
415
 
  return OK;
 
431
  return GNUNET_OK;
416
432
}
417
433
 
418
434
/**
419
435
 * Shutdown the module.
420
436
 */
421
437
int
422
 
stopTCPServer ()
 
438
GNUNET_CORE_stop_cs_server ()
423
439
{
424
440
  if (selector != NULL)
425
441
    {
426
 
      select_destroy (selector);
 
442
      GNUNET_select_destroy (selector);
427
443
      selector = NULL;
428
444
    }
429
 
  return OK;
 
445
  return GNUNET_OK;
430
446
}
431
447
 
432
448
/**
435
451
 * @param type the message type
436
452
 * @param callback the method to call if a message of
437
453
 *        that type is received, if the callback returns
438
 
 *        SYSERR, processing of the message is discontinued
 
454
 *        GNUNET_SYSERR, processing of the message is discontinued
439
455
 *        afterwards (all other parts are ignored)
440
 
 * @return OK on success, SYSERR if there is already a
 
456
 * @return GNUNET_OK on success, GNUNET_SYSERR if there is already a
441
457
 *         handler for that type
442
458
 */
443
459
int
444
 
registerCSHandler (unsigned short type, CSHandler callback)
 
460
GNUNET_CORE_register_handler (unsigned short type,
 
461
                              GNUNET_ClientRequestHandler callback)
445
462
{
446
 
  MUTEX_LOCK (handlerlock);
 
463
  GNUNET_mutex_lock (handlerlock);
447
464
  if (type < max_registeredType)
448
465
    {
449
466
      if (handlers[type] != NULL)
450
467
        {
451
 
          MUTEX_UNLOCK (handlerlock);
452
 
          GE_LOG (ectx,
453
 
                  GE_WARNING | GE_DEVELOPER | GE_BULK,
454
 
                  _("%s failed, message type %d already in use.\n"),
455
 
                  __FUNCTION__, type);
456
 
          return SYSERR;
 
468
          GNUNET_mutex_unlock (handlerlock);
 
469
          GNUNET_GE_LOG (ectx,
 
470
                         GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER |
 
471
                         GNUNET_GE_BULK,
 
472
                         _("%s failed, message type %d already in use.\n"),
 
473
                         __FUNCTION__, type);
 
474
          return GNUNET_SYSERR;
457
475
        }
458
476
    }
459
477
  else
460
 
    GROW (handlers, max_registeredType, type + 8);
 
478
    GNUNET_array_grow (handlers, max_registeredType, type + 8);
461
479
  handlers[type] = callback;
462
 
  MUTEX_UNLOCK (handlerlock);
463
 
  return OK;
 
480
  GNUNET_mutex_unlock (handlerlock);
 
481
  return GNUNET_OK;
464
482
}
465
483
 
466
484
/**
470
488
 * @param type the message type
471
489
 * @param callback the method to call if a message of
472
490
 *        that type is received, if the callback returns
473
 
 *        SYSERR, processing of the message is discontinued
 
491
 *        GNUNET_SYSERR, processing of the message is discontinued
474
492
 *        afterwards (all other parts are ignored)
475
 
 * @return OK on success, SYSERR if there is no or another
 
493
 * @return GNUNET_OK on success, GNUNET_SYSERR if there is no or another
476
494
 *         handler for that type
477
495
 */
478
496
int
479
 
unregisterCSHandler (unsigned short type, CSHandler callback)
 
497
GNUNET_CORE_unregister_handler (unsigned short type,
 
498
                                GNUNET_ClientRequestHandler callback)
480
499
{
481
 
  MUTEX_LOCK (handlerlock);
 
500
  GNUNET_mutex_lock (handlerlock);
482
501
  if (type < max_registeredType)
483
502
    {
484
503
      if (handlers[type] != callback)
485
504
        {
486
 
          MUTEX_UNLOCK (handlerlock);
487
 
          return SYSERR;        /* another handler present */
 
505
          GNUNET_mutex_unlock (handlerlock);
 
506
          return GNUNET_SYSERR; /* another handler present */
488
507
        }
489
508
      else
490
509
        {
491
510
          handlers[type] = NULL;
492
 
          MUTEX_UNLOCK (handlerlock);
493
 
          return OK;            /* success */
 
511
          GNUNET_mutex_unlock (handlerlock);
 
512
          return GNUNET_OK;     /* success */
494
513
        }
495
514
    }
496
515
  else
497
516
    {                           /* can't be there */
498
 
      MUTEX_UNLOCK (handlerlock);
499
 
      return SYSERR;
 
517
      GNUNET_mutex_unlock (handlerlock);
 
518
      return GNUNET_SYSERR;
500
519
    }
501
520
}
502
521
 
505
524
 * TCP.
506
525
 * @param sock the TCP socket
507
526
 * @param ret the return value to send via TCP
508
 
 * @return SYSERR on error, OK if the return value was
 
527
 * @return GNUNET_SYSERR on error, GNUNET_OK if the return value was
509
528
 *         send successfully
510
529
 */
511
530
int
512
 
sendTCPResultToClient (struct ClientHandle *sock, int ret)
 
531
GNUNET_CORE_cs_send_result_to_client (struct GNUNET_ClientHandle *sock,
 
532
                                      int ret)
513
533
{
514
 
  RETURN_VALUE_MESSAGE rv;
 
534
  GNUNET_MessageReturnValue rv;
515
535
 
516
 
  rv.header.size = htons (sizeof (RETURN_VALUE_MESSAGE));
517
 
  rv.header.type = htons (CS_PROTO_RETURN_VALUE);
 
536
  rv.header.size = htons (sizeof (GNUNET_MessageReturnValue));
 
537
  rv.header.type = htons (GNUNET_CS_PROTO_RETURN_VALUE);
518
538
  rv.return_value = htonl (ret);
519
 
  return sendToClient (sock, &rv.header, YES);
 
539
  return GNUNET_CORE_cs_send_to_client (sock, &rv.header, GNUNET_YES);
520
540
}
521
541
 
522
542
/**
524
544
 * TCP.
525
545
 * @param sock the TCP socket
526
546
 * @param message the error message to send via TCP
527
 
 * @return SYSERR on error, OK if the return value was
 
547
 * @return GNUNET_SYSERR on error, GNUNET_OK if the return value was
528
548
 *         send successfully
529
549
 */
530
550
int
531
 
sendTCPErrorToClient (struct ClientHandle *sock,
532
 
                      GE_KIND kind, const char *message)
 
551
GNUNET_CORE_cs_send_error_to_client (struct GNUNET_ClientHandle *sock,
 
552
                                     GNUNET_GE_KIND kind, const char *message)
533
553
{
534
 
  RETURN_ERROR_MESSAGE *rv;
 
554
  GNUNET_MessageReturnErrorMessage *rv;
535
555
  size_t msgLen;
536
556
  int ret;
537
557
 
539
559
  msgLen = ((msgLen + 3) >> 2) << 2;
540
560
  if (msgLen > 60000)
541
561
    msgLen = 60000;
542
 
  rv = MALLOC (sizeof (RETURN_ERROR_MESSAGE) + msgLen);
543
 
  memset (rv, 0, sizeof (RETURN_ERROR_MESSAGE) + msgLen);
544
 
  rv->header.size = htons (sizeof (MESSAGE_HEADER) + msgLen);
545
 
  rv->header.type = htons (CS_PROTO_RETURN_ERROR);
 
562
  rv = GNUNET_malloc (sizeof (GNUNET_MessageReturnErrorMessage) + msgLen);
 
563
  memset (rv, 0, sizeof (GNUNET_MessageReturnErrorMessage) + msgLen);
 
564
  rv->header.size = htons (sizeof (GNUNET_MessageHeader) + msgLen);
 
565
  rv->header.type = htons (GNUNET_CS_PROTO_RETURN_ERROR);
546
566
  rv->kind = htonl (kind);
547
567
  memcpy (&rv[1], message, strlen (message));
548
 
  ret = sendToClient (sock, &rv->header, YES);
549
 
  FREE (rv);
 
568
  ret = GNUNET_CORE_cs_send_to_client (sock, &rv->header, GNUNET_YES);
 
569
  GNUNET_free (rv);
550
570
  return ret;
551
571
}
552
572
 
558
578
 * @return number of registered handlers (0 or 1)
559
579
 */
560
580
unsigned int
561
 
isCSHandlerRegistered (unsigned short type)
 
581
GNUNET_CORE_cs_test_handler_registered (unsigned short type)
562
582
{
563
 
  MUTEX_LOCK (handlerlock);
 
583
  GNUNET_mutex_lock (handlerlock);
564
584
  if (type < max_registeredType)
565
585
    {
566
586
      if (handlers[type] != NULL)
567
587
        {
568
 
          MUTEX_UNLOCK (handlerlock);
 
588
          GNUNET_mutex_unlock (handlerlock);
569
589
          return 1;
570
590
        }
571
591
    }
572
 
  MUTEX_UNLOCK (handlerlock);
 
592
  GNUNET_mutex_unlock (handlerlock);
573
593
  return 0;
574
594
}
575
595
 
585
605
 
586
606
static void
587
607
logClientLogContext (void *ctx,
588
 
                     GE_KIND kind, const char *date, const char *msg)
 
608
                     GNUNET_GE_KIND kind, const char *date, const char *msg)
589
609
{
590
 
  sendTCPErrorToClient (ctx, kind, msg);
 
610
  GNUNET_CORE_cs_send_error_to_client (ctx, kind, msg);
591
611
}
592
612
 
593
 
struct GE_Context *
594
 
createClientLogContext (GE_KIND mask, struct ClientHandle *handle)
 
613
struct GNUNET_GE_Context *
 
614
GNUNET_CORE_cs_create_client_log_context (GNUNET_GE_KIND mask,
 
615
                                          struct GNUNET_ClientHandle *handle)
595
616
{
596
 
  return GE_create_context_callback (mask,
597
 
                                     &logClientLogContext,
598
 
                                     handle,
599
 
                                     &freeClientLogContext,
600
 
                                     &confirmClientLogContext);
 
617
  return GNUNET_GE_create_context_callback (mask,
 
618
                                            &logClientLogContext,
 
619
                                            handle,
 
620
                                            &freeClientLogContext,
 
621
                                            &confirmClientLogContext);
601
622
}
602
623
 
603
624
/* end of tcpserver.c */