aboutsummaryrefslogtreecommitdiff
path: root/src/nat-auto/gnunet-nat-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat-auto/gnunet-nat-server.c')
-rw-r--r--src/nat-auto/gnunet-nat-server.c212
1 files changed, 107 insertions, 105 deletions
diff --git a/src/nat-auto/gnunet-nat-server.c b/src/nat-auto/gnunet-nat-server.c
index 371e4b27e..590fad4d6 100644
--- a/src/nat-auto/gnunet-nat-server.c
+++ b/src/nat-auto/gnunet-nat-server.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V. 3 Copyright (C) 2011, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -31,9 +31,21 @@
31 31
32 32
33/** 33/**
34 * Our server. 34 * Information we track per client.
35 */ 35 */
36static struct GNUNET_SERVER_Handle *server; 36struct ClientData
37{
38 /**
39 * Timeout task.
40 */
41 struct GNUNET_SCHEDULER_Task *tt;
42
43 /**
44 * Client handle.
45 */
46 struct GNUNET_SERVICE_Client *client;
47};
48
37 49
38/** 50/**
39 * Our configuration. 51 * Our configuration.
@@ -248,21 +260,18 @@ try_send_udp (uint32_t dst_ipv4,
248 * We've received a request to probe a NAT 260 * We've received a request to probe a NAT
249 * traversal. Do it. 261 * traversal. Do it.
250 * 262 *
251 * @param cls unused 263 * @param cls handle to client (we always close)
252 * @param client handle to client (we always close)
253 * @param msg message with details about what to test 264 * @param msg message with details about what to test
254 */ 265 */
255static void 266static void
256test (void *cls, 267handle_test (void *cls,
257 struct GNUNET_SERVER_Client *client, 268 const struct GNUNET_NAT_AUTO_TestMessage *tm)
258 const struct GNUNET_MessageHeader *msg)
259{ 269{
260 const struct GNUNET_NAT_AUTO_TestMessage *tm; 270 struct ClientData *cd = cls;
261 uint16_t dport; 271 uint16_t dport;
262 272
263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 273 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
264 "Received test request\n"); 274 "Received test request\n");
265 tm = (const struct GNUNET_NAT_AUTO_TestMessage *) msg;
266 dport = ntohs (tm->dport); 275 dport = ntohs (tm->dport);
267 if (0 == dport) 276 if (0 == dport)
268 try_anat (tm->dst_ipv4, 277 try_anat (tm->dst_ipv4,
@@ -276,126 +285,119 @@ test (void *cls,
276 try_send_udp (tm->dst_ipv4, 285 try_send_udp (tm->dst_ipv4,
277 dport, 286 dport,
278 tm->data); 287 tm->data);
279 GNUNET_SERVER_receive_done (client, 288 GNUNET_SERVICE_client_drop (cd->client);
280 GNUNET_NO);
281} 289}
282 290
283 291
284/** 292/**
285 * Task run during shutdown. 293 * Main function that will be run.
286 * 294 *
287 * @param cls unused 295 * @param cls closure
296 * @param c configuration
297 * @param srv service handle
288 */ 298 */
289static void 299static void
290shutdown_task (void *cls) 300run (void *cls,
301 const struct GNUNET_CONFIGURATION_Handle *c,
302 struct GNUNET_SERVICE_Handle *srv)
291{ 303{
292 GNUNET_SERVER_destroy (server); 304 cfg = c;
293 server = NULL;
294} 305}
295 306
296 307
297/** 308/**
298 * Main function that will be run. 309 * Forcefully drops client after 1s.
299 * 310 *
300 * @param cls closure 311 * @param cls our `struct ClientData` of a client to drop
301 * @param args remaining command-line arguments
302 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
303 * @param c configuration
304 */ 312 */
305static void 313static void
306run (void *cls, 314force_timeout (void *cls)
307 char *const *args,
308 const char *cfgfile,
309 const struct GNUNET_CONFIGURATION_Handle *c)
310{ 315{
311 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 316 struct ClientData *cd = cls;
312 {&test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST,
313 sizeof (struct GNUNET_NAT_AUTO_TestMessage)},
314 {NULL, NULL, 0, 0}
315 };
316 unsigned int port;
317 struct sockaddr_in in4;
318 struct sockaddr_in6 in6;
319
320 socklen_t slen[] = {
321 sizeof (in4),
322 sizeof (in6),
323 0
324 };
325 struct sockaddr *sa[] = {
326 (struct sockaddr *) &in4,
327 (struct sockaddr *) &in6,
328 NULL
329 };
330 317
331 cfg = c; 318 cd->tt = NULL;
332 if ( (NULL == args[0]) || 319 GNUNET_SERVICE_client_drop (cd->client);
333 (1 != SSCANF (args[0], "%u", &port)) ||
334 (0 == port) ||
335 (65536 <= port) )
336 {
337 FPRINTF (stderr,
338 _("Please pass valid port number as the first argument! (got `%s')\n"),
339 args[0]);
340 return;
341 }
342 memset (&in4, 0, sizeof (in4));
343 memset (&in6, 0, sizeof (in6));
344 in4.sin_family = AF_INET;
345 in4.sin_port = htons ((uint16_t) port);
346 in6.sin6_family = AF_INET6;
347 in6.sin6_port = htons ((uint16_t) port);
348#if HAVE_SOCKADDR_IN_SIN_LEN
349 in4.sin_len = sizeof (in4);
350 in6.sin6_len = sizeof (in6);
351#endif
352 server = GNUNET_SERVER_create (NULL,
353 NULL,
354 (struct sockaddr * const *) sa,
355 slen,
356 GNUNET_TIME_UNIT_SECONDS,
357 GNUNET_YES);
358 GNUNET_SERVER_add_handlers (server,
359 handlers);
360 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
361 NULL);
362} 320}
363 321
364 322
323
365/** 324/**
366 * Main function of gnunet-nat-server. 325 * Callback called when a client connects to the service.
367 * 326 *
368 * @param argc number of command-line arguments 327 * @param cls closure for the service
369 * @param argv command line 328 * @param c the new client that connected to the service
370 * @return 0 on success, -1 on error 329 * @param mq the message queue used to send messages to the client
330 * @return our `struct ClientData`
371 */ 331 */
372int 332static void *
373main (int argc, char *const argv[]) 333client_connect_cb (void *cls,
334 struct GNUNET_SERVICE_Client *c,
335 struct GNUNET_MQ_Handle *mq)
374{ 336{
375 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 337 struct ClientData *cd;
376 GNUNET_GETOPT_OPTION_END 338
377 }; 339 cd = GNUNET_new (struct ClientData);
378 340 cd->client = c;
379 if (GNUNET_OK != 341 cd->tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
380 GNUNET_STRINGS_get_utf8_args (argc, argv, 342 &force_timeout,
381 &argc, &argv)) 343 cd);
382 return 2; 344 return cd;
383 345}
384 if (GNUNET_OK != 346
385 GNUNET_PROGRAM_run (argc, 347
386 argv, 348/**
387 "gnunet-nat-server [options] PORT", 349 * Callback called when a client disconnected from the service
388 _("GNUnet NAT traversal test helper daemon"), 350 *
389 options, 351 * @param cls closure for the service
390 &run, 352 * @param c the client that disconnected
391 NULL)) 353 * @param internal_cls our `struct ClientData`
392 { 354 */
393 GNUNET_free ((void*) argv); 355static void
394 return 1; 356client_disconnect_cb (void *cls,
395 } 357 struct GNUNET_SERVICE_Client *c,
396 GNUNET_free ((void*) argv); 358 void *internal_cls)
397 return 0; 359{
360 struct ClientData *cd = internal_cls;
361
362 if (NULL != cd->tt)
363 GNUNET_SCHEDULER_cancel (cd->tt);
364 GNUNET_free (cd);
398} 365}
399 366
400 367
368/**
369 * Define "main" method using service macro.
370 */
371GNUNET_SERVICE_MAIN
372("nat-server",
373 GNUNET_SERVICE_OPTION_NONE,
374 &run,
375 &client_connect_cb,
376 &client_disconnect_cb,
377 NULL,
378 GNUNET_MQ_hd_fixed_size (test,
379 GNUNET_MESSAGE_TYPE_NAT_TEST,
380 struct GNUNET_NAT_AUTO_TestMessage,
381 NULL),
382 GNUNET_MQ_handler_end ());
383
384
385#if defined(LINUX) && defined(__GLIBC__)
386#include <malloc.h>
387
388/**
389 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
390 */
391void __attribute__ ((constructor))
392GNUNET_ARM_memory_init ()
393{
394 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
395 mallopt (M_TOP_PAD, 1 * 1024);
396 malloc_trim (0);
397}
398#endif
399
400
401
402
401/* end of gnunet-nat-server.c */ 403/* end of gnunet-nat-server.c */