diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-11-18 16:29:06 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-11-18 16:29:06 +0000 |
commit | 4c83f8ec2199f9ba1dd792f08c0d934ffcdcb8f9 (patch) | |
tree | a51f20a4afede5ff4bbc5469d35c08636ba8788a /src/transport/plugin_transport_udp.c | |
parent | 55a8c591f7ad6796b2dc2c4c3d97c1daac5f425c (diff) | |
download | gnunet-4c83f8ec2199f9ba1dd792f08c0d934ffcdcb8f9.tar.gz gnunet-4c83f8ec2199f9ba1dd792f08c0d934ffcdcb8f9.zip |
udp now supports broadcasts using ipv6 multicast
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r-- | src/transport/plugin_transport_udp.c | 413 |
1 files changed, 347 insertions, 66 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 4fbd3f0ac..8a8cef806 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -346,42 +346,87 @@ struct Plugin | |||
346 | struct GNUNET_NETWORK_Handle *sockv6; | 346 | struct GNUNET_NETWORK_Handle *sockv6; |
347 | 347 | ||
348 | /** | 348 | /** |
349 | * Broadcast? | 349 | * Beacon broadcasting |
350 | * ------------------- | ||
350 | */ | 351 | */ |
351 | int broadcast; | 352 | |
353 | /** | ||
354 | * Broadcast interval | ||
355 | */ | ||
356 | struct GNUNET_TIME_Relative broadcast_interval; | ||
357 | |||
358 | /** | ||
359 | * Broadcast with IPv4 | ||
360 | */ | ||
361 | int broadcast_ipv4; | ||
352 | 362 | ||
353 | /** | 363 | /** |
354 | * Tokenizer for inbound messages. | 364 | * Tokenizer for inbound messages. |
355 | */ | 365 | */ |
356 | struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_mst; | 366 | struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_ipv4_mst; |
357 | 367 | ||
358 | /** | 368 | /** |
359 | * The read socket for IPv4 | 369 | * The read socket for IPv4 |
360 | */ | 370 | */ |
361 | struct GNUNET_NETWORK_Handle *sockv4_broadcast; | 371 | struct GNUNET_NETWORK_Handle *sockv4_broadcast; |
362 | 372 | ||
363 | struct BroadcastAddress *head; | ||
364 | struct BroadcastAddress *tail; | 373 | struct BroadcastAddress *tail; |
374 | struct BroadcastAddress *head; | ||
365 | 375 | ||
366 | /** | 376 | /** |
367 | * ID of select broadcast task | 377 | * ID of select broadcast task |
368 | */ | 378 | */ |
369 | GNUNET_SCHEDULER_TaskIdentifier select_broadcast_task; | 379 | GNUNET_SCHEDULER_TaskIdentifier select_ipv4_broadcast_task; |
370 | 380 | ||
371 | /** | 381 | /** |
372 | * ID of select broadcast task | 382 | * ID of select broadcast task |
373 | */ | 383 | */ |
374 | GNUNET_SCHEDULER_TaskIdentifier send_broadcast_task; | 384 | GNUNET_SCHEDULER_TaskIdentifier send_ipv4_broadcast_task; |
375 | 385 | ||
376 | /** | 386 | /** |
377 | * FD Read set | 387 | * FD Read set |
378 | */ | 388 | */ |
379 | struct GNUNET_NETWORK_FDSet *broadcast_rs; | 389 | struct GNUNET_NETWORK_FDSet *broadcast_ipv4_rs; |
390 | |||
380 | 391 | ||
381 | /** | 392 | /** |
382 | * Broadcast interval | 393 | * Broadcast with IPv6 |
383 | */ | 394 | */ |
384 | struct GNUNET_TIME_Relative broadcast_interval; | 395 | int broadcast_ipv6; |
396 | |||
397 | |||
398 | /** | ||
399 | * Tokenizer for inbound messages. | ||
400 | */ | ||
401 | struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_ipv6_mst; | ||
402 | |||
403 | /** | ||
404 | * The read socket for IPv6 | ||
405 | */ | ||
406 | struct GNUNET_NETWORK_Handle *sockv6_broadcast; | ||
407 | |||
408 | |||
409 | /** | ||
410 | * ID of select broadcast task | ||
411 | */ | ||
412 | GNUNET_SCHEDULER_TaskIdentifier select_ipv6_broadcast_task; | ||
413 | |||
414 | /** | ||
415 | * ID of select broadcast task | ||
416 | */ | ||
417 | GNUNET_SCHEDULER_TaskIdentifier send_ipv6_broadcast_task; | ||
418 | |||
419 | |||
420 | /** | ||
421 | * FD Read set | ||
422 | */ | ||
423 | struct GNUNET_NETWORK_FDSet *broadcast_ipv6_rs; | ||
424 | |||
425 | /** | ||
426 | * IPv6 multicast address | ||
427 | */ | ||
428 | struct sockaddr_in6 ipv6_multicast_address; | ||
429 | |||
385 | 430 | ||
386 | /** | 431 | /** |
387 | * expected delay for ACKs | 432 | * expected delay for ACKs |
@@ -1423,19 +1468,63 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1423 | } | 1468 | } |
1424 | 1469 | ||
1425 | 1470 | ||
1426 | struct MstContext | 1471 | struct Mstv4Context |
1427 | { | 1472 | { |
1428 | struct Plugin *plugin; | 1473 | struct Plugin *plugin; |
1429 | 1474 | ||
1430 | struct IPv4UdpAddress addr; | 1475 | struct IPv4UdpAddress addr; |
1431 | }; | 1476 | }; |
1432 | 1477 | ||
1478 | struct Mstv6Context | ||
1479 | { | ||
1480 | struct Plugin *plugin; | ||
1481 | |||
1482 | struct IPv6UdpAddress addr; | ||
1483 | }; | ||
1484 | |||
1485 | void | ||
1486 | broadcast_ipv4_mst_cb (void *cls, void *client, | ||
1487 | const struct GNUNET_MessageHeader *message) | ||
1488 | { | ||
1489 | struct Plugin *plugin = cls; | ||
1490 | struct Mstv4Context *mc = client; | ||
1491 | const struct GNUNET_MessageHeader *hello; | ||
1492 | struct UDP_Beacon_Message *msg; | ||
1493 | |||
1494 | msg = (struct UDP_Beacon_Message *) message; | ||
1495 | |||
1496 | if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON != | ||
1497 | ntohs (msg->header.type)) | ||
1498 | return; | ||
1499 | |||
1500 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1501 | "Received beacon with %u bytes from peer `%s' via address `%s'\n", | ||
1502 | ntohs (msg->header.size), GNUNET_i2s (&msg->sender), | ||
1503 | udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr))); | ||
1504 | |||
1505 | struct GNUNET_ATS_Information ats; | ||
1506 | |||
1507 | ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); | ||
1508 | ats.value = htonl (1); | ||
1509 | |||
1510 | hello = (struct GNUNET_MessageHeader *) &msg[1]; | ||
1511 | plugin->env->receive (plugin->env->cls, &msg->sender, hello, &ats, 1, NULL, | ||
1512 | (const char *) &mc->addr, sizeof (mc->addr)); | ||
1513 | |||
1514 | GNUNET_STATISTICS_update (plugin->env->stats, | ||
1515 | _("# HELLO beacons received via udp"), 1, | ||
1516 | GNUNET_NO); | ||
1517 | GNUNET_free (mc); | ||
1518 | } | ||
1519 | |||
1520 | |||
1433 | void | 1521 | void |
1434 | udp_broadcast_mst_cb (void *cls, void *client, | 1522 | broadcast_ipv6_mst_cb (void *cls, void *client, |
1435 | const struct GNUNET_MessageHeader *message) | 1523 | const struct GNUNET_MessageHeader *message) |
1436 | { | 1524 | { |
1525 | |||
1437 | struct Plugin *plugin = cls; | 1526 | struct Plugin *plugin = cls; |
1438 | struct MstContext *mc = client; | 1527 | struct Mstv6Context *mc = client; |
1439 | const struct GNUNET_MessageHeader *hello; | 1528 | const struct GNUNET_MessageHeader *hello; |
1440 | struct UDP_Beacon_Message *msg; | 1529 | struct UDP_Beacon_Message *msg; |
1441 | 1530 | ||
@@ -1445,7 +1534,7 @@ udp_broadcast_mst_cb (void *cls, void *client, | |||
1445 | ntohs (msg->header.type)) | 1534 | ntohs (msg->header.type)) |
1446 | return; | 1535 | return; |
1447 | 1536 | ||
1448 | LOG (GNUNET_ERROR_TYPE_ERROR, | 1537 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1449 | "Received beacon with %u bytes from peer `%s' via address `%s'\n", | 1538 | "Received beacon with %u bytes from peer `%s' via address `%s'\n", |
1450 | ntohs (msg->header.size), GNUNET_i2s (&msg->sender), | 1539 | ntohs (msg->header.size), GNUNET_i2s (&msg->sender), |
1451 | udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr))); | 1540 | udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr))); |
@@ -1465,6 +1554,9 @@ udp_broadcast_mst_cb (void *cls, void *client, | |||
1465 | GNUNET_free (mc); | 1554 | GNUNET_free (mc); |
1466 | } | 1555 | } |
1467 | 1556 | ||
1557 | |||
1558 | |||
1559 | |||
1468 | /** | 1560 | /** |
1469 | * Read and process a message from the given socket. | 1561 | * Read and process a message from the given socket. |
1470 | * | 1562 | * |
@@ -1478,7 +1570,7 @@ udp_broadcast_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) | |||
1478 | char addr[32]; | 1570 | char addr[32]; |
1479 | char buf[65536]; | 1571 | char buf[65536]; |
1480 | ssize_t ret; | 1572 | ssize_t ret; |
1481 | struct MstContext *mc; | 1573 | |
1482 | 1574 | ||
1483 | 1575 | ||
1484 | fromlen = sizeof (addr); | 1576 | fromlen = sizeof (addr); |
@@ -1492,22 +1584,41 @@ udp_broadcast_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) | |||
1492 | return; | 1584 | return; |
1493 | } | 1585 | } |
1494 | 1586 | ||
1495 | mc = GNUNET_malloc (sizeof (struct MstContext)); | 1587 | if (fromlen == sizeof (struct sockaddr_in)) |
1496 | 1588 | { | |
1497 | struct sockaddr_in *av4 = (struct sockaddr_in *) &addr; | 1589 | struct Mstv4Context *mc; |
1498 | 1590 | mc = GNUNET_malloc (sizeof (struct Mstv4Context)); | |
1499 | mc->addr.ipv4_addr = av4->sin_addr.s_addr; | 1591 | struct sockaddr_in *av4 = (struct sockaddr_in *) &addr; |
1500 | mc->addr.u4_port = av4->sin_port; | ||
1501 | 1592 | ||
1502 | if (GNUNET_OK != | 1593 | mc->addr.ipv4_addr = av4->sin_addr.s_addr; |
1503 | GNUNET_SERVER_mst_receive (plugin->broadcast_mst, mc, buf, ret, GNUNET_NO, | 1594 | mc->addr.u4_port = av4->sin_port; |
1595 | if (GNUNET_OK != | ||
1596 | GNUNET_SERVER_mst_receive (plugin->broadcast_ipv4_mst, mc, buf, ret, GNUNET_NO, | ||
1504 | GNUNET_NO)) | 1597 | GNUNET_NO)) |
1505 | GNUNET_free (mc); | 1598 | GNUNET_free (mc); |
1599 | } | ||
1600 | else if (fromlen == sizeof (struct sockaddr_in6)) | ||
1601 | { | ||
1602 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received IPv6 HELLO beacon broadcast with %i bytes from address %s\n", | ||
1603 | ret, GNUNET_a2s((const struct sockaddr *) &addr, fromlen)); | ||
1604 | |||
1605 | struct Mstv6Context *mc; | ||
1606 | mc = GNUNET_malloc (sizeof (struct Mstv6Context)); | ||
1607 | struct sockaddr_in6 *av6 = (struct sockaddr_in6 *) &addr; | ||
1608 | |||
1609 | mc->addr.ipv6_addr = av6->sin6_addr; | ||
1610 | mc->addr.u6_port = av6->sin6_port; | ||
1611 | |||
1612 | if (GNUNET_OK != | ||
1613 | GNUNET_SERVER_mst_receive (plugin->broadcast_ipv6_mst, mc, buf, ret, GNUNET_NO, | ||
1614 | GNUNET_NO)) | ||
1615 | GNUNET_free (mc); | ||
1616 | } | ||
1506 | } | 1617 | } |
1507 | 1618 | ||
1508 | 1619 | ||
1509 | static void | 1620 | static void |
1510 | udp_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1621 | udp_ipv4_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1511 | { | 1622 | { |
1512 | struct Plugin *plugin = cls; | 1623 | struct Plugin *plugin = cls; |
1513 | int sent; | 1624 | int sent; |
@@ -1515,12 +1626,11 @@ udp_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1515 | uint16_t hello_size; | 1626 | uint16_t hello_size; |
1516 | char buf[65536]; | 1627 | char buf[65536]; |
1517 | 1628 | ||
1518 | // /ssize_t ret; | ||
1519 | const struct GNUNET_MessageHeader *hello; | 1629 | const struct GNUNET_MessageHeader *hello; |
1520 | struct UDP_Beacon_Message *msg; | 1630 | struct UDP_Beacon_Message *msg; |
1521 | struct BroadcastAddress * baddr; | 1631 | struct BroadcastAddress * baddr; |
1522 | 1632 | ||
1523 | plugin->send_broadcast_task = GNUNET_SCHEDULER_NO_TASK; | 1633 | plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; |
1524 | 1634 | ||
1525 | 1635 | ||
1526 | hello = plugin->env->get_our_hello (); | 1636 | hello = plugin->env->get_our_hello (); |
@@ -1556,10 +1666,54 @@ udp_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1556 | baddr = baddr->next; | 1666 | baddr = baddr->next; |
1557 | } | 1667 | } |
1558 | 1668 | ||
1559 | plugin->send_broadcast_task = | 1669 | plugin->send_ipv4_broadcast_task = |
1560 | GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, | 1670 | GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, |
1561 | &udp_broadcast_send, plugin); | 1671 | &udp_ipv4_broadcast_send, plugin); |
1672 | } | ||
1562 | 1673 | ||
1674 | static void | ||
1675 | udp_ipv6_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1676 | { | ||
1677 | struct Plugin *plugin = cls; | ||
1678 | int sent; | ||
1679 | uint16_t msg_size; | ||
1680 | uint16_t hello_size; | ||
1681 | char buf[65536]; | ||
1682 | |||
1683 | const struct GNUNET_MessageHeader *hello; | ||
1684 | struct UDP_Beacon_Message *msg; | ||
1685 | |||
1686 | plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK; | ||
1687 | |||
1688 | hello = plugin->env->get_our_hello (); | ||
1689 | hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello); | ||
1690 | msg_size = hello_size + sizeof (struct UDP_Beacon_Message); | ||
1691 | |||
1692 | if (hello_size < (sizeof (struct GNUNET_MessageHeader)) || | ||
1693 | (msg_size > (UDP_MTU))) | ||
1694 | return; | ||
1695 | |||
1696 | msg = (struct UDP_Beacon_Message *) buf; | ||
1697 | msg->sender = *(plugin->env->my_identity); | ||
1698 | msg->header.size = ntohs (msg_size); | ||
1699 | msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON); | ||
1700 | memcpy (&msg[1], hello, hello_size); | ||
1701 | sent = 0; | ||
1702 | |||
1703 | sent = GNUNET_NETWORK_socket_sendto (plugin->sockv6_broadcast, msg, msg_size, | ||
1704 | (const struct sockaddr *) &plugin->ipv6_multicast_address, | ||
1705 | sizeof(struct sockaddr_in6)); | ||
1706 | if (sent == GNUNET_SYSERR) | ||
1707 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "sendto"); | ||
1708 | else | ||
1709 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending IPv6 HELLO beacon broadcast with %i bytes to address %s\n", | ||
1710 | sent, GNUNET_a2s((const struct sockaddr *) &plugin->ipv6_multicast_address, sizeof(struct sockaddr_in6))); | ||
1711 | |||
1712 | |||
1713 | |||
1714 | plugin->send_ipv6_broadcast_task = | ||
1715 | GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, | ||
1716 | &udp_ipv6_broadcast_send, plugin); | ||
1563 | } | 1717 | } |
1564 | 1718 | ||
1565 | /** | 1719 | /** |
@@ -1571,12 +1725,12 @@ udp_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1571 | * @param tc the scheduling context (for rescheduling this function again) | 1725 | * @param tc the scheduling context (for rescheduling this function again) |
1572 | */ | 1726 | */ |
1573 | static void | 1727 | static void |
1574 | udp_plugin_broadcast_select (void *cls, | 1728 | udp_plugin_ipv4_broadcast_select (void *cls, |
1575 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1729 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1576 | { | 1730 | { |
1577 | struct Plugin *plugin = cls; | 1731 | struct Plugin *plugin = cls; |
1578 | 1732 | ||
1579 | plugin->select_broadcast_task = GNUNET_SCHEDULER_NO_TASK; | 1733 | plugin->select_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; |
1580 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | 1734 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) |
1581 | return; | 1735 | return; |
1582 | 1736 | ||
@@ -1584,14 +1738,45 @@ udp_plugin_broadcast_select (void *cls, | |||
1584 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4_broadcast))) | 1738 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4_broadcast))) |
1585 | udp_broadcast_read (plugin, plugin->sockv4_broadcast); | 1739 | udp_broadcast_read (plugin, plugin->sockv4_broadcast); |
1586 | 1740 | ||
1587 | plugin->select_broadcast_task = | 1741 | plugin->select_ipv4_broadcast_task = |
1588 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 1742 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
1589 | GNUNET_SCHEDULER_NO_TASK, | 1743 | GNUNET_SCHEDULER_NO_TASK, |
1590 | GNUNET_TIME_UNIT_FOREVER_REL, | 1744 | GNUNET_TIME_UNIT_FOREVER_REL, |
1591 | plugin->broadcast_rs, NULL, | 1745 | plugin->broadcast_ipv4_rs, NULL, |
1592 | &udp_plugin_broadcast_select, plugin); | 1746 | &udp_plugin_ipv4_broadcast_select, plugin); |
1593 | } | 1747 | } |
1594 | 1748 | ||
1749 | /** | ||
1750 | * We have been notified that our writeset has something to read. We don't | ||
1751 | * know which socket needs to be read, so we have to check each one | ||
1752 | * Then reschedule this function to be called again once more is available. | ||
1753 | * | ||
1754 | * @param cls the plugin handle | ||
1755 | * @param tc the scheduling context (for rescheduling this function again) | ||
1756 | */ | ||
1757 | static void | ||
1758 | udp_plugin_ipv6_broadcast_select (void *cls, | ||
1759 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1760 | { | ||
1761 | struct Plugin *plugin = cls; | ||
1762 | |||
1763 | plugin->select_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK; | ||
1764 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | ||
1765 | return; | ||
1766 | |||
1767 | if ((NULL != plugin->sockv6_broadcast) && | ||
1768 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6_broadcast))) | ||
1769 | { | ||
1770 | udp_broadcast_read (plugin, plugin->sockv6_broadcast); | ||
1771 | } | ||
1772 | |||
1773 | plugin->select_ipv6_broadcast_task = | ||
1774 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
1775 | GNUNET_SCHEDULER_NO_TASK, | ||
1776 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
1777 | plugin->broadcast_ipv6_rs, NULL, | ||
1778 | &udp_plugin_ipv6_broadcast_select, plugin); | ||
1779 | } | ||
1595 | 1780 | ||
1596 | 1781 | ||
1597 | /** | 1782 | /** |
@@ -1898,17 +2083,23 @@ iface_proc (void *cls, const char *name, | |||
1898 | { | 2083 | { |
1899 | struct Plugin *plugin = cls; | 2084 | struct Plugin *plugin = cls; |
1900 | 2085 | ||
1901 | if (broadcast_addr != NULL) | 2086 | if (addr != NULL) |
1902 | { | 2087 | { |
1903 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding broadcast address %s for interface %s %p\n ", | 2088 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address %s for interface %s %p\n ", |
2089 | GNUNET_a2s(addr,addrlen), name, addr); | ||
2090 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "broadcast address %s for interface %s %p\n ", | ||
1904 | GNUNET_a2s(broadcast_addr,addrlen), name, broadcast_addr); | 2091 | GNUNET_a2s(broadcast_addr,addrlen), name, broadcast_addr); |
2092 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ", | ||
2093 | GNUNET_a2s(netmask,addrlen), name, netmask); | ||
1905 | 2094 | ||
1906 | struct BroadcastAddress * ba = GNUNET_malloc(sizeof (struct BroadcastAddress)); | 2095 | if (broadcast_addr != NULL) |
1907 | ba->addr = GNUNET_malloc(addrlen); | 2096 | { |
1908 | memcpy(ba->addr, broadcast_addr, addrlen); | 2097 | struct BroadcastAddress * ba = GNUNET_malloc(sizeof (struct BroadcastAddress)); |
1909 | ba->addrlen = addrlen; | 2098 | ba->addr = GNUNET_malloc(addrlen); |
1910 | 2099 | memcpy(ba->addr, broadcast_addr, addrlen); | |
1911 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, ba); | 2100 | ba->addrlen = addrlen; |
2101 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, ba); | ||
2102 | } | ||
1912 | } | 2103 | } |
1913 | return GNUNET_OK; | 2104 | return GNUNET_OK; |
1914 | } | 2105 | } |
@@ -1989,7 +2180,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
1989 | plugin->port = port; | 2180 | plugin->port = port; |
1990 | plugin->aport = aport; | 2181 | plugin->aport = aport; |
1991 | plugin->broadcast_port = bport; | 2182 | plugin->broadcast_port = bport; |
1992 | plugin->broadcast = broadcast; | 2183 | plugin->broadcast_ipv4 = broadcast; |
1993 | plugin->env = env; | 2184 | plugin->env = env; |
1994 | plugin->broadcast_interval = interval; | 2185 | plugin->broadcast_interval = interval; |
1995 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 2186 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
@@ -2156,9 +2347,10 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2156 | NULL, &udp_plugin_select, plugin); | 2347 | NULL, &udp_plugin_select, plugin); |
2157 | 2348 | ||
2158 | 2349 | ||
2159 | /* create broadcast socket */ | 2350 | |
2160 | if (broadcast) | 2351 | if (broadcast) |
2161 | { | 2352 | { |
2353 | /* create IPv4 broadcast socket */ | ||
2162 | plugin->sockv4_broadcast = | 2354 | plugin->sockv4_broadcast = |
2163 | GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0); | 2355 | GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0); |
2164 | if (NULL == plugin->sockv4_broadcast) | 2356 | if (NULL == plugin->sockv4_broadcast) |
@@ -2168,7 +2360,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2168 | else | 2360 | else |
2169 | { | 2361 | { |
2170 | #if HAVE_SOCKADDR_IN_SIN_LEN | 2362 | #if HAVE_SOCKADDR_IN_SIN_LEN |
2171 | serverAddrv4.sin_len = sizeof (serverAddrv4); | 2363 | serverAddrv4.sin4_len = sizeof (serverAddrv4); |
2172 | #endif | 2364 | #endif |
2173 | serverAddrv4.sin_family = AF_INET; | 2365 | serverAddrv4.sin_family = AF_INET; |
2174 | serverAddrv4.sin_addr.s_addr = INADDR_ANY; | 2366 | serverAddrv4.sin_addr.s_addr = INADDR_ANY; |
@@ -2206,37 +2398,102 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2206 | } | 2398 | } |
2207 | else | 2399 | else |
2208 | { | 2400 | { |
2209 | plugin->broadcast_rs = GNUNET_NETWORK_fdset_create (); | 2401 | plugin->broadcast_ipv4_rs = GNUNET_NETWORK_fdset_create (); |
2210 | GNUNET_NETWORK_fdset_set (plugin->broadcast_rs, | 2402 | GNUNET_NETWORK_fdset_set (plugin->broadcast_ipv4_rs, |
2211 | plugin->sockv4_broadcast); | 2403 | plugin->sockv4_broadcast); |
2212 | } | 2404 | } |
2213 | } | 2405 | } |
2214 | } | ||
2215 | |||
2216 | if (plugin->sockv4_broadcast != NULL) | 2406 | if (plugin->sockv4_broadcast != NULL) |
2217 | { | 2407 | { |
2218 | plugin->broadcast = GNUNET_YES; | 2408 | plugin->broadcast_ipv4 = GNUNET_YES; |
2219 | plugin->broadcast_mst = | 2409 | plugin->broadcast_ipv4_mst = |
2220 | GNUNET_SERVER_mst_create (udp_broadcast_mst_cb, plugin); | 2410 | GNUNET_SERVER_mst_create (broadcast_ipv4_mst_cb, plugin); |
2221 | GNUNET_STATISTICS_update (plugin->env->stats, | 2411 | GNUNET_STATISTICS_update (plugin->env->stats, |
2222 | _("# HELLO beacons received via udp"), 1, | 2412 | _("# HELLO beacons received via udp"), 1, |
2223 | GNUNET_NO); | 2413 | GNUNET_NO); |
2224 | plugin->select_broadcast_task = | 2414 | plugin->select_ipv4_broadcast_task = |
2225 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 2415 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
2226 | GNUNET_SCHEDULER_NO_TASK, | 2416 | GNUNET_SCHEDULER_NO_TASK, |
2227 | GNUNET_TIME_UNIT_FOREVER_REL, | 2417 | GNUNET_TIME_UNIT_FOREVER_REL, |
2228 | plugin->broadcast_rs, NULL, | 2418 | plugin->broadcast_ipv4_rs, NULL, |
2229 | &udp_plugin_broadcast_select, plugin); | 2419 | &udp_plugin_ipv4_broadcast_select, plugin); |
2230 | 2420 | ||
2231 | GNUNET_OS_network_interfaces_list(iface_proc, plugin); | 2421 | GNUNET_OS_network_interfaces_list(iface_proc, plugin); |
2232 | plugin->send_broadcast_task = | 2422 | plugin->send_ipv4_broadcast_task = |
2233 | GNUNET_SCHEDULER_add_now (&udp_broadcast_send, plugin); | 2423 | GNUNET_SCHEDULER_add_now (&udp_ipv4_broadcast_send, plugin); |
2234 | 2424 | ||
2425 | LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv4 Broadcasting on port %d running\n", | ||
2426 | ntohs (serverAddrv4.sin_port)); | ||
2235 | } | 2427 | } |
2236 | else | 2428 | else |
2237 | plugin->broadcast = GNUNET_NO; | 2429 | plugin->broadcast_ipv4 = GNUNET_NO; |
2430 | |||
2431 | /* create IPv6 broadcast socket */ | ||
2432 | plugin->sockv6_broadcast = | ||
2433 | GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0); | ||
2434 | if (NULL == plugin->sockv6_broadcast) | ||
2435 | { | ||
2436 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); | ||
2437 | } | ||
2438 | else | ||
2439 | { | ||
2440 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
2441 | serverAddrv6.sin_len = sizeof (serverAddrv6); | ||
2442 | #endif | ||
2443 | serverAddrv6.sin6_family = AF_INET6; | ||
2444 | serverAddrv6.sin6_addr = in6addr_any; | ||
2445 | serverAddrv6.sin6_port = htons (plugin->broadcast_port); | ||
2446 | addrlen = sizeof (serverAddrv6); | ||
2447 | serverAddr = (struct sockaddr *) &serverAddrv6; | ||
2448 | #if DEBUG_UDP | ||
2449 | #endif | ||
2450 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding Broadcast to IPv6 port %d\n", | ||
2451 | ntohs (serverAddrv6.sin6_port)); | ||
2452 | |||
2453 | if (GNUNET_NETWORK_socket_bind | ||
2454 | (plugin->sockv6_broadcast, serverAddr, addrlen) != GNUNET_OK) | ||
2455 | { | ||
2456 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2457 | _("Failed to create IPv6 broadcast socket on port %d\n"), | ||
2458 | ntohs (serverAddrv6.sin6_port)); | ||
2459 | GNUNET_NETWORK_socket_close (plugin->sockv6_broadcast); | ||
2460 | plugin->sockv6_broadcast = NULL; | ||
2461 | } | ||
2462 | plugin->broadcast_ipv6_rs = GNUNET_NETWORK_fdset_create (); | ||
2463 | GNUNET_NETWORK_fdset_set (plugin->broadcast_ipv6_rs, | ||
2464 | plugin->sockv6_broadcast); | ||
2465 | } | ||
2466 | } | ||
2467 | |||
2468 | if (plugin->sockv6_broadcast != NULL) | ||
2469 | { | ||
2470 | plugin->broadcast_ipv6 = GNUNET_YES; | ||
2471 | plugin->broadcast_ipv6_mst = | ||
2472 | GNUNET_SERVER_mst_create (broadcast_ipv6_mst_cb, plugin); | ||
2473 | plugin->select_ipv6_broadcast_task = | ||
2474 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
2475 | GNUNET_SCHEDULER_NO_TASK, | ||
2476 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
2477 | plugin->broadcast_ipv6_rs, NULL, | ||
2478 | &udp_plugin_ipv6_broadcast_select, plugin); | ||
2479 | |||
2480 | memset (&plugin->ipv6_multicast_address, 0, sizeof (struct sockaddr_in6)); | ||
2481 | GNUNET_assert (1 == inet_pton(AF_INET6, "ff02::1", &plugin->ipv6_multicast_address.sin6_addr)); | ||
2482 | |||
2483 | plugin->ipv6_multicast_address.sin6_family = AF_INET6; | ||
2484 | plugin->ipv6_multicast_address.sin6_port = htons(plugin->broadcast_port); | ||
2485 | |||
2486 | LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 Broadcasting on port %d running\n", | ||
2487 | ntohs (serverAddrv6.sin6_port)); | ||
2488 | |||
2489 | plugin->send_ipv6_broadcast_task = | ||
2490 | GNUNET_SCHEDULER_add_now (&udp_ipv6_broadcast_send, plugin); | ||
2491 | } | ||
2492 | else | ||
2493 | plugin->broadcast_ipv6 = GNUNET_NO; | ||
2238 | } | 2494 | } |
2239 | 2495 | ||
2496 | |||
2240 | if (sockets_created == 0) | 2497 | if (sockets_created == 0) |
2241 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n")); | 2498 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n")); |
2242 | plugin->nat = | 2499 | plugin->nat = |
@@ -2244,6 +2501,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2244 | (const struct sockaddr **) addrs, addrlens, | 2501 | (const struct sockaddr **) addrs, addrlens, |
2245 | &udp_nat_port_map_callback, NULL, plugin); | 2502 | &udp_nat_port_map_callback, NULL, plugin); |
2246 | return api; | 2503 | return api; |
2504 | udp_ipv6_broadcast_send(NULL, NULL); | ||
2247 | } | 2505 | } |
2248 | 2506 | ||
2249 | /** | 2507 | /** |
@@ -2291,27 +2549,27 @@ libgnunet_plugin_transport_udp_done (void *cls) | |||
2291 | plugin->sockv6 = NULL; | 2549 | plugin->sockv6 = NULL; |
2292 | } | 2550 | } |
2293 | 2551 | ||
2294 | if (plugin->broadcast) | 2552 | if (plugin->broadcast_ipv4) |
2295 | { | 2553 | { |
2296 | if (plugin->select_broadcast_task != GNUNET_SCHEDULER_NO_TASK) | 2554 | if (plugin->select_ipv4_broadcast_task != GNUNET_SCHEDULER_NO_TASK) |
2297 | { | 2555 | { |
2298 | GNUNET_SCHEDULER_cancel (plugin->select_broadcast_task); | 2556 | GNUNET_SCHEDULER_cancel (plugin->select_ipv4_broadcast_task); |
2299 | plugin->select_broadcast_task = GNUNET_SCHEDULER_NO_TASK; | 2557 | plugin->select_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; |
2300 | } | 2558 | } |
2301 | if (plugin->send_broadcast_task != GNUNET_SCHEDULER_NO_TASK) | 2559 | if (plugin->send_ipv4_broadcast_task != GNUNET_SCHEDULER_NO_TASK) |
2302 | { | 2560 | { |
2303 | GNUNET_SCHEDULER_cancel (plugin->send_broadcast_task); | 2561 | GNUNET_SCHEDULER_cancel (plugin->send_ipv4_broadcast_task); |
2304 | plugin->send_broadcast_task = GNUNET_SCHEDULER_NO_TASK; | 2562 | plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; |
2305 | } | 2563 | } |
2306 | if (plugin->broadcast_mst != NULL) | 2564 | if (plugin->broadcast_ipv4_mst != NULL) |
2307 | GNUNET_SERVER_mst_destroy (plugin->broadcast_mst); | 2565 | GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv4_mst); |
2308 | if (plugin->sockv4_broadcast != NULL) | 2566 | if (plugin->sockv4_broadcast != NULL) |
2309 | { | 2567 | { |
2310 | GNUNET_break (GNUNET_OK == | 2568 | GNUNET_break (GNUNET_OK == |
2311 | GNUNET_NETWORK_socket_close (plugin->sockv4_broadcast)); | 2569 | GNUNET_NETWORK_socket_close (plugin->sockv4_broadcast)); |
2312 | plugin->sockv4_broadcast = NULL; | 2570 | plugin->sockv4_broadcast = NULL; |
2313 | } | 2571 | } |
2314 | GNUNET_NETWORK_fdset_destroy (plugin->broadcast_rs); | 2572 | GNUNET_NETWORK_fdset_destroy (plugin->broadcast_ipv4_rs); |
2315 | 2573 | ||
2316 | while (plugin->head != NULL) | 2574 | while (plugin->head != NULL) |
2317 | { | 2575 | { |
@@ -2322,6 +2580,29 @@ libgnunet_plugin_transport_udp_done (void *cls) | |||
2322 | } | 2580 | } |
2323 | } | 2581 | } |
2324 | 2582 | ||
2583 | if (plugin->broadcast_ipv6) | ||
2584 | { | ||
2585 | if (plugin->select_ipv6_broadcast_task != GNUNET_SCHEDULER_NO_TASK) | ||
2586 | { | ||
2587 | GNUNET_SCHEDULER_cancel (plugin->select_ipv6_broadcast_task); | ||
2588 | plugin->select_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK; | ||
2589 | } | ||
2590 | if (plugin->send_ipv6_broadcast_task != GNUNET_SCHEDULER_NO_TASK) | ||
2591 | { | ||
2592 | GNUNET_SCHEDULER_cancel (plugin->send_ipv6_broadcast_task); | ||
2593 | plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK; | ||
2594 | } | ||
2595 | if (plugin->broadcast_ipv6_mst != NULL) | ||
2596 | GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv6_mst); | ||
2597 | if (plugin->sockv6_broadcast != NULL) | ||
2598 | { | ||
2599 | GNUNET_break (GNUNET_OK == | ||
2600 | GNUNET_NETWORK_socket_close (plugin->sockv6_broadcast)); | ||
2601 | plugin->sockv6_broadcast = NULL; | ||
2602 | } | ||
2603 | GNUNET_NETWORK_fdset_destroy (plugin->broadcast_ipv6_rs); | ||
2604 | } | ||
2605 | |||
2325 | GNUNET_SERVER_mst_destroy (plugin->mst); | 2606 | GNUNET_SERVER_mst_destroy (plugin->mst); |
2326 | GNUNET_NETWORK_fdset_destroy (plugin->rs); | 2607 | GNUNET_NETWORK_fdset_destroy (plugin->rs); |
2327 | 2608 | ||