diff options
-rw-r--r-- | src/include/gnunet_protocols.h | 6 | ||||
-rw-r--r-- | src/transport/gnunet-transport-wlan-helper.c | 26 | ||||
-rw-r--r-- | src/transport/plugin_transport_wlan.c | 604 | ||||
-rw-r--r-- | src/transport/plugin_transport_wlan.h | 146 |
4 files changed, 680 insertions, 102 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 784964b49..aa3accc1a 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -653,7 +653,6 @@ extern "C" | |||
653 | /** | 653 | /** |
654 | * Type of messages between the gnunet-wlan-helper and the daemon | 654 | * Type of messages between the gnunet-wlan-helper and the daemon |
655 | * | 655 | * |
656 | * data messages | ||
657 | */ | 656 | */ |
658 | 657 | ||
659 | #define GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA 195 | 658 | #define GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA 195 |
@@ -667,11 +666,8 @@ extern "C" | |||
667 | /** | 666 | /** |
668 | * Type of messages for advertisement over wlan | 667 | * Type of messages for advertisement over wlan |
669 | */ | 668 | */ |
670 | #define GNUNET_MESSAGE_TYPE_WLAN_HELPER_ADVERTISEMENT 196 | 669 | #define GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT 197 |
671 | 670 | ||
672 | /** | ||
673 | * Type of messages for wlan | ||
674 | */ | ||
675 | 671 | ||
676 | /** | 672 | /** |
677 | * Type of messages to query the local service-dns | 673 | * Type of messages to query the local service-dns |
diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c index 19ea8de79..3ea8a74f5 100644 --- a/src/transport/gnunet-transport-wlan-helper.c +++ b/src/transport/gnunet-transport-wlan-helper.c | |||
@@ -28,6 +28,7 @@ | |||
28 | * gnunet | 28 | * gnunet |
29 | */ | 29 | */ |
30 | #include "gnunet-transport-wlan-helper.h" | 30 | #include "gnunet-transport-wlan-helper.h" |
31 | #include "plugin_transport_wlan.h" | ||
31 | #include "ieee80211_radiotap.h" | 32 | #include "ieee80211_radiotap.h" |
32 | 33 | ||
33 | #include <pcap.h> | 34 | #include <pcap.h> |
@@ -57,31 +58,6 @@ static const u8 u8aRatesToUse[] = { | |||
57 | 1*2 | 58 | 1*2 |
58 | }; | 59 | }; |
59 | 60 | ||
60 | /* Penumbra IEEE80211 header */ | ||
61 | static const u8 u8aIeeeHeader[] = { | ||
62 | 0x08, 0x01, 0x00, 0x00, | ||
63 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
64 | 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, | ||
65 | 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, | ||
66 | 0x10, 0x86, | ||
67 | }; | ||
68 | |||
69 | /* this is the template radiotap header we send packets out with */ | ||
70 | |||
71 | static const u8 u8aRadiotapHeader[] = { | ||
72 | |||
73 | 0x00, 0x00, // <-- radiotap version | ||
74 | 0x19, 0x00, // <- radiotap header length | ||
75 | 0x6f, 0x08, 0x00, 0x00, // <-- bitmap | ||
76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp | ||
77 | 0x00, // <-- flags (Offset +0x10) | ||
78 | 0x6c, // <-- rate (0ffset +0x11) | ||
79 | 0x71, 0x09, 0xc0, 0x00, // <-- channel | ||
80 | 0xde, // <-- antsignal | ||
81 | 0x00, // <-- antnoise | ||
82 | 0x01, // <-- antenna | ||
83 | |||
84 | }; | ||
85 | #define OFFSET_FLAGS 0x10 | 61 | #define OFFSET_FLAGS 0x10 |
86 | #define OFFSET_RATE 0x11 | 62 | #define OFFSET_RATE 0x11 |
87 | 63 | ||
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 0d7f476aa..bebfe7ea4 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c | |||
@@ -20,8 +20,8 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file transport/plugin_transport_wlan.c | 22 | * @file transport/plugin_transport_wlan.c |
23 | * @brief template for a new transport service | 23 | * @brief transport plugin for wlan |
24 | * @author Christian Grothoff | 24 | * @author David Brodski |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "platform.h" | 27 | #include "platform.h" |
@@ -30,8 +30,11 @@ | |||
30 | #include "gnunet_statistics_service.h" | 30 | #include "gnunet_statistics_service.h" |
31 | #include "gnunet_transport_service.h" | 31 | #include "gnunet_transport_service.h" |
32 | #include "plugin_transport.h" | 32 | #include "plugin_transport.h" |
33 | #include "plugin_transport_wlan.h" | ||
34 | #include "gnunet_common.h" | ||
33 | 35 | ||
34 | #define PROTOCOL_PREFIX "wlan" | 36 | #define PROTOCOL_PREFIX "wlan" |
37 | #define WLAN_MTU 3000 | ||
35 | 38 | ||
36 | #define DEBUG_wlan GNUNET_NO | 39 | #define DEBUG_wlan GNUNET_NO |
37 | 40 | ||
@@ -42,12 +45,111 @@ | |||
42 | */ | 45 | */ |
43 | #define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6) | 46 | #define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6) |
44 | 47 | ||
48 | /** | ||
49 | * Initial handshake message for a session. | ||
50 | */ | ||
51 | struct WelcomeMessage | ||
52 | { | ||
53 | /** | ||
54 | * Type is GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME. | ||
55 | */ | ||
56 | struct GNUNET_MessageHeader header; | ||
57 | |||
58 | /** | ||
59 | * Identity of the node connecting (TCP client) | ||
60 | */ | ||
61 | struct GNUNET_PeerIdentity clientIdentity; | ||
62 | |||
63 | }; | ||
45 | 64 | ||
46 | /** | 65 | /** |
47 | * Encapsulation of all of the state of the plugin. | 66 | * Encapsulation of all of the state of the plugin. |
48 | */ | 67 | */ |
49 | struct Plugin; | 68 | struct Plugin |
69 | { | ||
70 | /** | ||
71 | * Our environment. | ||
72 | */ | ||
73 | struct GNUNET_TRANSPORT_PluginEnvironment *env; | ||
50 | 74 | ||
75 | /** | ||
76 | * List of open sessions. | ||
77 | */ | ||
78 | struct Session *sessions; | ||
79 | |||
80 | /** | ||
81 | * encapsulation to the local wlan server prog | ||
82 | */ | ||
83 | |||
84 | struct GNUNET_SERVER_MessageStreamTokenizer * consoltoken; | ||
85 | |||
86 | |||
87 | /** | ||
88 | * stdout pipe handle for the gnunet-wlan-helper process | ||
89 | */ | ||
90 | struct GNUNET_DISK_PipeHandle *server_stdout; | ||
91 | |||
92 | /** | ||
93 | * stdout file handle for the gnunet-wlan-helper process | ||
94 | */ | ||
95 | const struct GNUNET_DISK_FileHandle *server_stdout_handle; | ||
96 | |||
97 | /** | ||
98 | * stdin pipe handle for the gnunet-wlan-helper process | ||
99 | */ | ||
100 | struct GNUNET_DISK_PipeHandle *server_stdin; | ||
101 | |||
102 | /** | ||
103 | * stdin file handle for the gnunet-wlan-helper process | ||
104 | */ | ||
105 | const struct GNUNET_DISK_FileHandle *server_stdin_handle; | ||
106 | |||
107 | /** | ||
108 | * ID of select gnunet-nat-server std read task | ||
109 | */ | ||
110 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; | ||
111 | |||
112 | /** | ||
113 | * ID of select gnunet-nat-server std read task | ||
114 | */ | ||
115 | GNUNET_SCHEDULER_TaskIdentifier server_write_task; | ||
116 | |||
117 | /** | ||
118 | * The process id of the server process (if behind NAT) | ||
119 | */ | ||
120 | pid_t server_pid; | ||
121 | |||
122 | /** | ||
123 | * The interface of the wlan card given to us by the user. | ||
124 | */ | ||
125 | char *interface; | ||
126 | |||
127 | /** | ||
128 | * The mac_address of the wlan card given to us by the helper. | ||
129 | */ | ||
130 | char *mac_address; | ||
131 | |||
132 | /** | ||
133 | * Sessions currently pending for transmission | ||
134 | * to this peer, if any. | ||
135 | */ | ||
136 | struct Sessionqueue * pending_Sessions; | ||
137 | |||
138 | /** | ||
139 | * Sessions currently pending for transmission | ||
140 | * to this peer, if any. | ||
141 | */ | ||
142 | struct Sessionqueue * all_Sessions; | ||
143 | |||
144 | }; | ||
145 | |||
146 | |||
147 | struct Sessionqueue | ||
148 | { | ||
149 | struct Sessionqueue * next; | ||
150 | struct Sessionqueue * prev; | ||
151 | struct Session * content; | ||
152 | }; | ||
51 | 153 | ||
52 | /** | 154 | /** |
53 | * Session handle for connections. | 155 | * Session handle for connections. |
@@ -56,9 +158,9 @@ struct Session | |||
56 | { | 158 | { |
57 | 159 | ||
58 | /** | 160 | /** |
59 | * Stored in a linked list. | 161 | * API requirement. |
60 | */ | 162 | */ |
61 | struct Session *next; | 163 | struct SessionHeader header; |
62 | 164 | ||
63 | /** | 165 | /** |
64 | * Pointer to the global plugin struct. | 166 | * Pointer to the global plugin struct. |
@@ -66,118 +168,391 @@ struct Session | |||
66 | struct Plugin *plugin; | 168 | struct Plugin *plugin; |
67 | 169 | ||
68 | /** | 170 | /** |
69 | * The client (used to identify this connection) | 171 | * Messages currently pending for transmission |
172 | * to this peer, if any. | ||
70 | */ | 173 | */ |
71 | /* void *client; */ | 174 | struct PendingMessage *pending_messages_head; |
72 | 175 | ||
73 | /** | 176 | /** |
74 | * Continuation function to call once the transmission buffer | 177 | * Messages currently pending for transmission |
75 | * has again space available. NULL if there is no | 178 | * to this peer, if any. |
76 | * continuation to call. | ||
77 | */ | 179 | */ |
78 | GNUNET_TRANSPORT_TransmitContinuation transmit_cont; | 180 | struct PendingMessage *pending_messages_tail; |
79 | 181 | ||
80 | /** | 182 | /** |
81 | * Closure for transmit_cont. | 183 | * To whom are we talking to (set to our identity |
184 | * if we are still waiting for the welcome message) | ||
82 | */ | 185 | */ |
83 | void *transmit_cont_cls; | 186 | struct GNUNET_PeerIdentity * target; |
84 | 187 | ||
85 | /** | 188 | /** |
86 | * To whom are we talking to (set to our identity | 189 | * encapsulation of the data |
87 | * if we are still waiting for the welcome message) | 190 | */ |
191 | |||
192 | struct GNUNET_SERVER_MessageStreamTokenizer * datatoken; | ||
193 | |||
194 | /** | ||
195 | * peer mac address | ||
196 | */ | ||
197 | |||
198 | char addr[6]; | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Address of the other peer (either based on our 'connect' | ||
203 | * call or on our 'accept' call). | ||
88 | */ | 204 | */ |
89 | struct GNUNET_PeerIdentity sender; | 205 | void *connect_addr; |
90 | 206 | ||
91 | /** | 207 | /** |
92 | * At what time did we reset last_received last? | 208 | * Last activity on this connection. Used to select preferred |
209 | * connection. | ||
93 | */ | 210 | */ |
94 | struct GNUNET_TIME_Absolute last_quota_update; | 211 | struct GNUNET_TIME_Absolute last_activity; |
95 | 212 | ||
96 | /** | 213 | /** |
97 | * How many bytes have we received since the "last_quota_update" | 214 | * number of message, to distinguish between the messages |
98 | * timestamp? | ||
99 | */ | 215 | */ |
100 | uint64_t last_received; | 216 | |
217 | uint16_t message_num_in; | ||
101 | 218 | ||
102 | /** | 219 | /** |
103 | * Number of bytes per ms that this peer is allowed | 220 | * number of message, to distinguish between the messages |
104 | * to send to us. | ||
105 | */ | 221 | */ |
106 | uint32_t quota; | 222 | |
223 | uint16_t message_num_out; | ||
224 | |||
107 | 225 | ||
108 | }; | 226 | }; |
109 | 227 | ||
110 | /** | 228 | /** |
111 | * Encapsulation of all of the state of the plugin. | 229 | * Information kept for each message that is yet to |
230 | * be transmitted. | ||
112 | */ | 231 | */ |
113 | struct Plugin | 232 | struct PendingMessage |
114 | { | 233 | { |
234 | |||
115 | /** | 235 | /** |
116 | * Our environment. | 236 | * This is a doubly-linked list. |
117 | */ | 237 | */ |
118 | struct GNUNET_TRANSPORT_PluginEnvironment *env; | 238 | struct PendingMessage *next; |
119 | 239 | ||
120 | /** | 240 | /** |
121 | * List of open sessions. | 241 | * This is a doubly-linked list. |
122 | * TODO? | ||
123 | */ | 242 | */ |
124 | struct Session *sessions; | 243 | struct PendingMessage *prev; |
125 | 244 | ||
126 | /** | 245 | /** |
127 | * encapsulation to the local wlan server prog | 246 | * The pending message |
128 | */ | 247 | */ |
248 | const char *msg; | ||
129 | 249 | ||
130 | struct GNUNET_SERVER_MessageStreamTokenizer * consoltoken; | ||
131 | 250 | ||
132 | /** | 251 | /** |
133 | * encapsulation of the data | 252 | * Continuation function to call once the message |
253 | * has been sent. Can be NULL if there is no | ||
254 | * continuation to call. | ||
134 | */ | 255 | */ |
256 | GNUNET_TRANSPORT_TransmitContinuation transmit_cont; | ||
135 | 257 | ||
136 | struct GNUNET_SERVER_MessageStreamTokenizer * datatoken; | 258 | /** |
259 | * Cls for transmit_cont | ||
260 | */ | ||
261 | |||
262 | void * transmit_cont_cls; | ||
137 | 263 | ||
138 | /** | 264 | /** |
139 | * stdout pipe handle for the gnunet-wlan-helper process | 265 | * Timeout value for the pending message. |
140 | */ | 266 | */ |
141 | struct GNUNET_DISK_PipeHandle *server_stdout; | 267 | struct GNUNET_TIME_Absolute timeout; |
142 | 268 | ||
143 | /** | 269 | /** |
144 | * stdout file handle for the gnunet-wlan-helper process | 270 | * Size of the message |
145 | */ | 271 | */ |
146 | const struct GNUNET_DISK_FileHandle *server_stdout_handle; | 272 | size_t message_size; |
147 | 273 | ||
148 | /** | 274 | /** |
149 | * stdin pipe handle for the gnunet-wlan-helper process | 275 | * pos in the message, for fragmentation/segmentation |
150 | */ | 276 | */ |
151 | struct GNUNET_DISK_PipeHandle *server_stdin; | 277 | size_t message_pos; |
278 | }; | ||
279 | |||
280 | |||
281 | /** | ||
282 | * Header for messages which need fragmentation | ||
283 | */ | ||
284 | |||
285 | struct FragmentationHeader | ||
286 | { | ||
152 | 287 | ||
153 | /** | 288 | /** |
154 | * stdin file handle for the gnunet-wlan-helper process | 289 | * To whom are we talking to (set to our identity |
290 | * if we are still waiting for the welcome message) | ||
155 | */ | 291 | */ |
156 | const struct GNUNET_DISK_FileHandle *server_stdin_handle; | 292 | struct GNUNET_PeerIdentity * target GNUNET_PACKED; |
157 | 293 | ||
158 | /** | 294 | /** |
159 | * ID of select gnunet-nat-server std read task | 295 | * number of message, to distinguish between the messages |
160 | */ | 296 | */ |
161 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; | 297 | |
298 | uint16_t message_num GNUNET_PACKED; | ||
162 | 299 | ||
163 | /** | 300 | /** |
164 | * The process id of the server process (if behind NAT) | 301 | * number of this fragment, for fragmentation/segmentation |
165 | */ | 302 | */ |
166 | pid_t server_pid; | 303 | uint16_t fregment_num GNUNET_PACKED; |
304 | |||
167 | 305 | ||
168 | /** | 306 | /** |
169 | * The interface of the wlan card given to us by the user. | 307 | * number of fregments in this message |
170 | */ | 308 | */ |
171 | char *interface; | 309 | uint16_t ack_message_num GNUNET_PACKED; |
172 | 310 | ||
173 | /** | 311 | /** |
174 | * The mac_address of the wlan card given to us by the helper. | 312 | * number of this fragment, for fragmentation/segmentation |
175 | */ | 313 | */ |
176 | char *mac_address; | 314 | uint16_t ack_fregment_num GNUNET_PACKED; |
315 | |||
316 | /** | ||
317 | * Flags | ||
318 | * 0x1 ack | ||
319 | * 0x2 has data (not only ack) | ||
320 | * 0x4 last fragment of message | ||
321 | * 0x8 new message | ||
322 | */ | ||
323 | |||
324 | uint32_t flags GNUNET_PACKED; | ||
325 | |||
177 | 326 | ||
327 | /** | ||
328 | * checksum/error correction | ||
329 | */ | ||
330 | |||
331 | uint32_t crc GNUNET_PACKED; | ||
178 | }; | 332 | }; |
179 | 333 | ||
180 | struct Plugin* plugin; | 334 | enum { ACK_FRAGMENT = 1, DATA_FRAGMENT = 2, LAST_FRAGMENT = 4, NEW_MESSAGE = 8 }; |
335 | |||
336 | int getRadiotapHeader (struct RadiotapHeader * Header); | ||
337 | int getWlanHeader (struct IeeeHeader * Header); | ||
338 | static int wlan_plugin_address_suggested (void *cls, | ||
339 | const void *addr, | ||
340 | size_t addrlen); | ||
341 | /** | ||
342 | * get Session from address | ||
343 | * | ||
344 | */ | ||
345 | |||
346 | //TODO add other possibilities to find the right session (are there other?) | ||
347 | static struct Session * | ||
348 | get_Session (struct Plugin *plugin, | ||
349 | char * addr) | ||
350 | { | ||
351 | struct Sessionqueue * queue = plugin->all_Sessions; | ||
352 | struct Sessionqueue * lastitem = NULL; | ||
353 | |||
354 | while (queue != NULL){ | ||
355 | // content is never NULL | ||
356 | GNUNET_assert (queue->content == NULL); | ||
357 | char * addr2 = (queue->content)->addr; | ||
358 | if (memcmp(addr, addr2, 6) == 0){ | ||
359 | //sesion found | ||
360 | return queue->content; | ||
361 | } | ||
362 | // try next | ||
363 | lastitem = queue; | ||
364 | queue = queue->next; | ||
365 | } | ||
366 | // new session | ||
367 | queue = GNUNET_malloc (sizeof (struct Sessionqueue)); | ||
368 | |||
369 | if (plugin->all_Sessions == NULL){ | ||
370 | //is first session | ||
371 | plugin->all_Sessions = queue; | ||
372 | } else { | ||
373 | lastitem->next = queue; | ||
374 | queue->prev = lastitem; | ||
375 | } | ||
376 | |||
377 | queue->content = GNUNET_malloc (sizeof (struct Session)); | ||
378 | (queue->content)->plugin = plugin; | ||
379 | memcpy((queue->content)->addr, addr, 6); | ||
380 | |||
381 | //queue welcome | ||
382 | struct WelcomeMessage welcome; | ||
383 | struct PendingMessage *pm; | ||
384 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct WelcomeMessage)); | ||
385 | pm->msg = (const char*) &pm[1]; | ||
386 | pm->message_size = sizeof (struct WelcomeMessage); | ||
387 | welcome.header.size = htons (sizeof (struct WelcomeMessage)); | ||
388 | welcome.header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); | ||
389 | welcome.clientIdentity = *plugin->env->my_identity; | ||
390 | memcpy (&pm[1], &welcome, sizeof (welcome)); | ||
391 | pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
392 | GNUNET_CONTAINER_DLL_insert ((queue->content)->pending_messages_head, | ||
393 | (queue->content)->pending_messages_tail, | ||
394 | pm); | ||
395 | |||
396 | return queue->content; | ||
397 | |||
398 | } | ||
399 | |||
400 | /** | ||
401 | * Queue the session to send data | ||
402 | */ | ||
403 | |||
404 | static void | ||
405 | queue_Session (struct Plugin *plugin, | ||
406 | struct Session * session) | ||
407 | { | ||
408 | struct Sessionqueue * queue = plugin->pending_Sessions; | ||
409 | struct Sessionqueue * lastitem = NULL; | ||
410 | |||
411 | while (queue != NULL){ | ||
412 | // content is never NULL | ||
413 | GNUNET_assert (queue->content == NULL); | ||
414 | // is session already in queue? | ||
415 | if (session == queue->content){ | ||
416 | return; | ||
417 | } | ||
418 | // try next | ||
419 | lastitem = queue; | ||
420 | queue = queue->next; | ||
421 | } | ||
422 | |||
423 | // Session is not in the queue | ||
424 | |||
425 | queue = GNUNET_malloc (sizeof (struct Sessionqueue)); | ||
426 | if (plugin->pending_Sessions == NULL){ | ||
427 | //is first session | ||
428 | plugin->pending_Sessions = queue; | ||
429 | } else { | ||
430 | lastitem->next = queue; | ||
431 | queue->prev = lastitem; | ||
432 | } | ||
433 | |||
434 | queue->content = session; | ||
435 | |||
436 | } | ||
437 | |||
438 | /** | ||
439 | * Function called to when wlan helper is ready to get some data | ||
440 | * | ||
441 | * @param cls closure | ||
442 | * @param GNUNET_SCHEDULER_TaskContext | ||
443 | */ | ||
444 | |||
445 | static void | ||
446 | do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
447 | { | ||
448 | struct Plugin * plugin = cls; | ||
449 | char * msg; | ||
450 | ssize_t bytes; | ||
451 | |||
452 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
453 | return; | ||
454 | |||
455 | struct Session * session; | ||
456 | struct Sessionqueue * queue; | ||
457 | struct PendingMessage * pm; | ||
458 | struct IeeeHeader * wlanheader; | ||
459 | struct RadiotapHeader * RadioHeader; | ||
460 | struct GNUNET_MessageHeader * msgheader; | ||
461 | uint16_t size = 0; | ||
462 | |||
463 | queue = plugin->pending_Sessions; | ||
464 | |||
465 | //check if the are some pending sessions/messages ... | ||
466 | GNUNET_assert(queue != NULL); | ||
467 | |||
468 | session = queue->content; | ||
469 | GNUNET_assert(session != NULL); | ||
470 | |||
471 | pm = session->pending_messages_head; | ||
472 | GNUNET_assert(pm != NULL); | ||
473 | |||
474 | //check if msg is valid to send | ||
475 | if (GNUNET_TIME_absolute_get_remaining(pm->timeout).value > 0){ | ||
476 | // fixme split msg if to large | ||
477 | |||
478 | //increment one, this is a new message | ||
479 | session->message_num_out ++; | ||
480 | // fixme peer id is needed in each packet | ||
481 | size = pm->message_size + sizeof(struct RadiotapHeader) | ||
482 | + sizeof(struct IeeeHeader) + sizeof(struct GNUNET_MessageHeader) | ||
483 | + sizeof(struct FragmentationHeader); | ||
484 | msg = GNUNET_malloc(size); | ||
485 | |||
486 | msgheader = msg; | ||
487 | msgheader->size = pm->message_size + sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader); | ||
488 | msgheader->type = GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA; | ||
489 | |||
490 | RadioHeader = &msgheader[1]; | ||
491 | getRadiotapHeader(RadioHeader); | ||
492 | |||
493 | wlanheader = &RadioHeader[1]; | ||
494 | getWlanHeader(wlanheader); | ||
495 | |||
496 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msg, size); | ||
497 | } else { | ||
498 | //remove message | ||
499 | GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, | ||
500 | session->pending_messages_tail, | ||
501 | pm); | ||
502 | GNUNET_free(pm->msg); | ||
503 | GNUNET_free(pm); | ||
504 | |||
505 | } | ||
506 | |||
507 | |||
508 | |||
509 | |||
510 | |||
511 | if (bytes < 1) | ||
512 | { | ||
513 | return; | ||
514 | } | ||
515 | |||
516 | //plugin->server_read_task = | ||
517 | //GNUNET_SCHEDULER_add_read_file (plugin->env->sched, | ||
518 | // GNUNET_TIME_UNIT_FOREVER_REL, | ||
519 | // plugin->server_stdout_handle, &wlan_plugin_helper_read, plugin); | ||
520 | |||
521 | } | ||
522 | |||
523 | /** | ||
524 | * If we have pending messages, ask the server to | ||
525 | * transmit them (schedule the respective tasks, etc.) | ||
526 | * | ||
527 | * @param Plugin env to get everything needed | ||
528 | */ | ||
529 | static void | ||
530 | process_pending_messages (struct Plugin * plugin) | ||
531 | { | ||
532 | struct Sessionqueue * queue; | ||
533 | struct Session * session; | ||
534 | |||
535 | if (plugin->pending_Sessions == NULL) | ||
536 | return; | ||
537 | |||
538 | queue = plugin->pending_Sessions; | ||
539 | //contet should not be empty | ||
540 | GNUNET_assert(queue->content != NULL); | ||
541 | |||
542 | session = queue->content; | ||
543 | //pending sessions should have some msg | ||
544 | GNUNET_assert(session->pending_messages_head != NULL); | ||
545 | |||
546 | // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg | ||
547 | plugin->server_write_task | ||
548 | = GNUNET_SCHEDULER_add_write_file(plugin->env->sched, | ||
549 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
550 | plugin->server_stdin_handle, | ||
551 | &do_transmit, | ||
552 | plugin); | ||
553 | } | ||
554 | |||
555 | |||
181 | 556 | ||
182 | /** | 557 | /** |
183 | * Function that can be used by the transport service to transmit | 558 | * Function that can be used by the transport service to transmit |
@@ -207,8 +582,7 @@ struct Plugin* plugin; | |||
207 | */ | 582 | */ |
208 | static ssize_t | 583 | static ssize_t |
209 | wlan_plugin_send (void *cls, | 584 | wlan_plugin_send (void *cls, |
210 | const struct GNUNET_PeerIdentity * | 585 | const struct GNUNET_PeerIdentity * target, |
211 | target, | ||
212 | const char *msgbuf, | 586 | const char *msgbuf, |
213 | size_t msgbuf_size, | 587 | size_t msgbuf_size, |
214 | unsigned int priority, | 588 | unsigned int priority, |
@@ -217,12 +591,79 @@ wlan_plugin_send (void *cls, | |||
217 | const void *addr, | 591 | const void *addr, |
218 | size_t addrlen, | 592 | size_t addrlen, |
219 | int force_address, | 593 | int force_address, |
220 | GNUNET_TRANSPORT_TransmitContinuation | 594 | GNUNET_TRANSPORT_TransmitContinuation cont, |
221 | cont, void *cont_cls) | 595 | void *cont_cls) |
222 | { | 596 | { |
223 | int bytes_sent = 0; | 597 | int bytes_sent = 0; |
224 | /* struct Plugin *plugin = cls; */ | 598 | char * msg; |
225 | return bytes_sent; | 599 | |
600 | struct Plugin * plugin = cls; | ||
601 | |||
602 | struct PendingMessage * newmsg = NULL; | ||
603 | |||
604 | //check if msglen > 0 | ||
605 | GNUNET_assert(msgbuf_size > 0); | ||
606 | |||
607 | //get session if needed | ||
608 | if (session == NULL) { | ||
609 | if ( wlan_plugin_address_suggested(plugin , addr, addrlen) == GNUNET_OK){ | ||
610 | session = get_Session(plugin, addr); | ||
611 | } else { | ||
612 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
613 | _("Wlan Address len %d is wrong\n"), | ||
614 | addrlen); | ||
615 | return -1; | ||
616 | } | ||
617 | } | ||
618 | |||
619 | //TODO target "problem" not solved | ||
620 | session->target = target; | ||
621 | |||
622 | //queue message: | ||
623 | //first queue session | ||
624 | queue_Session(plugin, session); | ||
625 | |||
626 | //queue message in session | ||
627 | newmsg = GNUNET_malloc(sizeof(struct PendingMessage)); | ||
628 | newmsg->msg = GNUNET_malloc(msgbuf_size); | ||
629 | //copy msg to buffer, not fragmented / segmented yet | ||
630 | memcpy(newmsg->msg, msgbuf, msgbuf_size); | ||
631 | newmsg->transmit_cont = cont; | ||
632 | newmsg->transmit_cont_cls = cont_cls; | ||
633 | newmsg->timeout = GNUNET_TIME_relative_to_absolute(timeout); | ||
634 | newmsg->message_pos = 0; | ||
635 | newmsg->message_size = msgbuf_size; | ||
636 | newmsg->next = NULL; | ||
637 | |||
638 | //check if queue is empty | ||
639 | struct PendingMessage * tailmsg; | ||
640 | tailmsg = session->pending_messages_tail; | ||
641 | |||
642 | //new tail is the new msg | ||
643 | session->pending_messages_tail = newmsg; | ||
644 | newmsg->prev = tailmsg; | ||
645 | |||
646 | //test if tail was not NULL (queue is empty) | ||
647 | if (tailmsg == NULL){ | ||
648 | // head should be NULL too | ||
649 | GNUNET_assert(session->pending_messages_head == NULL); | ||
650 | |||
651 | session->pending_messages_head = newmsg; | ||
652 | |||
653 | } else { | ||
654 | //next at the tail should be NULL | ||
655 | GNUNET_assert(tailmsg->next == NULL); | ||
656 | |||
657 | //queue the msg | ||
658 | tailmsg->next = newmsg; | ||
659 | } | ||
660 | |||
661 | process_pending_messages(plugin); | ||
662 | |||
663 | |||
664 | //FIXME not the correct size | ||
665 | return msgbuf_size; | ||
666 | |||
226 | } | 667 | } |
227 | 668 | ||
228 | 669 | ||
@@ -230,7 +671,7 @@ wlan_plugin_send (void *cls, | |||
230 | /** | 671 | /** |
231 | * Function that can be used to force the plugin to disconnect | 672 | * Function that can be used to force the plugin to disconnect |
232 | * from the given peer and cancel all previous transmissions | 673 | * from the given peer and cancel all previous transmissions |
233 | * (and their continuationc). | 674 | * (and their continuation). |
234 | * | 675 | * |
235 | * @param cls closure | 676 | * @param cls closure |
236 | * @param target peer from which to disconnect | 677 | * @param target peer from which to disconnect |
@@ -302,6 +743,8 @@ wlan_plugin_address_pretty_printer (void *cls, | |||
302 | * @return GNUNET_OK if this is a plausible address for this peer | 743 | * @return GNUNET_OK if this is a plausible address for this peer |
303 | * and transport | 744 | * and transport |
304 | */ | 745 | */ |
746 | |||
747 | |||
305 | static int | 748 | static int |
306 | wlan_plugin_address_suggested (void *cls, | 749 | wlan_plugin_address_suggested (void *cls, |
307 | const void *addr, | 750 | const void *addr, |
@@ -322,6 +765,7 @@ wlan_plugin_address_suggested (void *cls, | |||
322 | return GNUNET_SYSERR; | 765 | return GNUNET_SYSERR; |
323 | } | 766 | } |
324 | 767 | ||
768 | return GNUNET_SYSERR; | ||
325 | } | 769 | } |
326 | 770 | ||
327 | 771 | ||
@@ -361,18 +805,19 @@ wlan_plugin_address_to_string (void *cls, | |||
361 | } | 805 | } |
362 | 806 | ||
363 | 807 | ||
364 | #if 0 | 808 | #if 1 |
365 | /** | 809 | /** |
366 | * Function for used to process the data from the suid process | 810 | * Function used for to process the data from the suid process |
367 | */ | 811 | */ |
368 | static void | 812 | static void |
369 | wlan_process_helper (void *cls, | 813 | wlan_process_helper (void *cls, |
370 | void *client_identity, | 814 | void *client, |
371 | struct GNUNET_MessageHeader *hdr) | 815 | const struct GNUNET_MessageHeader *hdr) |
372 | { | 816 | { |
817 | struct Plugin *plugin = cls; | ||
373 | if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA){ | 818 | if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA){ |
374 | //TODO DATA | 819 | //TODO DATA |
375 | } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_ADVERTISEMENT){ | 820 | } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT){ |
376 | //TODO ADV | 821 | //TODO ADV |
377 | } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL){ | 822 | } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL){ |
378 | //TODO Control | 823 | //TODO Control |
@@ -380,7 +825,8 @@ wlan_process_helper (void *cls, | |||
380 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying transport of address %s\n", wlan_plugin_address_to_string(cls, plugin->mac_address, hdr->size)); | 825 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying transport of address %s\n", wlan_plugin_address_to_string(cls, plugin->mac_address, hdr->size)); |
381 | plugin->env->notify_address (plugin->env->cls, | 826 | plugin->env->notify_address (plugin->env->cls, |
382 | "wlan", | 827 | "wlan", |
383 | &plugin->mac_address, sizeof(plugin->mac_address), GNUNET_TIME_UNIT_FOREVER_REL); | 828 | &plugin->mac_address, sizeof(plugin->mac_address), |
829 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
384 | } else { | 830 | } else { |
385 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Wrong wlan mac address %s\n", plugin->mac_address); | 831 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Wrong wlan mac address %s\n", plugin->mac_address); |
386 | } | 832 | } |
@@ -396,7 +842,7 @@ static void | |||
396 | wlan_plugin_helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 842 | wlan_plugin_helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
397 | { | 843 | { |
398 | struct Plugin *plugin = cls; | 844 | struct Plugin *plugin = cls; |
399 | char mybuf[3000]; //max size of packet from helper | 845 | char mybuf[WLAN_MTU]; //max size of packet from helper |
400 | ssize_t bytes; | 846 | ssize_t bytes; |
401 | //memset(&mybuf, 0, sizeof(mybuf)); //? | 847 | //memset(&mybuf, 0, sizeof(mybuf)); //? |
402 | 848 | ||
@@ -414,16 +860,13 @@ wlan_plugin_helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *t | |||
414 | return; | 860 | return; |
415 | } | 861 | } |
416 | 862 | ||
417 | plugin->server_read_task = | 863 | GNUNET_SERVER_mst_receive(plugin->consoltoken,NULL,&mybuf,bytes,0, GNUNET_NO); |
418 | GNUNET_SCHEDULER_add_read_file (plugin->env->sched, | ||
419 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
420 | plugin->server_stdout_handle, &wlan_plugin_helper_read, plugin); | ||
421 | 864 | ||
422 | } | 865 | } |
423 | 866 | ||
424 | 867 | ||
425 | /** | 868 | /** |
426 | * Start the gnunet-wlan-helper process for users behind NAT. | 869 | * Start the gnunet-wlan-helper process. |
427 | * | 870 | * |
428 | * @param plugin the transport plugin | 871 | * @param plugin the transport plugin |
429 | * | 872 | * |
@@ -459,7 +902,7 @@ wlan_transport_start_wlan_helper(struct Plugin *plugin) | |||
459 | GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE); | 902 | GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE); |
460 | 903 | ||
461 | /* Close the read end of the write pipe */ | 904 | /* Close the read end of the write pipe */ |
462 | GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ); | 905 | GNUNET_DISK_pipe_close_end(plugin->server_stdin, GNUNET_DISK_PIPE_END_READ); |
463 | 906 | ||
464 | plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ); | 907 | plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ); |
465 | plugin->server_stdin_handle = GNUNET_DISK_pipe_handle(plugin->server_stdin, GNUNET_DISK_PIPE_END_WRITE); | 908 | plugin->server_stdin_handle = GNUNET_DISK_pipe_handle(plugin->server_stdin, GNUNET_DISK_PIPE_END_WRITE); |
@@ -478,19 +921,36 @@ wlan_transport_start_wlan_helper(struct Plugin *plugin) | |||
478 | 921 | ||
479 | /** | 922 | /** |
480 | * Entry point for the plugin. | 923 | * Entry point for the plugin. |
924 | * | ||
925 | * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*' | ||
926 | * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error | ||
481 | */ | 927 | */ |
482 | void * | 928 | void * |
483 | gnunet_plugin_transport_wlan_init (void *cls) | 929 | gnunet_plugin_transport_wlan_init (void *cls) |
484 | { | 930 | { |
931 | struct GNUNET_SERVICE_Context *service; | ||
485 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; | 932 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; |
486 | struct GNUNET_TRANSPORT_PluginFunctions *api; | 933 | struct GNUNET_TRANSPORT_PluginFunctions *api; |
487 | struct Plugin *plugin; | 934 | struct Plugin *plugin; |
488 | 935 | ||
489 | GNUNET_assert(cls !=NULL); | 936 | GNUNET_assert(cls !=NULL); |
490 | 937 | ||
938 | service = GNUNET_SERVICE_start ("transport-wlan", env->sched, env->cfg); | ||
939 | if (service == NULL){ | ||
940 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
941 | _("Failed to start service for `%s' transport plugin.\n"), | ||
942 | "wlan"); | ||
943 | return NULL; | ||
944 | } | ||
945 | |||
491 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 946 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
492 | plugin->env = env; | 947 | plugin->env = env; |
493 | 948 | ||
949 | wlan_transport_start_wlan_helper(plugin); | ||
950 | plugin->consoltoken = GNUNET_SERVER_mst_create(&wlan_process_helper,plugin); | ||
951 | |||
952 | //plugin->all_Sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); | ||
953 | //plugin->pending_Sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); | ||
494 | 954 | ||
495 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 955 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
496 | api->cls = plugin; | 956 | api->cls = plugin; |
diff --git a/src/transport/plugin_transport_wlan.h b/src/transport/plugin_transport_wlan.h new file mode 100644 index 000000000..c870e4d65 --- /dev/null +++ b/src/transport/plugin_transport_wlan.h | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file transport/plugin_transport_wlan.h | ||
23 | * @brief header for transport plugin and the helper for wlan | ||
24 | * @author David Brodski | ||
25 | */ | ||
26 | |||
27 | #include "gnunet_common.h" | ||
28 | |||
29 | typedef unsigned int uint32_t; | ||
30 | typedef unsigned short uint16_t; | ||
31 | |||
32 | /* Wlan IEEE80211 header default */ | ||
33 | static const uint8_t u8aIeeeHeader[] = { | ||
34 | 0x08, 0x01, 0x00, 0x00, | ||
35 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
36 | 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, | ||
37 | 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, | ||
38 | 0x10, 0x86, | ||
39 | }; | ||
40 | |||
41 | /** | ||
42 | * Wlan header | ||
43 | */ | ||
44 | |||
45 | struct IeeeHeader | ||
46 | { | ||
47 | /** | ||
48 | * Wlan flags | ||
49 | */ | ||
50 | uint8_t flags[4] GNUNET_PACKED; | ||
51 | |||
52 | /** | ||
53 | * first mac | ||
54 | */ | ||
55 | uint8_t mac1[6] GNUNET_PACKED; | ||
56 | |||
57 | /** | ||
58 | * second mac | ||
59 | */ | ||
60 | uint8_t mac2[6] GNUNET_PACKED; | ||
61 | |||
62 | /** | ||
63 | * third mac | ||
64 | */ | ||
65 | uint8_t mac3[6] GNUNET_PACKED; | ||
66 | |||
67 | /** | ||
68 | * Wlan flags2 | ||
69 | */ | ||
70 | uint8_t flags2[2] GNUNET_PACKED; | ||
71 | }; | ||
72 | |||
73 | /* this is the template radiotap header we send packets out with */ | ||
74 | |||
75 | static const uint8_t u8aRadiotapHeader[] = { | ||
76 | |||
77 | 0x00, 0x00, // <-- radiotap version | ||
78 | 0x19, 0x00, // <- radiotap header length | ||
79 | 0x6f, 0x08, 0x00, 0x00, // <-- bitmap | ||
80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp | ||
81 | 0x00, // <-- flags (Offset +0x10) | ||
82 | 0x6c, // <-- rate (0ffset +0x11) | ||
83 | 0x71, 0x09, 0xc0, 0x00, // <-- channel | ||
84 | 0xde, // <-- antsignal | ||
85 | 0x00, // <-- antnoise | ||
86 | 0x01, // <-- antenna | ||
87 | |||
88 | }; | ||
89 | |||
90 | /** | ||
91 | * Radiotap Header | ||
92 | */ | ||
93 | |||
94 | struct RadiotapHeader | ||
95 | { | ||
96 | /** | ||
97 | * radiotap version | ||
98 | */ | ||
99 | uint8_t version[2] GNUNET_PACKED; | ||
100 | |||
101 | /** | ||
102 | * radiotap header length | ||
103 | */ | ||
104 | uint8_t lenght[2] GNUNET_PACKED; | ||
105 | |||
106 | /** | ||
107 | * bitmap | ||
108 | */ | ||
109 | uint8_t bitmap[4] GNUNET_PACKED; | ||
110 | |||
111 | /** | ||
112 | * timestamp | ||
113 | */ | ||
114 | uint8_t timestamp[8] GNUNET_PACKED; | ||
115 | |||
116 | /** | ||
117 | * radiotap flags | ||
118 | */ | ||
119 | uint8_t flags GNUNET_PACKED; | ||
120 | |||
121 | /** | ||
122 | * wlan send rate | ||
123 | */ | ||
124 | uint8_t rate GNUNET_PACKED; | ||
125 | |||
126 | /** | ||
127 | * Wlan channel | ||
128 | */ | ||
129 | uint8_t channel[4] GNUNET_PACKED; | ||
130 | |||
131 | /** | ||
132 | * antsignal | ||
133 | */ | ||
134 | uint8_t antsignal GNUNET_PACKED; | ||
135 | |||
136 | /** | ||
137 | * antnoise | ||
138 | */ | ||
139 | uint8_t antnoise GNUNET_PACKED; | ||
140 | |||
141 | /** | ||
142 | * antenna | ||
143 | */ | ||
144 | uint8_t antenna GNUNET_PACKED; | ||
145 | }; | ||
146 | |||