aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_udp_broadcasting.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_udp_broadcasting.c')
-rw-r--r--src/transport/plugin_transport_udp_broadcasting.c624
1 files changed, 318 insertions, 306 deletions
diff --git a/src/transport/plugin_transport_udp_broadcasting.c b/src/transport/plugin_transport_udp_broadcasting.c
index 470c03af8..d8fdfe886 100644
--- a/src/transport/plugin_transport_udp_broadcasting.c
+++ b/src/transport/plugin_transport_udp_broadcasting.c
@@ -38,7 +38,7 @@
38#include "gnunet_transport_plugin.h" 38#include "gnunet_transport_plugin.h"
39#include "transport.h" 39#include "transport.h"
40 40
41#define LOG(kind, ...) GNUNET_log_from(kind, "transport-udp", __VA_ARGS__) 41#define LOG(kind, ...) GNUNET_log_from (kind, "transport-udp", __VA_ARGS__)
42 42
43/* *********** Cryogenic ********** */ 43/* *********** Cryogenic ********** */
44#if LINUX 44#if LINUX
@@ -50,9 +50,10 @@
50#include <sys/time.h> 50#include <sys/time.h>
51 51
52#define PM_MAGIC 'k' 52#define PM_MAGIC 'k'
53#define PM_SET_DELAY_AND_TIMEOUT _IOW(PM_MAGIC, 1, struct pm_times) 53#define PM_SET_DELAY_AND_TIMEOUT _IOW (PM_MAGIC, 1, struct pm_times)
54 54
55struct pm_times { 55struct pm_times
56{
56 unsigned long delay_msecs; 57 unsigned long delay_msecs;
57 unsigned long timeout_msecs; 58 unsigned long timeout_msecs;
58}; 59};
@@ -60,7 +61,8 @@ struct pm_times {
60/************************************/ 61/************************************/
61 62
62 63
63struct UDP_Beacon_Message { 64struct UDP_Beacon_Message
65{
64 /** 66 /**
65 * Message header. 67 * Message header.
66 */ 68 */
@@ -73,7 +75,8 @@ struct UDP_Beacon_Message {
73}; 75};
74 76
75 77
76struct BroadcastAddress { 78struct BroadcastAddress
79{
77 struct BroadcastAddress *next; 80 struct BroadcastAddress *next;
78 81
79 struct BroadcastAddress *prev; 82 struct BroadcastAddress *prev;
@@ -81,7 +84,7 @@ struct BroadcastAddress {
81 /** 84 /**
82 * ID of select broadcast task 85 * ID of select broadcast task
83 */ 86 */
84 struct GNUNET_SCHEDULER_Task * broadcast_task; 87 struct GNUNET_SCHEDULER_Task *broadcast_task;
85 88
86 struct Plugin *plugin; 89 struct Plugin *plugin;
87 90
@@ -106,7 +109,8 @@ struct BroadcastAddress {
106/** 109/**
107 * Client-specific context for #broadcast_mst_cb(). 110 * Client-specific context for #broadcast_mst_cb().
108 */ 111 */
109struct MstContext { 112struct MstContext
113{
110 struct Plugin *plugin; 114 struct Plugin *plugin;
111 115
112 const union UdpAddress *udp_addr; 116 const union UdpAddress *udp_addr;
@@ -129,8 +133,8 @@ struct MstContext {
129 * @return #GNUNET_OK (always) 133 * @return #GNUNET_OK (always)
130 */ 134 */
131static int 135static int
132broadcast_mst_cb(void *cls, 136broadcast_mst_cb (void *cls,
133 const struct GNUNET_MessageHeader *message) 137 const struct GNUNET_MessageHeader *message)
134{ 138{
135 struct MstContext *mc = cls; 139 struct MstContext *mc = cls;
136 struct Plugin *plugin = mc->plugin; 140 struct Plugin *plugin = mc->plugin;
@@ -138,32 +142,32 @@ broadcast_mst_cb(void *cls,
138 const struct GNUNET_MessageHeader *hello; 142 const struct GNUNET_MessageHeader *hello;
139 const struct UDP_Beacon_Message *msg; 143 const struct UDP_Beacon_Message *msg;
140 144
141 msg = (const struct UDP_Beacon_Message *)message; 145 msg = (const struct UDP_Beacon_Message *) message;
142 146
143 if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON != 147 if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON !=
144 ntohs(msg->header.type)) 148 ntohs (msg->header.type))
145 return GNUNET_OK; 149 return GNUNET_OK;
146 LOG(GNUNET_ERROR_TYPE_DEBUG, 150 LOG (GNUNET_ERROR_TYPE_DEBUG,
147 "Received beacon with %u bytes from peer `%s' via address `%s'\n", 151 "Received beacon with %u bytes from peer `%s' via address `%s'\n",
148 ntohs(msg->header.size), 152 ntohs (msg->header.size),
149 GNUNET_i2s(&msg->sender), 153 GNUNET_i2s (&msg->sender),
150 udp_address_to_string(NULL, 154 udp_address_to_string (NULL,
151 mc->udp_addr, 155 mc->udp_addr,
152 mc->udp_addr_len)); 156 mc->udp_addr_len));
153 hello = (struct GNUNET_MessageHeader *)&msg[1]; 157 hello = (struct GNUNET_MessageHeader *) &msg[1];
154 address = GNUNET_HELLO_address_allocate(&msg->sender, 158 address = GNUNET_HELLO_address_allocate (&msg->sender,
155 PLUGIN_NAME, 159 PLUGIN_NAME,
156 mc->udp_addr, 160 mc->udp_addr,
157 mc->udp_addr_len, 161 mc->udp_addr_len,
158 GNUNET_HELLO_ADDRESS_INFO_NONE); 162 GNUNET_HELLO_ADDRESS_INFO_NONE);
159 plugin->env->receive(plugin->env->cls, 163 plugin->env->receive (plugin->env->cls,
160 address, 164 address,
161 NULL, 165 NULL,
162 hello); 166 hello);
163 GNUNET_HELLO_address_free(address); 167 GNUNET_HELLO_address_free (address);
164 GNUNET_STATISTICS_update(plugin->env->stats, 168 GNUNET_STATISTICS_update (plugin->env->stats,
165 _("# Multicast HELLO beacons received via UDP"), 169 _ ("# Multicast HELLO beacons received via UDP"),
166 1, GNUNET_NO); 170 1, GNUNET_NO);
167 return GNUNET_OK; 171 return GNUNET_OK;
168} 172}
169 173
@@ -180,59 +184,59 @@ broadcast_mst_cb(void *cls,
180 * @param network_type network type of the sender's address 184 * @param network_type network type of the sender's address
181 */ 185 */
182void 186void
183udp_broadcast_receive(struct Plugin *plugin, 187udp_broadcast_receive (struct Plugin *plugin,
184 const char *buf, 188 const char *buf,
185 ssize_t size, 189 ssize_t size,
186 const union UdpAddress *udp_addr, 190 const union UdpAddress *udp_addr,
187 size_t udp_addr_len, 191 size_t udp_addr_len,
188 enum GNUNET_NetworkType network_type) 192 enum GNUNET_NetworkType network_type)
189{ 193{
190 struct GNUNET_MessageStreamTokenizer *broadcast_mst; 194 struct GNUNET_MessageStreamTokenizer *broadcast_mst;
191 struct MstContext mc; 195 struct MstContext mc;
192 196
193 broadcast_mst = GNUNET_MST_create(&broadcast_mst_cb, 197 broadcast_mst = GNUNET_MST_create (&broadcast_mst_cb,
194 &mc); 198 &mc);
195 mc.plugin = plugin; 199 mc.plugin = plugin;
196 mc.udp_addr = udp_addr; 200 mc.udp_addr = udp_addr;
197 mc.udp_addr_len = udp_addr_len; 201 mc.udp_addr_len = udp_addr_len;
198 mc.ats_address_network_type = network_type; 202 mc.ats_address_network_type = network_type;
199 GNUNET_MST_from_buffer(broadcast_mst, 203 GNUNET_MST_from_buffer (broadcast_mst,
200 buf, size, 204 buf, size,
201 GNUNET_NO, 205 GNUNET_NO,
202 GNUNET_NO); 206 GNUNET_NO);
203 GNUNET_MST_destroy(broadcast_mst); 207 GNUNET_MST_destroy (broadcast_mst);
204} 208}
205 209
206 210
207static unsigned int 211static unsigned int
208prepare_beacon(struct Plugin *plugin, 212prepare_beacon (struct Plugin *plugin,
209 struct UDP_Beacon_Message *msg) 213 struct UDP_Beacon_Message *msg)
210{ 214{
211 uint16_t hello_size; 215 uint16_t hello_size;
212 uint16_t msg_size; 216 uint16_t msg_size;
213 217
214 const struct GNUNET_MessageHeader *hello; 218 const struct GNUNET_MessageHeader *hello;
215 219
216 hello = plugin->env->get_our_hello(); 220 hello = plugin->env->get_our_hello ();
217 if (NULL == hello) 221 if (NULL == hello)
218 return 0; 222 return 0;
219 hello_size = GNUNET_HELLO_size((struct GNUNET_HELLO_Message *)hello); 223 hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
220 msg_size = hello_size + sizeof(struct UDP_Beacon_Message); 224 msg_size = hello_size + sizeof(struct UDP_Beacon_Message);
221 225
222 if (hello_size < (sizeof(struct GNUNET_MessageHeader)) || 226 if ((hello_size < (sizeof(struct GNUNET_MessageHeader)))||
223 (msg_size > (UDP_MTU))) 227 (msg_size > (UDP_MTU)))
224 return 0; 228 return 0;
225 229
226 msg->sender = *(plugin->env->my_identity); 230 msg->sender = *(plugin->env->my_identity);
227 msg->header.size = htons(msg_size); 231 msg->header.size = htons (msg_size);
228 msg->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON); 232 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON);
229 GNUNET_memcpy(&msg[1], hello, hello_size); 233 GNUNET_memcpy (&msg[1], hello, hello_size);
230 return msg_size; 234 return msg_size;
231} 235}
232 236
233 237
234static void 238static void
235udp_ipv4_broadcast_send(void *cls) 239udp_ipv4_broadcast_send (void *cls)
236{ 240{
237 struct BroadcastAddress *baddr = cls; 241 struct BroadcastAddress *baddr = cls;
238 struct Plugin *plugin = baddr->plugin; 242 struct Plugin *plugin = baddr->plugin;
@@ -242,82 +246,84 @@ udp_ipv4_broadcast_send(void *cls)
242 246
243 baddr->broadcast_task = NULL; 247 baddr->broadcast_task = NULL;
244 248
245 msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *)&buf); 249 msg_size = prepare_beacon (plugin, (struct UDP_Beacon_Message *) &buf);
246 if (0 != msg_size) 250 if (0 != msg_size)
251 {
252 struct sockaddr_in *addr = (struct sockaddr_in *) baddr->addr;
253
254 addr->sin_port = htons (plugin->port);
255 sent = GNUNET_NETWORK_socket_sendto (plugin->sockv4, &buf, msg_size,
256 (const struct sockaddr *) addr,
257 baddr->addrlen);
258 if (sent == GNUNET_SYSERR)
247 { 259 {
248 struct sockaddr_in *addr = (struct sockaddr_in *)baddr->addr; 260 if ((ENETUNREACH == errno) || (ENETDOWN == errno))
249 261 {
250 addr->sin_port = htons(plugin->port); 262 /* "Network unreachable" or "Network down"
251 sent = GNUNET_NETWORK_socket_sendto(plugin->sockv4, &buf, msg_size, 263 *
252 (const struct sockaddr *)addr, 264 * This indicates that we just do not have network connectivity
253 baddr->addrlen); 265 */
254 if (sent == GNUNET_SYSERR) 266 GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING,
255 { 267 "Network connectivity is down, cannot send beacon!\n");
256 if ((ENETUNREACH == errno) || (ENETDOWN == errno)) 268 }
257 {
258 /* "Network unreachable" or "Network down"
259 *
260 * This indicates that we just do not have network connectivity
261 */
262 GNUNET_log(GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING,
263 "Network connectivity is down, cannot send beacon!\n");
264 }
265 else
266 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "sendto");
267 }
268 else 269 else
269 { 270 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
270 LOG(GNUNET_ERROR_TYPE_DEBUG, 271 }
271 "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent, 272 else
272 GNUNET_a2s(baddr->addr, baddr->addrlen)); 273 {
273 } 274 LOG (GNUNET_ERROR_TYPE_DEBUG,
275 "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent,
276 GNUNET_a2s (baddr->addr, baddr->addrlen));
274 } 277 }
278 }
275 279
276#if LINUX 280#if LINUX
277 /* 281 /*
278 * Cryogenic 282 * Cryogenic
279 */ 283 */
280 if (NULL != baddr->cryogenic_fd) 284 if (NULL != baddr->cryogenic_fd)
285 {
286 baddr->cryogenic_times.delay_msecs =
287 (plugin->broadcast_interval.rel_value_us / 1000.0) * 0.5;
288 baddr->cryogenic_times.timeout_msecs =
289 (plugin->broadcast_interval.rel_value_us / 1000.0) * 1.5;
290
291 if (ioctl (baddr->cryogenic_fd->fd,
292 PM_SET_DELAY_AND_TIMEOUT,
293 &baddr->cryogenic_times) < 0)
281 { 294 {
282 baddr->cryogenic_times.delay_msecs = (plugin->broadcast_interval.rel_value_us / 1000.0) * 0.5; 295 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctl");
283 baddr->cryogenic_times.timeout_msecs = (plugin->broadcast_interval.rel_value_us / 1000.0) * 1.5; 296 baddr->broadcast_task =
284 297 GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval,
285 if (ioctl(baddr->cryogenic_fd->fd, 298 &udp_ipv4_broadcast_send, baddr);
286 PM_SET_DELAY_AND_TIMEOUT,
287 &baddr->cryogenic_times) < 0)
288 {
289 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "ioctl");
290 baddr->broadcast_task =
291 GNUNET_SCHEDULER_add_delayed(plugin->broadcast_interval,
292 &udp_ipv4_broadcast_send, baddr);
293 }
294 else
295 GNUNET_SCHEDULER_add_write_file(GNUNET_TIME_UNIT_FOREVER_REL,
296 baddr->cryogenic_fd,
297 &udp_ipv4_broadcast_send,
298 baddr);
299 } 299 }
300 else
301 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
302 baddr->cryogenic_fd,
303 &udp_ipv4_broadcast_send,
304 baddr);
305 }
300 else 306 else
301#endif 307#endif
302 baddr->broadcast_task = 308 baddr->broadcast_task =
303 GNUNET_SCHEDULER_add_delayed(plugin->broadcast_interval, 309 GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval,
304 &udp_ipv4_broadcast_send, baddr); 310 &udp_ipv4_broadcast_send, baddr);
305} 311}
306 312
307 313
308static void 314static void
309udp_ipv6_broadcast_send(void *cls) 315udp_ipv6_broadcast_send (void *cls)
310{ 316{
311 struct BroadcastAddress *baddr = cls; 317 struct BroadcastAddress *baddr = cls;
312 struct Plugin *plugin = baddr->plugin; 318 struct Plugin *plugin = baddr->plugin;
313 ssize_t sent; 319 ssize_t sent;
314 uint16_t msg_size; 320 uint16_t msg_size;
315 char buf[65536] GNUNET_ALIGN; 321 char buf[65536] GNUNET_ALIGN;
316 const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)baddr->addr; 322 const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) baddr->addr;
317 323
318 baddr->broadcast_task = NULL; 324 baddr->broadcast_task = NULL;
319 325
320 msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *)&buf); 326 msg_size = prepare_beacon (plugin, (struct UDP_Beacon_Message *) &buf);
321 /* Note: unclear if this actually works to limit the multicast to 327 /* Note: unclear if this actually works to limit the multicast to
322 the specified interface as we're not (necessarily) using a 328 the specified interface as we're not (necessarily) using a
323 link-local multicast group and the kernel suggests that the 329 link-local multicast group and the kernel suggests that the
@@ -327,63 +333,65 @@ udp_ipv6_broadcast_send(void *cls)
327 in that case, we might want to revert to only doing this 333 in that case, we might want to revert to only doing this
328 once, and not per interface (hard to test...) */ 334 once, and not per interface (hard to test...) */
329 plugin->ipv6_multicast_address.sin6_scope_id = s6->sin6_scope_id; 335 plugin->ipv6_multicast_address.sin6_scope_id = s6->sin6_scope_id;
330 sent = GNUNET_NETWORK_socket_sendto(plugin->sockv6, &buf, msg_size, 336 sent = GNUNET_NETWORK_socket_sendto (plugin->sockv6, &buf, msg_size,
331 (const struct sockaddr *) 337 (const struct sockaddr *)
332 &plugin->ipv6_multicast_address, 338 &plugin->ipv6_multicast_address,
333 sizeof(struct sockaddr_in6)); 339 sizeof(struct sockaddr_in6));
334 plugin->ipv6_multicast_address.sin6_scope_id = 0; 340 plugin->ipv6_multicast_address.sin6_scope_id = 0;
335 if (sent == GNUNET_SYSERR) 341 if (sent == GNUNET_SYSERR)
342 {
343 if ((ENETUNREACH == errno) || (ENETDOWN == errno))
336 { 344 {
337 if ((ENETUNREACH == errno) || (ENETDOWN == errno)) 345 /* "Network unreachable" or "Network down"
338 { 346 *
339 /* "Network unreachable" or "Network down" 347 * This indicates that this system is IPv6 enabled, but does not
340 * 348 * have a valid global IPv6 address assigned
341 * This indicates that this system is IPv6 enabled, but does not 349 */
342 * have a valid global IPv6 address assigned 350 GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING,
343 */ 351 "Network connectivity is down, cannot send beacon!\n");
344 GNUNET_log(GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING,
345 "Network connectivity is down, cannot send beacon!\n");
346 }
347 else
348 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "sendto");
349 } 352 }
353 else
354 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
355 }
350 else 356 else
351 { 357 {
352 LOG(GNUNET_ERROR_TYPE_DEBUG, 358 LOG (GNUNET_ERROR_TYPE_DEBUG,
353 "Sending IPv6 HELLO beacon broadcast with %d bytes to address %s\n", 359 "Sending IPv6 HELLO beacon broadcast with %d bytes to address %s\n",
354 (int)sent, 360 (int) sent,
355 GNUNET_a2s((const struct sockaddr *)&plugin->ipv6_multicast_address, 361 GNUNET_a2s ((const struct sockaddr *) &plugin->ipv6_multicast_address,
356 sizeof(struct sockaddr_in6))); 362 sizeof(struct sockaddr_in6)));
357 } 363 }
358#if LINUX 364#if LINUX
359 /* 365 /*
360 * Cryogenic 366 * Cryogenic
361 */ 367 */
362 if (NULL != baddr->cryogenic_fd) 368 if (NULL != baddr->cryogenic_fd)
369 {
370 baddr->cryogenic_times.delay_msecs =
371 (plugin->broadcast_interval.rel_value_us / 1000.0) * 0.5;
372 baddr->cryogenic_times.timeout_msecs =
373 (plugin->broadcast_interval.rel_value_us / 1000.0) * 1.5;
374
375 if (ioctl (baddr->cryogenic_fd->fd,
376 PM_SET_DELAY_AND_TIMEOUT,
377 &baddr->cryogenic_times) < 0)
363 { 378 {
364 baddr->cryogenic_times.delay_msecs = (plugin->broadcast_interval.rel_value_us / 1000.0) * 0.5; 379 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctl");
365 baddr->cryogenic_times.timeout_msecs = (plugin->broadcast_interval.rel_value_us / 1000.0) * 1.5; 380 baddr->broadcast_task =
366 381 GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval,
367 if (ioctl(baddr->cryogenic_fd->fd, 382 &udp_ipv6_broadcast_send, baddr);
368 PM_SET_DELAY_AND_TIMEOUT,
369 &baddr->cryogenic_times) < 0)
370 {
371 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "ioctl");
372 baddr->broadcast_task =
373 GNUNET_SCHEDULER_add_delayed(plugin->broadcast_interval,
374 &udp_ipv6_broadcast_send, baddr);
375 }
376 else
377 GNUNET_SCHEDULER_add_write_file(GNUNET_TIME_UNIT_FOREVER_REL,
378 baddr->cryogenic_fd,
379 &udp_ipv6_broadcast_send,
380 baddr);
381 } 383 }
384 else
385 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
386 baddr->cryogenic_fd,
387 &udp_ipv6_broadcast_send,
388 baddr);
389 }
382 else 390 else
383#endif 391#endif
384 baddr->broadcast_task = 392 baddr->broadcast_task =
385 GNUNET_SCHEDULER_add_delayed(plugin->broadcast_interval, 393 GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval,
386 &udp_ipv6_broadcast_send, baddr); 394 &udp_ipv6_broadcast_send, baddr);
387} 395}
388 396
389 397
@@ -400,12 +408,12 @@ udp_ipv6_broadcast_send(void *cls)
400 * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort 408 * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort
401 */ 409 */
402static int 410static int
403iface_proc(void *cls, 411iface_proc (void *cls,
404 const char *name, 412 const char *name,
405 int isDefault, 413 int isDefault,
406 const struct sockaddr *addr, 414 const struct sockaddr *addr,
407 const struct sockaddr *broadcast_addr, 415 const struct sockaddr *broadcast_addr,
408 const struct sockaddr *netmask, socklen_t addrlen) 416 const struct sockaddr *netmask, socklen_t addrlen)
409{ 417{
410 struct Plugin *plugin = cls; 418 struct Plugin *plugin = cls;
411 struct BroadcastAddress *ba; 419 struct BroadcastAddress *ba;
@@ -413,113 +421,115 @@ iface_proc(void *cls,
413 421
414 if (NULL == addr) 422 if (NULL == addr)
415 return GNUNET_OK; 423 return GNUNET_OK;
416 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
417 "address %s for interface %s %p\n ", 425 "address %s for interface %s %p\n ",
418 GNUNET_a2s(addr, addrlen), name, addr); 426 GNUNET_a2s (addr, addrlen), name, addr);
419 if (NULL == broadcast_addr) 427 if (NULL == broadcast_addr)
420 return GNUNET_OK; 428 return GNUNET_OK;
421 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 429 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
422 "broadcast address %s for interface %s %p\n ", 430 "broadcast address %s for interface %s %p\n ",
423 GNUNET_a2s(broadcast_addr, addrlen), name, broadcast_addr); 431 GNUNET_a2s (broadcast_addr, addrlen), name, broadcast_addr);
424 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ", 432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ",
425 GNUNET_a2s(netmask, addrlen), name, netmask); 433 GNUNET_a2s (netmask, addrlen), name, netmask);
426 434
427 network = plugin->env->get_address_type(plugin->env->cls, broadcast_addr, addrlen); 435 network = plugin->env->get_address_type (plugin->env->cls, broadcast_addr,
436 addrlen);
428 if (GNUNET_NT_LOOPBACK == network) 437 if (GNUNET_NT_LOOPBACK == network)
429 { 438 {
430 /* Broadcasting on loopback does not make sense */ 439 /* Broadcasting on loopback does not make sense */
431 return GNUNET_YES; 440 return GNUNET_YES;
432 } 441 }
433 442
434 ba = GNUNET_new(struct BroadcastAddress); 443 ba = GNUNET_new (struct BroadcastAddress);
435 ba->plugin = plugin; 444 ba->plugin = plugin;
436 ba->addr = GNUNET_malloc(addrlen); 445 ba->addr = GNUNET_malloc (addrlen);
437 GNUNET_memcpy(ba->addr, broadcast_addr, addrlen); 446 GNUNET_memcpy (ba->addr, broadcast_addr, addrlen);
438 ba->addrlen = addrlen; 447 ba->addrlen = addrlen;
439 448
440 if ((GNUNET_YES == plugin->enable_ipv4) && 449 if ((GNUNET_YES == plugin->enable_ipv4) &&
441 (NULL != plugin->sockv4) && 450 (NULL != plugin->sockv4) &&
442 (addrlen == sizeof(struct sockaddr_in))) 451 (addrlen == sizeof(struct sockaddr_in)))
443 { 452 {
444#if LINUX 453#if LINUX
445 /* 454 /*
446 * setup Cryogenic FD for ipv4 broadcasting 455 * setup Cryogenic FD for ipv4 broadcasting
447 */ 456 */
448 char *filename; 457 char *filename;
449 458
450 GNUNET_asprintf(&filename, 459 GNUNET_asprintf (&filename,
451 "/dev/cryogenic/%s", 460 "/dev/cryogenic/%s",
452 name); 461 name);
453 if (0 == access(name, R_OK)) 462 if (0 == access (name, R_OK))
454 { 463 {
455 ba->cryogenic_fd = 464 ba->cryogenic_fd =
456 GNUNET_DISK_file_open(filename, 465 GNUNET_DISK_file_open (filename,
457 GNUNET_DISK_OPEN_WRITE, 466 GNUNET_DISK_OPEN_WRITE,
458 GNUNET_DISK_PERM_NONE); 467 GNUNET_DISK_PERM_NONE);
459 }
460 GNUNET_free(filename);
461#endif
462 ba->broadcast_task =
463 GNUNET_SCHEDULER_add_now(&udp_ipv4_broadcast_send, ba);
464 } 468 }
469 GNUNET_free (filename);
470#endif
471 ba->broadcast_task =
472 GNUNET_SCHEDULER_add_now (&udp_ipv4_broadcast_send, ba);
473 }
465 if ((GNUNET_YES == plugin->enable_ipv6) && 474 if ((GNUNET_YES == plugin->enable_ipv6) &&
466 (NULL != plugin->sockv6) && 475 (NULL != plugin->sockv6) &&
467 (addrlen == sizeof(struct sockaddr_in6))) 476 (addrlen == sizeof(struct sockaddr_in6)))
477 {
478 /* Create IPv6 multicast request */
479 struct ipv6_mreq multicastRequest;
480 const struct sockaddr_in6 *s6 = (const struct
481 sockaddr_in6 *) broadcast_addr;
482
483 multicastRequest.ipv6mr_multiaddr =
484 plugin->ipv6_multicast_address.sin6_addr;
485 /* http://tools.ietf.org/html/rfc2553#section-5.2:
486 *
487 * IPV6_JOIN_GROUP
488 *
489 * Join a multicast group on a specified local interface. If the
490 * interface index is specified as 0, the kernel chooses the local
491 * interface. For example, some kernels look up the multicast
492 * group in the normal IPv6 routing table and using the resulting
493 * interface; we do this for each interface, so no need to use
494 * zero (anymore...).
495 */
496 multicastRequest.ipv6mr_interface = s6->sin6_scope_id;
497
498 /* Join the multicast group */
499 if (GNUNET_OK !=
500 GNUNET_NETWORK_socket_setsockopt
501 (plugin->sockv6, IPPROTO_IPV6, IPV6_JOIN_GROUP,
502 &multicastRequest, sizeof(multicastRequest)))
468 { 503 {
469 /* Create IPv6 multicast request */ 504 LOG (GNUNET_ERROR_TYPE_WARNING,
470 struct ipv6_mreq multicastRequest; 505 "Failed to join IPv6 multicast group: IPv6 broadcasting not running\n");
471 const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)broadcast_addr; 506 }
472 507 else
473 multicastRequest.ipv6mr_multiaddr = 508 {
474 plugin->ipv6_multicast_address.sin6_addr; 509#if LINUX
475 /* http://tools.ietf.org/html/rfc2553#section-5.2: 510 /*
476 * 511 * setup Cryogenic FD for ipv6 broadcasting
477 * IPV6_JOIN_GROUP
478 *
479 * Join a multicast group on a specified local interface. If the
480 * interface index is specified as 0, the kernel chooses the local
481 * interface. For example, some kernels look up the multicast
482 * group in the normal IPv6 routing table and using the resulting
483 * interface; we do this for each interface, so no need to use
484 * zero (anymore...).
485 */ 512 */
486 multicastRequest.ipv6mr_interface = s6->sin6_scope_id; 513 char *filename;
487 514
488 /* Join the multicast group */ 515 GNUNET_asprintf (&filename,
489 if (GNUNET_OK != 516 "/dev/cryogenic/%s",
490 GNUNET_NETWORK_socket_setsockopt 517 name);
491 (plugin->sockv6, IPPROTO_IPV6, IPV6_JOIN_GROUP, 518 if (0 == access (name, R_OK))
492 &multicastRequest, sizeof(multicastRequest))) 519 {
493 { 520 ba->cryogenic_fd =
494 LOG(GNUNET_ERROR_TYPE_WARNING, 521 GNUNET_DISK_file_open (filename,
495 "Failed to join IPv6 multicast group: IPv6 broadcasting not running\n"); 522 GNUNET_DISK_OPEN_WRITE,
496 } 523 GNUNET_DISK_PERM_NONE);
497 else 524 }
498 { 525 GNUNET_free (filename);
499#if LINUX
500 /*
501 * setup Cryogenic FD for ipv6 broadcasting
502 */
503 char *filename;
504
505 GNUNET_asprintf(&filename,
506 "/dev/cryogenic/%s",
507 name);
508 if (0 == access(name, R_OK))
509 {
510 ba->cryogenic_fd =
511 GNUNET_DISK_file_open(filename,
512 GNUNET_DISK_OPEN_WRITE,
513 GNUNET_DISK_PERM_NONE);
514 }
515 GNUNET_free(filename);
516#endif 526#endif
517 ba->broadcast_task = 527 ba->broadcast_task =
518 GNUNET_SCHEDULER_add_now(&udp_ipv6_broadcast_send, ba); 528 GNUNET_SCHEDULER_add_now (&udp_ipv6_broadcast_send, ba);
519 }
520 } 529 }
521 GNUNET_CONTAINER_DLL_insert(plugin->broadcast_head, 530 }
522 plugin->broadcast_tail, ba); 531 GNUNET_CONTAINER_DLL_insert (plugin->broadcast_head,
532 plugin->broadcast_tail, ba);
523 return GNUNET_OK; 533 return GNUNET_OK;
524} 534}
525 535
@@ -532,48 +542,50 @@ iface_proc(void *cls,
532 * @param server_addrv4 542 * @param server_addrv4
533 */ 543 */
534void 544void
535setup_broadcast(struct Plugin *plugin, 545setup_broadcast (struct Plugin *plugin,
536 struct sockaddr_in6 *server_addrv6, 546 struct sockaddr_in6 *server_addrv6,
537 struct sockaddr_in *server_addrv4) 547 struct sockaddr_in *server_addrv4)
538{ 548{
539 if (GNUNET_YES == 549 if (GNUNET_YES ==
540 GNUNET_CONFIGURATION_get_value_yesno(plugin->env->cfg, 550 GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg,
541 "topology", 551 "topology",
542 "FRIENDS-ONLY")) 552 "FRIENDS-ONLY"))
543 { 553 {
544 LOG(GNUNET_ERROR_TYPE_WARNING, 554 LOG (GNUNET_ERROR_TYPE_WARNING,
545 _("Disabling HELLO broadcasting due to friend-to-friend only configuration!\n")); 555 _ (
546 return; 556 "Disabling HELLO broadcasting due to friend-to-friend only configuration!\n"));
547 } 557 return;
558 }
548 559
549 if (GNUNET_YES != plugin->enable_broadcasting) 560 if (GNUNET_YES != plugin->enable_broadcasting)
550 return; /* We do not send, just receive */ 561 return; /* We do not send, just receive */
551 562
552 /* create IPv4 broadcast socket */ 563 /* create IPv4 broadcast socket */
553 if ((GNUNET_YES == plugin->enable_ipv4) && (NULL != plugin->sockv4)) 564 if ((GNUNET_YES == plugin->enable_ipv4) && (NULL != plugin->sockv4))
554 { 565 {
555 static int yes = 1; 566 static int yes = 1;
556 567
557 if (GNUNET_NETWORK_socket_setsockopt 568 if (GNUNET_NETWORK_socket_setsockopt
558 (plugin->sockv4, SOL_SOCKET, SO_BROADCAST, &yes, 569 (plugin->sockv4, SOL_SOCKET, SO_BROADCAST, &yes,
559 sizeof(int)) != GNUNET_OK) 570 sizeof(int)) != GNUNET_OK)
560 { 571 {
561 LOG(GNUNET_ERROR_TYPE_WARNING, 572 LOG (GNUNET_ERROR_TYPE_WARNING,
562 _("Failed to set IPv4 broadcast option for broadcast socket on port %d\n"), 573 _ (
563 ntohs(server_addrv4->sin_port)); 574 "Failed to set IPv4 broadcast option for broadcast socket on port %d\n"),
564 } 575 ntohs (server_addrv4->sin_port));
565 } 576 }
577 }
566 /* create IPv6 multicast socket */ 578 /* create IPv6 multicast socket */
567 if ((GNUNET_YES == plugin->enable_ipv6) && (plugin->sockv6 != NULL)) 579 if ((GNUNET_YES == plugin->enable_ipv6) && (plugin->sockv6 != NULL))
568 { 580 {
569 memset(&plugin->ipv6_multicast_address, 0, sizeof(struct sockaddr_in6)); 581 memset (&plugin->ipv6_multicast_address, 0, sizeof(struct sockaddr_in6));
570 GNUNET_assert(1 == 582 GNUNET_assert (1 ==
571 inet_pton(AF_INET6, "FF05::13B", 583 inet_pton (AF_INET6, "FF05::13B",
572 &plugin->ipv6_multicast_address.sin6_addr)); 584 &plugin->ipv6_multicast_address.sin6_addr));
573 plugin->ipv6_multicast_address.sin6_family = AF_INET6; 585 plugin->ipv6_multicast_address.sin6_family = AF_INET6;
574 plugin->ipv6_multicast_address.sin6_port = htons(plugin->port); 586 plugin->ipv6_multicast_address.sin6_port = htons (plugin->port);
575 } 587 }
576 GNUNET_OS_network_interfaces_list(&iface_proc, plugin); 588 GNUNET_OS_network_interfaces_list (&iface_proc, plugin);
577} 589}
578 590
579 591
@@ -583,55 +595,55 @@ setup_broadcast(struct Plugin *plugin,
583 * @param plugin 595 * @param plugin
584 */ 596 */
585void 597void
586stop_broadcast(struct Plugin *plugin) 598stop_broadcast (struct Plugin *plugin)
587{ 599{
588 if (GNUNET_YES == plugin->enable_broadcasting) 600 if (GNUNET_YES == plugin->enable_broadcasting)
601 {
602 /* Disable broadcasting */
603 while (plugin->broadcast_head != NULL)
589 { 604 {
590 /* Disable broadcasting */ 605 struct BroadcastAddress *p = plugin->broadcast_head;
591 while (plugin->broadcast_head != NULL) 606
607 if (p->broadcast_task != NULL)
608 {
609 GNUNET_SCHEDULER_cancel (p->broadcast_task);
610 p->broadcast_task = NULL;
611 }
612 if ((GNUNET_YES == plugin->enable_ipv6) &&
613 (NULL != plugin->sockv6) &&
614 (p->addrlen == sizeof(struct sockaddr_in6)))
615 {
616 /* Create IPv6 multicast request */
617 struct ipv6_mreq multicastRequest;
618 const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) p->addr;
619
620 multicastRequest.ipv6mr_multiaddr =
621 plugin->ipv6_multicast_address.sin6_addr;
622 multicastRequest.ipv6mr_interface = s6->sin6_scope_id;
623
624 /* Leave the multicast group */
625 if (GNUNET_OK ==
626 GNUNET_NETWORK_socket_setsockopt
627 (plugin->sockv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
628 &multicastRequest, sizeof(multicastRequest)))
592 { 629 {
593 struct BroadcastAddress *p = plugin->broadcast_head; 630 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt");
594 631 }
595 if (p->broadcast_task != NULL) 632 else
596 { 633 {
597 GNUNET_SCHEDULER_cancel(p->broadcast_task); 634 LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 multicasting stopped\n");
598 p->broadcast_task = NULL; 635 }
599 } 636 }
600 if ((GNUNET_YES == plugin->enable_ipv6) &&
601 (NULL != plugin->sockv6) &&
602 (p->addrlen == sizeof(struct sockaddr_in6)))
603 {
604 /* Create IPv6 multicast request */
605 struct ipv6_mreq multicastRequest;
606 const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)p->addr;
607
608 multicastRequest.ipv6mr_multiaddr =
609 plugin->ipv6_multicast_address.sin6_addr;
610 multicastRequest.ipv6mr_interface = s6->sin6_scope_id;
611
612 /* Leave the multicast group */
613 if (GNUNET_OK ==
614 GNUNET_NETWORK_socket_setsockopt
615 (plugin->sockv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
616 &multicastRequest, sizeof(multicastRequest)))
617 {
618 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "setsockopt");
619 }
620 else
621 {
622 LOG(GNUNET_ERROR_TYPE_DEBUG, "IPv6 multicasting stopped\n");
623 }
624 }
625 637
626#if LINUX 638#if LINUX
627 GNUNET_DISK_file_close(p->cryogenic_fd); 639 GNUNET_DISK_file_close (p->cryogenic_fd);
628#endif 640#endif
629 GNUNET_CONTAINER_DLL_remove(plugin->broadcast_head, 641 GNUNET_CONTAINER_DLL_remove (plugin->broadcast_head,
630 plugin->broadcast_tail, p); 642 plugin->broadcast_tail, p);
631 GNUNET_free(p->addr); 643 GNUNET_free (p->addr);
632 GNUNET_free(p); 644 GNUNET_free (p);
633 }
634 } 645 }
646 }
635} 647}
636 648
637/* end of plugin_transport_udp_broadcasting.c */ 649/* end of plugin_transport_udp_broadcasting.c */