aboutsummaryrefslogtreecommitdiff
path: root/src/nat/gnunet-nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat/gnunet-nat.c')
-rw-r--r--src/nat/gnunet-nat.c223
1 files changed, 102 insertions, 121 deletions
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c
index 275553203..6c533374e 100644
--- a/src/nat/gnunet-nat.c
+++ b/src/nat/gnunet-nat.c
@@ -120,20 +120,19 @@ test_finished ()
120 */ 120 */
121static void 121static void
122address_cb (void *cls, 122address_cb (void *cls,
123 void **app_ctx, 123 void **app_ctx,
124 int add_remove, 124 int add_remove,
125 enum GNUNET_NAT_AddressClass ac, 125 enum GNUNET_NAT_AddressClass ac,
126 const struct sockaddr *addr, 126 const struct sockaddr *addr,
127 socklen_t addrlen) 127 socklen_t addrlen)
128{ 128{
129 (void) cls; 129 (void) cls;
130 (void) app_ctx; 130 (void) app_ctx;
131 131
132 fprintf (stdout, 132 fprintf (stdout,
133 "%s %s (%d)\n", 133 "%s %s (%d)\n",
134 add_remove ? "+" : "-", 134 add_remove ? "+" : "-",
135 GNUNET_a2s (addr, 135 GNUNET_a2s (addr, addrlen),
136 addrlen),
137 (int) ac); 136 (int) ac);
138} 137}
139 138
@@ -149,13 +148,12 @@ address_cb (void *cls,
149 */ 148 */
150static void 149static void
151reversal_cb (void *cls, 150reversal_cb (void *cls,
152 const struct sockaddr *remote_addr, 151 const struct sockaddr *remote_addr,
153 socklen_t remote_addrlen) 152 socklen_t remote_addrlen)
154{ 153{
155 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 154 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
156 "Connection reversal requested by %s\n", 155 "Connection reversal requested by %s\n",
157 GNUNET_a2s (remote_addr, 156 GNUNET_a2s (remote_addr, remote_addrlen));
158 remote_addrlen));
159} 157}
160 158
161 159
@@ -194,9 +192,9 @@ stun_read_task (void *cls)
194 ssize_t size; 192 ssize_t size;
195 193
196 rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 194 rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
197 ls, 195 ls,
198 &stun_read_task, 196 &stun_read_task,
199 NULL); 197 NULL);
200 size = GNUNET_NETWORK_socket_recvfrom_amount (ls); 198 size = GNUNET_NETWORK_socket_recvfrom_amount (ls);
201 if (size > 0) 199 if (size > 0)
202 { 200 {
@@ -212,10 +210,10 @@ stun_read_task (void *cls)
212 ssize_t ret; 210 ssize_t ret;
213 211
214 ret = GNUNET_NETWORK_socket_recvfrom (ls, 212 ret = GNUNET_NETWORK_socket_recvfrom (ls,
215 buf, 213 buf,
216 size + 1, 214 size + 1,
217 (struct sockaddr *) &sa, 215 (struct sockaddr *) &sa,
218 &salen); 216 &salen);
219 if (ret != size) 217 if (ret != size)
220 { 218 {
221 GNUNET_break (0); 219 GNUNET_break (0);
@@ -224,10 +222,10 @@ stun_read_task (void *cls)
224 return; 222 return;
225 } 223 }
226 (void) GNUNET_NAT_stun_handle_packet (nh, 224 (void) GNUNET_NAT_stun_handle_packet (nh,
227 (const struct sockaddr *) &sa, 225 (const struct sockaddr *) &sa,
228 salen, 226 salen,
229 buf, 227 buf,
230 ret); 228 ret);
231 } 229 }
232} 230}
233 231
@@ -254,8 +252,7 @@ run (void *cls,
254 252
255 if (use_tcp && use_udp) 253 if (use_tcp && use_udp)
256 { 254 {
257 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 255 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Cannot use TCP and UDP\n");
258 "Cannot use TCP and UDP\n");
259 global_ret = 1; 256 global_ret = 1;
260 return; 257 return;
261 } 258 }
@@ -265,13 +262,11 @@ run (void *cls,
265 if (use_udp) 262 if (use_udp)
266 proto = IPPROTO_UDP; 263 proto = IPPROTO_UDP;
267 264
268 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 265 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
269 NULL);
270 266
271 if (0 == proto) 267 if (0 == proto)
272 { 268 {
273 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 269 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Must specify either TCP or UDP\n");
274 "Must specify either TCP or UDP\n");
275 global_ret = 1; 270 global_ret = 1;
276 return; 271 return;
277 } 272 }
@@ -281,28 +276,26 @@ run (void *cls,
281 remote_sa = NULL; 276 remote_sa = NULL;
282 if (NULL != local_addr) 277 if (NULL != local_addr)
283 { 278 {
284 local_len = (socklen_t) GNUNET_STRINGS_parse_socket_addr (local_addr, 279 local_len =
285 &af, 280 (socklen_t) GNUNET_STRINGS_parse_socket_addr (local_addr, &af, &local_sa);
286 &local_sa);
287 if (0 == local_len) 281 if (0 == local_len)
288 { 282 {
289 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 283 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
290 "Invalid socket address `%s'\n", 284 "Invalid socket address `%s'\n",
291 local_addr); 285 local_addr);
292 goto fail_and_shutdown; 286 goto fail_and_shutdown;
293 } 287 }
294 } 288 }
295 289
296 if (NULL != remote_addr) 290 if (NULL != remote_addr)
297 { 291 {
298 remote_len = GNUNET_STRINGS_parse_socket_addr (remote_addr, 292 remote_len =
299 &af, 293 GNUNET_STRINGS_parse_socket_addr (remote_addr, &af, &remote_sa);
300 &remote_sa);
301 if (0 == remote_len) 294 if (0 == remote_len)
302 { 295 {
303 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 296 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
304 "Invalid socket address `%s'\n", 297 "Invalid socket address `%s'\n",
305 remote_addr); 298 remote_addr);
306 goto fail_and_shutdown; 299 goto fail_and_shutdown;
307 } 300 }
308 } 301 }
@@ -312,19 +305,19 @@ run (void *cls,
312 if (NULL == section_name) 305 if (NULL == section_name)
313 section_name = GNUNET_strdup ("undefined"); 306 section_name = GNUNET_strdup ("undefined");
314 nh = GNUNET_NAT_register (c, 307 nh = GNUNET_NAT_register (c,
315 section_name, 308 section_name,
316 proto, 309 proto,
317 1, 310 1,
318 (const struct sockaddr **) &local_sa, 311 (const struct sockaddr **) &local_sa,
319 &local_len, 312 &local_len,
320 &address_cb, 313 &address_cb,
321 (listen_reversal) ? &reversal_cb : NULL, 314 (listen_reversal) ? &reversal_cb : NULL,
322 NULL); 315 NULL);
323 } 316 }
324 else if (listen_reversal) 317 else if (listen_reversal)
325 { 318 {
326 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 319 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
327 "Use of `-W` only effective in combination with `-i`\n"); 320 "Use of `-W` only effective in combination with `-i`\n");
328 goto fail_and_shutdown; 321 goto fail_and_shutdown;
329 } 322 }
330 323
@@ -332,33 +325,32 @@ run (void *cls,
332 { 325 {
333 int ret; 326 int ret;
334 327
335 if ( (NULL == nh) || 328 if ((NULL == nh) || (sizeof (struct sockaddr_in) != local_len))
336 (sizeof (struct sockaddr_in) != local_len) )
337 { 329 {
338 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 330 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
339 "Require IPv4 local address to initiate connection reversal\n"); 331 "Require IPv4 local address to initiate connection reversal\n");
340 goto fail_and_shutdown; 332 goto fail_and_shutdown;
341 } 333 }
342 if (sizeof (struct sockaddr_in) != remote_len) 334 if (sizeof (struct sockaddr_in) != remote_len)
343 { 335 {
344 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 336 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
345 "Require IPv4 reversal target address\n"); 337 "Require IPv4 reversal target address\n");
346 goto fail_and_shutdown; 338 goto fail_and_shutdown;
347 } 339 }
348 GNUNET_assert (AF_INET == local_sa->sa_family); 340 GNUNET_assert (AF_INET == local_sa->sa_family);
349 GNUNET_assert (AF_INET == remote_sa->sa_family); 341 GNUNET_assert (AF_INET == remote_sa->sa_family);
350 ret = GNUNET_NAT_request_reversal (nh, 342 ret = GNUNET_NAT_request_reversal (nh,
351 (const struct sockaddr_in *) local_sa, 343 (const struct sockaddr_in *) local_sa,
352 (const struct sockaddr_in *) remote_sa); 344 (const struct sockaddr_in *) remote_sa);
353 switch (ret) 345 switch (ret)
354 { 346 {
355 case GNUNET_SYSERR: 347 case GNUNET_SYSERR:
356 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 348 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
357 "Connection reversal internal error\n"); 349 "Connection reversal internal error\n");
358 break; 350 break;
359 case GNUNET_NO: 351 case GNUNET_NO:
360 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 352 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
361 "Connection reversal unavailable\n"); 353 "Connection reversal unavailable\n");
362 break; 354 break;
363 case GNUNET_OK: 355 case GNUNET_OK:
364 /* operation in progress */ 356 /* operation in progress */
@@ -371,46 +363,38 @@ run (void *cls,
371 if (NULL == local_addr) 363 if (NULL == local_addr)
372 { 364 {
373 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 365 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
374 "Require local address to support STUN requests\n"); 366 "Require local address to support STUN requests\n");
375 goto fail_and_shutdown; 367 goto fail_and_shutdown;
376 } 368 }
377 if (IPPROTO_UDP != proto) 369 if (IPPROTO_UDP != proto)
378 { 370 {
379 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 371 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "STUN only supported over UDP\n");
380 "STUN only supported over UDP\n");
381 goto fail_and_shutdown; 372 goto fail_and_shutdown;
382 } 373 }
383 ls = GNUNET_NETWORK_socket_create (af, 374 ls = GNUNET_NETWORK_socket_create (af, SOCK_DGRAM, IPPROTO_UDP);
384 SOCK_DGRAM,
385 IPPROTO_UDP);
386 if (NULL == ls) 375 if (NULL == ls)
387 { 376 {
388 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 377 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Failed to create socket\n");
389 "Failed to create socket\n");
390 goto fail_and_shutdown; 378 goto fail_and_shutdown;
391 } 379 }
392 if (GNUNET_OK != 380 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (ls, local_sa, local_len))
393 GNUNET_NETWORK_socket_bind (ls,
394 local_sa,
395 local_len))
396 { 381 {
397 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 382 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
398 "Failed to bind to %s: %s\n", 383 "Failed to bind to %s: %s\n",
399 GNUNET_a2s (local_sa, 384 GNUNET_a2s (local_sa, local_len),
400 local_len), 385 strerror (errno));
401 STRERROR (errno));
402 goto fail_and_shutdown; 386 goto fail_and_shutdown;
403 } 387 }
404 rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 388 rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
405 ls, 389 ls,
406 &stun_read_task, 390 &stun_read_task,
407 NULL); 391 NULL);
408 } 392 }
409 GNUNET_free_non_null (remote_sa); 393 GNUNET_free_non_null (remote_sa);
410 GNUNET_free_non_null (local_sa); 394 GNUNET_free_non_null (local_sa);
411 test_finished (); 395 test_finished ();
412 return; 396 return;
413 fail_and_shutdown: 397fail_and_shutdown:
414 global_ret = 1; 398 global_ret = 1;
415 GNUNET_SCHEDULER_shutdown (); 399 GNUNET_SCHEDULER_shutdown ();
416 GNUNET_free_non_null (remote_sa); 400 GNUNET_free_non_null (remote_sa);
@@ -426,66 +410,63 @@ run (void *cls,
426 * @return 0 on success, -1 on error 410 * @return 0 on success, -1 on error
427 */ 411 */
428int 412int
429main (int argc, 413main (int argc, char *const argv[])
430 char *const argv[])
431{ 414{
432 struct GNUNET_GETOPT_CommandLineOption options[] = { 415 struct GNUNET_GETOPT_CommandLineOption options[] = {
433 416
434 GNUNET_GETOPT_option_string ('i', 417 GNUNET_GETOPT_option_string (
435 "in", 418 'i',
436 "ADDRESS", 419 "in",
437 gettext_noop ("which IP and port are we locally using to bind/listen to"), 420 "ADDRESS",
438 &local_addr), 421 gettext_noop ("which IP and port are we locally using to bind/listen to"),
439 422 &local_addr),
440 GNUNET_GETOPT_option_string ('r', 423
441 "remote", 424 GNUNET_GETOPT_option_string (
442 "ADDRESS", 425 'r',
443 gettext_noop ("which remote IP and port should be asked for connection reversal"), 426 "remote",
444 &remote_addr), 427 "ADDRESS",
445 428 gettext_noop (
446 GNUNET_GETOPT_option_string ('S', 429 "which remote IP and port should be asked for connection reversal"),
447 "section", 430 &remote_addr),
448 NULL, 431
449 gettext_noop ("name of configuration section to find additional options, such as manual host punching data"), 432 GNUNET_GETOPT_option_string (
450 &section_name), 433 'S',
434 "section",
435 NULL,
436 gettext_noop (
437 "name of configuration section to find additional options, such as manual host punching data"),
438 &section_name),
451 439
452 GNUNET_GETOPT_option_flag ('s', 440 GNUNET_GETOPT_option_flag ('s',
453 "stun", 441 "stun",
454 gettext_noop ("enable STUN processing"), 442 gettext_noop ("enable STUN processing"),
455 &do_stun), 443 &do_stun),
456 444
457 GNUNET_GETOPT_option_flag ('t', 445 GNUNET_GETOPT_option_flag ('t', "tcp", gettext_noop ("use TCP"), &use_tcp),
458 "tcp",
459 gettext_noop ("use TCP"),
460 &use_tcp),
461 446
462 GNUNET_GETOPT_option_flag ('u', 447 GNUNET_GETOPT_option_flag ('u', "udp", gettext_noop ("use UDP"), &use_udp),
463 "udp",
464 gettext_noop ("use UDP"),
465 &use_udp),
466 448
467 GNUNET_GETOPT_option_flag ('W', 449 GNUNET_GETOPT_option_flag ('W',
468 "watch", 450 "watch",
469 gettext_noop ("watch for connection reversal requests"), 451 gettext_noop (
470 &listen_reversal), 452 "watch for connection reversal requests"),
471 GNUNET_GETOPT_OPTION_END 453 &listen_reversal),
472 }; 454 GNUNET_GETOPT_OPTION_END};
473 455
474 if (GNUNET_OK != 456 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
475 GNUNET_STRINGS_get_utf8_args (argc, argv,
476 &argc, &argv))
477 return 2; 457 return 2;
478 if (GNUNET_OK != 458 if (GNUNET_OK !=
479 GNUNET_PROGRAM_run (argc, argv, 459 GNUNET_PROGRAM_run (argc,
480 "gnunet-nat [options]", 460 argv,
481 _("GNUnet NAT traversal autoconfigure daemon"), 461 "gnunet-nat [options]",
482 options, 462 _ ("GNUnet NAT traversal autoconfigure daemon"),
463 options,
483 &run, 464 &run,
484 NULL)) 465 NULL))
485 { 466 {
486 global_ret = 1; 467 global_ret = 1;
487 } 468 }
488 GNUNET_free ((void*) argv); 469 GNUNET_free ((void *) argv);
489 return global_ret; 470 return global_ret;
490} 471}
491 472