aboutsummaryrefslogtreecommitdiff
path: root/src/nat-auto
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat-auto')
-rw-r--r--src/nat-auto/Makefile.am5
-rw-r--r--src/nat-auto/gnunet-nat-auto.c69
-rw-r--r--src/nat-auto/gnunet-nat-server.c216
-rw-r--r--src/nat-auto/nat_auto_api.c8
-rw-r--r--src/nat-auto/nat_auto_api_test.c20
5 files changed, 166 insertions, 152 deletions
diff --git a/src/nat-auto/Makefile.am b/src/nat-auto/Makefile.am
index 19695fabd..14f3f2330 100644
--- a/src/nat-auto/Makefile.am
+++ b/src/nat-auto/Makefile.am
@@ -37,11 +37,11 @@ lib_LTLIBRARIES = \
37 37
38libgnunetnatauto_la_SOURCES = \ 38libgnunetnatauto_la_SOURCES = \
39 nat_auto_api.c \ 39 nat_auto_api.c \
40 nat_auto_api_test.c 40 nat_auto_api_test.c
41libgnunetnatauto_la_LIBADD = \ 41libgnunetnatauto_la_LIBADD = \
42 $(top_builddir)/src/nat/libgnunetnatnew.la \ 42 $(top_builddir)/src/nat/libgnunetnatnew.la \
43 $(top_builddir)/src/util/libgnunetutil.la \ 43 $(top_builddir)/src/util/libgnunetutil.la \
44 $(GN_LIBINTL) @EXT_LIBS@ 44 $(GN_LIBINTL) @EXT_LIBS@
45libgnunetnatauto_la_LDFLAGS = \ 45libgnunetnatauto_la_LDFLAGS = \
46 $(GN_LIB_LDFLAGS) $(WINFLAGS) \ 46 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
47 -version-info 0:0:0 47 -version-info 0:0:0
@@ -55,4 +55,3 @@ gnunet_service_nat_auto_LDADD = \
55 $(LIBGCRYPT_LIBS) \ 55 $(LIBGCRYPT_LIBS) \
56 -lgcrypt \ 56 -lgcrypt \
57 $(GN_LIBINTL) 57 $(GN_LIBINTL)
58
diff --git a/src/nat-auto/gnunet-nat-auto.c b/src/nat-auto/gnunet-nat-auto.c
index 9ba81eb5f..7d09253b8 100644
--- a/src/nat-auto/gnunet-nat-auto.c
+++ b/src/nat-auto/gnunet-nat-auto.c
@@ -63,7 +63,7 @@ static char *section_name;
63/** 63/**
64 * Should we run autoconfiguration? 64 * Should we run autoconfiguration?
65 */ 65 */
66static unsigned int do_auto; 66static int do_auto;
67 67
68/** 68/**
69 * Handle to a NAT test operation. 69 * Handle to a NAT test operation.
@@ -174,6 +174,9 @@ auto_config_cb (void *cls,
174 GNUNET_NAT_AUTO_status2string (result), 174 GNUNET_NAT_AUTO_status2string (result),
175 nat_type); 175 nat_type);
176 176
177 if (NULL == diff)
178 return;
179
177 /* Shortcut: if there are no changes suggested, bail out early. */ 180 /* Shortcut: if there are no changes suggested, bail out early. */
178 if (GNUNET_NO == 181 if (GNUNET_NO ==
179 GNUNET_CONFIGURATION_is_dirty (diff)) 182 GNUNET_CONFIGURATION_is_dirty (diff))
@@ -186,20 +189,16 @@ auto_config_cb (void *cls,
186 to the user */ 189 to the user */
187 new_cfg = write_cfg ? GNUNET_CONFIGURATION_dup (cfg) : NULL; 190 new_cfg = write_cfg ? GNUNET_CONFIGURATION_dup (cfg) : NULL;
188 191
189 if (NULL != diff) 192 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
190 { 193 _("Suggested configuration changes:\n"));
191 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 194 GNUNET_CONFIGURATION_iterate_section_values (diff,
192 _("Suggested configuration changes:\n")); 195 "nat",
193 GNUNET_CONFIGURATION_iterate_section_values (diff, 196 &auto_conf_iter,
194 "nat", 197 new_cfg);
195 &auto_conf_iter,
196 new_cfg);
197 }
198 198
199 /* If desired, write configuration to file; we write only the 199 /* If desired, write configuration to file; we write only the
200 changes to the defaults to keep things compact. */ 200 changes to the defaults to keep things compact. */
201 if ( (write_cfg) && 201 if (write_cfg)
202 (NULL != diff) )
203 { 202 {
204 struct GNUNET_CONFIGURATION_Handle *def_cfg; 203 struct GNUNET_CONFIGURATION_Handle *def_cfg;
205 204
@@ -298,8 +297,8 @@ run (void *cls,
298 if (do_auto) 297 if (do_auto)
299 { 298 {
300 ah = GNUNET_NAT_AUTO_autoconfig_start (c, 299 ah = GNUNET_NAT_AUTO_autoconfig_start (c,
301 &auto_config_cb, 300 &auto_config_cb,
302 NULL); 301 NULL);
303 } 302 }
304 303
305 if (use_tcp && use_udp) 304 if (use_tcp && use_udp)
@@ -340,22 +339,32 @@ int
340main (int argc, 339main (int argc,
341 char *const argv[]) 340 char *const argv[])
342{ 341{
343 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 342 struct GNUNET_GETOPT_CommandLineOption options[] = {
344 {'a', "auto", NULL, 343 GNUNET_GETOPT_option_flag ('a',
345 gettext_noop ("run autoconfiguration"), 344 "auto",
346 GNUNET_NO, &GNUNET_GETOPT_set_one, &do_auto }, 345 gettext_noop ("run autoconfiguration"),
347 {'S', "section", "NAME", 346 &do_auto),
348 gettext_noop ("section name providing the configuration for the adapter"), 347
349 GNUNET_YES, &GNUNET_GETOPT_set_string, &section_name }, 348 GNUNET_GETOPT_option_string ('S',
350 {'t', "tcp", NULL, 349 "section",
351 gettext_noop ("use TCP"), 350 "NAME",
352 GNUNET_NO, &GNUNET_GETOPT_set_one, &use_tcp }, 351 gettext_noop ("section name providing the configuration for the adapter"),
353 {'u', "udp", NULL, 352 &section_name),
354 gettext_noop ("use UDP"), 353
355 GNUNET_NO, &GNUNET_GETOPT_set_one, &use_udp }, 354 GNUNET_GETOPT_option_flag ('t',
356 {'w', "write", NULL, 355 "tcp",
357 gettext_noop ("write configuration file (for autoconfiguration)"), 356 gettext_noop ("use TCP"),
358 GNUNET_NO, &GNUNET_GETOPT_set_one, &write_cfg }, 357 &use_tcp),
358
359 GNUNET_GETOPT_option_flag ('u',
360 "udp",
361 gettext_noop ("use UDP"),
362 &use_udp),
363
364 GNUNET_GETOPT_option_flag ('w',
365 "write",
366 gettext_noop ("write configuration file (for autoconfiguration)"),
367 &write_cfg),
359 GNUNET_GETOPT_OPTION_END 368 GNUNET_GETOPT_OPTION_END
360 }; 369 };
361 370
diff --git a/src/nat-auto/gnunet-nat-server.c b/src/nat-auto/gnunet-nat-server.c
index dd08f8d36..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.
@@ -56,6 +68,7 @@ try_anat (uint32_t dst_ipv4,
56 struct GNUNET_NAT_Handle *h; 68 struct GNUNET_NAT_Handle *h;
57 struct sockaddr_in lsa; 69 struct sockaddr_in lsa;
58 struct sockaddr_in rsa; 70 struct sockaddr_in rsa;
71 const struct sockaddr *sa;
59 socklen_t sa_len; 72 socklen_t sa_len;
60 73
61 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 74 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -77,11 +90,12 @@ try_anat (uint32_t dst_ipv4,
77 rsa.sin_addr.s_addr = dst_ipv4; 90 rsa.sin_addr.s_addr = dst_ipv4;
78 rsa.sin_port = htons (dport); 91 rsa.sin_port = htons (dport);
79 sa_len = sizeof (lsa); 92 sa_len = sizeof (lsa);
93 sa = (const struct sockaddr *) &lsa;
80 h = GNUNET_NAT_register (cfg, 94 h = GNUNET_NAT_register (cfg,
81 "none", 95 "none",
82 is_tcp ? IPPROTO_TCP : IPPROTO_UDP, 96 is_tcp ? IPPROTO_TCP : IPPROTO_UDP,
83 1, 97 1,
84 (const struct sockaddr **) &lsa, 98 &sa,
85 &sa_len, 99 &sa_len,
86 NULL, NULL, NULL); 100 NULL, NULL, NULL);
87 GNUNET_NAT_request_reversal (h, 101 GNUNET_NAT_request_reversal (h,
@@ -246,21 +260,18 @@ try_send_udp (uint32_t dst_ipv4,
246 * We've received a request to probe a NAT 260 * We've received a request to probe a NAT
247 * traversal. Do it. 261 * traversal. Do it.
248 * 262 *
249 * @param cls unused 263 * @param cls handle to client (we always close)
250 * @param client handle to client (we always close)
251 * @param msg message with details about what to test 264 * @param msg message with details about what to test
252 */ 265 */
253static void 266static void
254test (void *cls, 267handle_test (void *cls,
255 struct GNUNET_SERVER_Client *client, 268 const struct GNUNET_NAT_AUTO_TestMessage *tm)
256 const struct GNUNET_MessageHeader *msg)
257{ 269{
258 const struct GNUNET_NAT_AUTO_TestMessage *tm; 270 struct ClientData *cd = cls;
259 uint16_t dport; 271 uint16_t dport;
260 272
261 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 273 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
262 "Received test request\n"); 274 "Received test request\n");
263 tm = (const struct GNUNET_NAT_AUTO_TestMessage *) msg;
264 dport = ntohs (tm->dport); 275 dport = ntohs (tm->dport);
265 if (0 == dport) 276 if (0 == dport)
266 try_anat (tm->dst_ipv4, 277 try_anat (tm->dst_ipv4,
@@ -274,126 +285,119 @@ test (void *cls,
274 try_send_udp (tm->dst_ipv4, 285 try_send_udp (tm->dst_ipv4,
275 dport, 286 dport,
276 tm->data); 287 tm->data);
277 GNUNET_SERVER_receive_done (client, 288 GNUNET_SERVICE_client_drop (cd->client);
278 GNUNET_NO);
279} 289}
280 290
281 291
282/** 292/**
283 * Task run during shutdown. 293 * Main function that will be run.
284 * 294 *
285 * @param cls unused 295 * @param cls closure
296 * @param c configuration
297 * @param srv service handle
286 */ 298 */
287static void 299static void
288shutdown_task (void *cls) 300run (void *cls,
301 const struct GNUNET_CONFIGURATION_Handle *c,
302 struct GNUNET_SERVICE_Handle *srv)
289{ 303{
290 GNUNET_SERVER_destroy (server); 304 cfg = c;
291 server = NULL;
292} 305}
293 306
294 307
295/** 308/**
296 * Main function that will be run. 309 * Forcefully drops client after 1s.
297 * 310 *
298 * @param cls closure 311 * @param cls our `struct ClientData` of a client to drop
299 * @param args remaining command-line arguments
300 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
301 * @param c configuration
302 */ 312 */
303static void 313static void
304run (void *cls, 314force_timeout (void *cls)
305 char *const *args,
306 const char *cfgfile,
307 const struct GNUNET_CONFIGURATION_Handle *c)
308{ 315{
309 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 316 struct ClientData *cd = cls;
310 {&test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST,
311 sizeof (struct GNUNET_NAT_AUTO_TestMessage)},
312 {NULL, NULL, 0, 0}
313 };
314 unsigned int port;
315 struct sockaddr_in in4;
316 struct sockaddr_in6 in6;
317
318 socklen_t slen[] = {
319 sizeof (in4),
320 sizeof (in6),
321 0
322 };
323 struct sockaddr *sa[] = {
324 (struct sockaddr *) &in4,
325 (struct sockaddr *) &in6,
326 NULL
327 };
328 317
329 cfg = c; 318 cd->tt = NULL;
330 if ( (NULL == args[0]) || 319 GNUNET_SERVICE_client_drop (cd->client);
331 (1 != SSCANF (args[0], "%u", &port)) ||
332 (0 == port) ||
333 (65536 <= port) )
334 {
335 FPRINTF (stderr,
336 _("Please pass valid port number as the first argument! (got `%s')\n"),
337 args[0]);
338 return;
339 }
340 memset (&in4, 0, sizeof (in4));
341 memset (&in6, 0, sizeof (in6));
342 in4.sin_family = AF_INET;
343 in4.sin_port = htons ((uint16_t) port);
344 in6.sin6_family = AF_INET6;
345 in6.sin6_port = htons ((uint16_t) port);
346#if HAVE_SOCKADDR_IN_SIN_LEN
347 in4.sin_len = sizeof (in4);
348 in6.sin6_len = sizeof (in6);
349#endif
350 server = GNUNET_SERVER_create (NULL,
351 NULL,
352 (struct sockaddr * const *) sa,
353 slen,
354 GNUNET_TIME_UNIT_SECONDS,
355 GNUNET_YES);
356 GNUNET_SERVER_add_handlers (server,
357 handlers);
358 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
359 NULL);
360} 320}
361 321
362 322
323
363/** 324/**
364 * Main function of gnunet-nat-server. 325 * Callback called when a client connects to the service.
365 * 326 *
366 * @param argc number of command-line arguments 327 * @param cls closure for the service
367 * @param argv command line 328 * @param c the new client that connected to the service
368 * @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`
369 */ 331 */
370int 332static void *
371main (int argc, char *const argv[]) 333client_connect_cb (void *cls,
334 struct GNUNET_SERVICE_Client *c,
335 struct GNUNET_MQ_Handle *mq)
372{ 336{
373 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 337 struct ClientData *cd;
374 GNUNET_GETOPT_OPTION_END 338
375 }; 339 cd = GNUNET_new (struct ClientData);
376 340 cd->client = c;
377 if (GNUNET_OK != 341 cd->tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
378 GNUNET_STRINGS_get_utf8_args (argc, argv, 342 &force_timeout,
379 &argc, &argv)) 343 cd);
380 return 2; 344 return cd;
381 345}
382 if (GNUNET_OK != 346
383 GNUNET_PROGRAM_run (argc, 347
384 argv, 348/**
385 "gnunet-nat-server [options] PORT", 349 * Callback called when a client disconnected from the service
386 _("GNUnet NAT traversal test helper daemon"), 350 *
387 options, 351 * @param cls closure for the service
388 &run, 352 * @param c the client that disconnected
389 NULL)) 353 * @param internal_cls our `struct ClientData`
390 { 354 */
391 GNUNET_free ((void*) argv); 355static void
392 return 1; 356client_disconnect_cb (void *cls,
393 } 357 struct GNUNET_SERVICE_Client *c,
394 GNUNET_free ((void*) argv); 358 void *internal_cls)
395 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);
396} 365}
397 366
398 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
399/* end of gnunet-nat-server.c */ 403/* end of gnunet-nat-server.c */
diff --git a/src/nat-auto/nat_auto_api.c b/src/nat-auto/nat_auto_api.c
index a5b41ac49..8a7eaf264 100644
--- a/src/nat-auto/nat_auto_api.c
+++ b/src/nat-auto/nat_auto_api.c
@@ -42,7 +42,7 @@ struct GNUNET_NAT_AUTO_AutoHandle
42 * Configuration we use. 42 * Configuration we use.
43 */ 43 */
44 const struct GNUNET_CONFIGURATION_Handle *cfg; 44 const struct GNUNET_CONFIGURATION_Handle *cfg;
45 45
46 /** 46 /**
47 * Message queue for communicating with the NAT service. 47 * Message queue for communicating with the NAT service.
48 */ 48 */
@@ -206,8 +206,8 @@ ah_error_handler (void *cls,
206 */ 206 */
207struct GNUNET_NAT_AUTO_AutoHandle * 207struct GNUNET_NAT_AUTO_AutoHandle *
208GNUNET_NAT_AUTO_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 208GNUNET_NAT_AUTO_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
209 GNUNET_NAT_AUTO_AutoResultCallback cb, 209 GNUNET_NAT_AUTO_AutoResultCallback cb,
210 void *cb_cls) 210 void *cb_cls)
211{ 211{
212 struct GNUNET_NAT_AUTO_AutoHandle *ah = GNUNET_new (struct GNUNET_NAT_AUTO_AutoHandle); 212 struct GNUNET_NAT_AUTO_AutoHandle *ah = GNUNET_new (struct GNUNET_NAT_AUTO_AutoHandle);
213 struct GNUNET_MQ_MessageHandler handlers[] = { 213 struct GNUNET_MQ_MessageHandler handlers[] = {
@@ -224,7 +224,7 @@ GNUNET_NAT_AUTO_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
224 224
225 buf = GNUNET_CONFIGURATION_serialize (cfg, 225 buf = GNUNET_CONFIGURATION_serialize (cfg,
226 &size); 226 &size);
227 if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*req)) 227 if (size > GNUNET_MAX_MESSAGE_SIZE - sizeof (*req))
228 { 228 {
229 GNUNET_break (0); 229 GNUNET_break (0);
230 GNUNET_free (buf); 230 GNUNET_free (buf);
diff --git a/src/nat-auto/nat_auto_api_test.c b/src/nat-auto/nat_auto_api_test.c
index fb2bcd679..c72b611bf 100644
--- a/src/nat-auto/nat_auto_api_test.c
+++ b/src/nat-auto/nat_auto_api_test.c
@@ -28,7 +28,7 @@
28#include "gnunet_nat_auto_service.h" 28#include "gnunet_nat_auto_service.h"
29#include "nat-auto.h" 29#include "nat-auto.h"
30 30
31#define LOG(kind,...) GNUNET_log_from (kind, "nat", __VA_ARGS__) 31#define LOG(kind,...) GNUNET_log_from (kind, "nat-auto", __VA_ARGS__)
32 32
33#define NAT_SERVER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) 33#define NAT_SERVER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
34 34
@@ -508,19 +508,21 @@ GNUNET_NAT_AUTO_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
508 { 508 {
509 nh->lsock 509 nh->lsock
510 = GNUNET_NETWORK_socket_create (AF_INET, 510 = GNUNET_NETWORK_socket_create (AF_INET,
511 proto, 511 (IPPROTO_UDP == proto)
512 0); 512 ? SOCK_DGRAM
513 : SOCK_STREAM,
514 proto);
513 if ( (NULL == nh->lsock) || 515 if ( (NULL == nh->lsock) ||
514 (GNUNET_OK != 516 (GNUNET_OK !=
515 GNUNET_NETWORK_socket_bind (nh->lsock, 517 GNUNET_NETWORK_socket_bind (nh->lsock,
516 (const struct sockaddr *) &sa, 518 (const struct sockaddr *) &sa,
517 sizeof (sa)))) 519 sizeof (sa))))
518 { 520 {
519 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 521 LOG (GNUNET_ERROR_TYPE_ERROR,
520 _("Failed to create listen socket bound to `%s' for NAT test: %s\n"), 522 _("Failed to create socket bound to `%s' for NAT test: %s\n"),
521 GNUNET_a2s ((const struct sockaddr *) &sa, 523 GNUNET_a2s ((const struct sockaddr *) &sa,
522 sizeof (sa)), 524 sizeof (sa)),
523 STRERROR (errno)); 525 STRERROR (errno));
524 if (NULL != nh->lsock) 526 if (NULL != nh->lsock)
525 { 527 {
526 GNUNET_NETWORK_socket_close (nh->lsock); 528 GNUNET_NETWORK_socket_close (nh->lsock);
@@ -551,7 +553,7 @@ GNUNET_NAT_AUTO_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
551 nh); 553 nh);
552 } 554 }
553 LOG (GNUNET_ERROR_TYPE_INFO, 555 LOG (GNUNET_ERROR_TYPE_INFO,
554 "NAT test listens on port %u (%s)\n", 556 "NAT test listens on port %llu (%s)\n",
555 bnd_port, 557 bnd_port,
556 (IPPROTO_TCP == proto) ? "tcp" : "udp"); 558 (IPPROTO_TCP == proto) ? "tcp" : "udp");
557 nh->nat = GNUNET_NAT_register (cfg, 559 nh->nat = GNUNET_NAT_register (cfg,