diff options
Diffstat (limited to 'src/transport/plugin_transport_udp_broadcasting.c')
-rw-r--r-- | src/transport/plugin_transport_udp_broadcasting.c | 643 |
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 | ||
55 | struct pm_times { | 55 | struct 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 | ||
63 | struct UDP_Beacon_Message | 63 | struct 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 | ||
77 | struct BroadcastAddress | 76 | struct 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 | */ |
111 | struct MstContext | 109 | struct 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 | */ |
134 | static int | 131 | static int |
135 | broadcast_mst_cb (void *cls, | 132 | broadcast_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 | */ |
185 | void | 182 | void |
186 | udp_broadcast_receive (struct Plugin *plugin, | 183 | udp_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 | ||
210 | static unsigned int | 207 | static unsigned int |
211 | prepare_beacon (struct Plugin *plugin, | 208 | prepare_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 | ||
236 | static void | 234 | static void |
237 | udp_ipv4_broadcast_send (void *cls) | 235 | udp_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 | ||
311 | static void | 308 | static void |
312 | udp_ipv6_broadcast_send (void *cls) | 309 | udp_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 | */ |
405 | static int | 402 | static int |
406 | iface_proc (void *cls, | 403 | iface_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 | */ |
537 | void | 534 | void |
538 | setup_broadcast (struct Plugin *plugin, | 535 | setup_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 | */ |
588 | void | 585 | void |
589 | stop_broadcast (struct Plugin *plugin) | 586 | stop_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 */ |