aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r--src/transport/plugin_transport_udp.c124
1 files changed, 102 insertions, 22 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 70c60c387..076fb6b3b 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -115,6 +115,20 @@ struct UDP_ACK_Message
115}; 115};
116 116
117 117
118struct UDP_Beacon_Message
119{
120 /**
121 * Message header.
122 */
123 struct GNUNET_MessageHeader header;
124
125 /**
126 * What is the identity of the sender
127 */
128 struct GNUNET_PeerIdentity sender;
129};
130
131
118/** 132/**
119 * Network format for IPv4 addresses. 133 * Network format for IPv4 addresses.
120 */ 134 */
@@ -327,6 +341,12 @@ struct Plugin
327 */ 341 */
328 int broadcast; 342 int broadcast;
329 343
344
345 /**
346 * Tokenizer for inbound messages.
347 */
348 struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_mst;
349
330 /** 350 /**
331 * The read socket for IPv4 351 * The read socket for IPv4
332 */ 352 */
@@ -1373,6 +1393,41 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1373} 1393}
1374 1394
1375 1395
1396struct MstContext
1397{
1398 struct Plugin * plugin;
1399
1400 struct IPv4UdpAddress addr;
1401};
1402
1403void udp_broadcast_mst_cb (void *cls, void *client,
1404 const struct
1405 GNUNET_MessageHeader *
1406 message)
1407{
1408 struct Plugin * plugin = cls;
1409 struct MstContext * mc = client;
1410 const struct GNUNET_MessageHeader* hello;
1411 struct UDP_Beacon_Message * msg;
1412 msg = (struct UDP_Beacon_Message *) message;
1413
1414 if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON != ntohs(msg->header.type))
1415 return;
1416
1417 LOG (GNUNET_ERROR_TYPE_DEBUG,
1418 "Received beacon with %u bytes from peer `%s' via address `%s'\n",
1419 ntohs(msg->header.size),
1420 GNUNET_i2s (&msg->sender),
1421 udp_address_to_string(NULL, &mc->addr, sizeof (mc->addr)));
1422
1423
1424 hello = &message[1];
1425 plugin->env->receive (plugin->env->cls, &msg->sender, hello, NULL, 0, NULL, (const char *) &mc->addr, sizeof (mc->addr));
1426
1427 GNUNET_STATISTICS_update(plugin->env->cfg, _("# HELLO beacons received via udp"), 1, GNUNET_NO);
1428 GNUNET_free (mc);
1429}
1430
1376/** 1431/**
1377 * Read and process a message from the given socket. 1432 * Read and process a message from the given socket.
1378 * 1433 *
@@ -1386,28 +1441,35 @@ udp_broadcast_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
1386 char addr[32]; 1441 char addr[32];
1387 char buf[65536]; 1442 char buf[65536];
1388 ssize_t ret; 1443 ssize_t ret;
1389 const struct GNUNET_MessageHeader *msg; 1444 struct MstContext * mc;
1445
1390 1446
1391 fromlen = sizeof (addr); 1447 fromlen = sizeof (addr);
1392 memset (&addr, 0, sizeof (addr)); 1448 memset (&addr, 0, sizeof (addr));
1393 ret = GNUNET_NETWORK_socket_recvfrom (rsock, buf, sizeof (buf), 1449 ret = GNUNET_NETWORK_socket_recvfrom (rsock, buf, sizeof (buf), (struct sockaddr *) &addr, &fromlen);
1394 (struct sockaddr *) &addr, &fromlen);
1395 if (ret < sizeof (struct GNUNET_MessageHeader)) 1450 if (ret < sizeof (struct GNUNET_MessageHeader))
1396 { 1451 {
1397 GNUNET_break_op (0); 1452 /* malformed beacon, just throw it away */
1398 return; 1453 return;
1399 } 1454 }
1400 msg = (const struct GNUNET_MessageHeader *) buf;
1401
1402 LOG (GNUNET_ERROR_TYPE_ERROR,
1403 "UDP received %u-byte message from `%s' type %i\n", (unsigned int) ret,
1404 GNUNET_a2s ((const struct sockaddr *) addr, fromlen), ntohs(msg->type));
1405 1455
1406 if (ret != ntohs (msg->size)) 1456 if (GNUNET_YES == GNUNET_NAT_test_address (plugin->nat,
1457 &((struct sockaddr_in *) addr)->sin_addr,
1458 sizeof (struct in_addr)))
1407 { 1459 {
1408 GNUNET_break_op (0); 1460 /* received my own beacon */
1409 return; 1461 return;
1410 } 1462 }
1463
1464
1465 mc = GNUNET_malloc(sizeof (struct MstContext));
1466
1467 struct sockaddr_in * av4 = (struct sockaddr_in *) &addr;
1468 mc->addr.ipv4_addr = av4->sin_addr.s_addr;
1469 mc->addr.u4_port = av4->sin_port;
1470
1471 if (GNUNET_OK != GNUNET_SERVER_mst_receive(plugin->broadcast_mst, mc, buf, ret, GNUNET_NO, GNUNET_NO))
1472 GNUNET_free (mc);
1411} 1473}
1412 1474
1413 1475
@@ -1416,8 +1478,13 @@ udp_broadcast_send (void *cls,
1416 const struct GNUNET_SCHEDULER_TaskContext *tc) 1478 const struct GNUNET_SCHEDULER_TaskContext *tc)
1417{ 1479{
1418 struct Plugin * plugin = cls; 1480 struct Plugin * plugin = cls;
1419 struct GNUNET_MessageHeader msg;
1420 int sent; 1481 int sent;
1482 uint16_t msg_size;
1483 uint16_t hello_size;
1484 char buf[65536];
1485// /ssize_t ret;
1486 const struct GNUNET_MessageHeader *hello;
1487 struct UDP_Beacon_Message * msg;
1421 1488
1422 plugin->send_broadcast_task = GNUNET_SCHEDULER_NO_TASK; 1489 plugin->send_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
1423 1490
@@ -1426,14 +1493,25 @@ udp_broadcast_send (void *cls,
1426 baddr.sin_port = htons (plugin->broadcast_port); 1493 baddr.sin_port = htons (plugin->broadcast_port);
1427 baddr.sin_addr.s_addr=htonl(-1); /* send message to 255.255.255.255 */ 1494 baddr.sin_addr.s_addr=htonl(-1); /* send message to 255.255.255.255 */
1428 1495
1429 msg.size = htons(sizeof (struct GNUNET_MessageHeader)); 1496 hello = plugin->env->get_our_hello ();
1430 msg.type = htons (500); 1497 hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
1498 msg_size = hello_size + sizeof (struct UDP_Beacon_Message);
1499
1500 if (hello_size < (sizeof (struct GNUNET_MessageHeader)) ||(msg_size > (UDP_MTU)))
1501 return;
1502
1503 msg = (struct UDP_Beacon_Message *) buf;
1504 msg->sender = *(plugin->env->my_identity);
1505 msg->header.size = ntohs (msg_size);
1506 msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON);
1507 memcpy (&msg[1], hello, hello_size);
1431 1508
1432 sent = GNUNET_NETWORK_socket_sendto (plugin->sockv4_broadcast, &msg, ntohs (msg.size), 1509 sent = GNUNET_NETWORK_socket_sendto (plugin->sockv4_broadcast, msg, msg_size,
1433 (const struct sockaddr *) &baddr, sizeof (struct sockaddr_in)); 1510 (const struct sockaddr *) &baddr, sizeof (struct sockaddr_in));
1434 1511
1435 LOG (GNUNET_ERROR_TYPE_ERROR, 1512 LOG (GNUNET_ERROR_TYPE_DEBUG,
1436 "Sent broadcast with %i bytes\n", sent); 1513 "Sent HELLO beacon broadcast with %i bytes\n", sent);
1514
1437 plugin->send_broadcast_task = GNUNET_SCHEDULER_add_delayed(plugin->broadcast_interval, &udp_broadcast_send, plugin); 1515 plugin->send_broadcast_task = GNUNET_SCHEDULER_add_delayed(plugin->broadcast_interval, &udp_broadcast_send, plugin);
1438 1516
1439} 1517}
@@ -2021,7 +2099,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
2021 serverAddr = (struct sockaddr *) &serverAddrv4; 2099 serverAddr = (struct sockaddr *) &serverAddrv4;
2022 #if DEBUG_UDP 2100 #if DEBUG_UDP
2023 #endif 2101 #endif
2024 LOG (GNUNET_ERROR_TYPE_ERROR, "Binding Broadcast to IPv4 port %d\n", 2102 LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding Broadcast to IPv4 port %d\n",
2025 ntohs (serverAddrv4.sin_port)); 2103 ntohs (serverAddrv4.sin_port));
2026 2104
2027 if (GNUNET_NETWORK_socket_bind (plugin->sockv4_broadcast, serverAddr, addrlen) != GNUNET_OK) 2105 if (GNUNET_NETWORK_socket_bind (plugin->sockv4_broadcast, serverAddr, addrlen) != GNUNET_OK)
@@ -2031,7 +2109,6 @@ libgnunet_plugin_transport_udp_init (void *cls)
2031 } 2109 }
2032 if (plugin->sockv4_broadcast != NULL) 2110 if (plugin->sockv4_broadcast != NULL)
2033 { 2111 {
2034 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("UDP Broadcast sockets on port %u \n"), bport);
2035 int yes = 1; 2112 int yes = 1;
2036 if (GNUNET_NETWORK_socket_setsockopt (plugin->sockv4_broadcast, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(int)) != GNUNET_OK) 2113 if (GNUNET_NETWORK_socket_setsockopt (plugin->sockv4_broadcast, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(int)) != GNUNET_OK)
2037 { 2114 {
@@ -2049,13 +2126,15 @@ libgnunet_plugin_transport_udp_init (void *cls)
2049 if (plugin->sockv4_broadcast != NULL) 2126 if (plugin->sockv4_broadcast != NULL)
2050 { 2127 {
2051 plugin->broadcast = GNUNET_YES; 2128 plugin->broadcast = GNUNET_YES;
2129 plugin->broadcast_mst = GNUNET_SERVER_mst_create (udp_broadcast_mst_cb, plugin);
2130 GNUNET_STATISTICS_update(plugin->env->cfg, _("# HELLO beacons received via udp"), 1, GNUNET_NO);
2052 plugin->select_broadcast_task = 2131 plugin->select_broadcast_task =
2053 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 2132 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
2054 GNUNET_SCHEDULER_NO_TASK, 2133 GNUNET_SCHEDULER_NO_TASK,
2055 GNUNET_TIME_UNIT_FOREVER_REL, plugin->broadcast_rs, 2134 GNUNET_TIME_UNIT_FOREVER_REL, plugin->broadcast_rs,
2056 NULL, &udp_plugin_broadcast_select, plugin); 2135 NULL, &udp_plugin_broadcast_select, plugin);
2057 2136
2058 plugin->send_broadcast_task = GNUNET_SCHEDULER_add_delayed(plugin->broadcast_interval, &udp_broadcast_send, plugin); 2137 plugin->send_broadcast_task = GNUNET_SCHEDULER_add_now (&udp_broadcast_send, plugin);
2059 } 2138 }
2060 else 2139 else
2061 plugin->broadcast = GNUNET_NO; 2140 plugin->broadcast = GNUNET_NO;
@@ -2127,7 +2206,8 @@ libgnunet_plugin_transport_udp_done (void *cls)
2127 GNUNET_SCHEDULER_cancel (plugin->send_broadcast_task ); 2206 GNUNET_SCHEDULER_cancel (plugin->send_broadcast_task );
2128 plugin->send_broadcast_task = GNUNET_SCHEDULER_NO_TASK; 2207 plugin->send_broadcast_task = GNUNET_SCHEDULER_NO_TASK;
2129 } 2208 }
2130 2209 if (plugin->broadcast_mst != NULL)
2210 GNUNET_SERVER_mst_destroy(plugin->broadcast_mst);
2131 if (plugin->sockv4_broadcast != NULL) 2211 if (plugin->sockv4_broadcast != NULL)
2132 { 2212 {
2133 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4_broadcast)); 2213 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4_broadcast));