diff options
Diffstat (limited to 'src/transport/plugin_transport_udp_broadcasting.c')
-rw-r--r-- | src/transport/plugin_transport_udp_broadcasting.c | 624 |
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 | ||
55 | struct pm_times { | 55 | struct 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 | ||
63 | struct UDP_Beacon_Message { | 64 | struct 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 | ||
76 | struct BroadcastAddress { | 78 | struct 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 | */ |
109 | struct MstContext { | 112 | struct 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 | */ |
131 | static int | 135 | static int |
132 | broadcast_mst_cb(void *cls, | 136 | broadcast_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 | */ |
182 | void | 186 | void |
183 | udp_broadcast_receive(struct Plugin *plugin, | 187 | udp_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 | ||
207 | static unsigned int | 211 | static unsigned int |
208 | prepare_beacon(struct Plugin *plugin, | 212 | prepare_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 | ||
234 | static void | 238 | static void |
235 | udp_ipv4_broadcast_send(void *cls) | 239 | udp_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 | ||
308 | static void | 314 | static void |
309 | udp_ipv6_broadcast_send(void *cls) | 315 | udp_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 | */ |
402 | static int | 410 | static int |
403 | iface_proc(void *cls, | 411 | iface_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 | */ |
534 | void | 544 | void |
535 | setup_broadcast(struct Plugin *plugin, | 545 | setup_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 | */ |
585 | void | 597 | void |
586 | stop_broadcast(struct Plugin *plugin) | 598 | stop_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 */ |