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