aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-11-27 14:43:02 +0100
committerChristian Grothoff <christian@grothoff.org>2016-11-27 14:43:02 +0100
commitc30f9fe5daf92a89849f7d6d22eacb603918b42d (patch)
tree70b07926e1170c5b19a3d09a773ec2c1422d84df /src
parentb035390c73b241ddb513f420671043e9113c237c (diff)
downloadgnunet-c30f9fe5daf92a89849f7d6d22eacb603918b42d.tar.gz
gnunet-c30f9fe5daf92a89849f7d6d22eacb603918b42d.zip
largely completing gnunet-nat tool, using new service API (but untested)
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_strings_lib.h25
-rw-r--r--src/nat/Makefile.am2
-rw-r--r--src/nat/gnunet-nat.c210
-rw-r--r--src/util/strings.c78
4 files changed, 296 insertions, 19 deletions
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
index 15d4f57ac..0328882dd 100644
--- a/src/include/gnunet_strings_lib.h
+++ b/src/include/gnunet_strings_lib.h
@@ -349,25 +349,27 @@ GNUNET_STRINGS_base64_encode (const char *data, size_t len, char **output);
349 * 349 *
350 * @param data the data to encode 350 * @param data the data to encode
351 * @param len the length of the input 351 * @param len the length of the input
352 * @param output where to write the output (*output should be NULL, 352 * @param[out] output where to write the output (*output should be NULL,
353 * is allocated) 353 * is allocated)
354 * @return the size of the output 354 * @return the size of the output
355 */ 355 */
356size_t 356size_t
357GNUNET_STRINGS_base64_decode (const char *data, size_t len, char **output); 357GNUNET_STRINGS_base64_decode (const char *data,
358 size_t len,
359 char **output);
358 360
359 361
360/** 362/**
361 * Parse a path that might be an URI. 363 * Parse a path that might be an URI.
362 * 364 *
363 * @param path path to parse. Must be NULL-terminated. 365 * @param path path to parse. Must be NULL-terminated.
364 * @param scheme_part a pointer to 'char *' where a pointer to a string that 366 * @param[out] scheme_part pointer to a string that
365 * represents the URI scheme will be stored. Can be NULL. The string is 367 * represents the URI scheme will be stored. Can be NULL. The string is
366 * allocated by the function, and should be freed by GNUNET_free() when 368 * allocated by the function, and should be freed by GNUNET_free() when
367 * it is no longer needed. 369 * it is no longer needed.
368 * @param path_part a pointer to 'const char *' where a pointer to the path 370 * @param path_part a pointer to 'const char *' where a pointer to the path
369 * part of the URI will be stored. Can be NULL. Points to the same block 371 * part of the URI will be stored. Can be NULL. Points to the same block
370 * of memory as 'path', and thus must not be freed. Might point to '\0', 372 * of memory as @a path, and thus must not be freed. Might point to '\0',
371 * if path part is zero-length. 373 * if path part is zero-length.
372 * @return #GNUNET_YES if it's an URI, #GNUNET_NO otherwise. If 'path' is not 374 * @return #GNUNET_YES if it's an URI, #GNUNET_NO otherwise. If 'path' is not
373 * an URI, '* scheme_part' and '*path_part' will remain unchanged 375 * an URI, '* scheme_part' and '*path_part' will remain unchanged
@@ -475,6 +477,21 @@ GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
475 477
476 478
477/** 479/**
480 * Parse an address given as a string into a
481 * `struct sockaddr`.
482 *
483 * @param addr the address
484 * @param[out] af set to the parsed address family (i.e. AF_INET)
485 * @param[out] sa set to the parsed address
486 * @return 0 on error, otherwise number of bytes in @a sa
487 */
488size_t
489GNUNET_STRINGS_parse_socket_addr (const char *addr,
490 uint8_t *af,
491 struct sockaddr **sa);
492
493
494/**
478 * Tries to convert @a addr string to an IP (v4 or v6) address. 495 * Tries to convert @a addr string to an IP (v4 or v6) address.
479 * Will automatically decide whether to treat 'addr' as v4 or v6 address. 496 * Will automatically decide whether to treat 'addr' as v4 or v6 address.
480 * 497 *
diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am
index d8d50e1a4..c3477930d 100644
--- a/src/nat/Makefile.am
+++ b/src/nat/Makefile.am
@@ -58,7 +58,7 @@ gnunet_helper_nat_client_SOURCES = \
58gnunet_nat_SOURCES = \ 58gnunet_nat_SOURCES = \
59 gnunet-nat.c nat.h 59 gnunet-nat.c nat.h
60gnunet_nat_LDADD = \ 60gnunet_nat_LDADD = \
61 libgnunetnat.la \ 61 libgnunetnatnew.la \
62 $(top_builddir)/src/util/libgnunetutil.la 62 $(top_builddir)/src/util/libgnunetutil.la
63 63
64 64
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c
index 10d5aef8e..6be3319b5 100644
--- a/src/nat/gnunet-nat.c
+++ b/src/nat/gnunet-nat.c
@@ -39,9 +39,9 @@ static int global_ret;
39static struct GNUNET_NAT_AutoHandle *ah; 39static struct GNUNET_NAT_AutoHandle *ah;
40 40
41/** 41/**
42 * Port we use. 42 * Port we advertise.
43 */ 43 */
44static unsigned int port; 44static unsigned int adv_port;
45 45
46/** 46/**
47 * Flag set to 1 if we use IPPROTO_UDP. 47 * Flag set to 1 if we use IPPROTO_UDP.
@@ -198,6 +198,68 @@ auto_config_cb (void *cls,
198 198
199 199
200/** 200/**
201 * Function called to report success or failure for
202 * NAT configuration test.
203 *
204 * @param cls closure
205 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
206 */
207static void
208test_report_cb (void *cls,
209 enum GNUNET_NAT_StatusCode result)
210{
211 nt = NULL;
212 PRINTF ("NAT test result: %s\n",
213 GNUNET_NAT_status2string (result));
214 test_finished ();
215}
216
217
218/**
219 * Signature of the callback passed to #GNUNET_NAT_register() for
220 * a function to call whenever our set of 'valid' addresses changes.
221 *
222 * @param cls closure
223 * @param add_remove #GNUNET_YES to add a new public IP address,
224 * #GNUNET_NO to remove a previous (now invalid) one
225 * @param ac address class the address belongs to
226 * @param addr either the previous or the new public IP address
227 * @param addrlen actual length of the @a addr
228 */
229static void
230address_cb (void *cls,
231 int add_remove,
232 enum GNUNET_NAT_AddressClass ac,
233 const struct sockaddr *addr,
234 socklen_t addrlen)
235{
236 // FIXME: print!
237}
238
239
240/**
241 * Signature of the callback passed to #GNUNET_NAT_register().
242 * for a function to call whenever someone asks us to do connection
243 * reversal.
244 *
245 * @param cls closure
246 * @param local_addr address where we received the request
247 * @param local_addrlen actual length of the @a local_addr
248 * @param remote_addr public IP address of the other peer
249 * @param remote_addrlen actual length of the @a remote_addr
250 */
251static void
252reversal_cb (void *cls,
253 const struct sockaddr *local_addr,
254 socklen_t local_addrlen,
255 const struct sockaddr *remote_addr,
256 socklen_t remote_addrlen)
257{
258 // FIXME: print!
259}
260
261
262/**
201 * Task run on shutdown. 263 * Task run on shutdown.
202 * 264 *
203 * @param cls NULL 265 * @param cls NULL
@@ -237,6 +299,14 @@ run (void *cls,
237 const char *cfgfile, 299 const char *cfgfile,
238 const struct GNUNET_CONFIGURATION_Handle *c) 300 const struct GNUNET_CONFIGURATION_Handle *c)
239{ 301{
302 uint8_t af;
303 struct sockaddr_in bind_sa;
304 struct sockaddr_in extern_sa;
305 struct sockaddr *local_sa;
306 struct sockaddr *remote_sa;
307 size_t local_len;
308 size_t remote_len;
309
240 if (use_tcp && use_udp) 310 if (use_tcp && use_udp)
241 { 311 {
242 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 312 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
@@ -256,6 +326,130 @@ run (void *cls,
256 global_ret = 1; 326 global_ret = 1;
257 return; 327 return;
258 } 328 }
329 if (NULL != bind_addr)
330 {
331 if (GNUNET_OK !=
332 GNUNET_STRINGS_to_address_ipv4 (bind_addr,
333 strlen (bind_addr),
334 &bind_sa))
335 {
336 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
337 "Invalid socket address `%s'\n",
338 bind_addr);
339 global_ret = 1;
340 return;
341 }
342 }
343 if (NULL != extern_addr)
344 {
345 if (GNUNET_OK !=
346 GNUNET_STRINGS_to_address_ipv4 (extern_addr,
347 strlen (extern_addr),
348 &extern_sa))
349 {
350 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
351 "Invalid socket address `%s'\n",
352 extern_addr);
353 global_ret = 1;
354 return;
355 }
356 }
357 if (NULL != local_addr)
358 {
359 local_len = GNUNET_STRINGS_parse_socket_addr (local_addr,
360 &af,
361 &local_sa);
362 if (0 == local_len)
363 {
364 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
365 "Invalid socket address `%s'\n",
366 local_addr);
367 global_ret = 1;
368 return;
369 }
370 }
371 if (NULL != remote_addr)
372 {
373 remote_len = GNUNET_STRINGS_parse_socket_addr (remote_addr,
374 &af,
375 &remote_sa);
376 if (0 == remote_len)
377 {
378 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
379 "Invalid socket address `%s'\n",
380 remote_addr);
381 global_ret = 1;
382 return;
383 }
384 }
385
386 if (NULL != bind_addr)
387 {
388 if (NULL == extern_addr)
389 extern_sa = bind_sa;
390 nt = GNUNET_NAT_test_start (c,
391 proto,
392 bind_sa.sin_addr,
393 ntohs (bind_sa.sin_port),
394 extern_sa.sin_addr,
395 ntohs (extern_sa.sin_port),
396 &test_report_cb,
397 NULL);
398 }
399
400 if (NULL != local_addr)
401 {
402 nh = GNUNET_NAT_register (c,
403 proto,
404 (uint16_t) adv_port,
405 1,
406 (const struct sockaddr **) &local_sa,
407 &local_len,
408 &address_cb,
409 (listen_reversal) ? &reversal_cb : NULL,
410 NULL);
411 }
412
413 if (NULL != remote_addr)
414 {
415 int ret;
416
417 if ( (NULL == nh) ||
418 (sizeof (struct sockaddr_in) != local_len) )
419 {
420 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
421 "Require IPv4 local address to initiate connection reversal\n");
422 global_ret = 1;
423 GNUNET_SCHEDULER_shutdown ();
424 return;
425 }
426 if (sizeof (struct sockaddr_in) != remote_len)
427 {
428 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
429 "Require IPv4 reversal target address\n");
430 global_ret = 1;
431 GNUNET_SCHEDULER_shutdown ();
432 return;
433 }
434 ret = GNUNET_NAT_request_reversal (nh,
435 (const struct sockaddr_in *) &local_sa,
436 (const struct sockaddr_in *) &remote_sa);
437 switch (ret)
438 {
439 case GNUNET_SYSERR:
440 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
441 "Connection reversal internal error\n");
442 break;
443 case GNUNET_NO:
444 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
445 "Connection reversal unavailable\n");
446 break;
447 case GNUNET_OK:
448 /* operation in progress */
449 break;
450 }
451 }
452
259 if (do_auto) 453 if (do_auto)
260 { 454 {
261 ah = GNUNET_NAT_autoconfig_start (c, 455 ah = GNUNET_NAT_autoconfig_start (c,
@@ -285,22 +479,22 @@ main (int argc,
285 GNUNET_NO, &GNUNET_GETOPT_set_one, &do_auto }, 479 GNUNET_NO, &GNUNET_GETOPT_set_one, &do_auto },
286 {'b', "bind", "ADDRESS", 480 {'b', "bind", "ADDRESS",
287 gettext_noop ("which IP and port are we bound to"), 481 gettext_noop ("which IP and port are we bound to"),
288 GNUNET_YES, &GNUNET_GETOPT_set_string, &bind_addr}, 482 GNUNET_YES, &GNUNET_GETOPT_set_string, &bind_addr },
289 {'e', "external", "ADDRESS", 483 {'e', "external", "ADDRESS",
290 gettext_noop ("which external IP and port should be used to test"), 484 gettext_noop ("which external IP and port should be used to test"),
291 GNUNET_YES, &GNUNET_GETOPT_set_string, &extern_addr}, 485 GNUNET_YES, &GNUNET_GETOPT_set_string, &extern_addr },
292 {'l', "local", "ADDRESS", 486 {'l', "local", "ADDRESS",
293 gettext_noop ("which IP and port are we locally using to listen to for connection reversals"), 487 gettext_noop ("which IP and port are we locally using to listen to for connection reversals"),
294 GNUNET_YES, &GNUNET_GETOPT_set_string, &local_addr}, 488 GNUNET_YES, &GNUNET_GETOPT_set_string, &local_addr },
295 {'r', "remote", "ADDRESS", 489 {'r', "remote", "ADDRESS",
296 gettext_noop ("which remote IP and port should be asked for connection reversal"), 490 gettext_noop ("which remote IP and port should be asked for connection reversal"),
297 GNUNET_YES, &GNUNET_GETOPT_set_string, &remote_addr}, 491 GNUNET_YES, &GNUNET_GETOPT_set_string, &remote_addr },
298 {'L', "listen", NULL, 492 {'L', "listen", NULL,
299 gettext_noop ("listen for connection reversal requests"), 493 gettext_noop ("listen for connection reversal requests"),
300 GNUNET_NO, &GNUNET_GETOPT_set_one, &listen_reversal }, 494 GNUNET_NO, &GNUNET_GETOPT_set_one, &listen_reversal },
301 {'p', "port", NULL, 495 {'p', "port", NULL,
302 gettext_noop ("port to use"), 496 gettext_noop ("port to use to advertise"),
303 GNUNET_YES, &GNUNET_GETOPT_set_uint, &port}, 497 GNUNET_YES, &GNUNET_GETOPT_set_uint, &adv_port },
304 {'s', "stun", NULL, 498 {'s', "stun", NULL,
305 gettext_noop ("enable STUN processing"), 499 gettext_noop ("enable STUN processing"),
306 GNUNET_NO, &GNUNET_GETOPT_set_one, &do_stun }, 500 GNUNET_NO, &GNUNET_GETOPT_set_one, &do_stun },
diff --git a/src/util/strings.c b/src/util/strings.c
index 6a6cad6fe..46eab856f 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -1209,7 +1209,7 @@ GNUNET_STRINGS_check_filename (const char *filename,
1209 1209
1210 1210
1211/** 1211/**
1212 * Tries to convert 'zt_addr' string to an IPv6 address. 1212 * Tries to convert @a zt_addr string to an IPv6 address.
1213 * The string is expected to have the format "[ABCD::01]:80". 1213 * The string is expected to have the format "[ABCD::01]:80".
1214 * 1214 *
1215 * @param zt_addr 0-terminated string. May be mangled by the function. 1215 * @param zt_addr 0-terminated string. May be mangled by the function.
@@ -1292,7 +1292,8 @@ GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
1292 * the contents of @a r_buf are undefined. 1292 * the contents of @a r_buf are undefined.
1293 */ 1293 */
1294int 1294int
1295GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, uint16_t addrlen, 1295GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
1296 uint16_t addrlen,
1296 struct sockaddr_in *r_buf) 1297 struct sockaddr_in *r_buf)
1297{ 1298{
1298 unsigned int temps[4]; 1299 unsigned int temps[4];
@@ -1301,7 +1302,13 @@ GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, uint16_t addrlen,
1301 1302
1302 if (addrlen < 9) 1303 if (addrlen < 9)
1303 return GNUNET_SYSERR; 1304 return GNUNET_SYSERR;
1304 cnt = SSCANF (zt_addr, "%u.%u.%u.%u:%u", &temps[0], &temps[1], &temps[2], &temps[3], &port); 1305 cnt = SSCANF (zt_addr,
1306 "%u.%u.%u.%u:%u",
1307 &temps[0],
1308 &temps[1],
1309 &temps[2],
1310 &temps[3],
1311 &port);
1305 if (5 != cnt) 1312 if (5 != cnt)
1306 return GNUNET_SYSERR; 1313 return GNUNET_SYSERR;
1307 for (cnt = 0; cnt < 4; cnt++) 1314 for (cnt = 0; cnt < 4; cnt++)
@@ -1328,8 +1335,8 @@ GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, uint16_t addrlen,
1328 * @param addrlen number of bytes in @a addr (if addr is 0-terminated, 1335 * @param addrlen number of bytes in @a addr (if addr is 0-terminated,
1329 * 0-terminator should not be counted towards addrlen). 1336 * 0-terminator should not be counted towards addrlen).
1330 * @param r_buf a buffer to fill. 1337 * @param r_buf a buffer to fill.
1331 * @return #GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which 1338 * @return #GNUNET_OK if conversion succeded. #GNUNET_SYSERR otherwise, in which
1332 * case the contents of r_buf are undefined. 1339 * case the contents of @a r_buf are undefined.
1333 */ 1340 */
1334int 1341int
1335GNUNET_STRINGS_to_address_ip (const char *addr, 1342GNUNET_STRINGS_to_address_ip (const char *addr,
@@ -1347,6 +1354,62 @@ GNUNET_STRINGS_to_address_ip (const char *addr,
1347 1354
1348 1355
1349/** 1356/**
1357 * Parse an address given as a string into a
1358 * `struct sockaddr`.
1359 *
1360 * @param addr the address
1361 * @param[out] af set to the parsed address family (i.e. AF_INET)
1362 * @param[out] sa set to the parsed address
1363 * @return 0 on error, otherwise number of bytes in @a sa
1364 */
1365size_t
1366GNUNET_STRINGS_parse_socket_addr (const char *addr,
1367 uint8_t *af,
1368 struct sockaddr **sa)
1369{
1370 char *cp = GNUNET_strdup (addr);
1371
1372 *af = AF_UNSPEC;
1373 if ('[' == *addr)
1374 {
1375 /* IPv6 */
1376 *sa = GNUNET_malloc (sizeof (struct sockaddr_in6));
1377 if (GNUNET_OK !=
1378 GNUNET_STRINGS_to_address_ipv6 (cp,
1379 strlen (cp),
1380 (struct sockaddr_in6 *) *sa))
1381 {
1382 GNUNET_free (*sa);
1383 *sa = NULL;
1384 GNUNET_free (cp);
1385 return 0;
1386 }
1387 *af = AF_INET6;
1388 GNUNET_free (cp);
1389 return sizeof (struct sockaddr_in6);
1390 }
1391 else
1392 {
1393 /* IPv4 */
1394 *sa = GNUNET_malloc (sizeof (struct sockaddr_in));
1395 if (GNUNET_OK !=
1396 GNUNET_STRINGS_to_address_ipv4 (cp,
1397 strlen (cp),
1398 (struct sockaddr_in *) *sa))
1399 {
1400 GNUNET_free (*sa);
1401 *sa = NULL;
1402 GNUNET_free (cp);
1403 return 0;
1404 }
1405 *af = AF_INET;
1406 GNUNET_free (cp);
1407 return sizeof (struct sockaddr_in);
1408 }
1409}
1410
1411
1412/**
1350 * Makes a copy of argv that consists of a single memory chunk that can be 1413 * Makes a copy of argv that consists of a single memory chunk that can be
1351 * freed with a single call to GNUNET_free(); 1414 * freed with a single call to GNUNET_free();
1352 */ 1415 */
@@ -1388,7 +1451,10 @@ _make_continuous_arg_copy (int argc,
1388 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 1451 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
1389 */ 1452 */
1390int 1453int
1391GNUNET_STRINGS_get_utf8_args (int argc, char *const *argv, int *u8argc, char *const **u8argv) 1454GNUNET_STRINGS_get_utf8_args (int argc,
1455 char *const *argv,
1456 int *u8argc,
1457 char *const **u8argv)
1392{ 1458{
1393#if WINDOWS 1459#if WINDOWS
1394 wchar_t *wcmd; 1460 wchar_t *wcmd;