aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-11-18 16:29:06 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-11-18 16:29:06 +0000
commit4c83f8ec2199f9ba1dd792f08c0d934ffcdcb8f9 (patch)
treea51f20a4afede5ff4bbc5469d35c08636ba8788a /src
parent55a8c591f7ad6796b2dc2c4c3d97c1daac5f425c (diff)
downloadgnunet-4c83f8ec2199f9ba1dd792f08c0d934ffcdcb8f9.tar.gz
gnunet-4c83f8ec2199f9ba1dd792f08c0d934ffcdcb8f9.zip
udp now supports broadcasts using ipv6 multicast
Diffstat (limited to 'src')
-rw-r--r--src/transport/plugin_transport_udp.c413
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
1426struct MstContext 1471struct 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
1478struct Mstv6Context
1479{
1480 struct Plugin *plugin;
1481
1482 struct IPv6UdpAddress addr;
1483};
1484
1485void
1486broadcast_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
1433void 1521void
1434udp_broadcast_mst_cb (void *cls, void *client, 1522broadcast_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
1509static void 1620static void
1510udp_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 1621udp_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
1674static void
1675udp_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 */
1573static void 1727static void
1574udp_plugin_broadcast_select (void *cls, 1728udp_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 */
1757static void
1758udp_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