diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-05-08 19:55:05 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-05-08 19:55:05 +0000 |
commit | 535c983e0dcf6dba67e69e15f2f8c882bf305796 (patch) | |
tree | 2d07e6de940f26e25d3d67e84233f0af9ae2e072 /src/transport/plugin_transport_wlan.c | |
parent | b437294d389fcde182fb4e11a6782e228271606b (diff) | |
download | gnunet-535c983e0dcf6dba67e69e15f2f8c882bf305796.tar.gz gnunet-535c983e0dcf6dba67e69e15f2f8c882bf305796.zip |
-clean up WLAN plugin
Diffstat (limited to 'src/transport/plugin_transport_wlan.c')
-rw-r--r-- | src/transport/plugin_transport_wlan.c | 3318 |
1 files changed, 1035 insertions, 2283 deletions
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 7711dec06..142095035 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c | |||
@@ -23,10 +23,10 @@ | |||
23 | * @brief transport plugin for wlan | 23 | * @brief transport plugin for wlan |
24 | * @author David Brodski | 24 | * @author David Brodski |
25 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
26 | * | ||
27 | * TODO: | ||
28 | * - HELPER-continuation may be called after fragment times out (-> use after free, see FIXME) | ||
26 | */ | 29 | */ |
27 | |||
28 | //TODO split rx and tx structures for better handling | ||
29 | |||
30 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include "gnunet_hello_lib.h" | 31 | #include "gnunet_hello_lib.h" |
32 | #include "gnunet_protocols.h" | 32 | #include "gnunet_protocols.h" |
@@ -40,59 +40,31 @@ | |||
40 | #include "gnunet_fragmentation_lib.h" | 40 | #include "gnunet_fragmentation_lib.h" |
41 | #include "gnunet_constants.h" | 41 | #include "gnunet_constants.h" |
42 | 42 | ||
43 | |||
44 | #define PROTOCOL_PREFIX "wlan" | 43 | #define PROTOCOL_PREFIX "wlan" |
45 | 44 | ||
46 | #define PLUGIN_LOG_NAME "wlan-plugin" | 45 | #define LOG(kind,...) GNUNET_log_from (kind, "transport-wlan",__VA_ARGS__) |
47 | 46 | ||
48 | /** | 47 | /** |
49 | * Max size of packet | 48 | * Max size of packet (that we give to the WLAN driver for transmission) |
50 | */ | 49 | */ |
51 | #define WLAN_MTU 1430 | 50 | #define WLAN_MTU 1430 |
52 | 51 | ||
53 | /** | 52 | /** |
54 | * time out of a session | ||
55 | */ | ||
56 | #define SESSION_TIMEOUT GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT | ||
57 | |||
58 | /** | ||
59 | * time out of a mac endpoint | 53 | * time out of a mac endpoint |
60 | */ | 54 | */ |
61 | #define MACENDPOINT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2) | 55 | #define MACENDPOINT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2) |
62 | 56 | ||
63 | /** | 57 | /** |
64 | * scaling factor for hello beacon | 58 | * We reduce the frequence of HELLO beacons in relation to |
65 | */ | 59 | * the number of MAC addresses currently visible to us. |
66 | #define HELLO_BEACON_SCALING_FACTOR 30 | 60 | * This is the multiplication factor. |
67 | |||
68 | /** | ||
69 | * scaling factor for restarting the helper | ||
70 | */ | ||
71 | #define HELPER_RESTART_SCALING_FACTOR 2 | ||
72 | |||
73 | /** | ||
74 | * max size of fragment queue | ||
75 | */ | ||
76 | #define FRAGMENT_QUEUE_SIZE 10 | ||
77 | /** | ||
78 | * max messages in fragment queue per session/client | ||
79 | */ | ||
80 | #define FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION 1 | ||
81 | |||
82 | /** | ||
83 | * max messages in fragment queue per MAC | ||
84 | */ | ||
85 | #define FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT 1 | ||
86 | |||
87 | /** | ||
88 | * max messages in in queue | ||
89 | */ | 61 | */ |
90 | #define MESSAGES_IN_QUEUE_SIZE 10 | 62 | #define HELLO_BEACON_SCALING_FACTOR GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) |
91 | 63 | ||
92 | /** | 64 | /** |
93 | * max messages in in queue per session/client | 65 | * Maximum number of messages in defragmentation queue per MAC |
94 | */ | 66 | */ |
95 | #define MESSAGES_IN_DEFRAG_QUEUE_PER_MAC 1 | 67 | #define MESSAGES_IN_DEFRAG_QUEUE_PER_MAC 2 |
96 | 68 | ||
97 | /** | 69 | /** |
98 | * Link layer control fields for better compatibility | 70 | * Link layer control fields for better compatibility |
@@ -102,1068 +74,416 @@ | |||
102 | #define WLAN_LLC_SSAP_FIELD 0x1f | 74 | #define WLAN_LLC_SSAP_FIELD 0x1f |
103 | 75 | ||
104 | 76 | ||
105 | 77 | GNUNET_NETWORK_STRUCT_BEGIN | |
106 | /** | 78 | /** |
107 | * Encapsulation of all of the state of the plugin. | 79 | * Header for messages which need fragmentation. This is the format of |
80 | * a message we obtain AFTER defragmentation. We then need to check | ||
81 | * the CRC and then tokenize the payload and pass it to the | ||
82 | * 'receive' callback. | ||
108 | */ | 83 | */ |
109 | struct Plugin | 84 | struct WlanHeader |
110 | { | 85 | { |
111 | /** | ||
112 | * Our environment. | ||
113 | */ | ||
114 | struct GNUNET_TRANSPORT_PluginEnvironment *env; | ||
115 | 86 | ||
116 | /** | 87 | /** |
117 | * List of open connections. head | 88 | * Message type is GNUNET_MESSAGE_TYPE_WLAN_DATA. |
118 | */ | ||
119 | struct MacEndpoint *mac_head; | ||
120 | |||
121 | /** | ||
122 | * List of open connections. tail | ||
123 | */ | ||
124 | struct MacEndpoint *mac_tail; | ||
125 | |||
126 | /** | ||
127 | * Number of connections | ||
128 | */ | ||
129 | unsigned int mac_count; | ||
130 | |||
131 | /** | ||
132 | * encapsulation of data from the local wlan helper program | ||
133 | */ | ||
134 | struct GNUNET_SERVER_MessageStreamTokenizer *suid_tokenizer; | ||
135 | |||
136 | /** | ||
137 | * encapsulation of packets received from the wlan helper | ||
138 | */ | ||
139 | struct GNUNET_SERVER_MessageStreamTokenizer *data_tokenizer; | ||
140 | |||
141 | /** | ||
142 | * stdout pipe handle for the gnunet-helper-transport-wlan process | ||
143 | */ | ||
144 | struct GNUNET_DISK_PipeHandle *server_stdout; | ||
145 | |||
146 | /** | ||
147 | * stdout file handle for the gnunet-helper-transport-wlan process | ||
148 | */ | 89 | */ |
149 | const struct GNUNET_DISK_FileHandle *server_stdout_handle; | 90 | struct GNUNET_MessageHeader header; |
150 | 91 | ||
151 | /** | 92 | /** |
152 | * stdin pipe handle for the gnunet-helper-transport-wlan process | 93 | * CRC32 checksum (only over the payload), in NBO. |
153 | */ | 94 | */ |
154 | struct GNUNET_DISK_PipeHandle *server_stdin; | 95 | uint32_t crc GNUNET_PACKED; |
155 | 96 | ||
156 | /** | 97 | /** |
157 | * stdin file handle for the gnunet-helper-transport-wlan process | 98 | * Sender of the message. |
158 | */ | 99 | */ |
159 | const struct GNUNET_DISK_FileHandle *server_stdin_handle; | 100 | struct GNUNET_PeerIdentity sender; |
160 | 101 | ||
161 | /** | 102 | /** |
162 | * ID of the gnunet-wlan-server std read task | 103 | * Target of the message. |
163 | */ | 104 | */ |
164 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; | 105 | struct GNUNET_PeerIdentity target; |
165 | 106 | ||
166 | /** | 107 | /* followed by payload, possibly including |
167 | * ID of the gnunet-wlan-server std read task | 108 | multiple messages! */ |
168 | */ | ||
169 | GNUNET_SCHEDULER_TaskIdentifier server_write_task; | ||
170 | 109 | ||
171 | /** | 110 | }; |
172 | * ID of the delay task for writing | 111 | GNUNET_NETWORK_STRUCT_END |
173 | */ | ||
174 | GNUNET_SCHEDULER_TaskIdentifier server_write_delay_task; | ||
175 | 112 | ||
176 | /** | ||
177 | * The process id of the wlan process | ||
178 | */ | ||
179 | struct GNUNET_OS_Process *server_proc; | ||
180 | 113 | ||
114 | /** | ||
115 | * Information kept for each message that is yet to be fragmented and | ||
116 | * transmitted. | ||
117 | */ | ||
118 | struct PendingMessage | ||
119 | { | ||
181 | /** | 120 | /** |
182 | * The interface of the wlan card given to us by the user. | 121 | * next entry in the DLL |
183 | */ | 122 | */ |
184 | char *interface; | 123 | struct PendingMessage *next; |
185 | 124 | ||
186 | /** | 125 | /** |
187 | * Mode of operation for the helper, 0 = normal, 1 = first loopback, 2 = second loopback | 126 | * previous entry in the DLL |
188 | */ | 127 | */ |
189 | long long unsigned int testmode; | 128 | struct PendingMessage *prev; |
190 | 129 | ||
191 | /** | 130 | /** |
192 | * The mac_address of the wlan card given to us by the helper. | 131 | * The pending message |
193 | */ | 132 | */ |
194 | struct GNUNET_TRANSPORT_WLAN_MacAddress mac_address; | 133 | struct WlanHeader *msg; |
195 | 134 | ||
196 | /** | 135 | /** |
197 | * Sessions currently pending for transmission | 136 | * Continuation function to call once the message |
198 | * to a peer, if any. | 137 | * has been sent. Can be NULL if there is no |
138 | * continuation to call. | ||
199 | */ | 139 | */ |
200 | struct Sessionqueue *pending_Sessions_head; | 140 | GNUNET_TRANSPORT_TransmitContinuation transmit_cont; |
201 | 141 | ||
202 | /** | 142 | /** |
203 | * Sessions currently pending for transmission | 143 | * Cls for transmit_cont |
204 | * to a peer (tail), if any. | ||
205 | */ | 144 | */ |
206 | struct Sessionqueue *pending_Sessions_tail; | 145 | void *transmit_cont_cls; |
207 | 146 | ||
208 | /** | 147 | /** |
209 | * number of pending sessions | 148 | * Timeout task (for this message). |
210 | */ | 149 | */ |
211 | unsigned int pendingsessions; | 150 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
212 | 151 | ||
213 | /** | 152 | }; |
214 | * Messages in the sending queues | ||
215 | */ | ||
216 | int pending_Fragment_Messages; | ||
217 | 153 | ||
218 | /** | ||
219 | * messages ready for send, head | ||
220 | */ | ||
221 | struct FragmentMessage_queue *sending_messages_head; | ||
222 | 154 | ||
223 | /** | 155 | /** |
224 | * messages ready for send, tail | 156 | * Session handle for connections with other peers. |
225 | */ | 157 | */ |
226 | struct FragmentMessage_queue *sending_messages_tail; | 158 | struct Session |
159 | { | ||
227 | 160 | ||
228 | /** | 161 | /** |
229 | * time of the next "hello-beacon" | 162 | * API requirement (must be first). |
230 | */ | 163 | */ |
231 | struct GNUNET_TIME_Absolute beacon_time; | 164 | struct SessionHeader header; |
232 | 165 | ||
233 | /** | 166 | /** |
234 | * queue to send acks for received fragments (head) | 167 | * We keep all sessions in a DLL at their respective |
168 | * 'struct MACEndpoint'. | ||
235 | */ | 169 | */ |
236 | struct AckSendQueue *ack_send_queue_head; | 170 | struct Session *next; |
237 | 171 | ||
238 | /** | 172 | /** |
239 | * queue to send acks for received fragments (tail) | 173 | * We keep all sessions in a DLL at their respective |
174 | * 'struct MACEndpoint'. | ||
240 | */ | 175 | */ |
241 | struct AckSendQueue *ack_send_queue_tail; | 176 | struct Session *prev; |
242 | 177 | ||
243 | /** | 178 | /** |
244 | * Tracker for bandwidth limit | 179 | * MAC endpoint with the address of this peer. |
245 | */ | 180 | */ |
246 | struct GNUNET_BANDWIDTH_Tracker tracker; | 181 | struct MacEndpoint *mac; |
247 | 182 | ||
248 | /** | 183 | /** |
249 | * saves the current state of the helper process | 184 | * Head of messages currently pending for transmission to this peer. |
250 | */ | 185 | */ |
251 | int helper_is_running; | 186 | struct PendingMessage *pending_message_head; |
252 | }; | ||
253 | 187 | ||
254 | /** | ||
255 | * Struct to store data if file write did not accept the whole packet | ||
256 | */ | ||
257 | struct Finish_send | ||
258 | { | ||
259 | /** | 188 | /** |
260 | * pointer to the global plugin struct | 189 | * Tail of messages currently pending for transmission to this peer. |
261 | */ | 190 | */ |
262 | struct Plugin *plugin; | 191 | struct PendingMessage *pending_message_tail; |
263 | 192 | ||
264 | /** | 193 | /** |
265 | * head of the next part to send to the helper | 194 | * To whom are we talking to (set to our identity |
195 | * if we are still waiting for the welcome message) | ||
266 | */ | 196 | */ |
267 | const char *head_of_next_write; | 197 | struct GNUNET_PeerIdentity target; |
268 | 198 | ||
269 | /** | 199 | /** |
270 | * Start of the message to send, needed for free | 200 | * When should this session time out? |
271 | */ | 201 | */ |
272 | struct GNUNET_MessageHeader *msgstart; | 202 | struct GNUNET_TIME_Absolute timeout; |
273 | 203 | ||
274 | /** | 204 | /** |
275 | * rest size to send | 205 | * Timeout task (for the session). |
276 | */ | 206 | */ |
277 | ssize_t size; | 207 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
278 | }; | ||
279 | |||
280 | /** | ||
281 | * Queue of sessions, for the general session queue and the pending session queue | ||
282 | */ | ||
283 | //TODO DOXYGEN | ||
284 | struct Sessionqueue | ||
285 | { | ||
286 | struct Sessionqueue *next; | ||
287 | struct Sessionqueue *prev; | ||
288 | struct Session *content; | ||
289 | #if !HAVE_UNALIGNED_64_ACCESS | ||
290 | void *dummy; /* for alignment, see #1909 */ | ||
291 | #endif | ||
292 | }; | ||
293 | |||
294 | |||
295 | /** | ||
296 | * Queue of fragmented messages, for the sending queue of the plugin | ||
297 | */ | ||
298 | //TODO DOXYGEN | ||
299 | struct FragmentMessage_queue | ||
300 | { | ||
301 | struct FragmentMessage_queue *next; | ||
302 | struct FragmentMessage_queue *prev; | ||
303 | struct FragmentMessage *content; | ||
304 | }; | ||
305 | |||
306 | |||
307 | /** | ||
308 | * Queue for the fragments received | ||
309 | */ | ||
310 | //TODO DOXYGEN | ||
311 | struct Receive_Fragment_Queue | ||
312 | { | ||
313 | struct Receive_Fragment_Queue *next; | ||
314 | struct Receive_Fragment_Queue *prev; | ||
315 | |||
316 | uint16_t num; | ||
317 | // const char *msg; | ||
318 | // uint16_t size; | ||
319 | struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rx_msg; | ||
320 | }; | ||
321 | |||
322 | |||
323 | //TODO DOXYGEN | ||
324 | struct MacEndpoint_id_fragment_triple | ||
325 | { | ||
326 | struct MacEndpoint *endpoint; | ||
327 | uint32_t message_id; | ||
328 | struct FragmentMessage *fm; | ||
329 | }; | ||
330 | 208 | ||
331 | //TODO DOXYGEN | ||
332 | struct Plugin_Session_pair | ||
333 | { | ||
334 | struct Plugin *plugin; | ||
335 | struct Session *session; | ||
336 | }; | 209 | }; |
337 | 210 | ||
338 | 211 | ||
339 | GNUNET_NETWORK_STRUCT_BEGIN | ||
340 | |||
341 | /** | 212 | /** |
342 | * Header for messages which need fragmentation | 213 | * Struct for messages that are being fragmented in a MAC's transmission queue. |
343 | */ | 214 | */ |
344 | struct WlanHeader | 215 | struct FragmentMessage |
345 | { | 216 | { |
346 | 217 | ||
347 | /** | 218 | /** |
348 | * Message type is GNUNET_MESSAGE_TYPE_WLAN_DATA. | 219 | * This is a doubly-linked list. |
349 | */ | ||
350 | struct GNUNET_MessageHeader header; | ||
351 | |||
352 | /** | ||
353 | * checksum/error correction | ||
354 | */ | 220 | */ |
355 | uint32_t crc GNUNET_PACKED; | 221 | struct FragmentMessage *next; |
356 | 222 | ||
357 | /** | 223 | /** |
358 | * To whom are we talking to (set to our identity | 224 | * This is a doubly-linked list. |
359 | * if we are still waiting for the welcome message) | ||
360 | */ | 225 | */ |
361 | struct GNUNET_PeerIdentity target; | 226 | struct FragmentMessage *prev; |
362 | 227 | ||
363 | /** | 228 | /** |
364 | * Where the packet came from | 229 | * MAC endpoint this message belongs to |
365 | */ | 230 | */ |
366 | struct GNUNET_PeerIdentity source; | 231 | struct MacEndpoint *macendpoint; |
367 | |||
368 | // followed by payload | ||
369 | |||
370 | }; | ||
371 | GNUNET_NETWORK_STRUCT_END | ||
372 | 232 | ||
373 | /** | ||
374 | * Information kept for each message that is yet to | ||
375 | * be transmitted. | ||
376 | */ | ||
377 | struct PendingMessage | ||
378 | { | ||
379 | /** | 233 | /** |
380 | * dll next | 234 | * Fragmentation context |
381 | */ | 235 | */ |
382 | struct PendingMessage *next; | 236 | struct GNUNET_FRAGMENT_Context *fragcontext; |
383 | 237 | ||
384 | /** | 238 | /** |
385 | * dll prev | 239 | * Transmission handle to helper (to cancel if the frag context |
240 | * is destroyed early for some reason). | ||
386 | */ | 241 | */ |
387 | struct PendingMessage *prev; | 242 | struct GNUNET_HELPER_SendHandle *sh; |
388 | 243 | ||
389 | /** | 244 | /** |
390 | * The pending message | 245 | * Intended recipient. |
391 | */ | 246 | */ |
392 | struct WlanHeader *msg; | 247 | struct GNUNET_PeerIdentity target; |
393 | 248 | ||
394 | /** | 249 | /** |
395 | * Size of the message | 250 | * Timeout value for the message. |
396 | */ | 251 | */ |
397 | size_t message_size; | 252 | struct GNUNET_TIME_Absolute timeout; |
398 | 253 | ||
399 | /** | 254 | /** |
400 | * Continuation function to call once the message | 255 | * Timeout task. |
401 | * has been sent. Can be NULL if there is no | ||
402 | * continuation to call. | ||
403 | */ | 256 | */ |
404 | GNUNET_TRANSPORT_TransmitContinuation transmit_cont; | 257 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
405 | 258 | ||
406 | /** | 259 | /** |
407 | * Cls for transmit_cont | 260 | * Continuation to call when we're done with this message. |
408 | */ | 261 | */ |
409 | void *transmit_cont_cls; | 262 | GNUNET_TRANSPORT_TransmitContinuation cont; |
410 | 263 | ||
411 | /** | 264 | /** |
412 | * Timeout value for the pending message. | 265 | * Closure for 'cont' |
413 | */ | 266 | */ |
414 | struct GNUNET_TIME_Absolute timeout; | 267 | void *cont_cls; |
415 | 268 | ||
416 | }; | 269 | }; |
417 | 270 | ||
418 | 271 | ||
419 | /** | 272 | /** |
420 | * Queue for acks to send for fragments recived | 273 | * Struct to represent one network card connection |
421 | */ | 274 | */ |
422 | struct AckSendQueue | 275 | struct MacEndpoint |
423 | { | 276 | { |
424 | 277 | ||
425 | /** | 278 | /** |
426 | * next ack in the ack send queue | 279 | * We keep all MACs in a DLL in the plugin. |
427 | */ | 280 | */ |
428 | struct AckSendQueue *next; | 281 | struct MacEndpoint *next; |
429 | 282 | ||
430 | /** | 283 | /** |
431 | * previous ack in the ack send queue | 284 | * We keep all MACs in a DLL in the plugin. |
432 | */ | 285 | */ |
433 | struct AckSendQueue *prev; | 286 | struct MacEndpoint *prev; |
434 | 287 | ||
435 | /** | 288 | /** |
436 | * pointer to the session this ack belongs to | 289 | * Pointer to the global plugin struct. |
437 | */ | 290 | */ |
438 | struct MacEndpoint *endpoint; | 291 | struct Plugin *plugin; |
439 | 292 | ||
440 | /** | 293 | /** |
441 | * ID of message, to distinguish between the messages, picked randomly. | 294 | * Head of sessions that use this MAC. |
442 | */ | 295 | */ |
443 | uint32_t message_id; | 296 | struct Session *sessions_head; |
444 | 297 | ||
445 | /** | 298 | /** |
446 | * pointer to the radiotap header with the ACK Message. | 299 | * Tail of sessions that use this MAC. |
447 | */ | 300 | */ |
448 | const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radioHeader; | 301 | struct Session *sessions_tail; |
449 | }; | ||
450 | |||
451 | |||
452 | /** | ||
453 | * Session handle for connections. | ||
454 | */ | ||
455 | struct Session | ||
456 | { | ||
457 | 302 | ||
458 | /** | 303 | /** |
459 | * API requirement. | 304 | * Head of messages we are currently sending to this MAC. |
460 | */ | 305 | */ |
461 | struct SessionHeader header; | 306 | struct FragmentMessage *sending_messages_head; |
462 | 307 | ||
463 | /** | 308 | /** |
464 | * Message currently pending for transmission | 309 | * Tail of messages we are currently sending to this MAC. |
465 | * to this peer, if any. head | ||
466 | */ | 310 | */ |
467 | struct PendingMessage *pending_message_head; | 311 | struct FragmentMessage *sending_messages_tail; |
468 | 312 | ||
469 | /** | 313 | /** |
470 | * Message currently pending for transmission | 314 | * Defrag context for this MAC |
471 | * to this peer, if any. tail | ||
472 | */ | 315 | */ |
473 | struct PendingMessage *pending_message_tail; | 316 | struct GNUNET_DEFRAGMENT_Context *defrag; |
474 | 317 | ||
475 | /** | 318 | /** |
476 | * To whom are we talking to (set to our identity | 319 | * When should this endpoint time out? |
477 | * if we are still waiting for the welcome message) | ||
478 | */ | 320 | */ |
479 | struct GNUNET_PeerIdentity target; | 321 | struct GNUNET_TIME_Absolute timeout; |
480 | 322 | ||
481 | /** | 323 | /** |
482 | * Address of the other peer (either based on our 'connect' | 324 | * Timeout task. |
483 | * call or on our 'accept' call). | ||
484 | */ | 325 | */ |
485 | void *connect_addr; | 326 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
486 | 327 | ||
487 | /** | 328 | /** |
488 | * Last activity on this connection. Used to select preferred | 329 | * count of messages in the fragment out queue for this mac endpoint |
489 | * connection and timeout | ||
490 | */ | 330 | */ |
491 | struct GNUNET_TIME_Absolute last_activity; | 331 | unsigned int fragment_messages_out_count; |
492 | 332 | ||
493 | /** | 333 | /** |
494 | * Timeout task. | 334 | * peer mac address |
495 | */ | 335 | */ |
496 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | 336 | struct GNUNET_TRANSPORT_WLAN_MacAddress addr; |
497 | 337 | ||
498 | /** | 338 | /** |
499 | * peer connection | 339 | * Desired transmission power for this MAC |
500 | */ | 340 | */ |
501 | struct MacEndpoint *mac; | 341 | uint16_t tx_power; |
502 | 342 | ||
503 | /** | 343 | /** |
504 | * count of messages in the fragment out queue for this session | 344 | * Desired transmission rate for this MAC |
505 | */ | 345 | */ |
346 | uint8_t rate; | ||
506 | 347 | ||
507 | int fragment_messages_out_count; | 348 | /** |
349 | * Antenna we should use for this MAC | ||
350 | */ | ||
351 | uint8_t antenna; | ||
508 | 352 | ||
509 | }; | 353 | }; |
510 | 354 | ||
355 | |||
511 | /** | 356 | /** |
512 | * Struct to represent one network card connection | 357 | * Encapsulation of all of the state of the plugin. |
513 | */ | 358 | */ |
514 | struct MacEndpoint | 359 | struct Plugin |
515 | { | 360 | { |
516 | |||
517 | /** | 361 | /** |
518 | * dll next | 362 | * Our environment. |
519 | */ | 363 | */ |
520 | struct MacEndpoint *next; | 364 | struct GNUNET_TRANSPORT_PluginEnvironment *env; |
521 | 365 | ||
522 | /** | 366 | /** |
523 | * dll prev | 367 | * Handle to helper process for priviledged operations. |
524 | */ | 368 | */ |
525 | struct MacEndpoint *prev; | 369 | struct GNUNET_HELPER_Handle *suid_helper; |
526 | 370 | ||
527 | /** | 371 | /** |
528 | * Pointer to the global plugin struct. | 372 | * ARGV-vector for the helper (all helpers take only the binary |
373 | * name, one actual argument, plus the NULL terminator for 'argv'). | ||
529 | */ | 374 | */ |
530 | struct Plugin *plugin; | 375 | char * helper_argv[3]; |
531 | 376 | ||
532 | /** | 377 | /** |
533 | * Struct to hold the session reachable over this mac; head | 378 | * The interface of the wlan card given to us by the user. |
534 | */ | 379 | */ |
535 | struct Sessionqueue *sessions_head; | 380 | char *interface; |
536 | 381 | ||
537 | /** | 382 | /** |
538 | * Struct to hold the session reachable over this mac; tail | 383 | * Tokenizer for demultiplexing of data packets resulting from defragmentation. |
539 | */ | 384 | */ |
540 | struct Sessionqueue *sessions_tail; | 385 | struct GNUNET_SERVER_MessageStreamTokenizer *fragment_data_tokenizer; |
541 | 386 | ||
542 | /** | 387 | /** |
543 | * Messages currently sending | 388 | * Tokenizer for demultiplexing of data packets received from the suid helper |
544 | * to a peer, if any. | ||
545 | */ | 389 | */ |
546 | struct FragmentMessage *sending_messages_head; | 390 | struct GNUNET_SERVER_MessageStreamTokenizer *helper_payload_tokenizer; |
547 | 391 | ||
548 | /** | 392 | /** |
549 | * Messages currently sending | 393 | * Tokenizer for demultiplexing of data packets that follow the WLAN Header |
550 | * to a peer (tail), if any. | ||
551 | */ | 394 | */ |
552 | struct FragmentMessage *sending_messages_tail; | 395 | struct GNUNET_SERVER_MessageStreamTokenizer *wlan_header_payload_tokenizer; |
553 | 396 | ||
554 | /** | 397 | /** |
555 | * peer mac address | 398 | * Head of list of open connections. |
556 | */ | 399 | */ |
557 | struct GNUNET_TRANSPORT_WLAN_MacAddress addr; | 400 | struct MacEndpoint *mac_head; |
558 | 401 | ||
559 | /** | 402 | /** |
560 | * Defrag context for this mac endpoint | 403 | * Tail of list of open connections. |
561 | */ | 404 | */ |
562 | struct GNUNET_DEFRAGMENT_Context *defrag; | 405 | struct MacEndpoint *mac_tail; |
563 | 406 | ||
564 | /** | 407 | /** |
565 | * count of messages in the fragment out queue for this mac endpoint | 408 | * Number of connections |
566 | */ | 409 | */ |
567 | int fragment_messages_out_count; | 410 | unsigned int mac_count; |
568 | |||
569 | //TODO DOXYGEN | ||
570 | uint8_t rate; | ||
571 | uint16_t tx_power; | ||
572 | uint8_t antenna; | ||
573 | 411 | ||
574 | /** | 412 | /** |
575 | * Duplicates received | 413 | * Task that periodically sends a HELLO beacon via the helper. |
576 | */ | 414 | */ |
577 | int dups; | 415 | GNUNET_SCHEDULER_TaskIdentifier beacon_task; |
578 | 416 | ||
579 | /** | 417 | /** |
580 | * Fragments received | 418 | * Tracker for bandwidth limit |
581 | */ | 419 | */ |
582 | int fragc; | 420 | struct GNUNET_BANDWIDTH_Tracker tracker; |
583 | 421 | ||
584 | /** | 422 | /** |
585 | * Acks received | 423 | * The mac_address of the wlan card given to us by the helper. |
586 | */ | 424 | */ |
587 | int acks; | 425 | struct GNUNET_TRANSPORT_WLAN_MacAddress mac_address; |
588 | 426 | ||
589 | /** | 427 | /** |
590 | * Last activity on this endpoint. Used to select preferred | 428 | * Have we received a control message with our MAC address yet? |
591 | * connection. | ||
592 | */ | 429 | */ |
593 | struct GNUNET_TIME_Absolute last_activity; | 430 | int have_mac; |
431 | |||
594 | 432 | ||
595 | /** | ||
596 | * Timeout task. | ||
597 | */ | ||
598 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | ||
599 | }; | 433 | }; |
600 | 434 | ||
435 | |||
601 | /** | 436 | /** |
602 | * Struct for Messages in the fragment queue | 437 | * Information associated with a message. Can contain |
438 | * the session or the MAC endpoint associated with the | ||
439 | * message (or both). | ||
603 | */ | 440 | */ |
604 | struct FragmentMessage | 441 | struct MacAndSession |
605 | { | 442 | { |
606 | |||
607 | /** | 443 | /** |
608 | * Session this message belongs to | 444 | * NULL if the identity of the other peer is not known. |
609 | */ | 445 | */ |
610 | struct Session *session; | 446 | struct Session *session; |
611 | 447 | ||
612 | /** | 448 | /** |
613 | * This is a doubly-linked list. | 449 | * MAC address of the other peer, NULL if not known. |
614 | */ | ||
615 | struct FragmentMessage *next; | ||
616 | |||
617 | /** | ||
618 | * This is a doubly-linked list. | ||
619 | */ | ||
620 | struct FragmentMessage *prev; | ||
621 | |||
622 | /** | ||
623 | * Fragmentation context | ||
624 | */ | ||
625 | struct GNUNET_FRAGMENT_Context *fragcontext; | ||
626 | |||
627 | /** | ||
628 | * Timeout value for the message. | ||
629 | */ | ||
630 | struct GNUNET_TIME_Absolute timeout; | ||
631 | |||
632 | /** | ||
633 | * Timeout task. | ||
634 | */ | ||
635 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | ||
636 | |||
637 | /** | ||
638 | * pointer to the radiotap header | ||
639 | */ | 450 | */ |
640 | struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radioHeader; | 451 | struct MacEndpoint *endpoint; |
641 | }; | 452 | }; |
642 | 453 | ||
643 | 454 | ||
644 | static void | ||
645 | do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
646 | |||
647 | |||
648 | static void | ||
649 | free_session (struct Plugin *plugin, struct Sessionqueue *queue, | ||
650 | int do_free_macendpoint); | ||
651 | |||
652 | |||
653 | static struct MacEndpoint * | ||
654 | create_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr); | ||
655 | |||
656 | |||
657 | static void | ||
658 | finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
659 | |||
660 | |||
661 | |||
662 | /** | ||
663 | * Function to find a MacEndpoint with a specific mac addr | ||
664 | * @param plugin pointer to the plugin struct | ||
665 | * @param addr pointer to the mac address | ||
666 | * @param create_new GNUNET_YES if a new end point should be created | ||
667 | * @return | ||
668 | */ | ||
669 | static struct MacEndpoint * | ||
670 | get_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr, | ||
671 | int create_new) | ||
672 | { | ||
673 | struct MacEndpoint *queue = plugin->mac_head; | ||
674 | |||
675 | while (queue != NULL) | ||
676 | { | ||
677 | //GNUNET_assert (queue->sessions_head != NULL); | ||
678 | if (memcmp (addr, &queue->addr, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) | ||
679 | return queue; /* session found */ | ||
680 | queue = queue->next; | ||
681 | } | ||
682 | |||
683 | if (create_new == GNUNET_YES) | ||
684 | { | ||
685 | return create_macendpoint (plugin, addr); | ||
686 | } | ||
687 | else | ||
688 | { | ||
689 | return NULL; | ||
690 | } | ||
691 | } | ||
692 | |||
693 | |||
694 | /** | ||
695 | * search for a session with the macendpoint and peer id | ||
696 | * | ||
697 | * @param plugin pointer to the plugin struct | ||
698 | * @param endpoint pointer to the mac endpoint of the peer | ||
699 | * @param peer pointer to the peerid | ||
700 | * @return returns the session | ||
701 | */ | ||
702 | static struct Session * | ||
703 | search_session (struct Plugin *plugin, const struct MacEndpoint *endpoint, | ||
704 | const struct GNUNET_PeerIdentity *peer) | ||
705 | { | ||
706 | GNUNET_assert (endpoint != NULL); | ||
707 | struct Sessionqueue *queue = endpoint->sessions_head; | ||
708 | |||
709 | while (queue != NULL) | ||
710 | { | ||
711 | GNUNET_assert (queue->content != NULL); | ||
712 | if (memcmp | ||
713 | (peer, &queue->content->target, | ||
714 | sizeof (struct GNUNET_PeerIdentity)) == 0) | ||
715 | return queue->content; /* session found */ | ||
716 | queue = queue->next; | ||
717 | } | ||
718 | return NULL; | ||
719 | } | ||
720 | |||
721 | /** | 455 | /** |
722 | * Function called for a quick conversion of the binary address to | 456 | * Print MAC addresses nicely. |
723 | * a numeric address. Note that the caller must not free the | ||
724 | * address and that the next call to this function is allowed | ||
725 | * to override the address again. | ||
726 | * | 457 | * |
727 | * @param cls closure | 458 | * @param mac the mac address |
728 | * @param addr binary address | 459 | * @return string to a static buffer with the human-readable mac, will be overwritten during the next call to this function |
729 | * @param addrlen length of the address | ||
730 | * @return string representing the same address | ||
731 | */ | 460 | */ |
732 | static const char * | 461 | static const char * |
733 | wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) | 462 | mac_to_string (const struct GNUNET_TRANSPORT_WLAN_MacAddress * mac) |
734 | { | ||
735 | static char ret[40]; | ||
736 | const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac; | ||
737 | |||
738 | if (addrlen != sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) | ||
739 | { | ||
740 | GNUNET_break (0); | ||
741 | return NULL; | ||
742 | } | ||
743 | mac = addr; | ||
744 | GNUNET_snprintf (ret, sizeof (ret), "%s Mac-Address %X:%X:%X:%X:%X:%X", | ||
745 | PROTOCOL_PREFIX, mac->mac[0], mac->mac[1], mac->mac[2], | ||
746 | mac->mac[3], mac->mac[4], mac->mac[5]); | ||
747 | |||
748 | return ret; | ||
749 | } | ||
750 | |||
751 | /** | ||
752 | * Function for the scheduler if a session times out | ||
753 | * @param cls pointer to the Sessionqueue | ||
754 | * @param tc pointer to the GNUNET_SCHEDULER_TaskContext | ||
755 | */ | ||
756 | static void | ||
757 | session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
758 | { | ||
759 | struct Sessionqueue *queue = cls; | ||
760 | |||
761 | GNUNET_assert (queue != NULL); | ||
762 | GNUNET_assert (queue->content != NULL); | ||
763 | queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
764 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
765 | { | ||
766 | return; | ||
767 | } | ||
768 | if (GNUNET_TIME_absolute_get_remaining | ||
769 | (GNUNET_TIME_absolute_add | ||
770 | (queue->content->last_activity, SESSION_TIMEOUT)).rel_value == 0) | ||
771 | { | ||
772 | |||
773 | GNUNET_assert (queue->content->mac != NULL); | ||
774 | GNUNET_assert (queue->content->mac->plugin != NULL); | ||
775 | GNUNET_STATISTICS_update (queue->content->mac->plugin->env->stats, | ||
776 | _("# wlan session timeouts"), 1, GNUNET_NO); | ||
777 | free_session (queue->content->mac->plugin, queue, GNUNET_YES); | ||
778 | } | ||
779 | else | ||
780 | { | ||
781 | queue->content->timeout_task = | ||
782 | GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue); | ||
783 | } | ||
784 | } | ||
785 | |||
786 | /** | ||
787 | * create a new session | ||
788 | * | ||
789 | * @param plugin pointer to the plugin struct | ||
790 | * @param endpoint pointer to the mac endpoint of the peer | ||
791 | * @param peer peer identity to use for this session | ||
792 | * @return returns the session | ||
793 | */ | ||
794 | static struct Session * | ||
795 | create_session (struct Plugin *plugin, struct MacEndpoint *endpoint, | ||
796 | const struct GNUNET_PeerIdentity *peer) | ||
797 | { | ||
798 | GNUNET_assert (endpoint != NULL); | ||
799 | GNUNET_assert (plugin != NULL); | ||
800 | GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan session created"), 1, | ||
801 | GNUNET_NO); | ||
802 | struct Sessionqueue *queue = | ||
803 | GNUNET_malloc (sizeof (struct Sessionqueue) + sizeof (struct Session)); | ||
804 | |||
805 | GNUNET_CONTAINER_DLL_insert_tail (endpoint->sessions_head, | ||
806 | endpoint->sessions_tail, queue); | ||
807 | |||
808 | queue->content = (struct Session *) &queue[1]; | ||
809 | queue->content->mac = endpoint; | ||
810 | queue->content->target = *peer; | ||
811 | queue->content->last_activity = GNUNET_TIME_absolute_get (); | ||
812 | queue->content->timeout_task = | ||
813 | GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue); | ||
814 | |||
815 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
816 | "New session %p with endpoint %p: %s\n", queue->content, | ||
817 | endpoint, wlan_plugin_address_to_string (NULL, | ||
818 | endpoint->addr.mac, | ||
819 | 6)); | ||
820 | return queue->content; | ||
821 | } | ||
822 | |||
823 | /** | ||
824 | * Get session from address, create if no session exists | ||
825 | * | ||
826 | * @param plugin pointer to the plugin struct | ||
827 | * @param addr pointer to the mac address of the peer | ||
828 | * @param peer pointer to the peerid | ||
829 | * @return returns the session | ||
830 | */ | ||
831 | static struct Session * | ||
832 | get_session (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr, | ||
833 | const struct GNUNET_PeerIdentity *peer) | ||
834 | { | ||
835 | struct MacEndpoint *mac; | ||
836 | |||
837 | mac = get_macendpoint (plugin, addr, GNUNET_YES); | ||
838 | struct Session *session = search_session (plugin, mac, peer); | ||
839 | |||
840 | if (session != NULL) | ||
841 | return session; | ||
842 | return create_session (plugin, mac, peer); | ||
843 | } | ||
844 | |||
845 | /** | ||
846 | * Queue the session to send data | ||
847 | * checks if there is a message pending | ||
848 | * checks if this session is not allready in the queue | ||
849 | * @param plugin pointer to the plugin | ||
850 | * @param session pointer to the session to add | ||
851 | */ | ||
852 | static void | ||
853 | queue_session (struct Plugin *plugin, struct Session *session) | ||
854 | { | ||
855 | struct Sessionqueue *queue = plugin->pending_Sessions_head; | ||
856 | |||
857 | if (session->pending_message_head != NULL) | ||
858 | { | ||
859 | while (queue != NULL) | ||
860 | { | ||
861 | // content is never NULL | ||
862 | GNUNET_assert (queue->content != NULL); | ||
863 | // is session already in queue? | ||
864 | if (session == queue->content) | ||
865 | { | ||
866 | return; | ||
867 | } | ||
868 | // try next | ||
869 | queue = queue->next; | ||
870 | } | ||
871 | |||
872 | // Session is not in the queue | ||
873 | |||
874 | queue = GNUNET_malloc (sizeof (struct Sessionqueue)); | ||
875 | queue->content = session; | ||
876 | |||
877 | //insert at the tail | ||
878 | GNUNET_CONTAINER_DLL_insert_tail (plugin->pending_Sessions_head, | ||
879 | plugin->pending_Sessions_tail, queue); | ||
880 | plugin->pendingsessions++; | ||
881 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), | ||
882 | plugin->pendingsessions, GNUNET_NO); | ||
883 | } | ||
884 | |||
885 | } | ||
886 | |||
887 | /** | ||
888 | * Function to schedule the write task, executed after a delay | ||
889 | * @param cls pointer to the plugin struct | ||
890 | * @param tc GNUNET_SCHEDULER_TaskContext pointer | ||
891 | */ | ||
892 | static void | ||
893 | delay_fragment_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
894 | { | 463 | { |
895 | struct Plugin *plugin = cls; | 464 | static char macstr[20]; |
896 | |||
897 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
898 | |||
899 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
900 | return; | ||
901 | |||
902 | // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg | ||
903 | if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK) | ||
904 | { | ||
905 | plugin->server_write_task = | ||
906 | GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
907 | plugin->server_stdin_handle, | ||
908 | &do_transmit, plugin); | ||
909 | } | ||
910 | } | ||
911 | |||
912 | /** | ||
913 | * Function to calculate the time of the next periodic "hello-beacon" | ||
914 | * @param plugin pointer to the plugin struct | ||
915 | */ | ||
916 | static void | ||
917 | set_next_beacon_time (struct Plugin *const plugin) | ||
918 | { | ||
919 | //under 10 known peers: once a second | ||
920 | if (plugin->mac_count < 10) | ||
921 | { | ||
922 | plugin->beacon_time = | ||
923 | GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
924 | GNUNET_TIME_relative_multiply | ||
925 | (GNUNET_TIME_UNIT_SECONDS, | ||
926 | HELLO_BEACON_SCALING_FACTOR)); | ||
927 | } | ||
928 | //under 30 known peers: every 10 seconds | ||
929 | else if (plugin->mac_count < 30) | ||
930 | { | ||
931 | plugin->beacon_time = | ||
932 | GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
933 | GNUNET_TIME_relative_multiply | ||
934 | (GNUNET_TIME_UNIT_SECONDS, | ||
935 | 10 * HELLO_BEACON_SCALING_FACTOR)); | ||
936 | } | ||
937 | //over 30 known peers: once a minute | ||
938 | else | ||
939 | { | ||
940 | plugin->beacon_time = | ||
941 | GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
942 | GNUNET_TIME_relative_multiply | ||
943 | (GNUNET_TIME_UNIT_MINUTES, | ||
944 | HELLO_BEACON_SCALING_FACTOR)); | ||
945 | } | ||
946 | } | ||
947 | |||
948 | |||
949 | /** | ||
950 | * Function to set the timer for the next timeout of the fragment queue | ||
951 | * @param plugin the handle to the plugin struct | ||
952 | */ | ||
953 | static void | ||
954 | set_next_send (struct Plugin *plugin) | ||
955 | { | ||
956 | struct GNUNET_TIME_Relative next_send; | ||
957 | |||
958 | //abort if helper is not running | ||
959 | if (plugin->helper_is_running == GNUNET_NO) | ||
960 | { | ||
961 | return; | ||
962 | } | ||
963 | |||
964 | //cancel old task | ||
965 | if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK) | ||
966 | { | ||
967 | GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task); | ||
968 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
969 | } | ||
970 | |||
971 | //check if some acks are in the queue | ||
972 | if (plugin->ack_send_queue_head != NULL) | ||
973 | { | ||
974 | next_send = GNUNET_TIME_UNIT_ZERO; | ||
975 | } | ||
976 | |||
977 | //check if there are some fragments in the queue | ||
978 | else if (plugin->sending_messages_head != NULL) | ||
979 | { | ||
980 | next_send = GNUNET_TIME_UNIT_ZERO; | ||
981 | } | ||
982 | else | ||
983 | { | ||
984 | next_send = GNUNET_TIME_absolute_get_remaining (plugin->beacon_time); | ||
985 | } | ||
986 | |||
987 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
988 | "Next packet is send in: %u\n", next_send.rel_value); | ||
989 | if (next_send.rel_value == GNUNET_TIME_UNIT_ZERO.rel_value) | ||
990 | { | ||
991 | if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK) | ||
992 | { | ||
993 | plugin->server_write_task = | ||
994 | GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
995 | plugin->server_stdin_handle, | ||
996 | &do_transmit, plugin); | ||
997 | } | ||
998 | } | ||
999 | else | ||
1000 | { | ||
1001 | if (plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK) | ||
1002 | { | ||
1003 | plugin->server_write_delay_task = | ||
1004 | GNUNET_SCHEDULER_add_delayed (next_send, &delay_fragment_task, | ||
1005 | plugin); | ||
1006 | } | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | |||
1011 | /** | ||
1012 | * Function to get the next queued Session, removes the session from the queue | ||
1013 | * @param plugin pointer to the plugin struct | ||
1014 | * @return pointer to the session found, returns NULL if there is now session in the queue | ||
1015 | */ | ||
1016 | static struct Session * | ||
1017 | get_next_queue_session (struct Plugin *plugin) | ||
1018 | { | ||
1019 | struct Session *session; | ||
1020 | struct Sessionqueue *sessionqueue; | ||
1021 | struct Sessionqueue *sessionqueue_old; | ||
1022 | struct PendingMessage *pm; | ||
1023 | |||
1024 | sessionqueue = plugin->pending_Sessions_head; | ||
1025 | |||
1026 | while (sessionqueue != NULL) | ||
1027 | { | ||
1028 | session = sessionqueue->content; | ||
1029 | |||
1030 | GNUNET_assert (session != NULL); | ||
1031 | pm = session->pending_message_head; | ||
1032 | |||
1033 | if (pm == NULL) | ||
1034 | { | ||
1035 | sessionqueue_old = sessionqueue; | ||
1036 | sessionqueue = sessionqueue->next; | ||
1037 | plugin->pendingsessions--; | ||
1038 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), | ||
1039 | plugin->pendingsessions, GNUNET_NO); | ||
1040 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, | ||
1041 | plugin->pending_Sessions_tail, | ||
1042 | sessionqueue_old); | ||
1043 | |||
1044 | GNUNET_free (sessionqueue_old); | ||
1045 | continue; | ||
1046 | } | ||
1047 | |||
1048 | //check for message timeout | ||
1049 | if (GNUNET_TIME_absolute_get_remaining (pm->timeout).rel_value > 0) | ||
1050 | { | ||
1051 | //check if session has no message in the fragment queue | ||
1052 | if ((session->mac->fragment_messages_out_count < | ||
1053 | FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT) && | ||
1054 | (session->fragment_messages_out_count < | ||
1055 | FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION)) | ||
1056 | { | ||
1057 | plugin->pendingsessions--; | ||
1058 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), | ||
1059 | plugin->pendingsessions, GNUNET_NO); | ||
1060 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, | ||
1061 | plugin->pending_Sessions_tail, | ||
1062 | sessionqueue); | ||
1063 | GNUNET_free (sessionqueue); | ||
1064 | |||
1065 | return session; | ||
1066 | } | ||
1067 | else | ||
1068 | { | ||
1069 | sessionqueue = sessionqueue->next; | ||
1070 | } | ||
1071 | } | ||
1072 | else | ||
1073 | { | ||
1074 | GNUNET_CONTAINER_DLL_remove (session->pending_message_head, | ||
1075 | session->pending_message_tail, pm); | ||
1076 | |||
1077 | //call the cont func that it did not work | ||
1078 | if (pm->transmit_cont != NULL) | ||
1079 | pm->transmit_cont (pm->transmit_cont_cls, &(session->target), | ||
1080 | GNUNET_SYSERR); | ||
1081 | GNUNET_free (pm->msg); | ||
1082 | GNUNET_free (pm); | ||
1083 | |||
1084 | if (session->pending_message_head == NULL) | ||
1085 | { | ||
1086 | sessionqueue_old = sessionqueue; | ||
1087 | sessionqueue = sessionqueue->next; | ||
1088 | plugin->pendingsessions--; | ||
1089 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), | ||
1090 | plugin->pendingsessions, GNUNET_NO); | ||
1091 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, | ||
1092 | plugin->pending_Sessions_tail, | ||
1093 | sessionqueue_old); | ||
1094 | |||
1095 | GNUNET_free (sessionqueue_old); | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1099 | } | ||
1100 | return NULL; | ||
1101 | } | ||
1102 | |||
1103 | |||
1104 | /** | ||
1105 | * frees the space of a message in the fragment queue (send queue) | ||
1106 | * @param plugin the plugin struct | ||
1107 | * @param fm message to free | ||
1108 | */ | ||
1109 | static void | ||
1110 | free_fragment_message (struct Plugin *plugin, struct FragmentMessage *fm) | ||
1111 | { | ||
1112 | struct Session *session = fm->session; | ||
1113 | struct MacEndpoint *endpoint = session->mac; | ||
1114 | struct FragmentMessage_queue *fmq; | ||
1115 | struct FragmentMessage_queue *fmq_next; | ||
1116 | 465 | ||
1117 | fmq = plugin->sending_messages_head; | 466 | GNUNET_snprintf (macstr, sizeof (macstr), "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", mac->mac[0], mac->mac[1], |
1118 | while (fmq != NULL) | 467 | mac->mac[2], mac->mac[3], mac->mac[4], mac->mac[5]); |
1119 | { | 468 | return macstr; |
1120 | fmq_next = fmq->next; | ||
1121 | if (fmq->content == fm) | ||
1122 | { | ||
1123 | GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head, | ||
1124 | plugin->sending_messages_tail, fmq); | ||
1125 | GNUNET_free (fmq); | ||
1126 | } | ||
1127 | fmq = fmq_next; | ||
1128 | } | ||
1129 | session->mac->fragment_messages_out_count--; | ||
1130 | session->fragment_messages_out_count--; | ||
1131 | plugin->pending_Fragment_Messages--; | ||
1132 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"), | ||
1133 | plugin->pending_Fragment_Messages, GNUNET_NO); | ||
1134 | GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head, | ||
1135 | endpoint->sending_messages_tail, fm); | ||
1136 | GNUNET_FRAGMENT_context_destroy (fm->fragcontext); | ||
1137 | if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
1138 | { | ||
1139 | GNUNET_SCHEDULER_cancel (fm->timeout_task); | ||
1140 | fm->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
1141 | } | ||
1142 | GNUNET_free (fm); | ||
1143 | queue_session (plugin, session); | ||
1144 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
1145 | "Free pending fragment messages %p, session %p\n", fm, | ||
1146 | session); | ||
1147 | } | 469 | } |
1148 | 470 | ||
1149 | 471 | ||
1150 | /** | 472 | /** |
1151 | * function to fill the radiotap header | 473 | * Fill the radiotap header |
1152 | * | 474 | * |
1153 | * @param plugin pointer to the plugin struct | 475 | * @param endpoint pointer to the endpoint, can be NULL |
1154 | * @param endpoint pointer to the endpoint | ||
1155 | * @param header pointer to the radiotap header | 476 | * @param header pointer to the radiotap header |
1156 | * @param size total message size | 477 | * @param size total message size |
1157 | * @return GNUNET_YES at success | ||
1158 | */ | 478 | */ |
1159 | static int | 479 | static void |
1160 | getRadiotapHeader (struct Plugin *plugin, struct MacEndpoint *endpoint, | 480 | get_radiotap_header (struct MacEndpoint *endpoint, |
1161 | struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header, | 481 | struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header, |
1162 | uint16_t size) | 482 | uint16_t size) |
1163 | { | 483 | { |
1164 | header->header.type = ntohs (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER); | 484 | header->header.type = ntohs (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER); |
1165 | header->header.size = ntohs (size); | 485 | header->header.size = ntohs (size); |
1166 | if (endpoint != NULL) | 486 | if (NULL != endpoint) |
1167 | { | 487 | { |
1168 | header->rate = endpoint->rate; | 488 | header->rate = endpoint->rate; |
1169 | header->tx_power = endpoint->tx_power; | 489 | header->tx_power = endpoint->tx_power; |
@@ -1175,521 +495,302 @@ getRadiotapHeader (struct Plugin *plugin, struct MacEndpoint *endpoint, | |||
1175 | header->tx_power = 0; | 495 | header->tx_power = 0; |
1176 | header->antenna = 0; | 496 | header->antenna = 0; |
1177 | } | 497 | } |
1178 | |||
1179 | return GNUNET_YES; | ||
1180 | } | 498 | } |
1181 | 499 | ||
1182 | 500 | ||
1183 | /** | 501 | /** |
1184 | * function to generate the wlan hardware header for one packet | 502 | * Generate the WLAN hardware header for one packet |
1185 | * @param Header address to write the header to | 503 | * |
504 | * @param header address to write the header to | ||
1186 | * @param to_mac_addr address of the recipient | 505 | * @param to_mac_addr address of the recipient |
1187 | * @param plugin pointer to the plugin struct | ||
1188 | * @param size size of the whole packet, needed to calculate the time to send the packet | 506 | * @param size size of the whole packet, needed to calculate the time to send the packet |
1189 | * FIXME: 'size' is initialized inconsistently throughout the code (sometimes payload, sometimes everything) | ||
1190 | * @return GNUNET_YES if there was no error | ||
1191 | */ | 507 | */ |
1192 | static int | 508 | static void |
1193 | getWlanHeader (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *Header, | 509 | get_wlan_header (struct Plugin *plugin, |
1194 | const struct GNUNET_TRANSPORT_WLAN_MacAddress *to_mac_addr, struct Plugin *plugin, | 510 | struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *header, |
1195 | unsigned int size) | 511 | const struct GNUNET_TRANSPORT_WLAN_MacAddress *to_mac_addr, |
512 | unsigned int size) | ||
1196 | { | 513 | { |
1197 | const int rate = 11000000; | 514 | const int rate = 11000000; |
1198 | 515 | ||
1199 | Header->frame_control = htons (IEEE80211_FC0_TYPE_DATA); | 516 | header->frame_control = htons (IEEE80211_FC0_TYPE_DATA); |
1200 | Header->addr1 = *to_mac_addr; | 517 | header->addr1 = *to_mac_addr; |
1201 | Header->addr2 = plugin->mac_address; | 518 | header->addr2 = plugin->mac_address; |
1202 | Header->addr3 = mac_bssid_gnunet; | 519 | header->addr3 = mac_bssid_gnunet; |
1203 | Header->duration = GNUNET_htole16 ((size * 1000000) / rate + 290); | 520 | header->duration = GNUNET_htole16 ((size * 1000000) / rate + 290); |
1204 | Header->sequence_control = 0; // FIXME? | 521 | header->sequence_control = 0; // FIXME? |
1205 | Header->llc[0] = WLAN_LLC_DSAP_FIELD; | 522 | header->llc[0] = WLAN_LLC_DSAP_FIELD; |
1206 | Header->llc[1] = WLAN_LLC_SSAP_FIELD; | 523 | header->llc[1] = WLAN_LLC_SSAP_FIELD; |
1207 | Header->llc[2] = 0; // FIXME? | 524 | header->llc[2] = 0; // FIXME? |
1208 | Header->llc[3] = 0; // FIXME? | 525 | header->llc[3] = 0; // FIXME? |
1209 | return GNUNET_YES; | ||
1210 | } | 526 | } |
1211 | 527 | ||
1212 | 528 | ||
1213 | /** | 529 | /** |
1214 | * function to add a fragment of a message to send | 530 | * Send an ACK for a fragment we received. |
1215 | * @param cls FragmentMessage this message belongs to | 531 | * |
1216 | * @param hdr pointer to the start of the message | 532 | * @param cls the 'struct MacEndpoint' the ACK must be sent to |
533 | * @param msg_id id of the message | ||
534 | * @param hdr pointer to the hdr where the ack is stored | ||
1217 | */ | 535 | */ |
1218 | static void | 536 | static void |
1219 | add_message_for_send (void *cls, const struct GNUNET_MessageHeader *hdr) | 537 | send_ack (void *cls, uint32_t msg_id, |
538 | const struct GNUNET_MessageHeader *hdr) | ||
1220 | { | 539 | { |
1221 | struct FragmentMessage *fm = cls; | 540 | struct MacEndpoint *endpoint = cls; |
1222 | struct FragmentMessage_queue *fmqueue; | 541 | struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage* radio_header; |
1223 | struct MacEndpoint *endpoint; | 542 | uint16_t msize = ntohs (hdr->size); |
1224 | struct Plugin *plugin; | 543 | size_t size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + msize; |
1225 | uint16_t size; | 544 | char buf[size]; |
1226 | |||
1227 | GNUNET_assert (cls != NULL); | ||
1228 | endpoint = fm->session->mac; | ||
1229 | plugin = endpoint->plugin; | ||
1230 | 545 | ||
1231 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 546 | if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
1232 | "Adding fragment of message %p to send, session %p, endpoint %p, type %u\n", | 547 | { |
1233 | fm, fm->session, endpoint, hdr->type); | 548 | GNUNET_break (0); |
1234 | size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + ntohs (hdr->size); | 549 | return; |
1235 | fm->radioHeader = GNUNET_malloc (size); | 550 | } |
1236 | getRadiotapHeader (plugin, fm->session->mac, fm->radioHeader, size); | 551 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1237 | getWlanHeader (&fm->radioHeader->frame, &(fm->session->mac->addr), plugin, | 552 | "Sending ACK to helper\n"); |
1238 | size); | 553 | radio_header = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) buf; |
1239 | memcpy (&fm->radioHeader[1], hdr, ntohs (hdr->size)); | 554 | get_radiotap_header (endpoint, radio_header, size); |
1240 | // FIXME: yucky allocation structure! | 555 | get_wlan_header (endpoint->plugin, |
1241 | fmqueue = GNUNET_malloc (sizeof (struct FragmentMessage_queue)); | 556 | &radio_header->frame, |
1242 | fmqueue->content = fm; | 557 | &endpoint->addr, |
1243 | GNUNET_CONTAINER_DLL_insert_tail (plugin->sending_messages_head, | 558 | size); |
1244 | plugin->sending_messages_tail, fmqueue); | 559 | memcpy (&radio_header[1], hdr, msize); |
1245 | set_next_send (plugin); | 560 | if (NULL != |
561 | GNUNET_HELPER_send (endpoint->plugin->suid_helper, | ||
562 | &radio_header->header, | ||
563 | GNUNET_NO /* dropping ACKs is bad */, | ||
564 | NULL, NULL)) | ||
565 | GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN ACKs sent"), | ||
566 | 1, GNUNET_NO); | ||
1246 | } | 567 | } |
1247 | 568 | ||
1248 | 569 | ||
1249 | /** | 570 | /** |
1250 | * We have been notified that gnunet-helper-transport-wlan has written something to stdout. | 571 | * Handles the data after all fragments are put together |
1251 | * Handle the output, then reschedule this function to be called again once | ||
1252 | * more is available. | ||
1253 | * | 572 | * |
1254 | * @param cls the plugin handle | 573 | * @param cls macendpoint this messages belongs to |
1255 | * @param tc the scheduling context | 574 | * @param hdr pointer to the data |
1256 | */ | 575 | */ |
1257 | static void | 576 | static void |
1258 | wlan_plugin_helper_read (void *cls, | 577 | wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr) |
1259 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1260 | { | 578 | { |
1261 | struct Plugin *plugin = cls; | 579 | struct MacEndpoint *endpoint = cls; |
1262 | 580 | struct Plugin *plugin = endpoint->plugin; | |
1263 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 581 | struct MacAndSession mas; |
1264 | |||
1265 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
1266 | return; | ||
1267 | |||
1268 | char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)]; | ||
1269 | ssize_t bytes; | ||
1270 | 582 | ||
1271 | bytes = | 583 | GNUNET_STATISTICS_update (plugin->env->stats, |
1272 | GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf, | 584 | _("# WLAN messages defragmented"), 1, |
1273 | sizeof (mybuf)); | 585 | GNUNET_NO); |
1274 | if (bytes <= 0) | 586 | mas.session = NULL; |
1275 | { | 587 | mas.endpoint = endpoint; |
1276 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 588 | (void) GNUNET_SERVER_mst_receive (plugin->fragment_data_tokenizer, |
1277 | _ | 589 | &mas, |
1278 | ("Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n"), | 590 | (const char *) hdr, |
1279 | bytes); | 591 | ntohs (hdr->size), |
1280 | return; | 592 | GNUNET_YES, GNUNET_NO); |
1281 | } | ||
1282 | GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes, | ||
1283 | GNUNET_NO, GNUNET_NO); | ||
1284 | |||
1285 | GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); | ||
1286 | plugin->server_read_task = | ||
1287 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1288 | plugin->server_stdout_handle, | ||
1289 | &wlan_plugin_helper_read, plugin); | ||
1290 | } | 593 | } |
1291 | 594 | ||
595 | |||
1292 | /** | 596 | /** |
1293 | * Start the gnunet-helper-transport-wlan process. | 597 | * Free a session |
1294 | * | 598 | * |
1295 | * @param plugin the transport plugin | 599 | * @param session the session free |
1296 | * @return GNUNET_YES if process was started, GNUNET_SYSERR on error | ||
1297 | */ | 600 | */ |
1298 | static int | 601 | static void |
1299 | wlan_transport_start_wlan_helper (struct Plugin *plugin) | 602 | free_session (struct Session *session) |
1300 | { | 603 | { |
1301 | const char *filenamehw = "gnunet-helper-transport-wlan"; | 604 | struct MacEndpoint *endpoint = session->mac; |
1302 | const char *filenameloopback = "gnunet-helper-transport-wlan-dummy"; | 605 | struct PendingMessage *pm; |
1303 | char *absolute_filename = NULL; | 606 | |
1304 | 607 | endpoint->plugin->env->session_end (endpoint->plugin->env->cls, | |
1305 | if (plugin->helper_is_running == GNUNET_YES) | 608 | &session->target, |
1306 | { | 609 | session); |
1307 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 610 | while (NULL != (pm = session->pending_message_head)) |
1308 | "wlan_transport_start_wlan_helper not needed, helper already running!"); | 611 | { |
1309 | return GNUNET_YES; | 612 | GNUNET_CONTAINER_DLL_remove (session->pending_message_head, |
1310 | } | 613 | session->pending_message_tail, pm); |
1311 | 614 | if (GNUNET_SCHEDULER_NO_TASK != pm->timeout_task) | |
1312 | plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); | ||
1313 | if (plugin->server_stdout == NULL) | ||
1314 | return GNUNET_SYSERR; | ||
1315 | |||
1316 | plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); | ||
1317 | if (plugin->server_stdin == NULL) | ||
1318 | return GNUNET_SYSERR; | ||
1319 | |||
1320 | if ((plugin->testmode == 1) || (plugin->testmode == 2)) | ||
1321 | { | ||
1322 | if (GNUNET_OS_check_helper_binary (filenameloopback) == GNUNET_YES) | ||
1323 | { | ||
1324 | absolute_filename = GNUNET_strdup (filenameloopback); | ||
1325 | } | ||
1326 | else | ||
1327 | { | ||
1328 | char cwd[FILENAME_MAX]; | ||
1329 | |||
1330 | GNUNET_assert (getcwd (cwd, sizeof (cwd)) != NULL); | ||
1331 | |||
1332 | GNUNET_asprintf (&absolute_filename, "%s%s%s", cwd, DIR_SEPARATOR_STR, | ||
1333 | filenameloopback); | ||
1334 | |||
1335 | if (GNUNET_DISK_file_test (filenameloopback) != GNUNET_YES) | ||
1336 | { | ||
1337 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | ||
1338 | "Helper `%s' not found! %i\n", absolute_filename); | ||
1339 | GNUNET_break (0); | ||
1340 | } | ||
1341 | } | ||
1342 | } | ||
1343 | |||
1344 | /* Start the server process */ | ||
1345 | |||
1346 | if (plugin->testmode == 0) | ||
1347 | { | ||
1348 | |||
1349 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
1350 | "Starting gnunet-helper-transport-wlan process cmd: %s %s %i\n", | ||
1351 | filenamehw, plugin->interface, plugin->testmode); | ||
1352 | if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES) | ||
1353 | { | ||
1354 | plugin->server_proc = | ||
1355 | GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout, | ||
1356 | filenamehw, filenamehw, plugin->interface, | ||
1357 | NULL); | ||
1358 | } | ||
1359 | else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO) | ||
1360 | { | ||
1361 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | ||
1362 | "gnunet-helper-transport-wlan is not suid, please change it or look at the doku\n"); | ||
1363 | GNUNET_break (0); | ||
1364 | } | ||
1365 | else | ||
1366 | { | ||
1367 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | ||
1368 | "gnunet-helper-transport-wlan not found, please look if it exists and is the $PATH variable!\n"); | ||
1369 | GNUNET_break (0); | ||
1370 | } | ||
1371 | |||
1372 | } | ||
1373 | else if (plugin->testmode == 1) | ||
1374 | { | ||
1375 | |||
1376 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME, | ||
1377 | "Starting gnunet-helper-transport-wlan-dummy loopback 1 process cmd: %s %s %i\n", | ||
1378 | absolute_filename, plugin->interface, plugin->testmode); | ||
1379 | plugin->server_proc = | ||
1380 | GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout, | ||
1381 | absolute_filename, absolute_filename, "1", | ||
1382 | NULL); | ||
1383 | if (plugin->server_proc == NULL) | ||
1384 | { | ||
1385 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | ||
1386 | "`%s' not found, please look if it exists and is in the $PATH variable!\n", | ||
1387 | absolute_filename); | ||
1388 | GNUNET_break (0); | ||
1389 | } | ||
1390 | } | ||
1391 | else if (plugin->testmode == 2) | ||
1392 | { | ||
1393 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME, | ||
1394 | "Starting gnunet-helper-transport-wlan-dummy loopback 2 process cmd: %s %s %i\n", | ||
1395 | absolute_filename, plugin->interface, plugin->testmode); | ||
1396 | plugin->server_proc = | ||
1397 | GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout, | ||
1398 | absolute_filename, absolute_filename, "2", | ||
1399 | NULL); | ||
1400 | if (plugin->server_proc == NULL) | ||
1401 | { | 615 | { |
1402 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | 616 | GNUNET_SCHEDULER_cancel (pm->timeout_task); |
1403 | "`%s' not found, please look if it exists and is in the $PATH variable!\n", | 617 | pm->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1404 | absolute_filename); | ||
1405 | GNUNET_break (0); | ||
1406 | } | 618 | } |
619 | GNUNET_free (pm->msg); | ||
620 | GNUNET_free (pm); | ||
1407 | } | 621 | } |
1408 | if (absolute_filename != NULL) | 622 | GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head, |
1409 | GNUNET_free (absolute_filename); | 623 | endpoint->sessions_tail, |
1410 | if (plugin->server_proc == NULL) | 624 | session); |
625 | if (session->timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
1411 | { | 626 | { |
1412 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 627 | GNUNET_SCHEDULER_cancel (session->timeout_task); |
1413 | "Failed to start gnunet-helper-transport-wlan process\n"); | 628 | session->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1414 | return GNUNET_SYSERR; | ||
1415 | } | 629 | } |
1416 | 630 | GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN sessions allocated"), -1, | |
1417 | 631 | GNUNET_NO); | |
1418 | 632 | GNUNET_free (session); | |
1419 | /* Close the write end of the read pipe */ | ||
1420 | GNUNET_DISK_pipe_close_end (plugin->server_stdout, | ||
1421 | GNUNET_DISK_PIPE_END_WRITE); | ||
1422 | |||
1423 | /* Close the read end of the write pipe */ | ||
1424 | GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ); | ||
1425 | |||
1426 | plugin->server_stdout_handle = | ||
1427 | GNUNET_DISK_pipe_handle (plugin->server_stdout, | ||
1428 | GNUNET_DISK_PIPE_END_READ); | ||
1429 | plugin->server_stdin_handle = | ||
1430 | GNUNET_DISK_pipe_handle (plugin->server_stdin, | ||
1431 | GNUNET_DISK_PIPE_END_WRITE); | ||
1432 | |||
1433 | GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); | ||
1434 | |||
1435 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
1436 | "Adding server_read_task for the gnunet-helper-transport-wlan\n"); | ||
1437 | plugin->server_read_task = | ||
1438 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1439 | plugin->server_stdout_handle, | ||
1440 | &wlan_plugin_helper_read, plugin); | ||
1441 | |||
1442 | plugin->helper_is_running = GNUNET_YES; | ||
1443 | return GNUNET_YES; | ||
1444 | } | 633 | } |
1445 | 634 | ||
635 | |||
1446 | /** | 636 | /** |
1447 | * Stops the gnunet-helper-transport-wlan process. | 637 | * A session is timing out. Clean up. |
1448 | * | 638 | * |
1449 | * @param plugin the transport plugin | 639 | * @param cls pointer to the Session |
1450 | * @return GNUNET_YES if process was started, GNUNET_SYSERR on error | 640 | * @param tc pointer to the GNUNET_SCHEDULER_TaskContext |
1451 | */ | 641 | */ |
1452 | static int | 642 | static void |
1453 | wlan_transport_stop_wlan_helper (struct Plugin *plugin) | 643 | session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1454 | { | 644 | { |
1455 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 645 | struct Session * session = cls; |
1456 | "Stoping WLAN helper process\n"); | 646 | struct GNUNET_TIME_Relative timeout; |
1457 | 647 | ||
1458 | if (plugin->helper_is_running == GNUNET_NO) | 648 | session->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1459 | { | 649 | timeout = GNUNET_TIME_absolute_get_remaining (session->timeout); |
1460 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 650 | if (0 == timeout.rel_value) |
1461 | "wlan_transport_stop_wlan_helper not needed, helper already stopped!"); | ||
1462 | return GNUNET_YES; | ||
1463 | } | ||
1464 | if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK) | ||
1465 | { | 651 | { |
1466 | GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task); | 652 | free_session (session); |
1467 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | 653 | return; |
1468 | } | ||
1469 | if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK) | ||
1470 | { | ||
1471 | GNUNET_SCHEDULER_cancel (plugin->server_write_task); | ||
1472 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | ||
1473 | } | ||
1474 | if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK) | ||
1475 | { | ||
1476 | GNUNET_SCHEDULER_cancel (plugin->server_read_task); | ||
1477 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; | ||
1478 | } | 654 | } |
1479 | GNUNET_DISK_pipe_close (plugin->server_stdout); | 655 | session->timeout_task = |
1480 | GNUNET_DISK_pipe_close (plugin->server_stdin); | 656 | GNUNET_SCHEDULER_add_delayed (timeout, &session_timeout, session); |
1481 | GNUNET_OS_process_kill (plugin->server_proc, SIGKILL); | ||
1482 | GNUNET_OS_process_wait (plugin->server_proc); | ||
1483 | GNUNET_OS_process_destroy (plugin->server_proc); | ||
1484 | plugin->helper_is_running = GNUNET_NO; | ||
1485 | return GNUNET_YES; | ||
1486 | } | 657 | } |
1487 | 658 | ||
659 | |||
1488 | /** | 660 | /** |
1489 | * function for delayed restart of the helper process | 661 | * Create a new session |
1490 | * @param cls Finish_send struct if message should be finished | 662 | * |
1491 | * @param tc TaskContext | 663 | * @param endpoint pointer to the mac endpoint of the peer |
664 | * @param peer peer identity to use for this session | ||
665 | * @return returns the session | ||
1492 | */ | 666 | */ |
1493 | static void | 667 | static struct Session * |
1494 | delay_restart_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 668 | create_session (struct MacEndpoint *endpoint, |
669 | const struct GNUNET_PeerIdentity *peer) | ||
1495 | { | 670 | { |
1496 | struct Finish_send *finish = cls; | 671 | struct Session *session; |
1497 | struct Plugin *plugin; | ||
1498 | |||
1499 | plugin = finish->plugin; | ||
1500 | |||
1501 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | ||
1502 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | ||
1503 | { | ||
1504 | GNUNET_free_non_null (finish->msgstart); | ||
1505 | GNUNET_free (finish); | ||
1506 | return; | ||
1507 | } | ||
1508 | |||
1509 | wlan_transport_start_wlan_helper (plugin); | ||
1510 | |||
1511 | if (finish->size != 0) | ||
1512 | { | ||
1513 | plugin->server_write_task = | ||
1514 | GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1515 | plugin->server_stdin_handle, | ||
1516 | &finish_sending, finish); | ||
1517 | } | ||
1518 | else | ||
1519 | { | ||
1520 | set_next_send (plugin); | ||
1521 | GNUNET_free_non_null (finish->msgstart); | ||
1522 | GNUNET_free (finish); | ||
1523 | } | ||
1524 | 672 | ||
673 | for (session = endpoint->sessions_head; NULL != session; session = session->next) | ||
674 | if (0 == memcmp (peer, &session->target, | ||
675 | sizeof (struct GNUNET_PeerIdentity))) | ||
676 | { | ||
677 | session->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | ||
678 | return session; | ||
679 | } | ||
680 | GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN sessions allocated"), 1, | ||
681 | GNUNET_NO); | ||
682 | session = GNUNET_malloc (sizeof (struct Session)); | ||
683 | GNUNET_CONTAINER_DLL_insert_tail (endpoint->sessions_head, | ||
684 | endpoint->sessions_tail, | ||
685 | session); | ||
686 | session->mac = endpoint; | ||
687 | session->target = *peer; | ||
688 | session->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | ||
689 | session->timeout_task = | ||
690 | GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, &session_timeout, session); | ||
691 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
692 | "Created new session for peer `%s' with endpoint %s\n", | ||
693 | GNUNET_i2s (peer), | ||
694 | mac_to_string (&endpoint->addr)); | ||
695 | return session; | ||
1525 | } | 696 | } |
1526 | 697 | ||
698 | |||
1527 | /** | 699 | /** |
1528 | * Function to restart the helper | 700 | * Function called once we have successfully given the fragment |
1529 | * @param plugin pointer to the global plugin struct | 701 | * message to the SUID helper process and we are thus ready for |
1530 | * @param finish pointer to the Finish_send struct to finish | 702 | * the next fragment. |
703 | * | ||
704 | * @param cls the 'struct FragmentMessage' | ||
705 | * @param result result of the operation (GNUNET_OK on success, GNUNET_NO if the helper died, GNUNET_SYSERR | ||
706 | * if the helper was stopped) | ||
1531 | */ | 707 | */ |
1532 | static void | 708 | static void |
1533 | restart_helper (struct Plugin *plugin, struct Finish_send *finish) | 709 | fragment_transmission_done (void *cls, |
710 | int result) | ||
1534 | { | 711 | { |
1535 | static struct GNUNET_TIME_Relative next_try = { 1000 }; | 712 | struct FragmentMessage *fm = cls; |
1536 | GNUNET_assert (finish != NULL); | ||
1537 | |||
1538 | wlan_transport_stop_wlan_helper (plugin); | ||
1539 | plugin->server_write_task = | ||
1540 | GNUNET_SCHEDULER_add_delayed (next_try, &delay_restart_helper, finish); | ||
1541 | GNUNET_TIME_relative_multiply (next_try, HELPER_RESTART_SCALING_FACTOR); | ||
1542 | 713 | ||
714 | fm->sh = NULL; | ||
715 | GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext); | ||
1543 | } | 716 | } |
1544 | 717 | ||
718 | |||
1545 | /** | 719 | /** |
1546 | * function to finish a sending if not all could have been writen befor | 720 | * Transmit a fragment of a message. |
1547 | * @param cls pointer to the Finish_send struct | 721 | * |
1548 | * @param tc TaskContext | 722 | * @param cls 'struct FragmentMessage' this fragment message belongs to |
723 | * @param hdr pointer to the start of the fragment message | ||
1549 | */ | 724 | */ |
1550 | static void | 725 | static void |
1551 | finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 726 | transmit_fragment (void *cls, |
727 | const struct GNUNET_MessageHeader *hdr) | ||
1552 | { | 728 | { |
1553 | struct Finish_send *finish = cls; | 729 | struct FragmentMessage *fm = cls; |
1554 | struct Plugin *plugin; | 730 | struct MacEndpoint *endpoint = fm->macendpoint; |
1555 | ssize_t bytes; | 731 | size_t size; |
1556 | 732 | uint16_t msize; | |
1557 | plugin = finish->plugin; | 733 | |
1558 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | 734 | msize = ntohs (hdr->size); |
1559 | 735 | size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + msize; | |
1560 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 736 | { |
1561 | { | 737 | char buf[size]; |
1562 | GNUNET_free (finish->msgstart); | 738 | struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radio_header; |
1563 | GNUNET_free (finish); | 739 | |
1564 | return; | 740 | radio_header = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) buf; |
1565 | } | 741 | get_radiotap_header (endpoint, radio_header, size); |
1566 | bytes = | 742 | get_wlan_header (endpoint->plugin, |
1567 | GNUNET_DISK_file_write (plugin->server_stdin_handle, | 743 | &radio_header->frame, |
1568 | finish->head_of_next_write, finish->size); | 744 | &endpoint->addr, |
1569 | 745 | size); | |
1570 | if (bytes != finish->size) | 746 | memcpy (&radio_header[1], hdr, msize); |
1571 | { | 747 | GNUNET_assert (NULL == fm->sh); |
1572 | if (bytes != GNUNET_SYSERR) | 748 | fm->sh = GNUNET_HELPER_send (endpoint->plugin->suid_helper, |
1573 | { | 749 | &radio_header->header, |
1574 | finish->head_of_next_write += bytes; | 750 | GNUNET_NO, |
1575 | finish->size -= bytes; | 751 | &fragment_transmission_done, fm); |
1576 | plugin->server_write_task = | 752 | if (NULL != fm->sh) |
1577 | GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | 753 | GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN message fragments sent"), |
1578 | plugin->server_stdin_handle, | 754 | 1, GNUNET_NO); |
1579 | &finish_sending, finish); | ||
1580 | } | ||
1581 | else | 755 | else |
1582 | { | 756 | GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext); |
1583 | restart_helper (plugin, finish); | ||
1584 | } | ||
1585 | } | ||
1586 | else | ||
1587 | { | ||
1588 | GNUNET_free (finish->msgstart); | ||
1589 | GNUNET_free (finish); | ||
1590 | set_next_send (plugin); | ||
1591 | } | 757 | } |
1592 | } | 758 | } |
1593 | 759 | ||
1594 | 760 | ||
1595 | /** | 761 | /** |
1596 | * Function to send a HELLO beacon | 762 | * Frees the space of a message in the fragment queue (send queue) |
1597 | * | 763 | * |
1598 | * @param plugin pointer to the plugin struct | 764 | * @param fm message to free |
1599 | */ | 765 | */ |
1600 | static void | 766 | static void |
1601 | send_hello_beacon (struct Plugin *plugin) | 767 | free_fragment_message (struct FragmentMessage *fm) |
1602 | { | 768 | { |
1603 | uint16_t size; | 769 | struct MacEndpoint *endpoint = fm->macendpoint; |
1604 | ssize_t bytes; | ||
1605 | uint16_t hello_size; | ||
1606 | struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radioHeader; | ||
1607 | const struct GNUNET_MessageHeader *hello; | ||
1608 | struct Finish_send *finish; | ||
1609 | |||
1610 | GNUNET_assert (plugin != NULL); | ||
1611 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
1612 | "Sending hello beacon\n"); | ||
1613 | GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hello beacons send"), | ||
1614 | 1, GNUNET_NO); | ||
1615 | hello = plugin->env->get_our_hello (); | ||
1616 | hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello); | ||
1617 | GNUNET_assert (sizeof (struct WlanHeader) + hello_size <= WLAN_MTU); | ||
1618 | 770 | ||
1619 | size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + hello_size; | 771 | GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN messages pending (with fragmentation)"), |
1620 | radioHeader = GNUNET_malloc (size); | 772 | -1, GNUNET_NO); |
1621 | getRadiotapHeader (plugin, NULL, radioHeader, size); | 773 | GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head, |
1622 | getWlanHeader (&radioHeader->frame, &bc_all_mac, plugin, size); | 774 | endpoint->sending_messages_tail, fm); |
1623 | memcpy (&radioHeader[1], hello, hello_size); | 775 | if (NULL != fm->sh) |
1624 | bytes = GNUNET_DISK_file_write (plugin->server_stdin_handle, radioHeader, size); | ||
1625 | GNUNET_free (radioHeader); | ||
1626 | if (bytes == GNUNET_SYSERR) | ||
1627 | { | 776 | { |
1628 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | 777 | GNUNET_HELPER_send_cancel (fm->sh); |
1629 | _("Error writing to WLAN helper: %s\n"), | 778 | fm->sh = NULL; |
1630 | STRERROR (errno)); | ||
1631 | finish = GNUNET_malloc (sizeof (struct Finish_send)); | ||
1632 | finish->plugin = plugin; | ||
1633 | finish->head_of_next_write = NULL; | ||
1634 | finish->size = 0; | ||
1635 | finish->msgstart = NULL; | ||
1636 | restart_helper (plugin, finish); | ||
1637 | set_next_beacon_time (plugin); | ||
1638 | } | 779 | } |
1639 | else | 780 | GNUNET_FRAGMENT_context_destroy (fm->fragcontext); |
781 | if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
1640 | { | 782 | { |
1641 | GNUNET_assert (bytes == size); | 783 | GNUNET_SCHEDULER_cancel (fm->timeout_task); |
1642 | set_next_beacon_time (plugin); | 784 | fm->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1643 | set_next_send (plugin); | ||
1644 | } | 785 | } |
786 | GNUNET_free (fm); | ||
1645 | } | 787 | } |
1646 | 788 | ||
1647 | 789 | ||
1648 | /** | 790 | /** |
1649 | * function to add an ack to send it for a received fragment | 791 | * A FragmentMessage has timed out. Remove it. |
1650 | * | 792 | * |
1651 | * @param cls MacEndpoint this ack belongs to | 793 | * @param cls pointer to the 'struct FragmentMessage' |
1652 | * @param msg_id id of the message | ||
1653 | * @param hdr pointer to the hdr where the ack is stored | ||
1654 | */ | ||
1655 | static void | ||
1656 | add_ack_for_send (void *cls, uint32_t msg_id, | ||
1657 | const struct GNUNET_MessageHeader *hdr) | ||
1658 | { | ||
1659 | struct MacEndpoint *endpoint = cls; | ||
1660 | struct Plugin *plugin = endpoint->plugin; | ||
1661 | struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage* radioHeader; | ||
1662 | struct AckSendQueue *ack; | ||
1663 | struct GNUNET_MessageHeader *msgheader; | ||
1664 | uint16_t size; | ||
1665 | |||
1666 | GNUNET_assert (endpoint != NULL); | ||
1667 | size = sizeof (struct AckSendQueue) + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + ntohs (hdr->size); | ||
1668 | ack = GNUNET_malloc (size); | ||
1669 | ack->message_id = msg_id; | ||
1670 | ack->endpoint = endpoint; | ||
1671 | radioHeader = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage*) &ack[1]; | ||
1672 | ack->radioHeader = radioHeader; | ||
1673 | getRadiotapHeader (plugin, ack->endpoint, radioHeader, size - sizeof (struct AckSendQueue)); | ||
1674 | size = ntohs (hdr->size); | ||
1675 | getWlanHeader (&radioHeader->frame, | ||
1676 | &ack->endpoint->addr, | ||
1677 | plugin, | ||
1678 | size); | ||
1679 | msgheader = (struct GNUNET_MessageHeader *) &radioHeader[1]; | ||
1680 | memcpy (msgheader, hdr, size); | ||
1681 | GNUNET_CONTAINER_DLL_insert_tail (plugin->ack_send_queue_head, | ||
1682 | plugin->ack_send_queue_tail, ack); | ||
1683 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
1684 | "Adding ack with message id %u to send, AckSendQueue %p, endpoint %p\n", | ||
1685 | msg_id, ack, endpoint); | ||
1686 | set_next_send (plugin); | ||
1687 | } | ||
1688 | |||
1689 | |||
1690 | /** | ||
1691 | * Function for the scheduler if a FragmentMessage times out | ||
1692 | * @param cls pointer to the FragmentMessage | ||
1693 | * @param tc pointer to the GNUNET_SCHEDULER_TaskContext | 794 | * @param tc pointer to the GNUNET_SCHEDULER_TaskContext |
1694 | */ | 795 | */ |
1695 | static void | 796 | static void |
@@ -1698,257 +799,153 @@ fragmentmessage_timeout (void *cls, | |||
1698 | { | 799 | { |
1699 | struct FragmentMessage *fm = cls; | 800 | struct FragmentMessage *fm = cls; |
1700 | 801 | ||
1701 | GNUNET_assert (fm != NULL); | ||
1702 | fm->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 802 | fm->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1703 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 803 | if (NULL != fm->cont) |
1704 | return; | 804 | { |
1705 | free_fragment_message (fm->session->mac->plugin, fm); | 805 | fm->cont (fm->cont_cls, &fm->target, GNUNET_SYSERR); |
806 | fm->cont = NULL; | ||
807 | } | ||
808 | free_fragment_message (fm); | ||
1706 | } | 809 | } |
1707 | 810 | ||
1708 | 811 | ||
1709 | /** | 812 | /** |
1710 | * Function to check if there is some space in the fragment queue | 813 | * Transmit a message to the given destination with fragmentation. |
1711 | * inserts a message if space is available | 814 | * |
1712 | * @param plugin the plugin struct | 815 | * @param endpoint desired destination |
816 | * @param timeout how long can the message wait? | ||
817 | * @param target peer that should receive the message | ||
818 | * @param msg message to transmit | ||
819 | * @param cont continuation to call once the message has | ||
820 | * been transmitted (or if the transport is ready | ||
821 | * for the next transmission call; or if the | ||
822 | * peer disconnected...); can be NULL | ||
823 | * @param cont_cls closure for cont | ||
1713 | */ | 824 | */ |
1714 | static void | 825 | static void |
1715 | check_fragment_queue (struct Plugin *plugin) | 826 | send_with_fragmentation (struct MacEndpoint *endpoint, |
827 | struct GNUNET_TIME_Relative timeout, | ||
828 | const struct GNUNET_PeerIdentity *target, | ||
829 | const struct GNUNET_MessageHeader *msg, | ||
830 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) | ||
831 | |||
1716 | { | 832 | { |
1717 | struct Session *session; | ||
1718 | struct FragmentMessage *fm; | 833 | struct FragmentMessage *fm; |
1719 | struct GNUNET_PeerIdentity pid; | 834 | struct Plugin *plugin; |
1720 | |||
1721 | struct PendingMessage *pm; | ||
1722 | |||
1723 | if (plugin->pending_Fragment_Messages < FRAGMENT_QUEUE_SIZE) | ||
1724 | { | ||
1725 | session = get_next_queue_session (plugin); | ||
1726 | if (session != NULL) | ||
1727 | { | ||
1728 | pm = session->pending_message_head; | ||
1729 | GNUNET_assert (pm != NULL); | ||
1730 | GNUNET_CONTAINER_DLL_remove (session->pending_message_head, | ||
1731 | session->pending_message_tail, pm); | ||
1732 | session->mac->fragment_messages_out_count++; | ||
1733 | session->fragment_messages_out_count++; | ||
1734 | plugin->pending_Fragment_Messages++; | ||
1735 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"), | ||
1736 | plugin->pending_Fragment_Messages, GNUNET_NO); | ||
1737 | |||
1738 | fm = GNUNET_malloc (sizeof (struct FragmentMessage)); | ||
1739 | fm->session = session; | ||
1740 | fm->timeout.abs_value = pm->timeout.abs_value; | ||
1741 | fm->fragcontext = | ||
1742 | GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU, | ||
1743 | &plugin->tracker, | ||
1744 | GNUNET_TIME_UNIT_SECONDS, | ||
1745 | &(pm->msg->header), | ||
1746 | &add_message_for_send, fm); | ||
1747 | fm->timeout_task = | ||
1748 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining | ||
1749 | (fm->timeout), fragmentmessage_timeout, | ||
1750 | fm); | ||
1751 | GNUNET_CONTAINER_DLL_insert_tail (session->mac->sending_messages_head, | ||
1752 | session->mac->sending_messages_tail, | ||
1753 | fm); | ||
1754 | |||
1755 | if (pm->transmit_cont != NULL) | ||
1756 | { | ||
1757 | pid = session->target; | ||
1758 | pm->transmit_cont (pm->transmit_cont_cls, &pid, GNUNET_OK); | ||
1759 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
1760 | "called pm->transmit_cont for %p\n", session); | ||
1761 | } | ||
1762 | else | ||
1763 | { | ||
1764 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
1765 | "no pm->transmit_cont for %p\n", session); | ||
1766 | } | ||
1767 | GNUNET_free (pm); | ||
1768 | |||
1769 | if (session->pending_message_head != NULL) | ||
1770 | { | ||
1771 | //requeue session | ||
1772 | queue_session (plugin, session); | ||
1773 | } | ||
1774 | |||
1775 | } | ||
1776 | } | ||
1777 | 835 | ||
1778 | //check if timeout changed | 836 | plugin = endpoint->plugin; |
1779 | set_next_send (plugin); | 837 | fm = GNUNET_malloc (sizeof (struct FragmentMessage)); |
838 | fm->macendpoint = endpoint; | ||
839 | fm->target = *target; | ||
840 | fm->timeout = GNUNET_TIME_relative_to_absolute (timeout); | ||
841 | fm->fragcontext = | ||
842 | GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU, | ||
843 | &plugin->tracker, | ||
844 | GNUNET_TIME_UNIT_SECONDS, | ||
845 | msg, | ||
846 | &transmit_fragment, fm); | ||
847 | fm->timeout_task = | ||
848 | GNUNET_SCHEDULER_add_delayed (timeout, | ||
849 | &fragmentmessage_timeout, fm); | ||
850 | GNUNET_CONTAINER_DLL_insert_tail (endpoint->sending_messages_head, | ||
851 | endpoint->sending_messages_tail, | ||
852 | fm); | ||
1780 | } | 853 | } |
1781 | 854 | ||
1782 | 855 | ||
1783 | /** | 856 | /** |
1784 | * Function to send an ack, does not free the ack | 857 | * Free a MAC endpoint. |
1785 | * @param plugin pointer to the plugin | 858 | * |
859 | * @param endpoint pointer to the MacEndpoint to free | ||
1786 | */ | 860 | */ |
1787 | static void | 861 | static void |
1788 | send_ack (struct Plugin *plugin) | 862 | free_macendpoint (struct MacEndpoint *endpoint) |
1789 | { | 863 | { |
1790 | ssize_t bytes; | 864 | struct Plugin *plugin = endpoint->plugin; |
1791 | struct AckSendQueue *ack; | 865 | struct FragmentMessage *fm; |
1792 | struct Finish_send *finish; | 866 | struct Session *session; |
1793 | 867 | ||
1794 | GNUNET_assert (plugin != NULL); | 868 | GNUNET_STATISTICS_update (plugin->env->stats, |
1795 | ack = plugin->ack_send_queue_head; | 869 | _("# WLAN MAC endpoints allocated"), -1, GNUNET_NO); |
1796 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 870 | while (NULL != (session = endpoint->sessions_head)) |
1797 | "Sending ack for message_id %u for mac endpoint %p, size %u\n", | 871 | free_session (session); |
1798 | ack->message_id, ack->endpoint, | 872 | while (NULL != (fm = endpoint->sending_messages_head)) |
1799 | ntohs (ack->radioHeader->header.size)); | 873 | free_fragment_message (fm); |
1800 | GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks send"), 1, | 874 | GNUNET_CONTAINER_DLL_remove (plugin->mac_head, |
1801 | GNUNET_NO); | 875 | plugin->mac_tail, |
1802 | bytes = | 876 | endpoint); |
1803 | GNUNET_DISK_file_write (plugin->server_stdin_handle, ack->radioHeader, | 877 | plugin->mac_count--; |
1804 | ntohs (ack->radioHeader->header.size)); | 878 | if (GNUNET_SCHEDULER_NO_TASK != endpoint->timeout_task) |
1805 | if (bytes == GNUNET_SYSERR) | ||
1806 | { | 879 | { |
1807 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | 880 | GNUNET_SCHEDULER_cancel (endpoint->timeout_task); |
1808 | _ | 881 | endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1809 | ("Error writing to wlan helper. errno == %d, ERROR: %s\n"), | ||
1810 | errno, strerror (errno)); | ||
1811 | finish = GNUNET_malloc (sizeof (struct Finish_send)); | ||
1812 | finish->plugin = plugin; | ||
1813 | finish->head_of_next_write = NULL; | ||
1814 | finish->size = 0; | ||
1815 | finish->msgstart = NULL; | ||
1816 | restart_helper (plugin, finish); | ||
1817 | return; | ||
1818 | } | 882 | } |
1819 | GNUNET_assert (bytes == ntohs (ack->radioHeader->header.size)); | 883 | GNUNET_free (endpoint); |
1820 | GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head, | ||
1821 | plugin->ack_send_queue_tail, ack); | ||
1822 | GNUNET_free (ack); | ||
1823 | set_next_send (plugin); | ||
1824 | } | 884 | } |
1825 | 885 | ||
1826 | 886 | ||
1827 | /** | 887 | /** |
1828 | * Function called when wlan helper is ready to get some data | 888 | * A MAC endpoint is timing out. Clean up. |
1829 | * | 889 | * |
1830 | * @param cls closure | 890 | * @param cls pointer to the MacEndpoint |
1831 | * @param tc GNUNET_SCHEDULER_TaskContext | 891 | * @param tc pointer to the GNUNET_SCHEDULER_TaskContext |
1832 | */ | 892 | */ |
1833 | static void | 893 | static void |
1834 | do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 894 | macendpoint_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1835 | { | 895 | { |
1836 | struct Plugin *plugin = cls; | 896 | struct MacEndpoint *endpoint = cls; |
1837 | struct Session *session; | 897 | struct GNUNET_TIME_Relative timeout; |
1838 | struct FragmentMessage *fm; | ||
1839 | struct Finish_send *finish; | ||
1840 | struct FragmentMessage_queue *fmq; | ||
1841 | ssize_t bytes; | ||
1842 | 898 | ||
1843 | GNUNET_assert (plugin != NULL); | 899 | endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1844 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | 900 | timeout = GNUNET_TIME_absolute_get_remaining (endpoint->timeout); |
1845 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 901 | if (0 == timeout.rel_value) |
1846 | return; | ||
1847 | if (plugin->ack_send_queue_head != NULL) | ||
1848 | { | ||
1849 | send_ack (plugin); | ||
1850 | return; | ||
1851 | } | ||
1852 | //test if a "hello-beacon" has to be send | ||
1853 | if (GNUNET_TIME_absolute_get_remaining (plugin->beacon_time).rel_value == 0) | ||
1854 | { | ||
1855 | send_hello_beacon (plugin); | ||
1856 | return; | ||
1857 | } | ||
1858 | if (NULL == plugin->sending_messages_head) | ||
1859 | { | 902 | { |
1860 | /* nothing to do right now, check when to go again */ | 903 | free_macendpoint (endpoint); |
1861 | set_next_send (plugin); | ||
1862 | return; | 904 | return; |
1863 | } | 905 | } |
1864 | GNUNET_STATISTICS_update (plugin->env->stats, _("# WLAN fragments sent"), 1, | 906 | endpoint->timeout_task = |
1865 | GNUNET_NO); | 907 | GNUNET_SCHEDULER_add_delayed (timeout, &macendpoint_timeout, |
1866 | 908 | endpoint); | |
1867 | fmq = plugin->sending_messages_head; | ||
1868 | fm = fmq->content; | ||
1869 | GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head, | ||
1870 | plugin->sending_messages_tail, fmq); | ||
1871 | GNUNET_free (fmq); | ||
1872 | |||
1873 | session = fm->session; | ||
1874 | GNUNET_assert (session != NULL); | ||
1875 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
1876 | "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT for fragment message %p, size: %u\n", | ||
1877 | fm, ntohs (fm->radioHeader->header.size)); | ||
1878 | bytes = | ||
1879 | GNUNET_DISK_file_write (plugin->server_stdin_handle, | ||
1880 | fm->radioHeader, | ||
1881 | ntohs (fm->radioHeader->header.size)); | ||
1882 | if (bytes != ntohs (fm->radioHeader->header.size)) | ||
1883 | { | ||
1884 | finish = GNUNET_malloc (sizeof (struct Finish_send)); | ||
1885 | finish->plugin = plugin; | ||
1886 | finish->msgstart = &fm->radioHeader->header; | ||
1887 | GNUNET_assert (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); | ||
1888 | if (bytes == GNUNET_SYSERR) | ||
1889 | { | ||
1890 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | ||
1891 | _("Error writing to WLAN helper: %s\n"), | ||
1892 | STRERROR (errno)); | ||
1893 | finish->head_of_next_write = (char*) fm->radioHeader; | ||
1894 | finish->size = ntohs (fm->radioHeader->header.size); | ||
1895 | restart_helper (plugin, finish); | ||
1896 | } | ||
1897 | else | ||
1898 | { | ||
1899 | finish->head_of_next_write = ((char*) fm->radioHeader) + bytes; | ||
1900 | finish->size = ntohs (fm->radioHeader->header.size) - bytes; | ||
1901 | plugin->server_write_task = | ||
1902 | GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1903 | plugin->server_stdin_handle, | ||
1904 | &finish_sending, finish); | ||
1905 | } | ||
1906 | } | ||
1907 | else | ||
1908 | { | ||
1909 | GNUNET_free (fm->radioHeader); | ||
1910 | fm->radioHeader = NULL; | ||
1911 | set_next_send (plugin); | ||
1912 | } | ||
1913 | GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext); | ||
1914 | } | 909 | } |
1915 | 910 | ||
1916 | 911 | ||
1917 | /** | 912 | /** |
1918 | * Another peer has suggested an address for this | 913 | * Find (or create) a MacEndpoint with a specific MAC address |
1919 | * peer and transport plugin. Check that this could be a valid | ||
1920 | * address. If so, consider adding it to the list | ||
1921 | * of addresses. | ||
1922 | * | 914 | * |
1923 | * @param cls closure | 915 | * @param plugin pointer to the plugin struct |
1924 | * @param addr pointer to the address | 916 | * @param addr the MAC address of the endpoint |
1925 | * @param addrlen length of addr | 917 | * @return handle to our data structure for this MAC |
1926 | * @return GNUNET_OK if this is a plausible address for this peer | ||
1927 | * and transport | ||
1928 | */ | 918 | */ |
1929 | static int | 919 | static struct MacEndpoint * |
1930 | wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) | 920 | create_macendpoint (struct Plugin *plugin, |
921 | const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr) | ||
1931 | { | 922 | { |
1932 | //struct Plugin *plugin = cls; | 923 | struct MacEndpoint *pos; |
1933 | 924 | ||
1934 | /* check if the address is plausible; if so, | 925 | for (pos = plugin->mac_head; NULL != pos; pos = pos->next) |
1935 | * add it to our list! */ | 926 | if (0 == memcmp (addr, &pos->addr, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) |
1936 | 927 | return pos; | |
1937 | GNUNET_assert (cls != NULL); | 928 | pos = GNUNET_malloc (sizeof (struct MacEndpoint)); |
1938 | //FIXME mitm is not checked | 929 | pos->addr = *addr; |
1939 | //Mac Address has 6 bytes | 930 | pos->plugin = plugin; |
1940 | if (addrlen == 6) | 931 | pos->defrag = |
1941 | { | 932 | GNUNET_DEFRAGMENT_context_create (plugin->env->stats, WLAN_MTU, |
1942 | /* TODO check for bad addresses like multicast, broadcast, etc */ | 933 | MESSAGES_IN_DEFRAG_QUEUE_PER_MAC, |
1943 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 934 | pos, |
1944 | "wlan_plugin_address_suggested got good address, size %u!\n", | 935 | &wlan_data_message_handler, |
1945 | addrlen); | 936 | &send_ack); |
1946 | return GNUNET_OK; | 937 | pos->timeout = GNUNET_TIME_relative_to_absolute (MACENDPOINT_TIMEOUT); |
1947 | } | 938 | pos->timeout_task = |
1948 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 939 | GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout, |
1949 | "wlan_plugin_address_suggested got bad address, size %u!\n", | 940 | pos); |
1950 | addrlen); | 941 | GNUNET_CONTAINER_DLL_insert (plugin->mac_head, plugin->mac_tail, pos); |
1951 | return GNUNET_SYSERR; | 942 | plugin->mac_count++; |
943 | GNUNET_STATISTICS_update (plugin->env->stats, _("# WLAN MAC endpoints allocated"), | ||
944 | 1, GNUNET_NO); | ||
945 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
946 | "New MAC endpoint `%s'\n", | ||
947 | mac_to_string (addr)); | ||
948 | return pos; | ||
1952 | } | 949 | } |
1953 | 950 | ||
1954 | 951 | ||
@@ -1960,33 +957,55 @@ wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) | |||
1960 | * @param address the address | 957 | * @param address the address |
1961 | * @return the session or NULL of max connections exceeded | 958 | * @return the session or NULL of max connections exceeded |
1962 | */ | 959 | */ |
1963 | |||
1964 | static struct Session * | 960 | static struct Session * |
1965 | wlan_plugin_get_session (void *cls, | 961 | wlan_plugin_get_session (void *cls, |
1966 | const struct GNUNET_HELLO_Address *address) | 962 | const struct GNUNET_HELLO_Address *address) |
1967 | { | 963 | { |
1968 | struct Plugin *plugin = cls; | 964 | struct Plugin *plugin = cls; |
1969 | struct Session * s = NULL; | 965 | struct MacEndpoint *endpoint; |
1970 | |||
1971 | GNUNET_assert (plugin != NULL); | ||
1972 | GNUNET_assert (address != NULL); | ||
1973 | 966 | ||
1974 | if (GNUNET_OK == wlan_plugin_address_suggested (plugin, | 967 | if (NULL == address) |
1975 | address->address, | 968 | return NULL; |
1976 | address->address_length)) | 969 | if (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress) != address->address_length) |
1977 | { | ||
1978 | s = get_session (plugin, address->address, &address->peer); | ||
1979 | } | ||
1980 | else | ||
1981 | { | 970 | { |
1982 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, | 971 | GNUNET_break (0); |
1983 | _("Wlan Address len %d is wrong\n"), address->address_length); | 972 | return NULL; |
1984 | return s; | ||
1985 | } | 973 | } |
974 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
975 | "Service asked to create session for peer `%s' with MAC `%s'\n", | ||
976 | GNUNET_i2s (&address->peer), | ||
977 | mac_to_string (address->address)); | ||
978 | endpoint = create_macendpoint (plugin, address->address); | ||
979 | return create_session (endpoint, &address->peer); | ||
980 | } | ||
981 | |||
982 | |||
983 | /** | ||
984 | * Function that can be used to force the plugin to disconnect | ||
985 | * from the given peer and cancel all previous transmissions | ||
986 | * (and their continuation). | ||
987 | * | ||
988 | * @param cls closure | ||
989 | * @param target peer from which to disconnect | ||
990 | */ | ||
991 | static void | ||
992 | wlan_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | ||
993 | { | ||
994 | struct Plugin *plugin = cls; | ||
995 | struct Session *session; | ||
996 | struct MacEndpoint *endpoint; | ||
1986 | 997 | ||
1987 | return s; | 998 | for (endpoint = plugin->mac_head; NULL != endpoint; endpoint = endpoint->next) |
999 | for (session = endpoint->sessions_head; NULL != session; session = session->next) | ||
1000 | if (0 == memcmp (target, &session->target, | ||
1001 | sizeof (struct GNUNET_PeerIdentity))) | ||
1002 | { | ||
1003 | free_session (session); | ||
1004 | break; /* inner-loop only (in case peer has another MAC as well!) */ | ||
1005 | } | ||
1988 | } | 1006 | } |
1989 | 1007 | ||
1008 | |||
1990 | /** | 1009 | /** |
1991 | * Function that can be used by the transport service to transmit | 1010 | * Function that can be used by the transport service to transmit |
1992 | * a message using the plugin. Note that in the case of a | 1011 | * a message using the plugin. Note that in the case of a |
@@ -2023,801 +1042,489 @@ wlan_plugin_send (void *cls, | |||
2023 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) | 1042 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) |
2024 | { | 1043 | { |
2025 | struct Plugin *plugin = cls; | 1044 | struct Plugin *plugin = cls; |
2026 | struct PendingMessage *newmsg; | ||
2027 | struct WlanHeader *wlanheader; | 1045 | struct WlanHeader *wlanheader; |
2028 | 1046 | size_t size = msgbuf_size + sizeof (struct WlanHeader); | |
2029 | GNUNET_assert (plugin != NULL); | 1047 | char buf[size] GNUNET_ALIGN; |
2030 | GNUNET_assert (session != NULL); | 1048 | |
2031 | GNUNET_assert (msgbuf_size > 0); | 1049 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2032 | 1050 | "Transmitting %u bytes of payload to peer `%s' (starting with %u byte message of type %u)\n", | |
2033 | //queue message: | 1051 | msgbuf_size, |
2034 | 1052 | GNUNET_i2s (&session->target), | |
2035 | //queue message in session | 1053 | (unsigned int) ntohs (((struct GNUNET_MessageHeader*)msgbuf)->size), |
2036 | //test if there is no other message in the "queue" | 1054 | (unsigned int) ntohs (((struct GNUNET_MessageHeader*)msgbuf)->type)); |
2037 | //FIXME: to many send requests | 1055 | wlanheader = (struct WlanHeader *) buf; |
2038 | if (session->pending_message_head != NULL) | ||
2039 | { | ||
2040 | newmsg = session->pending_message_head; | ||
2041 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2042 | "wlan_plugin_send: a pending message is already in the queue for this client\n remaining time to send this message is %u, queued fragment messages for this mac connection %u\n", | ||
2043 | GNUNET_TIME_absolute_get_remaining (newmsg-> | ||
2044 | timeout).rel_value, | ||
2045 | session->mac->fragment_messages_out_count); | ||
2046 | } | ||
2047 | |||
2048 | newmsg = GNUNET_malloc (sizeof (struct PendingMessage)); | ||
2049 | newmsg->msg = GNUNET_malloc (msgbuf_size + sizeof (struct WlanHeader)); | ||
2050 | wlanheader = newmsg->msg; | ||
2051 | //copy msg to buffer, not fragmented / segmented yet, but with message header | ||
2052 | wlanheader->header.size = htons (msgbuf_size + sizeof (struct WlanHeader)); | 1056 | wlanheader->header.size = htons (msgbuf_size + sizeof (struct WlanHeader)); |
2053 | wlanheader->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA); | 1057 | wlanheader->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA); |
2054 | memcpy (&(wlanheader->target), &session->target, sizeof (struct GNUNET_PeerIdentity)); | 1058 | wlanheader->sender = *plugin->env->my_identity; |
2055 | memcpy (&(wlanheader->source), plugin->env->my_identity, | 1059 | wlanheader->target = session->target; |
2056 | sizeof (struct GNUNET_PeerIdentity)); | 1060 | wlanheader->crc = htonl (GNUNET_CRYPTO_crc32_n (msgbuf, msgbuf_size)); |
2057 | wlanheader->crc = 0; | ||
2058 | memcpy (&wlanheader[1], msgbuf, msgbuf_size); | 1061 | memcpy (&wlanheader[1], msgbuf, msgbuf_size); |
2059 | wlanheader->crc = | 1062 | send_with_fragmentation (session->mac, |
2060 | htonl (GNUNET_CRYPTO_crc32_n | 1063 | to, |
2061 | ((char *) wlanheader, msgbuf_size + sizeof (struct WlanHeader))); | 1064 | &session->target, |
2062 | 1065 | &wlanheader->header, | |
2063 | newmsg->transmit_cont = cont; | 1066 | cont, cont_cls); |
2064 | newmsg->transmit_cont_cls = cont_cls; | 1067 | return size; |
2065 | newmsg->timeout = GNUNET_TIME_relative_to_absolute (to); | ||
2066 | |||
2067 | newmsg->timeout.abs_value = newmsg->timeout.abs_value - 500; | ||
2068 | |||
2069 | newmsg->message_size = msgbuf_size + sizeof (struct WlanHeader); | ||
2070 | |||
2071 | GNUNET_CONTAINER_DLL_insert_tail (session->pending_message_head, | ||
2072 | session->pending_message_tail, newmsg); | ||
2073 | |||
2074 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2075 | "New message for %p with size (incl wlan header) %u added\n", | ||
2076 | session, newmsg->message_size); | ||
2077 | //queue session | ||
2078 | queue_session (plugin, session); | ||
2079 | |||
2080 | check_fragment_queue (plugin); | ||
2081 | //FIXME not the correct size | ||
2082 | return msgbuf_size; | ||
2083 | } | 1068 | } |
2084 | 1069 | ||
2085 | 1070 | ||
2086 | /** | 1071 | /** |
2087 | * function to free a mac endpoint | 1072 | * We have received data from the WLAN via some session. Process depending |
2088 | * @param plugin pointer to the plugin struct | 1073 | * on the message type (HELLO, DATA, FRAGMENTATION or FRAGMENTATION-ACK). |
2089 | * @param endpoint pointer to the MacEndpoint to free | ||
2090 | */ | ||
2091 | static void | ||
2092 | free_macendpoint (struct Plugin *plugin, struct MacEndpoint *endpoint) | ||
2093 | { | ||
2094 | struct Sessionqueue *sessions; | ||
2095 | struct Sessionqueue *sessions_next; | ||
2096 | |||
2097 | GNUNET_assert (endpoint != NULL); | ||
2098 | |||
2099 | sessions = endpoint->sessions_head; | ||
2100 | while (sessions != NULL) | ||
2101 | { | ||
2102 | sessions_next = sessions->next; | ||
2103 | free_session (plugin, sessions, GNUNET_NO); | ||
2104 | sessions = sessions_next; | ||
2105 | } | ||
2106 | |||
2107 | GNUNET_CONTAINER_DLL_remove (plugin->mac_head, plugin->mac_tail, endpoint); | ||
2108 | if (endpoint->timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
2109 | { | ||
2110 | GNUNET_SCHEDULER_cancel (endpoint->timeout_task); | ||
2111 | endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
2112 | } | ||
2113 | plugin->mac_count--; | ||
2114 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"), | ||
2115 | plugin->mac_count, GNUNET_NO); | ||
2116 | GNUNET_free (endpoint); | ||
2117 | |||
2118 | } | ||
2119 | |||
2120 | /** | ||
2121 | * function to free a session | ||
2122 | * @param plugin pointer to the plugin | ||
2123 | * @param queue pointer to the sessionqueue element to free | ||
2124 | * @param do_free_macendpoint if GNUNET_YES and mac endpoint would be empty, free mac endpoint | ||
2125 | */ | ||
2126 | static void | ||
2127 | free_session (struct Plugin *plugin, struct Sessionqueue *queue, | ||
2128 | int do_free_macendpoint) | ||
2129 | { | ||
2130 | struct Sessionqueue *pendingsession; | ||
2131 | struct Sessionqueue *pendingsession_tmp; | ||
2132 | struct PendingMessage *pm; | ||
2133 | struct MacEndpoint *endpoint; | ||
2134 | struct FragmentMessage *fm; | ||
2135 | struct FragmentMessage *fmnext; | ||
2136 | int check = 0; | ||
2137 | |||
2138 | GNUNET_assert (plugin != NULL); | ||
2139 | GNUNET_assert (queue != NULL); | ||
2140 | GNUNET_assert (queue->content != NULL); | ||
2141 | |||
2142 | //session found | ||
2143 | //is this session pending for send | ||
2144 | pendingsession = plugin->pending_Sessions_head; | ||
2145 | while (pendingsession != NULL) | ||
2146 | { | ||
2147 | pendingsession_tmp = pendingsession; | ||
2148 | pendingsession = pendingsession->next; | ||
2149 | GNUNET_assert (pendingsession_tmp->content != NULL); | ||
2150 | if (pendingsession_tmp->content == queue->content) | ||
2151 | { | ||
2152 | plugin->pendingsessions--; | ||
2153 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), | ||
2154 | plugin->pendingsessions, GNUNET_NO); | ||
2155 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, | ||
2156 | plugin->pending_Sessions_tail, | ||
2157 | pendingsession_tmp); | ||
2158 | GNUNET_free (pendingsession_tmp); | ||
2159 | |||
2160 | GNUNET_assert (check == 0); | ||
2161 | check = 1; | ||
2162 | } | ||
2163 | } | ||
2164 | |||
2165 | endpoint = queue->content->mac; | ||
2166 | fm = endpoint->sending_messages_head; | ||
2167 | while (fm != NULL) | ||
2168 | { | ||
2169 | fmnext = fm->next; | ||
2170 | if (fm->session == queue->content) | ||
2171 | free_fragment_message (plugin, fm); | ||
2172 | fm = fmnext; | ||
2173 | } | ||
2174 | |||
2175 | // remove PendingMessage | ||
2176 | pm = queue->content->pending_message_head; | ||
2177 | while (pm != NULL) | ||
2178 | { | ||
2179 | GNUNET_CONTAINER_DLL_remove (queue->content->pending_message_head, | ||
2180 | queue->content->pending_message_tail, pm); | ||
2181 | GNUNET_free (pm->msg); | ||
2182 | GNUNET_free (pm); | ||
2183 | pm = queue->content->pending_message_head; | ||
2184 | } | ||
2185 | |||
2186 | GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head, endpoint->sessions_tail, | ||
2187 | queue); | ||
2188 | //Check that no ohter session on this endpoint for this session exits | ||
2189 | GNUNET_assert (search_session (plugin, endpoint, &queue->content->target) == | ||
2190 | NULL); | ||
2191 | if (endpoint->sessions_head == NULL && do_free_macendpoint == GNUNET_YES) | ||
2192 | { | ||
2193 | free_macendpoint (plugin, endpoint); | ||
2194 | //check if no endpoint with the same address exists | ||
2195 | GNUNET_assert (get_macendpoint (plugin, &endpoint->addr, GNUNET_NO) == | ||
2196 | NULL); | ||
2197 | } | ||
2198 | |||
2199 | if (queue->content->timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
2200 | { | ||
2201 | GNUNET_SCHEDULER_cancel (queue->content->timeout_task); | ||
2202 | queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
2203 | } | ||
2204 | GNUNET_free (queue); | ||
2205 | |||
2206 | check_fragment_queue (plugin); | ||
2207 | } | ||
2208 | |||
2209 | /** | ||
2210 | * Function that can be used to force the plugin to disconnect | ||
2211 | * from the given peer and cancel all previous transmissions | ||
2212 | * (and their continuation). | ||
2213 | * | 1074 | * |
2214 | * @param cls closure | 1075 | * @param cls pointer to the plugin |
2215 | * @param target peer from which to disconnect | 1076 | * @param client pointer to the session this message belongs to |
1077 | * @param hdr start of the message | ||
2216 | */ | 1078 | */ |
2217 | static void | 1079 | static void |
2218 | wlan_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | 1080 | process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) |
2219 | { | 1081 | { |
2220 | struct Plugin *plugin = cls; | 1082 | struct Plugin *plugin = cls; |
2221 | struct Sessionqueue *queue; | 1083 | struct MacAndSession *mas = client; |
2222 | struct Sessionqueue *queue_next; | 1084 | struct MacAndSession xmas; |
2223 | struct MacEndpoint *endpoint = plugin->mac_head; | 1085 | #define NUM_ATS 2 |
2224 | struct MacEndpoint *endpoint_next; | 1086 | struct GNUNET_ATS_Information ats[NUM_ATS]; /* FIXME: do better here */ |
1087 | struct FragmentMessage *fm; | ||
1088 | struct GNUNET_PeerIdentity tmpsource; | ||
1089 | const struct WlanHeader *wlanheader; | ||
1090 | int ret; | ||
1091 | uint16_t msize; | ||
2225 | 1092 | ||
2226 | // just look at all the session for the needed one | 1093 | ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); |
2227 | while (endpoint != NULL) | 1094 | ats[0].value = htonl (1); |
1095 | ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); | ||
1096 | ats[1].value = htonl (GNUNET_ATS_NET_WLAN); | ||
1097 | msize = ntohs (hdr->size); | ||
1098 | switch (ntohs (hdr->type)) | ||
2228 | { | 1099 | { |
2229 | queue = endpoint->sessions_head; | 1100 | case GNUNET_MESSAGE_TYPE_HELLO: |
2230 | endpoint_next = endpoint->next; | 1101 | if (GNUNET_OK != |
2231 | while (queue != NULL) | 1102 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) hdr, &tmpsource)) |
2232 | { | 1103 | { |
2233 | // content is never NULL | 1104 | GNUNET_break_op (0); |
2234 | GNUNET_assert (queue->content != NULL); | 1105 | break; |
2235 | queue_next = queue->next; | ||
2236 | if (memcmp | ||
2237 | (target, &(queue->content->target), | ||
2238 | sizeof (struct GNUNET_PeerIdentity)) == 0) | ||
2239 | { | ||
2240 | free_session (plugin, queue, GNUNET_YES); | ||
2241 | } | ||
2242 | // try next | ||
2243 | queue = queue_next; | ||
2244 | } | 1106 | } |
2245 | endpoint = endpoint_next; | 1107 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2246 | } | 1108 | "Processing %u bytes of HELLO from peer `%s' at MAC %s\n", |
2247 | } | 1109 | (unsigned int) msize, |
2248 | 1110 | GNUNET_i2s (&tmpsource), | |
2249 | /** | 1111 | mac_to_string (&mas->endpoint->addr)); |
2250 | * Convert the transports address to a nice, human-readable | ||
2251 | * format. | ||
2252 | * | ||
2253 | * @param cls closure | ||
2254 | * @param type name of the transport that generated the address | ||
2255 | * @param addr one of the addresses of the host, NULL for the last address | ||
2256 | * the specific address format depends on the transport | ||
2257 | * @param addrlen length of the address | ||
2258 | * @param numeric should (IP) addresses be displayed in numeric form? | ||
2259 | * @param timeout after how long should we give up? | ||
2260 | * @param asc function to call on each string | ||
2261 | * @param asc_cls closure for asc | ||
2262 | */ | ||
2263 | static void | ||
2264 | wlan_plugin_address_pretty_printer (void *cls, const char *type, | ||
2265 | const void *addr, size_t addrlen, | ||
2266 | int numeric, | ||
2267 | struct GNUNET_TIME_Relative timeout, | ||
2268 | GNUNET_TRANSPORT_AddressStringCallback asc, | ||
2269 | void *asc_cls) | ||
2270 | { | ||
2271 | char *ret; | ||
2272 | const unsigned char *input; | ||
2273 | |||
2274 | //GNUNET_assert(cls !=NULL); | ||
2275 | if (addrlen != sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) | ||
2276 | { | ||
2277 | /* invalid address (MAC addresses have 6 bytes) */ | ||
2278 | //GNUNET_break (0); | ||
2279 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2280 | "Func wlan_plugin_address_pretty_printer got size: %u, worng size!\n", | ||
2281 | addrlen); | ||
2282 | asc (asc_cls, NULL); | ||
2283 | return; | ||
2284 | } | ||
2285 | input = (const unsigned char *) addr; | ||
2286 | GNUNET_asprintf (&ret, | ||
2287 | "Transport %s: %s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", | ||
2288 | type, PROTOCOL_PREFIX, input[0], input[1], input[2], | ||
2289 | input[3], input[4], input[5]); | ||
2290 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2291 | "Func wlan_plugin_address_pretty_printer got size: %u, nummeric %u, type %s; made string: %s\n", | ||
2292 | addrlen, numeric, type, ret); | ||
2293 | asc (asc_cls, ret); | ||
2294 | //only one mac address per plugin | ||
2295 | asc (asc_cls, NULL); | ||
2296 | } | ||
2297 | |||
2298 | |||
2299 | |||
2300 | /** | ||
2301 | * handels the data after all fragments are put together | ||
2302 | * @param cls macendpoint this messages belongs to | ||
2303 | * @param hdr pointer to the data | ||
2304 | */ | ||
2305 | static void | ||
2306 | wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr) | ||
2307 | { | ||
2308 | struct MacEndpoint *endpoint = (struct MacEndpoint *) cls; | ||
2309 | struct Plugin *plugin = endpoint->plugin; | ||
2310 | struct WlanHeader *wlanheader; | ||
2311 | struct Session *session; | ||
2312 | |||
2313 | const struct GNUNET_MessageHeader *temp_hdr; | ||
2314 | struct GNUNET_PeerIdentity tmpsource; | ||
2315 | int crc; | ||
2316 | |||
2317 | GNUNET_assert (plugin != NULL); | ||
2318 | |||
2319 | if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA) | ||
2320 | { | ||
2321 | |||
2322 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2323 | "Func wlan_data_message_handler got GNUNET_MESSAGE_TYPE_WLAN_DATA size: %u\n", | ||
2324 | ntohs (hdr->size)); | ||
2325 | 1112 | ||
2326 | if (ntohs (hdr->size) < | 1113 | GNUNET_STATISTICS_update (plugin->env->stats, |
2327 | sizeof (struct WlanHeader) + sizeof (struct GNUNET_MessageHeader)) | 1114 | _("# HELLO messages received via WLAN"), 1, |
1115 | GNUNET_NO); | ||
1116 | plugin->env->receive (plugin->env->cls, | ||
1117 | &tmpsource, | ||
1118 | hdr, | ||
1119 | ats, NUM_ATS, | ||
1120 | mas->session, | ||
1121 | (mas->endpoint == NULL) ? NULL : (const char *) &mas->endpoint->addr, | ||
1122 | (mas->endpoint == NULL) ? 0 : sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); | ||
1123 | break; | ||
1124 | case GNUNET_MESSAGE_TYPE_FRAGMENT: | ||
1125 | if (NULL == mas->endpoint) | ||
2328 | { | 1126 | { |
2329 | //packet not big enought | 1127 | GNUNET_break (0); |
2330 | return; | 1128 | break; |
2331 | } | 1129 | } |
2332 | 1130 | LOG (GNUNET_ERROR_TYPE_DEBUG, | |
1131 | "Processing %u bytes of FRAGMENT from MAC %s\n", | ||
1132 | (unsigned int) msize, | ||
1133 | mac_to_string (&mas->endpoint->addr)); | ||
2333 | GNUNET_STATISTICS_update (plugin->env->stats, | 1134 | GNUNET_STATISTICS_update (plugin->env->stats, |
2334 | _("# wlan whole messages received"), 1, | 1135 | _("# fragments received via WLAN"), 1, GNUNET_NO); |
2335 | GNUNET_NO); | 1136 | (void) GNUNET_DEFRAGMENT_process_fragment (mas->endpoint->defrag, |
2336 | wlanheader = (struct WlanHeader *) hdr; | 1137 | hdr); |
2337 | 1138 | break; | |
2338 | session = search_session (plugin, endpoint, &wlanheader->source); | 1139 | case GNUNET_MESSAGE_TYPE_FRAGMENT_ACK: |
2339 | 1140 | if (NULL == mas->endpoint) | |
2340 | temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1]; | ||
2341 | crc = ntohl (wlanheader->crc); | ||
2342 | wlanheader->crc = 0; | ||
2343 | if (GNUNET_CRYPTO_crc32_n | ||
2344 | ((char *) wlanheader, ntohs (wlanheader->header.size)) != crc) | ||
2345 | { | 1141 | { |
2346 | //wrong crc, dispose message | 1142 | GNUNET_break (0); |
2347 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME, | 1143 | break; |
2348 | "Wlan message header crc was wrong: %u != %u\n", | ||
2349 | GNUNET_CRYPTO_crc32_n ((char *) wlanheader, | ||
2350 | ntohs (wlanheader->header.size)), | ||
2351 | crc); | ||
2352 | return; | ||
2353 | } | 1144 | } |
2354 | 1145 | GNUNET_STATISTICS_update (plugin->env->stats, _("# ACKs received via WLAN"), | |
2355 | //if not in session list | 1146 | 1, GNUNET_NO); |
2356 | if (session == NULL) | 1147 | for (fm = mas->endpoint->sending_messages_head; NULL != fm; fm = fm->next) |
2357 | { | 1148 | { |
2358 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 1149 | ret = GNUNET_FRAGMENT_process_ack (fm->fragcontext, hdr); |
2359 | "WLAN client not in session list: packet size = %u, inner size = %u, header size = %u\n", | 1150 | if (GNUNET_OK == ret) |
2360 | ntohs (wlanheader->header.size), ntohs (temp_hdr->size), | ||
2361 | sizeof (struct WlanHeader)); | ||
2362 | //try if it is a hello message | ||
2363 | if (ntohs (wlanheader->header.size) >= | ||
2364 | ntohs (temp_hdr->size) + sizeof (struct WlanHeader)) | ||
2365 | { | 1151 | { |
2366 | if (ntohs (temp_hdr->type) == GNUNET_MESSAGE_TYPE_HELLO) | 1152 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2367 | { | 1153 | "Got last ACK, finished message transmission to `%s' (%p)\n", |
2368 | if (GNUNET_HELLO_get_id | 1154 | mac_to_string (&mas->endpoint->addr), |
2369 | ((const struct GNUNET_HELLO_Message *) temp_hdr, | 1155 | fm); |
2370 | &tmpsource) == GNUNET_OK) | 1156 | mas->endpoint->timeout = GNUNET_TIME_relative_to_absolute (MACENDPOINT_TIMEOUT); |
2371 | { | 1157 | if (NULL != fm->cont) |
2372 | session = create_session (plugin, endpoint, &tmpsource); | 1158 | { |
2373 | } | 1159 | fm->cont (fm->cont_cls, &fm->target, GNUNET_OK); |
2374 | else | 1160 | fm->cont = NULL; |
2375 | { | 1161 | } |
2376 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, | 1162 | free_fragment_message (fm); |
2377 | "WLAN client not in session list and hello message is not okay\n"); | 1163 | break; |
2378 | return; | ||
2379 | } | ||
2380 | |||
2381 | } | ||
2382 | else | ||
2383 | { | ||
2384 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, | ||
2385 | "WLAN client not in session list and not a hello message\n"); | ||
2386 | return; | ||
2387 | } | ||
2388 | } | 1164 | } |
2389 | else | 1165 | if (GNUNET_NO == ret) |
2390 | { | 1166 | { |
2391 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, | 1167 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2392 | "WLAN client not in session list and message size in does not fit\npacket size = %u, inner size = %u, header size = %u\n", | 1168 | "Got an ACK, message transmission to `%s' not yet finished\n", |
2393 | ntohs (wlanheader->header.size), | 1169 | mac_to_string (&mas->endpoint->addr)); |
2394 | ntohs (temp_hdr->size), sizeof (struct WlanHeader)); | 1170 | break; |
2395 | return; | ||
2396 | } | 1171 | } |
2397 | } | 1172 | } |
2398 | 1173 | LOG (GNUNET_ERROR_TYPE_DEBUG, | |
2399 | //"receive" the message | 1174 | "ACK not matched against any active fragmentation with MAC `%s'\n", |
2400 | 1175 | mac_to_string (&mas->endpoint->addr)); | |
2401 | if (memcmp | 1176 | break; |
2402 | (&wlanheader->source, &session->target, | 1177 | case GNUNET_MESSAGE_TYPE_WLAN_DATA: |
2403 | sizeof (struct GNUNET_PeerIdentity)) != 0) | 1178 | if (NULL == mas->endpoint) |
2404 | { | 1179 | { |
2405 | //wrong peer id | 1180 | GNUNET_break (0); |
2406 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 1181 | break; |
2407 | "WLAN peer source id doesn't match packet peer source id: session %p\n", | ||
2408 | session); | ||
2409 | return; | ||
2410 | } | 1182 | } |
2411 | 1183 | if (msize < sizeof (struct WlanHeader)) | |
2412 | if (memcmp | 1184 | { |
2413 | (&wlanheader->target, plugin->env->my_identity, | 1185 | GNUNET_break (0); |
2414 | sizeof (struct GNUNET_PeerIdentity)) != 0) | 1186 | break; |
1187 | } | ||
1188 | wlanheader = (const struct WlanHeader *) hdr; | ||
1189 | if (0 != memcmp (&wlanheader->target, | ||
1190 | plugin->env->my_identity, | ||
1191 | sizeof (struct GNUNET_PeerIdentity))) | ||
2415 | { | 1192 | { |
2416 | //wrong peer id | 1193 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2417 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 1194 | "WLAN data for `%s', not for me, ignoring\n", |
2418 | "WLAN peer target id doesn't match our peer id: session %p\n", | 1195 | GNUNET_i2s (&wlanheader->target)); |
2419 | session); | 1196 | break; |
2420 | return; | ||
2421 | } | 1197 | } |
2422 | 1198 | if (ntohl (wlanheader->crc) != | |
2423 | GNUNET_SERVER_mst_receive (plugin->data_tokenizer, session, | 1199 | GNUNET_CRYPTO_crc32_n (&wlanheader[1], msize - sizeof (struct WlanHeader))) |
2424 | (const char *) temp_hdr, | 1200 | { |
2425 | ntohs (hdr->size) - sizeof (struct WlanHeader), | 1201 | GNUNET_STATISTICS_update (plugin->env->stats, |
2426 | GNUNET_YES, GNUNET_NO); | 1202 | _("# WLAN DATA messages discarded due to CRC32 error"), 1, |
2427 | 1203 | GNUNET_NO); | |
2428 | return; | 1204 | break; |
2429 | } | 1205 | } |
2430 | else | 1206 | xmas.endpoint = mas->endpoint; |
2431 | { | 1207 | xmas.session = create_session (mas->endpoint, &wlanheader->sender); |
2432 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, | 1208 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2433 | "wlan_data_message_handler got wrong message type: %u\n", | 1209 | "Processing %u bytes of WLAN DATA from peer `%s'\n", |
2434 | ntohs (hdr->size)); | 1210 | (unsigned int) msize, |
2435 | return; | 1211 | GNUNET_i2s (&wlanheader->sender)); |
1212 | (void) GNUNET_SERVER_mst_receive (plugin->wlan_header_payload_tokenizer, | ||
1213 | &xmas, | ||
1214 | (const char *) &wlanheader[1], | ||
1215 | msize - sizeof (struct WlanHeader), | ||
1216 | GNUNET_YES, GNUNET_NO); | ||
1217 | break; | ||
1218 | default: | ||
1219 | if (NULL == mas->endpoint) | ||
1220 | { | ||
1221 | GNUNET_break (0); | ||
1222 | break; | ||
1223 | } | ||
1224 | if (NULL == mas->session) | ||
1225 | { | ||
1226 | GNUNET_break (0); | ||
1227 | break; | ||
1228 | } | ||
1229 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1230 | "Received packet with %u bytes of type %u from peer %s\n", | ||
1231 | (unsigned int) msize, | ||
1232 | (unsigned int) ntohs (hdr->type), | ||
1233 | GNUNET_i2s (&mas->session->target)); | ||
1234 | plugin->env->receive (plugin->env->cls, | ||
1235 | &mas->session->target, | ||
1236 | hdr, | ||
1237 | ats, NUM_ATS, | ||
1238 | mas->session, | ||
1239 | (mas->endpoint == NULL) ? NULL : (const char *) &mas->endpoint->addr, | ||
1240 | (mas->endpoint == NULL) ? 0 : sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); | ||
1241 | break; | ||
2436 | } | 1242 | } |
2437 | } | 1243 | } |
1244 | #undef NUM_ATS | ||
2438 | 1245 | ||
2439 | /** | ||
2440 | * function to process the a message, give it to the higher layer | ||
2441 | * @param cls pointer to the plugin | ||
2442 | * @param client pointer to the session this message belongs to | ||
2443 | * @param hdr start of the message | ||
2444 | */ | ||
2445 | //TODO ATS informations | ||
2446 | static void | ||
2447 | process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) | ||
2448 | { | ||
2449 | |||
2450 | GNUNET_assert (client != NULL); | ||
2451 | GNUNET_assert (cls != NULL); | ||
2452 | struct Session *session = (struct Session *) client; | ||
2453 | struct Plugin *plugin = (struct Plugin *) cls; | ||
2454 | struct GNUNET_ATS_Information ats[2]; | ||
2455 | |||
2456 | ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); | ||
2457 | ats[0].value = htonl (1); | ||
2458 | ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); | ||
2459 | ats[1].value = htonl (GNUNET_ATS_NET_WLAN); | ||
2460 | |||
2461 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2462 | "Calling plugin->env->receive for session %p; %s; size: %u\n", | ||
2463 | session, wlan_plugin_address_to_string (NULL, | ||
2464 | session->mac-> | ||
2465 | addr.mac, 6), | ||
2466 | htons (hdr->size)); | ||
2467 | plugin->env->receive (plugin->env->cls, &(session->target), hdr, | ||
2468 | (const struct GNUNET_ATS_Information *) &ats, 2, | ||
2469 | session, (const char *) &session->mac->addr, | ||
2470 | sizeof (session->mac->addr)); | ||
2471 | } | ||
2472 | 1246 | ||
2473 | /** | 1247 | /** |
2474 | * Function used for to process the data received from the wlan interface | 1248 | * Function used for to process the data from the suid process |
2475 | * | 1249 | * |
2476 | * @param cls the plugin handle | 1250 | * @param cls the plugin handle |
2477 | * @param hdr hdr of the GNUNET_MessageHeader | 1251 | * @param client client that send the data (not used) |
2478 | * @param rxinfo pointer to the radiotap informations got with this packet FIXME: give ATS info | 1252 | * @param hdr header of the GNUNET_MessageHeader |
2479 | */ | 1253 | */ |
2480 | static void | 1254 | static void |
2481 | wlan_data_helper (void *cls, | 1255 | handle_helper_message (void *cls, void *client, |
2482 | const struct GNUNET_MessageHeader *hdr, | 1256 | const struct GNUNET_MessageHeader *hdr) |
2483 | const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rxinfo) | ||
2484 | { | 1257 | { |
2485 | struct Plugin *plugin = cls; | 1258 | struct Plugin *plugin = cls; |
2486 | struct FragmentMessage *fm; | 1259 | const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rxinfo; |
2487 | struct FragmentMessage *fm2; | 1260 | const struct GNUNET_TRANSPORT_WLAN_HelperControlMessage *cm; |
2488 | struct GNUNET_PeerIdentity tmpsource; | 1261 | struct MacAndSession mas; |
2489 | struct MacEndpoint *macendpoint; | 1262 | uint16_t msize; |
2490 | struct Session *session; | ||
2491 | |||
2492 | // NOTE: session_light->addr = rxinfo->frame.addr2; | ||
2493 | macendpoint = get_macendpoint (plugin, &rxinfo->frame.addr2, GNUNET_YES); | ||
2494 | 1263 | ||
1264 | msize = ntohs (hdr->size); | ||
2495 | switch (ntohs (hdr->type)) | 1265 | switch (ntohs (hdr->type)) |
2496 | { | 1266 | { |
2497 | case GNUNET_MESSAGE_TYPE_HELLO: | 1267 | case GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL: |
2498 | //ADVERTISEMENT | 1268 | if (msize != sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage)) |
2499 | //TODO better DOS protection, error handling | ||
2500 | //TODO test first then create session | ||
2501 | if (GNUNET_HELLO_get_id | ||
2502 | ((const struct GNUNET_HELLO_Message *) hdr, &tmpsource) == GNUNET_OK) | ||
2503 | { | 1269 | { |
2504 | session = search_session (plugin, macendpoint, &tmpsource); | 1270 | GNUNET_break (0); |
2505 | if (session == NULL) | 1271 | break; |
2506 | { | ||
2507 | session = create_session (plugin, macendpoint, &tmpsource); | ||
2508 | } | ||
2509 | GNUNET_STATISTICS_update (plugin->env->stats, | ||
2510 | _("# wlan hello messages received"), 1, | ||
2511 | GNUNET_NO); | ||
2512 | plugin->env->receive (plugin->env->cls, &session->target, | ||
2513 | hdr, NULL, 0, session, | ||
2514 | (const char *) &session->mac->addr, | ||
2515 | sizeof (session->mac->addr)); | ||
2516 | } | 1272 | } |
2517 | else | 1273 | cm = (const struct GNUNET_TRANSPORT_WLAN_HelperControlMessage *) hdr; |
1274 | if (GNUNET_YES == plugin->have_mac) | ||
2518 | { | 1275 | { |
2519 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, | 1276 | if (0 == memcmp (&plugin->mac_address, |
2520 | "WLAN client not in session list and HELLO message is not okay\n"); | 1277 | &cm->mac, |
2521 | return; | 1278 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) |
1279 | break; /* no change */ | ||
1280 | /* remove old address */ | ||
1281 | plugin->env->notify_address (plugin->env->cls, GNUNET_NO, | ||
1282 | &plugin->mac_address, | ||
1283 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); | ||
2522 | } | 1284 | } |
1285 | plugin->mac_address = cm->mac; | ||
1286 | plugin->have_mac = GNUNET_YES; | ||
1287 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1288 | "Received WLAN_HELPER_CONTROL message with MAC address `%s' for peer `%s'\n", | ||
1289 | mac_to_string (&cm->mac), | ||
1290 | GNUNET_i2s (plugin->env->my_identity)); | ||
1291 | plugin->env->notify_address (plugin->env->cls, GNUNET_YES, | ||
1292 | &plugin->mac_address, | ||
1293 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); | ||
2523 | break; | 1294 | break; |
2524 | case GNUNET_MESSAGE_TYPE_FRAGMENT: | 1295 | case GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER: |
2525 | macendpoint = get_macendpoint (plugin, &rxinfo->frame.addr2, GNUNET_YES); | 1296 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1297 | "Got data message from helper with %u bytes\n", | ||
1298 | msize); | ||
2526 | GNUNET_STATISTICS_update (plugin->env->stats, | 1299 | GNUNET_STATISTICS_update (plugin->env->stats, |
2527 | _("# wlan fragments received"), 1, GNUNET_NO); | 1300 | _("# DATA messages received via WLAN"), 1, |
2528 | int ret = | 1301 | GNUNET_NO); |
2529 | GNUNET_DEFRAGMENT_process_fragment (macendpoint->defrag, | 1302 | if (msize < sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)) |
2530 | hdr); | ||
2531 | |||
2532 | if (ret == GNUNET_NO) | ||
2533 | { | 1303 | { |
2534 | macendpoint->dups++; | 1304 | GNUNET_break (0); |
1305 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1306 | "Size of packet is too small (%u bytes)\n", | ||
1307 | msize); | ||
1308 | break; | ||
2535 | } | 1309 | } |
2536 | else if (ret == GNUNET_OK) | 1310 | rxinfo = (const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) hdr; |
1311 | |||
1312 | /* check if message is actually for us */ | ||
1313 | if (0 != memcmp (&rxinfo->frame.addr3, &mac_bssid_gnunet, | ||
1314 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) | ||
2537 | { | 1315 | { |
2538 | macendpoint->fragc++; | 1316 | /* Not the GNUnet BSSID */ |
1317 | break; | ||
2539 | } | 1318 | } |
2540 | set_next_send (plugin); | 1319 | if ( (0 != memcmp (&rxinfo->frame.addr1, &bc_all_mac, |
2541 | break; | 1320 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) && |
2542 | case GNUNET_MESSAGE_TYPE_FRAGMENT_ACK: | 1321 | (0 != memcmp (&rxinfo->frame.addr1, &plugin->mac_address, |
2543 | if (NULL == macendpoint) | 1322 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) ) |
2544 | { | 1323 | { |
2545 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 1324 | /* Neither broadcast nor specifically for us */ |
2546 | "Macendpoint does not exist for this GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; %s\n", | 1325 | break; |
2547 | ntohs (hdr->size), wlan_plugin_address_to_string (NULL, | ||
2548 | &rxinfo->frame.addr2.mac, | ||
2549 | 6)); | ||
2550 | return; | ||
2551 | } | 1326 | } |
2552 | fm = macendpoint->sending_messages_head; | 1327 | if (0 == memcmp (&rxinfo->frame.addr2, &plugin->mac_address, |
2553 | while (fm != NULL) | 1328 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) |
2554 | { | 1329 | { |
2555 | fm2 = fm->next; | 1330 | /* packet is FROM us, thus not FOR us */ |
2556 | GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks received"), | 1331 | break; |
2557 | 1, GNUNET_NO); | ||
2558 | int ret = GNUNET_FRAGMENT_process_ack (fm->fragcontext, hdr); | ||
2559 | |||
2560 | if (ret == GNUNET_OK) | ||
2561 | { | ||
2562 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2563 | "Got last ack, finished fragment message %p\n", fm); | ||
2564 | macendpoint->acks++; | ||
2565 | fm->session->last_activity = GNUNET_TIME_absolute_get (); | ||
2566 | macendpoint->last_activity = fm->session->last_activity; | ||
2567 | free_fragment_message (plugin, fm); | ||
2568 | check_fragment_queue (plugin); | ||
2569 | return; | ||
2570 | } | ||
2571 | if (ret == GNUNET_NO) | ||
2572 | { | ||
2573 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2574 | "Got ack for: %p\n", fm); | ||
2575 | macendpoint->acks++; | ||
2576 | return; | ||
2577 | } | ||
2578 | fm = fm2; | ||
2579 | } | 1332 | } |
2580 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 1333 | |
2581 | "WLAN fragment not in fragment list\n"); | 1334 | GNUNET_STATISTICS_update (plugin->env->stats, |
2582 | return; | 1335 | _("# WLAN DATA messages processed"), |
1336 | 1, GNUNET_NO); | ||
1337 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1338 | "Receiving %u bytes of data from MAC `%s'\n", | ||
1339 | (unsigned int) (msize - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)), | ||
1340 | mac_to_string (&rxinfo->frame.addr2)); | ||
1341 | mas.endpoint = create_macendpoint (plugin, &rxinfo->frame.addr2); | ||
1342 | mas.session = NULL; | ||
1343 | (void) GNUNET_SERVER_mst_receive (plugin->helper_payload_tokenizer, | ||
1344 | &mas, | ||
1345 | (const char*) &rxinfo[1], | ||
1346 | msize - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage), | ||
1347 | GNUNET_YES, GNUNET_NO); | ||
1348 | break; | ||
2583 | default: | 1349 | default: |
2584 | // TODO Wrong data? | ||
2585 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME, | ||
2586 | "WLAN packet inside the WLAN helper packet has not the right type: %u size: %u\n", | ||
2587 | ntohs (hdr->type), ntohs (hdr->size)); | ||
2588 | GNUNET_break (0); | 1350 | GNUNET_break (0); |
2589 | return; | 1351 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1352 | "Unexpected message of type %u (%u bytes)", | ||
1353 | ntohs (hdr->type), ntohs (hdr->size)); | ||
1354 | break; | ||
2590 | } | 1355 | } |
2591 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2592 | "Helper finished\n"); | ||
2593 | } | 1356 | } |
2594 | 1357 | ||
1358 | |||
1359 | |||
2595 | /** | 1360 | /** |
2596 | * Function to print mac addresses nicely. | 1361 | * Task to (periodically) send a HELLO beacon |
2597 | * | 1362 | * |
2598 | * @param mac the mac address | 1363 | * @param cls pointer to the plugin struct |
2599 | * @return string to a static buffer with the human-readable mac, will be overwritten during the next call to this function | 1364 | * @param tc scheduler context |
2600 | */ | 1365 | */ |
2601 | static const char * | 1366 | static void |
2602 | macprinter (const struct GNUNET_TRANSPORT_WLAN_MacAddress * mac) | 1367 | send_hello_beacon (void *cls, |
1368 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2603 | { | 1369 | { |
2604 | static char macstr[20]; | 1370 | struct Plugin *plugin = cls; |
1371 | uint16_t size; | ||
1372 | uint16_t hello_size; | ||
1373 | struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radioHeader; | ||
1374 | const struct GNUNET_MessageHeader *hello; | ||
1375 | |||
1376 | hello = plugin->env->get_our_hello (); | ||
1377 | hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello); | ||
1378 | GNUNET_assert (sizeof (struct WlanHeader) + hello_size <= WLAN_MTU); | ||
1379 | size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + hello_size; | ||
1380 | { | ||
1381 | char buf[size] GNUNET_ALIGN; | ||
1382 | |||
1383 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1384 | "Sending %u byte HELLO beacon\n", | ||
1385 | (unsigned int) size); | ||
1386 | radioHeader = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage*) buf; | ||
1387 | get_radiotap_header (NULL, radioHeader, size); | ||
1388 | get_wlan_header (plugin, &radioHeader->frame, &bc_all_mac, size); | ||
1389 | memcpy (&radioHeader[1], hello, hello_size); | ||
1390 | if (NULL != | ||
1391 | GNUNET_HELPER_send (plugin->suid_helper, | ||
1392 | &radioHeader->header, | ||
1393 | GNUNET_YES /* can drop */, | ||
1394 | NULL, NULL)) | ||
1395 | GNUNET_STATISTICS_update (plugin->env->stats, _("# HELLO beacons sent via WLAN"), | ||
1396 | 1, GNUNET_NO); | ||
1397 | } | ||
1398 | plugin->beacon_task = | ||
1399 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
1400 | (HELLO_BEACON_SCALING_FACTOR, | ||
1401 | plugin->mac_count + 1), | ||
1402 | &send_hello_beacon, | ||
1403 | plugin); | ||
2605 | 1404 | ||
2606 | GNUNET_snprintf (macstr, sizeof (macstr), "%2X:%2X:%2X:%2X:%2X:%2X", mac->mac[0], mac->mac[1], | ||
2607 | mac->mac[2], mac->mac[3], mac->mac[4], mac->mac[5]); | ||
2608 | return macstr; | ||
2609 | } | 1405 | } |
2610 | 1406 | ||
1407 | |||
2611 | /** | 1408 | /** |
2612 | * Function for the scheduler if a mac endpoint times out | 1409 | * Another peer has suggested an address for this |
2613 | * @param cls pointer to the MacEndpoint | 1410 | * peer and transport plugin. Check that this could be a valid |
2614 | * @param tc pointer to the GNUNET_SCHEDULER_TaskContext | 1411 | * address. If so, consider adding it to the list |
1412 | * of addresses. | ||
1413 | * | ||
1414 | * @param cls closure | ||
1415 | * @param addr pointer to the address | ||
1416 | * @param addrlen length of addr | ||
1417 | * @return GNUNET_OK if this is a plausible address for this peer | ||
1418 | * and transport | ||
2615 | */ | 1419 | */ |
2616 | static void | 1420 | static int |
2617 | macendpoint_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1421 | wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) |
2618 | { | 1422 | { |
2619 | struct MacEndpoint *endpoint = cls; | 1423 | struct Plugin *plugin = cls; |
2620 | 1424 | ||
2621 | GNUNET_assert (endpoint != NULL); | 1425 | if (addrlen != sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) |
2622 | endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 1426 | { |
2623 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | 1427 | GNUNET_break_op (0); |
2624 | { | 1428 | return GNUNET_SYSERR; |
2625 | return; | ||
2626 | } | 1429 | } |
2627 | if (GNUNET_TIME_absolute_get_remaining | 1430 | if (GNUNET_YES != plugin->have_mac) |
2628 | (GNUNET_TIME_absolute_add | ||
2629 | (endpoint->last_activity, MACENDPOINT_TIMEOUT)).rel_value == 0) | ||
2630 | { | 1431 | { |
2631 | GNUNET_assert (endpoint->plugin != NULL); | 1432 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2632 | GNUNET_STATISTICS_update (endpoint->plugin->env->stats, | 1433 | "Rejecting MAC `%s': I don't know my MAC!\n", |
2633 | _("# wlan mac endpoints timeouts"), 1, GNUNET_NO); | 1434 | mac_to_string (addr)); |
2634 | free_macendpoint (endpoint->plugin, endpoint); | 1435 | return GNUNET_NO; /* don't know my MAC */ |
2635 | } | 1436 | } |
2636 | else | 1437 | if (0 != memcmp (addr, |
1438 | &plugin->mac_address, | ||
1439 | addrlen)) | ||
2637 | { | 1440 | { |
2638 | endpoint->timeout_task = | 1441 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2639 | GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout, | 1442 | "Rejecting MAC `%s': not my MAC!\n", |
2640 | endpoint); | 1443 | mac_to_string (addr)); |
1444 | return GNUNET_NO; /* not my MAC */ | ||
2641 | } | 1445 | } |
1446 | return GNUNET_OK; | ||
2642 | } | 1447 | } |
2643 | 1448 | ||
1449 | |||
2644 | /** | 1450 | /** |
2645 | * function to create an macendpoint | 1451 | * Function called for a quick conversion of the binary address to |
2646 | * @param plugin pointer to the plugin struct | 1452 | * a numeric address. Note that the caller must not free the |
2647 | * @param addr pointer to the macaddress | 1453 | * address and that the next call to this function is allowed |
2648 | * @return returns a macendpoint | 1454 | * to override the address again. |
1455 | * | ||
1456 | * @param cls closure | ||
1457 | * @param addr binary address | ||
1458 | * @param addrlen length of the address | ||
1459 | * @return string representing the same address | ||
2649 | */ | 1460 | */ |
2650 | static struct MacEndpoint * | 1461 | static const char * |
2651 | create_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr) | 1462 | wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) |
2652 | { | 1463 | { |
2653 | struct MacEndpoint *newend = GNUNET_malloc (sizeof (struct MacEndpoint)); | 1464 | static char ret[40]; |
2654 | 1465 | const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac; | |
2655 | GNUNET_assert (plugin != NULL); | ||
2656 | GNUNET_STATISTICS_update (plugin->env->stats, | ||
2657 | _("# wlan mac endpoints created"), 1, GNUNET_NO); | ||
2658 | newend->addr = *addr; | ||
2659 | newend->plugin = plugin; | ||
2660 | newend->addr = *addr; | ||
2661 | newend->fragment_messages_out_count = 0; | ||
2662 | newend->defrag = | ||
2663 | GNUNET_DEFRAGMENT_context_create (plugin->env->stats, WLAN_MTU, | ||
2664 | MESSAGES_IN_DEFRAG_QUEUE_PER_MAC, | ||
2665 | newend, &wlan_data_message_handler, | ||
2666 | &add_ack_for_send); | ||
2667 | newend->last_activity = GNUNET_TIME_absolute_get (); | ||
2668 | newend->timeout_task = | ||
2669 | GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout, | ||
2670 | newend); | ||
2671 | 1466 | ||
2672 | plugin->mac_count++; | 1467 | if (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress) != addrlen) |
2673 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"), | 1468 | { |
2674 | plugin->mac_count, GNUNET_NO); | 1469 | GNUNET_break (0); |
2675 | GNUNET_CONTAINER_DLL_insert_tail (plugin->mac_head, plugin->mac_tail, newend); | 1470 | return NULL; |
2676 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 1471 | } |
2677 | "New Mac Endpoint %p: %s\n", newend, | 1472 | mac = addr; |
2678 | wlan_plugin_address_to_string (NULL, newend->addr.mac, 6)); | 1473 | GNUNET_snprintf (ret, sizeof (ret), "%s MAC address %s", |
2679 | return newend; | 1474 | PROTOCOL_PREFIX, |
1475 | mac_to_string (mac)); | ||
1476 | return ret; | ||
2680 | } | 1477 | } |
2681 | 1478 | ||
1479 | |||
2682 | /** | 1480 | /** |
2683 | * Function used for to process the data from the suid process | 1481 | * Convert the transports address to a nice, human-readable format. |
2684 | * | 1482 | * |
2685 | * @param cls the plugin handle | 1483 | * @param cls closure |
2686 | * @param client client that send the data (not used) | 1484 | * @param type name of the transport that generated the address |
2687 | * @param hdr header of the GNUNET_MessageHeader | 1485 | * @param addr one of the addresses of the host, NULL for the last address |
1486 | * the specific address format depends on the transport | ||
1487 | * @param addrlen length of the address | ||
1488 | * @param numeric should (IP) addresses be displayed in numeric form? | ||
1489 | * @param timeout after how long should we give up? | ||
1490 | * @param asc function to call on each string | ||
1491 | * @param asc_cls closure for asc | ||
2688 | */ | 1492 | */ |
2689 | static void | 1493 | static void |
2690 | wlan_process_helper (void *cls, void *client, | 1494 | wlan_plugin_address_pretty_printer (void *cls, const char *type, |
2691 | const struct GNUNET_MessageHeader *hdr) | 1495 | const void *addr, size_t addrlen, |
1496 | int numeric, | ||
1497 | struct GNUNET_TIME_Relative timeout, | ||
1498 | GNUNET_TRANSPORT_AddressStringCallback asc, | ||
1499 | void *asc_cls) | ||
2692 | { | 1500 | { |
2693 | struct Plugin *plugin = cls; | 1501 | const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac; |
2694 | const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rxinfo; | 1502 | char *ret; |
2695 | const struct GNUNET_TRANSPORT_WLAN_HelperControlMessage *cm; | ||
2696 | const struct GNUNET_MessageHeader *temp_hdr = NULL; | ||
2697 | const char *end; | ||
2698 | int datasize = 0; | ||
2699 | int pos; | ||
2700 | 1503 | ||
2701 | GNUNET_assert (plugin != NULL); | 1504 | if (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress) != addrlen) |
2702 | switch (ntohs (hdr->type)) | ||
2703 | { | 1505 | { |
2704 | case GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER: | 1506 | /* invalid address */ |
2705 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 1507 | LOG (GNUNET_ERROR_TYPE_WARNING, |
2706 | "Got data message from helper with %u bytes\n", | 1508 | _("WLAN address with invalid size encountered\n")); |
2707 | ntohs (hdr->size)); | 1509 | asc (asc_cls, NULL); |
2708 | GNUNET_STATISTICS_update (plugin->env->stats, | ||
2709 | _("# wlan data messages received"), 1, | ||
2710 | GNUNET_NO); | ||
2711 | //call wlan_process_helper with the message inside, later with wlan: analyze signal | ||
2712 | if (ntohs (hdr->size) < sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)) | ||
2713 | { | ||
2714 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2715 | "Size of packet is too small; size: %u\n", | ||
2716 | ntohs (hdr->size)); | ||
2717 | GNUNET_break (0); | ||
2718 | /* FIXME: restart SUID process */ | ||
2719 | return; | ||
2720 | } | ||
2721 | |||
2722 | rxinfo = (const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) hdr; | ||
2723 | //process only if it is an broadcast or for this computer both with the gnunet bssid | ||
2724 | //check for bssid | ||
2725 | if (memcmp | ||
2726 | (&rxinfo->frame.addr3, &mac_bssid_gnunet, | ||
2727 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) | ||
2728 | { | ||
2729 | //check for broadcast or mac | ||
2730 | if ((memcmp | ||
2731 | (&rxinfo->frame.addr1, &bc_all_mac, | ||
2732 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) || | ||
2733 | (memcmp | ||
2734 | (&rxinfo->frame.addr1, &plugin->mac_address, | ||
2735 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)) | ||
2736 | { | ||
2737 | //if packet is from us return | ||
2738 | if ((memcmp | ||
2739 | (&rxinfo->frame.addr2, &plugin->mac_address, | ||
2740 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)) | ||
2741 | { | ||
2742 | /* not for us */ | ||
2743 | return; | ||
2744 | } | ||
2745 | datasize = ntohs (hdr->size) - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage); | ||
2746 | GNUNET_STATISTICS_update (plugin->env->stats, | ||
2747 | _("# wlan messages for this client received"), | ||
2748 | 1, GNUNET_NO); | ||
2749 | // FIXME: this is a job for SERVER_mst -- | ||
2750 | // what we are doing here is not good for alignment... | ||
2751 | pos = 0; | ||
2752 | end = (const char*) &rxinfo[1]; | ||
2753 | while (pos < datasize - sizeof (struct GNUNET_MessageHeader)) | ||
2754 | { | ||
2755 | temp_hdr = (struct GNUNET_MessageHeader *) &end[pos]; | ||
2756 | if (ntohs (temp_hdr->size) <= datasize - pos) | ||
2757 | { | ||
2758 | GNUNET_STATISTICS_update (plugin->env->stats, | ||
2759 | _ | ||
2760 | ("# wlan messages inside WLAN_HELPER_DATA received"), | ||
2761 | 1, GNUNET_NO); | ||
2762 | wlan_data_helper (plugin, temp_hdr, rxinfo); | ||
2763 | } | ||
2764 | else | ||
2765 | { | ||
2766 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2767 | "Size of packet is too small; size: %u > size of packet: %u\n", | ||
2768 | ntohs (temp_hdr->size), datasize - pos); | ||
2769 | } | ||
2770 | pos += ntohs (temp_hdr->size); | ||
2771 | } | ||
2772 | } | ||
2773 | else | ||
2774 | { | ||
2775 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2776 | "Func wlan_process_helper got wrong MAC: %s\n", | ||
2777 | macprinter (&rxinfo->frame.addr1)); | ||
2778 | } | ||
2779 | } | ||
2780 | else | ||
2781 | { | ||
2782 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2783 | "Func wlan_process_helper got wrong BSSID: %s\n", | ||
2784 | macprinter (&rxinfo->frame.addr2)); | ||
2785 | } | ||
2786 | break; | ||
2787 | case GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL: | ||
2788 | //TODO more control messages | ||
2789 | if (ntohs (hdr->size) != sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage)) | ||
2790 | { | ||
2791 | GNUNET_break (0); | ||
2792 | /* FIXME: restart SUID process */ | ||
2793 | return; | ||
2794 | } | ||
2795 | cm = (const struct GNUNET_TRANSPORT_WLAN_HelperControlMessage *) hdr; | ||
2796 | plugin->mac_address = cm->mac; | ||
2797 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2798 | "Received WLAN_HELPER_CONTROL message with transport of address %s\n", | ||
2799 | wlan_plugin_address_to_string (cls, &plugin->mac_address, | ||
2800 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))); | ||
2801 | plugin->env->notify_address (plugin->env->cls, GNUNET_YES, | ||
2802 | &plugin->mac_address, | ||
2803 | sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); | ||
2804 | break; | ||
2805 | default: | ||
2806 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2807 | "Func wlan_process_helper got unknown message with number %u, size %u\n", | ||
2808 | ntohs (hdr->type), ntohs (hdr->size)); | ||
2809 | GNUNET_break (0); | ||
2810 | return; | 1510 | return; |
2811 | } | 1511 | } |
1512 | mac = addr; | ||
1513 | GNUNET_asprintf (&ret, | ||
1514 | "%s MAC address %s", | ||
1515 | PROTOCOL_PREFIX, | ||
1516 | mac_to_string (mac)); | ||
1517 | asc (asc_cls, ret); | ||
1518 | GNUNET_free (ret); | ||
1519 | asc (asc_cls, NULL); | ||
2812 | } | 1520 | } |
2813 | 1521 | ||
2814 | 1522 | ||
2815 | |||
2816 | /** | 1523 | /** |
2817 | * Exit point from the plugin. | 1524 | * Exit point from the plugin. |
1525 | * | ||
2818 | * @param cls pointer to the api struct | 1526 | * @param cls pointer to the api struct |
2819 | */ | 1527 | */ |
2820 | //FIXME cleanup | ||
2821 | void * | 1528 | void * |
2822 | libgnunet_plugin_transport_wlan_done (void *cls) | 1529 | libgnunet_plugin_transport_wlan_done (void *cls) |
2823 | { | 1530 | { |
@@ -2831,26 +1538,37 @@ libgnunet_plugin_transport_wlan_done (void *cls) | |||
2831 | GNUNET_free (api); | 1538 | GNUNET_free (api); |
2832 | return NULL; | 1539 | return NULL; |
2833 | } | 1540 | } |
2834 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | 1541 | if (GNUNET_SCHEDULER_NO_TASK != plugin->beacon_task) |
2835 | "libgnunet_plugin_transport_wlan_done started\n"); | 1542 | { |
2836 | wlan_transport_stop_wlan_helper (plugin); | 1543 | GNUNET_SCHEDULER_cancel (plugin->beacon_task); |
2837 | 1544 | plugin->beacon_task = GNUNET_SCHEDULER_NO_TASK; | |
2838 | GNUNET_assert (cls != NULL); | 1545 | } |
2839 | //free sessions | 1546 | if (NULL != plugin->suid_helper) |
2840 | endpoint = plugin->mac_head; | 1547 | { |
2841 | while (endpoint != NULL) | 1548 | GNUNET_HELPER_stop (plugin->suid_helper); |
1549 | plugin->suid_helper = NULL; | ||
1550 | } | ||
1551 | endpoint_next = plugin->mac_head; | ||
1552 | while (NULL != (endpoint = endpoint_next)) | ||
2842 | { | 1553 | { |
2843 | endpoint_next = endpoint->next; | 1554 | endpoint_next = endpoint->next; |
2844 | free_macendpoint (plugin, endpoint); | 1555 | free_macendpoint (endpoint); |
2845 | endpoint = endpoint_next; | 1556 | } |
2846 | 1557 | if (NULL != plugin->fragment_data_tokenizer) | |
1558 | { | ||
1559 | GNUNET_SERVER_mst_destroy (plugin->fragment_data_tokenizer); | ||
1560 | plugin->fragment_data_tokenizer = NULL; | ||
1561 | } | ||
1562 | if (NULL != plugin->wlan_header_payload_tokenizer) | ||
1563 | { | ||
1564 | GNUNET_SERVER_mst_destroy (plugin->wlan_header_payload_tokenizer); | ||
1565 | plugin->wlan_header_payload_tokenizer = NULL; | ||
1566 | } | ||
1567 | if (NULL != plugin->helper_payload_tokenizer) | ||
1568 | { | ||
1569 | GNUNET_SERVER_mst_destroy (plugin->helper_payload_tokenizer); | ||
1570 | plugin->helper_payload_tokenizer = NULL; | ||
2847 | } | 1571 | } |
2848 | if (plugin->suid_tokenizer != NULL) | ||
2849 | GNUNET_SERVER_mst_destroy (plugin->suid_tokenizer); | ||
2850 | |||
2851 | if (plugin->data_tokenizer != NULL) | ||
2852 | GNUNET_SERVER_mst_destroy (plugin->data_tokenizer); | ||
2853 | |||
2854 | GNUNET_free_non_null (plugin->interface); | 1572 | GNUNET_free_non_null (plugin->interface); |
2855 | GNUNET_free (plugin); | 1573 | GNUNET_free (plugin); |
2856 | GNUNET_free (api); | 1574 | GNUNET_free (api); |
@@ -2870,7 +1588,10 @@ libgnunet_plugin_transport_wlan_init (void *cls) | |||
2870 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; | 1588 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; |
2871 | struct GNUNET_TRANSPORT_PluginFunctions *api; | 1589 | struct GNUNET_TRANSPORT_PluginFunctions *api; |
2872 | struct Plugin *plugin; | 1590 | struct Plugin *plugin; |
1591 | char *interface; | ||
1592 | unsigned long long testmode; | ||
2873 | 1593 | ||
1594 | /* check for 'special' mode */ | ||
2874 | if (NULL == env->receive) | 1595 | if (NULL == env->receive) |
2875 | { | 1596 | { |
2876 | /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully | 1597 | /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully |
@@ -2883,28 +1604,89 @@ libgnunet_plugin_transport_wlan_init (void *cls) | |||
2883 | return api; | 1604 | return api; |
2884 | } | 1605 | } |
2885 | 1606 | ||
1607 | /* check configuration */ | ||
1608 | if ( (GNUNET_YES == | ||
1609 | GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "TESTMODE")) && | ||
1610 | ( (GNUNET_SYSERR == | ||
1611 | GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan", | ||
1612 | "TESTMODE", &testmode)) || | ||
1613 | (testmode > 2) ) ) | ||
1614 | { | ||
1615 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1616 | _("Invalid configuration option `%s' in section `%s'\n"), | ||
1617 | "TESTMODE", | ||
1618 | "transport-wlan"); | ||
1619 | return NULL; | ||
1620 | } | ||
1621 | if ( (0 == testmode) && | ||
1622 | (GNUNET_YES != GNUNET_OS_check_helper_binary ("gnunet-helper-transport-wlan")) ) | ||
1623 | { | ||
1624 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1625 | _("Helper binary `%s' not SUID, cannot run WLAN transport\n"), | ||
1626 | "gnunet-helper-transport-wlan"); | ||
1627 | return NULL; | ||
1628 | } | ||
1629 | if (GNUNET_YES != | ||
1630 | GNUNET_CONFIGURATION_get_value_string | ||
1631 | (env->cfg, "transport-wlan", "INTERFACE", | ||
1632 | &interface)) | ||
1633 | { | ||
1634 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1635 | _("Missing configuration option `%s' in section `%s'\n"), | ||
1636 | "INTERFACE", | ||
1637 | "transport-wlan"); | ||
1638 | return NULL; | ||
1639 | } | ||
1640 | |||
2886 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 1641 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
1642 | plugin->interface = interface; | ||
2887 | plugin->env = env; | 1643 | plugin->env = env; |
2888 | plugin->pendingsessions = 0; | 1644 | GNUNET_STATISTICS_set (plugin->env->stats, _("# WLAN sessions allocated"), |
2889 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), | 1645 | 0, GNUNET_NO); |
2890 | plugin->pendingsessions, GNUNET_NO); | 1646 | GNUNET_STATISTICS_set (plugin->env->stats, _("# WLAN MAC endpoints allocated"), |
2891 | plugin->mac_count = 0; | 1647 | 0, 0); |
2892 | GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"), | ||
2893 | plugin->mac_count, GNUNET_NO); | ||
2894 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | ||
2895 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; | ||
2896 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
2897 | GNUNET_BANDWIDTH_tracker_init (&plugin->tracker, | 1648 | GNUNET_BANDWIDTH_tracker_init (&plugin->tracker, |
2898 | GNUNET_BANDWIDTH_value_init (100 * 1024 * | 1649 | GNUNET_BANDWIDTH_value_init (100 * 1024 * |
2899 | 1024 / 8), 100); | 1650 | 1024 / 8), 100); |
2900 | 1651 | plugin->fragment_data_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); | |
2901 | plugin->suid_tokenizer = | 1652 | plugin->wlan_header_payload_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); |
2902 | GNUNET_SERVER_mst_create (&wlan_process_helper, plugin); | 1653 | plugin->helper_payload_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); |
2903 | 1654 | #if BEACON | |
2904 | plugin->data_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); | 1655 | plugin->beacon_task = GNUNET_SCHEDULER_add_now (&send_hello_beacon, |
2905 | 1656 | plugin); | |
2906 | //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); | 1657 | #endif |
2907 | //plugin->pending_Sessions_head = GNUNET_malloc (sizeof (struct Sessionqueue)); | 1658 | switch (testmode) |
1659 | { | ||
1660 | case 0: /* normal */ | ||
1661 | plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan"; | ||
1662 | plugin->helper_argv[1] = interface; | ||
1663 | plugin->helper_argv[2] = NULL; | ||
1664 | plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan", | ||
1665 | plugin->helper_argv, | ||
1666 | &handle_helper_message, | ||
1667 | plugin); | ||
1668 | break; | ||
1669 | case 1: /* testmode, peer 1 */ | ||
1670 | plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan-dummy"; | ||
1671 | plugin->helper_argv[1] = (char *) "1"; | ||
1672 | plugin->helper_argv[2] = NULL; | ||
1673 | plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan-dummy", | ||
1674 | plugin->helper_argv, | ||
1675 | &handle_helper_message, | ||
1676 | plugin); | ||
1677 | break; | ||
1678 | case 2: /* testmode, peer 2 */ | ||
1679 | plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan-dummy"; | ||
1680 | plugin->helper_argv[1] = (char *) "2"; | ||
1681 | plugin->helper_argv[2] = NULL; | ||
1682 | plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan-dummy", | ||
1683 | plugin->helper_argv, | ||
1684 | &handle_helper_message, | ||
1685 | plugin); | ||
1686 | break; | ||
1687 | default: | ||
1688 | GNUNET_assert (0); | ||
1689 | } | ||
2908 | 1690 | ||
2909 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 1691 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
2910 | api->cls = plugin; | 1692 | api->cls = plugin; |
@@ -2914,38 +1696,8 @@ libgnunet_plugin_transport_wlan_init (void *cls) | |||
2914 | api->address_pretty_printer = &wlan_plugin_address_pretty_printer; | 1696 | api->address_pretty_printer = &wlan_plugin_address_pretty_printer; |
2915 | api->check_address = &wlan_plugin_address_suggested; | 1697 | api->check_address = &wlan_plugin_address_suggested; |
2916 | api->address_to_string = &wlan_plugin_address_to_string; | 1698 | api->address_to_string = &wlan_plugin_address_to_string; |
2917 | |||
2918 | //read config | ||
2919 | |||
2920 | if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "TESTMODE")) | ||
2921 | { | ||
2922 | if (GNUNET_SYSERR == | ||
2923 | GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan", | ||
2924 | "TESTMODE", &(plugin->testmode))) | ||
2925 | plugin->testmode = 0; //default value | ||
2926 | } | ||
2927 | |||
2928 | if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "INTERFACE")) | ||
2929 | { | ||
2930 | if (GNUNET_CONFIGURATION_get_value_string | ||
2931 | (env->cfg, "transport-wlan", "INTERFACE", | ||
2932 | &(plugin->interface)) != GNUNET_YES) | ||
2933 | { | ||
2934 | libgnunet_plugin_transport_wlan_done (api); | ||
2935 | return NULL; | ||
2936 | } | ||
2937 | } | ||
2938 | |||
2939 | //start the plugin | ||
2940 | wlan_transport_start_wlan_helper (plugin); | ||
2941 | set_next_beacon_time (plugin); | ||
2942 | set_next_send (plugin); | ||
2943 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, | ||
2944 | "wlan init finished\n"); | ||
2945 | return api; | 1699 | return api; |
2946 | } | 1700 | } |
2947 | 1701 | ||
2948 | 1702 | ||
2949 | |||
2950 | |||
2951 | /* end of plugin_transport_wlan.c */ | 1703 | /* end of plugin_transport_wlan.c */ |