diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-10-31 21:02:30 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-10-31 21:02:30 +0000 |
commit | db0bbaa1293f15ca825c69addfaa76beab40829e (patch) | |
tree | 5080d930bbe7a79934955c79e2a754f1988a742e | |
parent | 331e0e66df283db2d305bd6b80ac2b1896271d4f (diff) | |
download | gnunet-db0bbaa1293f15ca825c69addfaa76beab40829e.tar.gz gnunet-db0bbaa1293f15ca825c69addfaa76beab40829e.zip |
-more work towards NAT service
-rw-r--r-- | src/nat/gnunet-service-nat.c | 550 | ||||
-rw-r--r-- | src/nat/nat.c | 2 | ||||
-rw-r--r-- | src/nat/nat_api.c | 29 |
3 files changed, 568 insertions, 13 deletions
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c index 607797081..c3e134b35 100644 --- a/src/nat/gnunet-service-nat.c +++ b/src/nat/gnunet-service-nat.c | |||
@@ -39,6 +39,13 @@ | |||
39 | 39 | ||
40 | 40 | ||
41 | /** | 41 | /** |
42 | * How often should we ask the OS about a list of active | ||
43 | * network interfaces? | ||
44 | */ | ||
45 | #define SCAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) | ||
46 | |||
47 | |||
48 | /** | ||
42 | * Internal data structure we track for each of our clients. | 49 | * Internal data structure we track for each of our clients. |
43 | */ | 50 | */ |
44 | struct ClientHandle | 51 | struct ClientHandle |
@@ -63,16 +70,16 @@ struct ClientHandle | |||
63 | * Message queue for communicating with the client. | 70 | * Message queue for communicating with the client. |
64 | */ | 71 | */ |
65 | struct GNUNET_MQ_Handle *mq; | 72 | struct GNUNET_MQ_Handle *mq; |
66 | 73 | ||
67 | /** | 74 | /** |
68 | * What does this client care about? | 75 | * Array of addresses used by the service. |
69 | */ | 76 | */ |
70 | enum GNUNET_NAT_RegisterFlags flags; | 77 | struct sockaddr **addrs; |
71 | 78 | ||
72 | /** | 79 | /** |
73 | * Client's IPPROTO, e.g. IPPROTO_UDP or IPPROTO_TCP. | 80 | * What does this client care about? |
74 | */ | 81 | */ |
75 | uint8_t proto; | 82 | enum GNUNET_NAT_RegisterFlags flags; |
76 | 83 | ||
77 | /** | 84 | /** |
78 | * Port we would like as we are configured to use this one for | 85 | * Port we would like as we are configured to use this one for |
@@ -84,15 +91,47 @@ struct ClientHandle | |||
84 | * Number of addresses that this service is bound to. | 91 | * Number of addresses that this service is bound to. |
85 | */ | 92 | */ |
86 | uint16_t num_addrs; | 93 | uint16_t num_addrs; |
94 | |||
95 | /** | ||
96 | * Client's IPPROTO, e.g. IPPROTO_UDP or IPPROTO_TCP. | ||
97 | */ | ||
98 | uint8_t proto; | ||
99 | |||
100 | }; | ||
101 | |||
102 | |||
103 | /** | ||
104 | * List of local addresses this system has. | ||
105 | */ | ||
106 | struct LocalAddressList | ||
107 | { | ||
108 | /** | ||
109 | * This is a linked list. | ||
110 | */ | ||
111 | struct LocalAddressList *next; | ||
87 | 112 | ||
88 | /** | 113 | /** |
89 | * Array of addresses used by the service. | 114 | * Previous entry. |
90 | */ | 115 | */ |
91 | struct sockaddr **addrs; | 116 | struct LocalAddressList *prev; |
117 | |||
118 | /** | ||
119 | * The address itself (i.e. `struct in_addr` or `struct in6_addr`, | ||
120 | * in the respective byte order). Allocated at the end of this | ||
121 | * struct. | ||
122 | */ | ||
123 | const void *addr; | ||
124 | |||
125 | /** | ||
126 | * Address family. | ||
127 | */ | ||
128 | int af; | ||
92 | 129 | ||
93 | }; | 130 | }; |
94 | 131 | ||
95 | 132 | ||
133 | |||
134 | |||
96 | /** | 135 | /** |
97 | * Handle to our current configuration. | 136 | * Handle to our current configuration. |
98 | */ | 137 | */ |
@@ -118,20 +157,85 @@ static struct ClientHandle *ch_head; | |||
118 | */ | 157 | */ |
119 | static struct ClientHandle *ch_tail; | 158 | static struct ClientHandle *ch_tail; |
120 | 159 | ||
160 | /** | ||
161 | * Head of DLL of local addresses. | ||
162 | */ | ||
163 | static struct LocalAddressList *lal_head; | ||
121 | 164 | ||
122 | /** | 165 | /** |
123 | * Handler for #GNUNET_MESSAGE_TYPE_NAT_REGISTER message from client. | 166 | * Tail of DLL of local addresses. |
124 | * We remember the client for updates upon future NAT events. | 167 | */ |
168 | static struct LocalAddressList *lal_tail; | ||
169 | |||
170 | |||
171 | /** | ||
172 | * Free the DLL starting at #lal_head. | ||
173 | */ | ||
174 | static void | ||
175 | destroy_lal () | ||
176 | { | ||
177 | struct LocalAddressList *lal; | ||
178 | |||
179 | while (NULL != (lal = lal_head)) | ||
180 | { | ||
181 | GNUNET_CONTAINER_DLL_remove (lal_head, | ||
182 | lal_tail, | ||
183 | lal); | ||
184 | GNUNET_free (lal); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | |||
189 | /** | ||
190 | * Check validity of #GNUNET_MESSAGE_TYPE_NAT_REGISTER message from | ||
191 | * client. | ||
125 | * | 192 | * |
126 | * @param cls client who sent the message | 193 | * @param cls client who sent the message |
127 | * @param message the message received | 194 | * @param message the message received |
195 | * @return #GNUNET_OK if message is well-formed | ||
128 | */ | 196 | */ |
129 | static int | 197 | static int |
130 | check_register (void *cls, | 198 | check_register (void *cls, |
131 | const struct GNUNET_NAT_RegisterMessage *message) | 199 | const struct GNUNET_NAT_RegisterMessage *message) |
132 | { | 200 | { |
133 | GNUNET_break (0); // not implemented | 201 | uint16_t num_addrs = ntohs (message->num_addrs); |
134 | return GNUNET_SYSERR; | 202 | const char *off = (const char *) &message[1]; |
203 | size_t left = ntohs (message->header.size) - sizeof (*message); | ||
204 | |||
205 | for (unsigned int i=0;i<num_addrs;i++) | ||
206 | { | ||
207 | size_t alen; | ||
208 | const struct sockaddr *sa = (const struct sockaddr *) off; | ||
209 | |||
210 | if (sizeof (sa_family_t) > left) | ||
211 | { | ||
212 | GNUNET_break (0); | ||
213 | return GNUNET_SYSERR; | ||
214 | } | ||
215 | switch (sa->sa_family) | ||
216 | { | ||
217 | case AF_INET: | ||
218 | alen = sizeof (struct sockaddr_in); | ||
219 | break; | ||
220 | case AF_INET6: | ||
221 | alen = sizeof (struct sockaddr_in6); | ||
222 | break; | ||
223 | #if AF_UNIX | ||
224 | case AF_UNIX: | ||
225 | alen = sizeof (struct sockaddr_un); | ||
226 | break; | ||
227 | #endif | ||
228 | default: | ||
229 | GNUNET_break (0); | ||
230 | return GNUNET_SYSERR; | ||
231 | } | ||
232 | if (alen > left) | ||
233 | { | ||
234 | GNUNET_break (0); | ||
235 | return GNUNET_SYSERR; | ||
236 | } | ||
237 | } | ||
238 | return GNUNET_OK; | ||
135 | } | 239 | } |
136 | 240 | ||
137 | 241 | ||
@@ -147,10 +251,307 @@ handle_register (void *cls, | |||
147 | const struct GNUNET_NAT_RegisterMessage *message) | 251 | const struct GNUNET_NAT_RegisterMessage *message) |
148 | { | 252 | { |
149 | struct ClientHandle *ch = cls; | 253 | struct ClientHandle *ch = cls; |
150 | // struct GNUNET_MQ_Handle *mq; | 254 | const char *off; |
255 | size_t left; | ||
151 | 256 | ||
257 | if ( (0 != ch->proto) || | ||
258 | (NULL != ch->addrs) ) | ||
259 | { | ||
260 | /* double registration not allowed */ | ||
261 | GNUNET_break (0); | ||
262 | GNUNET_SERVICE_client_drop (ch->client); | ||
263 | return; | ||
264 | } | ||
152 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 265 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
153 | "Received REGISTER message from client\n"); | 266 | "Received REGISTER message from client\n"); |
267 | ch->flags = message->flags; | ||
268 | ch->proto = message->proto; | ||
269 | ch->adv_port = ntohs (message->adv_port); | ||
270 | ch->num_addrs = ntohs (message->adv_port); | ||
271 | ch->addrs = GNUNET_new_array (ch->num_addrs, | ||
272 | struct sockaddr *); | ||
273 | left = ntohs (message->header.size) - sizeof (*message); | ||
274 | off = (const char *) &message[1]; | ||
275 | for (unsigned int i=0;i<ch->num_addrs;i++) | ||
276 | { | ||
277 | size_t alen; | ||
278 | const struct sockaddr *sa = (const struct sockaddr *) off; | ||
279 | |||
280 | if (sizeof (sa_family_t) > left) | ||
281 | { | ||
282 | GNUNET_break (0); | ||
283 | GNUNET_SERVICE_client_drop (ch->client); | ||
284 | return; | ||
285 | } | ||
286 | switch (sa->sa_family) | ||
287 | { | ||
288 | case AF_INET: | ||
289 | alen = sizeof (struct sockaddr_in); | ||
290 | break; | ||
291 | case AF_INET6: | ||
292 | alen = sizeof (struct sockaddr_in6); | ||
293 | break; | ||
294 | #if AF_UNIX | ||
295 | case AF_UNIX: | ||
296 | alen = sizeof (struct sockaddr_un); | ||
297 | break; | ||
298 | #endif | ||
299 | default: | ||
300 | GNUNET_break (0); | ||
301 | GNUNET_SERVICE_client_drop (ch->client); | ||
302 | return; | ||
303 | } | ||
304 | GNUNET_assert (alen <= left); | ||
305 | ch->addrs[i] = GNUNET_malloc (alen); | ||
306 | GNUNET_memcpy (ch->addrs[i], | ||
307 | sa, | ||
308 | alen); | ||
309 | off += alen; | ||
310 | } | ||
311 | GNUNET_SERVICE_client_continue (ch->client); | ||
312 | } | ||
313 | |||
314 | |||
315 | /** | ||
316 | * Check validity of #GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN message from | ||
317 | * client. | ||
318 | * | ||
319 | * @param cls client who sent the message | ||
320 | * @param message the message received | ||
321 | * @return #GNUNET_OK if message is well-formed | ||
322 | */ | ||
323 | static int | ||
324 | check_stun (void *cls, | ||
325 | const struct GNUNET_NAT_HandleStunMessage *message) | ||
326 | { | ||
327 | size_t sa_len = ntohs (message->sender_addr_size); | ||
328 | size_t expect = sa_len + ntohs (message->payload_size); | ||
329 | |||
330 | if (ntohs (message->header.size) - sizeof (*message) != expect) | ||
331 | { | ||
332 | GNUNET_break (0); | ||
333 | return GNUNET_SYSERR; | ||
334 | } | ||
335 | if (sa_len < sizeof (sa_family_t)) | ||
336 | { | ||
337 | GNUNET_break (0); | ||
338 | return GNUNET_SYSERR; | ||
339 | } | ||
340 | return GNUNET_OK; | ||
341 | } | ||
342 | |||
343 | |||
344 | /** | ||
345 | * Handler for #GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN message from | ||
346 | * client. | ||
347 | * | ||
348 | * @param cls client who sent the message | ||
349 | * @param message the message received | ||
350 | */ | ||
351 | static void | ||
352 | handle_stun (void *cls, | ||
353 | const struct GNUNET_NAT_HandleStunMessage *message) | ||
354 | { | ||
355 | struct ClientHandle *ch = cls; | ||
356 | const char *buf = (const char *) &message[1]; | ||
357 | const struct sockaddr *sa; | ||
358 | const void *payload; | ||
359 | size_t sa_len; | ||
360 | size_t payload_size; | ||
361 | |||
362 | sa_len = ntohs (message->sender_addr_size); | ||
363 | payload_size = ntohs (message->payload_size); | ||
364 | sa = (const struct sockaddr *) &buf[0]; | ||
365 | payload = (const struct sockaddr *) &buf[sa_len]; | ||
366 | switch (sa->sa_family) | ||
367 | { | ||
368 | case AF_INET: | ||
369 | if (sa_len != sizeof (struct sockaddr_in)) | ||
370 | { | ||
371 | GNUNET_break (0); | ||
372 | GNUNET_SERVICE_client_drop (ch->client); | ||
373 | return; | ||
374 | } | ||
375 | break; | ||
376 | case AF_INET6: | ||
377 | if (sa_len != sizeof (struct sockaddr_in6)) | ||
378 | { | ||
379 | GNUNET_break (0); | ||
380 | GNUNET_SERVICE_client_drop (ch->client); | ||
381 | return; | ||
382 | } | ||
383 | break; | ||
384 | } | ||
385 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
386 | "Received HANDLE_STUN message from client\n"); | ||
387 | // FIXME: actually handle STUN request! | ||
388 | GNUNET_SERVICE_client_continue (ch->client); | ||
389 | } | ||
390 | |||
391 | |||
392 | /** | ||
393 | * Check validity of | ||
394 | * #GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL message from | ||
395 | * client. | ||
396 | * | ||
397 | * @param cls client who sent the message | ||
398 | * @param message the message received | ||
399 | * @return #GNUNET_OK if message is well-formed | ||
400 | */ | ||
401 | static int | ||
402 | check_request_connection_reversal (void *cls, | ||
403 | const struct GNUNET_NAT_RequestConnectionReversalMessage *message) | ||
404 | { | ||
405 | size_t expect; | ||
406 | |||
407 | expect = ntohs (message->local_addr_size) | ||
408 | + ntohs (message->remote_addr_size); | ||
409 | if (ntohs (message->header.size) - sizeof (*message) != expect) | ||
410 | { | ||
411 | GNUNET_break (0); | ||
412 | return GNUNET_SYSERR; | ||
413 | } | ||
414 | return GNUNET_OK; | ||
415 | } | ||
416 | |||
417 | |||
418 | /** | ||
419 | * Handler for #GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL | ||
420 | * message from client. | ||
421 | * | ||
422 | * @param cls client who sent the message | ||
423 | * @param message the message received | ||
424 | */ | ||
425 | static void | ||
426 | handle_request_connection_reversal (void *cls, | ||
427 | const struct GNUNET_NAT_RequestConnectionReversalMessage *message) | ||
428 | { | ||
429 | struct ClientHandle *ch = cls; | ||
430 | const char *buf = (const char *) &message[1]; | ||
431 | size_t local_sa_len = ntohs (message->local_addr_size); | ||
432 | size_t remote_sa_len = ntohs (message->remote_addr_size); | ||
433 | const struct sockaddr *local_sa = (const struct sockaddr *) &buf[0]; | ||
434 | const struct sockaddr *remote_sa = (const struct sockaddr *) &buf[local_sa_len]; | ||
435 | |||
436 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
437 | "Received REQUEST CONNECTION REVERSAL message from client\n"); | ||
438 | switch (local_sa->sa_family) | ||
439 | { | ||
440 | case AF_INET: | ||
441 | if (local_sa_len != sizeof (struct sockaddr_in)) | ||
442 | { | ||
443 | GNUNET_break (0); | ||
444 | GNUNET_SERVICE_client_drop (ch->client); | ||
445 | return; | ||
446 | } | ||
447 | break; | ||
448 | case AF_INET6: | ||
449 | if (local_sa_len != sizeof (struct sockaddr_in6)) | ||
450 | { | ||
451 | GNUNET_break (0); | ||
452 | GNUNET_SERVICE_client_drop (ch->client); | ||
453 | return; | ||
454 | } | ||
455 | break; | ||
456 | default: | ||
457 | GNUNET_break (0); | ||
458 | GNUNET_SERVICE_client_drop (ch->client); | ||
459 | return; | ||
460 | } | ||
461 | switch (remote_sa->sa_family) | ||
462 | { | ||
463 | case AF_INET: | ||
464 | if (remote_sa_len != sizeof (struct sockaddr_in)) | ||
465 | { | ||
466 | GNUNET_break (0); | ||
467 | GNUNET_SERVICE_client_drop (ch->client); | ||
468 | return; | ||
469 | } | ||
470 | break; | ||
471 | case AF_INET6: | ||
472 | if (remote_sa_len != sizeof (struct sockaddr_in6)) | ||
473 | { | ||
474 | GNUNET_break (0); | ||
475 | GNUNET_SERVICE_client_drop (ch->client); | ||
476 | return; | ||
477 | } | ||
478 | break; | ||
479 | default: | ||
480 | GNUNET_break (0); | ||
481 | GNUNET_SERVICE_client_drop (ch->client); | ||
482 | return; | ||
483 | } | ||
484 | /* FIXME: actually run the logic! */ | ||
485 | |||
486 | GNUNET_SERVICE_client_continue (ch->client); | ||
487 | } | ||
488 | |||
489 | |||
490 | /** | ||
491 | * Handler for #GNUNET_MESSAGE_TYPE_NAT_REQUEST_TEST message from | ||
492 | * client. | ||
493 | * | ||
494 | * @param cls client who sent the message | ||
495 | * @param message the message received | ||
496 | */ | ||
497 | static void | ||
498 | handle_test (void *cls, | ||
499 | const struct GNUNET_NAT_RequestTestMessage *message) | ||
500 | { | ||
501 | struct ClientHandle *ch = cls; | ||
502 | |||
503 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
504 | "Received REQUEST_TEST message from client\n"); | ||
505 | GNUNET_SERVICE_client_continue (ch->client); | ||
506 | } | ||
507 | |||
508 | |||
509 | /** | ||
510 | * Check validity of #GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG message | ||
511 | * from client. | ||
512 | * | ||
513 | * @param cls client who sent the message | ||
514 | * @param message the message received | ||
515 | * @return #GNUNET_OK if message is well-formed | ||
516 | */ | ||
517 | static int | ||
518 | check_autoconfig_request (void *cls, | ||
519 | const struct GNUNET_NAT_AutoconfigRequestMessage *message) | ||
520 | { | ||
521 | return GNUNET_OK; /* checked later */ | ||
522 | } | ||
523 | |||
524 | |||
525 | /** | ||
526 | * Handler for #GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG message from | ||
527 | * client. | ||
528 | * | ||
529 | * @param cls client who sent the message | ||
530 | * @param message the message received | ||
531 | */ | ||
532 | static void | ||
533 | handle_autoconfig_request (void *cls, | ||
534 | const struct GNUNET_NAT_AutoconfigRequestMessage *message) | ||
535 | { | ||
536 | struct ClientHandle *ch = cls; | ||
537 | size_t left = ntohs (message->header.size); | ||
538 | struct GNUNET_CONFIGURATION_Handle *c; | ||
539 | |||
540 | c = GNUNET_CONFIGURATION_create (); | ||
541 | if (GNUNET_OK != | ||
542 | GNUNET_CONFIGURATION_deserialize (c, | ||
543 | (const char *) &message[1], | ||
544 | left, | ||
545 | GNUNET_NO)) | ||
546 | { | ||
547 | GNUNET_break (0); | ||
548 | GNUNET_SERVICE_client_drop (ch->client); | ||
549 | return; | ||
550 | } | ||
551 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
552 | "Received REQUEST_AUTO_CONFIG message from client\n"); | ||
553 | // FIXME: actually handle request... | ||
554 | GNUNET_CONFIGURATION_destroy (c); | ||
154 | GNUNET_SERVICE_client_continue (ch->client); | 555 | GNUNET_SERVICE_client_continue (ch->client); |
155 | } | 556 | } |
156 | 557 | ||
@@ -173,6 +574,110 @@ shutdown_task (void *cls) | |||
173 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | 574 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); |
174 | stats = NULL; | 575 | stats = NULL; |
175 | } | 576 | } |
577 | destroy_lal (); | ||
578 | } | ||
579 | |||
580 | |||
581 | /** | ||
582 | * Closure for #ifc_proc. | ||
583 | */ | ||
584 | struct IfcProcContext | ||
585 | { | ||
586 | |||
587 | /** | ||
588 | * Head of DLL of local addresses. | ||
589 | */ | ||
590 | struct LocalAddressList *lal_head; | ||
591 | |||
592 | /** | ||
593 | * Tail of DLL of local addresses. | ||
594 | */ | ||
595 | struct LocalAddressList *lal_tail; | ||
596 | |||
597 | }; | ||
598 | |||
599 | |||
600 | /** | ||
601 | * Callback function invoked for each interface found. Adds them | ||
602 | * to our new address list. | ||
603 | * | ||
604 | * @param cls a `struct IfcProcContext *` | ||
605 | * @param name name of the interface (can be NULL for unknown) | ||
606 | * @param isDefault is this presumably the default interface | ||
607 | * @param addr address of this interface (can be NULL for unknown or unassigned) | ||
608 | * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned) | ||
609 | * @param netmask the network mask (can be NULL for unknown or unassigned) | ||
610 | * @param addrlen length of the address | ||
611 | * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort | ||
612 | */ | ||
613 | static int | ||
614 | ifc_proc (void *cls, | ||
615 | const char *name, | ||
616 | int isDefault, | ||
617 | const struct sockaddr *addr, | ||
618 | const struct sockaddr *broadcast_addr, | ||
619 | const struct sockaddr *netmask, | ||
620 | socklen_t addrlen) | ||
621 | { | ||
622 | struct IfcProcContext *ifc_ctx = cls; | ||
623 | struct LocalAddressList *lal; | ||
624 | size_t alen; | ||
625 | const void *ip; | ||
626 | |||
627 | switch (addr->sa_family) | ||
628 | { | ||
629 | case AF_INET: | ||
630 | alen = sizeof (struct in_addr); | ||
631 | ip = &((const struct sockaddr_in *) addr)->sin_addr; | ||
632 | break; | ||
633 | case AF_INET6: | ||
634 | alen = sizeof (struct in6_addr); | ||
635 | ip = &((const struct sockaddr_in6 *) addr)->sin6_addr; | ||
636 | break; | ||
637 | #if AF_UNIX | ||
638 | case AF_UNIX: | ||
639 | GNUNET_break (0); | ||
640 | return GNUNET_OK; | ||
641 | #endif | ||
642 | default: | ||
643 | GNUNET_break (0); | ||
644 | return GNUNET_OK; | ||
645 | } | ||
646 | lal = GNUNET_malloc (sizeof (*lal) + alen); | ||
647 | lal->af = addr->sa_family; | ||
648 | lal->addr = &lal[1]; | ||
649 | GNUNET_memcpy (&lal[1], | ||
650 | ip, | ||
651 | alen); | ||
652 | GNUNET_CONTAINER_DLL_insert (ifc_ctx->lal_head, | ||
653 | ifc_ctx->lal_tail, | ||
654 | lal); | ||
655 | return GNUNET_OK; | ||
656 | } | ||
657 | |||
658 | |||
659 | /** | ||
660 | * Task we run periodically to scan for network interfaces. | ||
661 | * | ||
662 | * @param cls NULL | ||
663 | */ | ||
664 | static void | ||
665 | run_scan (void *cls) | ||
666 | { | ||
667 | struct IfcProcContext ifc_ctx; | ||
668 | |||
669 | scan_task = GNUNET_SCHEDULER_add_delayed (SCAN_FREQ, | ||
670 | &run_scan, | ||
671 | NULL); | ||
672 | memset (&ifc_ctx, | ||
673 | 0, | ||
674 | sizeof (ifc_ctx)); | ||
675 | GNUNET_OS_network_interfaces_list (&ifc_proc, | ||
676 | &ifc_ctx); | ||
677 | /* FIXME: notify clients of changes in lal-DLL */ | ||
678 | destroy_lal (); | ||
679 | lal_head = ifc_ctx.lal_head; | ||
680 | lal_tail = ifc_ctx.lal_tail; | ||
176 | } | 681 | } |
177 | 682 | ||
178 | 683 | ||
@@ -193,6 +698,8 @@ run (void *cls, | |||
193 | NULL); | 698 | NULL); |
194 | stats = GNUNET_STATISTICS_create ("nat", | 699 | stats = GNUNET_STATISTICS_create ("nat", |
195 | cfg); | 700 | cfg); |
701 | scan_task = GNUNET_SCHEDULER_add_now (&run_scan, | ||
702 | NULL); | ||
196 | } | 703 | } |
197 | 704 | ||
198 | 705 | ||
@@ -238,6 +745,9 @@ client_disconnect_cb (void *cls, | |||
238 | GNUNET_CONTAINER_DLL_remove (ch_head, | 745 | GNUNET_CONTAINER_DLL_remove (ch_head, |
239 | ch_tail, | 746 | ch_tail, |
240 | ch); | 747 | ch); |
748 | for (unsigned int i=0;i<ch->num_addrs;i++) | ||
749 | GNUNET_free_non_null (ch->addrs[i]); | ||
750 | GNUNET_free_non_null (ch->addrs); | ||
241 | GNUNET_free (ch); | 751 | GNUNET_free (ch); |
242 | } | 752 | } |
243 | 753 | ||
@@ -256,6 +766,22 @@ GNUNET_SERVICE_MAIN | |||
256 | GNUNET_MESSAGE_TYPE_NAT_REGISTER, | 766 | GNUNET_MESSAGE_TYPE_NAT_REGISTER, |
257 | struct GNUNET_NAT_RegisterMessage, | 767 | struct GNUNET_NAT_RegisterMessage, |
258 | NULL), | 768 | NULL), |
769 | GNUNET_MQ_hd_var_size (stun, | ||
770 | GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN, | ||
771 | struct GNUNET_NAT_HandleStunMessage, | ||
772 | NULL), | ||
773 | GNUNET_MQ_hd_var_size (request_connection_reversal, | ||
774 | GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL, | ||
775 | struct GNUNET_NAT_RequestConnectionReversalMessage, | ||
776 | NULL), | ||
777 | GNUNET_MQ_hd_fixed_size (test, | ||
778 | GNUNET_MESSAGE_TYPE_NAT_REQUEST_TEST, | ||
779 | struct GNUNET_NAT_RequestTestMessage, | ||
780 | NULL), | ||
781 | GNUNET_MQ_hd_var_size (autoconfig_request, | ||
782 | GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG, | ||
783 | struct GNUNET_NAT_AutoconfigRequestMessage, | ||
784 | NULL), | ||
259 | GNUNET_MQ_handler_end ()); | 785 | GNUNET_MQ_handler_end ()); |
260 | 786 | ||
261 | 787 | ||
diff --git a/src/nat/nat.c b/src/nat/nat.c index 9a9ae18ac..08dd5dd1e 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c | |||
@@ -76,7 +76,7 @@ enum LocalAddressSource | |||
76 | */ | 76 | */ |
77 | LAL_EXTERNAL_IP, | 77 | LAL_EXTERNAL_IP, |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * Address was obtained by an external STUN server | 80 | * Address was obtained by an external STUN server |
81 | */ | 81 | */ |
82 | LAL_EXTERNAL_STUN_IP, | 82 | LAL_EXTERNAL_STUN_IP, |
diff --git a/src/nat/nat_api.c b/src/nat/nat_api.c index e567368d2..421befab3 100644 --- a/src/nat/nat_api.c +++ b/src/nat/nat_api.c | |||
@@ -403,6 +403,35 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
403 | off = (char *) &rm[1]; | 403 | off = (char *) &rm[1]; |
404 | for (unsigned int i=0;i<num_addrs;i++) | 404 | for (unsigned int i=0;i<num_addrs;i++) |
405 | { | 405 | { |
406 | switch (addrs[i]->sa_family) | ||
407 | { | ||
408 | case AF_INET: | ||
409 | if (sizeof (struct sockaddr_in) != addrlens[i]) | ||
410 | { | ||
411 | GNUNET_break (0); | ||
412 | return NULL; | ||
413 | } | ||
414 | break; | ||
415 | case AF_INET6: | ||
416 | if (sizeof (struct sockaddr_in6) != addrlens[i]) | ||
417 | { | ||
418 | GNUNET_break (0); | ||
419 | return NULL; | ||
420 | } | ||
421 | break; | ||
422 | #if AF_UNIX | ||
423 | case AF_UNIX: | ||
424 | if (sizeof (struct sockaddr_un) != addrlens[i]) | ||
425 | { | ||
426 | GNUNET_break (0); | ||
427 | return NULL; | ||
428 | } | ||
429 | break; | ||
430 | #endif | ||
431 | default: | ||
432 | GNUNET_break (0); | ||
433 | return NULL; | ||
434 | } | ||
406 | GNUNET_memcpy (off, | 435 | GNUNET_memcpy (off, |
407 | addrs[i], | 436 | addrs[i], |
408 | addrlens[i]); | 437 | addrlens[i]); |