2 This file is part of GNUnet
3 (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @file transport/plugin_transport_wlan.c
23 * @brief template for a new transport service
24 * @author Christian Grothoff
28 #include "gnunet_protocols.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_statistics_service.h"
31 #include "gnunet_transport_service.h"
32 #include "plugin_transport.h"
34 #define PROTOCOL_PREFIX "wlan"
36 #define DEBUG_wlan GNUNET_NO
39 * After how long do we expire an address that we
40 * learned from another peer if it is not reconfirmed
43 #define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
47 * Encapsulation of all of the state of the plugin.
53 * Session handle for connections.
59 * Stored in a linked list.
64 * Pointer to the global plugin struct.
66 struct Plugin *plugin;
69 * The client (used to identify this connection)
74 * Continuation function to call once the transmission buffer
75 * has again space available. NULL if there is no
76 * continuation to call.
78 GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
81 * Closure for transmit_cont.
83 void *transmit_cont_cls;
86 * To whom are we talking to (set to our identity
87 * if we are still waiting for the welcome message)
89 struct GNUNET_PeerIdentity sender;
92 * At what time did we reset last_received last?
94 struct GNUNET_TIME_Absolute last_quota_update;
97 * How many bytes have we received since the "last_quota_update"
100 uint64_t last_received;
103 * Number of bytes per ms that this peer is allowed
111 * Encapsulation of all of the state of the plugin.
118 struct GNUNET_TRANSPORT_PluginEnvironment *env;
121 * List of open sessions.
124 struct Session *sessions;
127 * encapsulation to the local wlan server prog
130 struct GNUNET_SERVER_MessageStreamTokenizer * consoltoken;
133 * encapsulation of the data
136 struct GNUNET_SERVER_MessageStreamTokenizer * datatoken;
139 * stdout pipe handle for the gnunet-wlan-helper process
141 struct GNUNET_DISK_PipeHandle *server_stdout;
144 * stdout file handle for the gnunet-wlan-helper process
146 const struct GNUNET_DISK_FileHandle *server_stdout_handle;
149 * stdin pipe handle for the gnunet-wlan-helper process
151 struct GNUNET_DISK_PipeHandle *server_stdin;
154 * stdin file handle for the gnunet-wlan-helper process
156 const struct GNUNET_DISK_FileHandle *server_stdin_handle;
159 * ID of select gnunet-nat-server std read task
161 GNUNET_SCHEDULER_TaskIdentifier server_read_task;
164 * The process id of the server process (if behind NAT)
169 * The interface of the wlan card given to us by the user.
174 * The mac_address of the wlan card given to us by the helper.
180 struct Plugin* plugin;
183 * Function that can be used by the transport service to transmit
184 * a message using the plugin.
187 * @param target who should receive this message
188 * @param priority how important is the message
189 * @param msgbuf the message to transmit
190 * @param msgbuf_size number of bytes in 'msgbuf'
191 * @param timeout when should we time out
192 * @param session which session must be used (or NULL for "any")
193 * @param addr the address to use (can be NULL if the plugin
194 * is "on its own" (i.e. re-use existing TCP connection))
195 * @param addrlen length of the address in bytes
196 * @param force_address GNUNET_YES if the plugin MUST use the given address,
197 * otherwise the plugin may use other addresses or
198 * existing connections (if available)
199 * @param cont continuation to call once the message has
200 * been transmitted (or if the transport is ready
201 * for the next transmission call; or if the
202 * peer disconnected...)
203 * @param cont_cls closure for cont
204 * @return number of bytes used (on the physical network, with overheads);
205 * -1 on hard errors (i.e. address invalid); 0 is a legal value
206 * and does NOT mean that the message was not transmitted (DV)
209 wlan_plugin_send (void *cls,
210 const struct GNUNET_PeerIdentity *
214 unsigned int priority,
215 struct GNUNET_TIME_Relative timeout,
216 struct Session *session,
220 GNUNET_TRANSPORT_TransmitContinuation
221 cont, void *cont_cls)
224 /* struct Plugin *plugin = cls; */
231 * Function that can be used to force the plugin to disconnect
232 * from the given peer and cancel all previous transmissions
233 * (and their continuationc).
236 * @param target peer from which to disconnect
239 wlan_plugin_disconnect (void *cls,
240 const struct GNUNET_PeerIdentity *target)
242 // struct Plugin *plugin = cls;
248 * Convert the transports address to a nice, human-readable
252 * @param type name of the transport that generated the address
253 * @param addr one of the addresses of the host, NULL for the last address
254 * the specific address format depends on the transport
255 * @param addrlen length of the address
256 * @param numeric should (IP) addresses be displayed in numeric form?
257 * @param timeout after how long should we give up?
258 * @param asc function to call on each string
259 * @param asc_cls closure for asc
262 wlan_plugin_address_pretty_printer (void *cls,
267 struct GNUNET_TIME_Relative timeout,
268 GNUNET_TRANSPORT_AddressStringCallback
272 const unsigned char * input;
274 GNUNET_assert(cls !=NULL);
277 /* invalid address (MAC addresses have 6 bytes) */
282 input = (const unsigned char*) addr;
283 GNUNET_snprintf (ret,
285 "%s Mac-Adress %X:%X:%X:%X:%X:%X",
287 input[0], input[1], input[2], input[3], input[4], input[5]);
294 * Another peer has suggested an address for this
295 * peer and transport plugin. Check that this could be a valid
296 * address. If so, consider adding it to the list
300 * @param addr pointer to the address
301 * @param addrlen length of addr
302 * @return GNUNET_OK if this is a plausible address for this peer
306 wlan_plugin_address_suggested (void *cls,
310 /* struct Plugin *plugin = cls; */
312 /* check if the address is plausible; if so,
313 add it to our list! */
315 GNUNET_assert(cls !=NULL);
317 //Mac Adress has 6 bytes
319 /* TODO check for bad addresses like milticast, broadcast, etc */
322 return GNUNET_SYSERR;
329 * Function called for a quick conversion of the binary address to
330 * a numeric address. Note that the caller must not free the
331 * address and that the next call to this function is allowed
332 * to override the address again.
335 * @param addr binary address
336 * @param addrlen length of the address
337 * @return string representing the same address
340 wlan_plugin_address_to_string (void *cls,
345 const unsigned char * input;
347 GNUNET_assert(cls !=NULL);
350 /* invalid address (MAC addresses have 6 bytes) */
354 input = (const unsigned char*) addr;
355 GNUNET_snprintf (ret,
357 "%s Mac-Adress %X:%X:%X:%X:%X:%X",
359 input[0], input[1], input[2], input[3], input[4], input[5]);
360 return GNUNET_strdup (ret);
366 * Function for used to process the data from the suid process
369 wlan_process_helper (void *cls,
370 void *client_identity,
371 struct GNUNET_MessageHeader *hdr)
373 if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA){
375 } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_ADVERTISEMENT){
377 } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL){
380 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,
383 &plugin->mac_address, sizeof(plugin->mac_address), GNUNET_TIME_UNIT_FOREVER_REL);
385 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Wrong wlan mac address %s\n", plugin->mac_address);
396 wlan_plugin_helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
398 struct Plugin *plugin = cls;
399 char mybuf[3000]; //max size of packet from helper
401 //memset(&mybuf, 0, sizeof(mybuf)); //?
403 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
406 bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, &mybuf, sizeof(mybuf));
411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
412 _("Finished reading from wlan-helper stdout with code: %d\n"), bytes);
417 plugin->server_read_task =
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);
426 * Start the gnunet-wlan-helper process for users behind NAT.
428 * @param plugin the transport plugin
430 * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
433 wlan_transport_start_wlan_helper(struct Plugin *plugin)
436 plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES);
437 if (plugin->server_stdout == NULL)
438 return GNUNET_SYSERR;
440 plugin->server_stdin = GNUNET_DISK_pipe(GNUNET_YES);
441 if (plugin->server_stdin == NULL)
442 return GNUNET_SYSERR;
445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
446 "Starting gnunet-wlan-helper process cmd: %s %s\n", "gnunet-wlan-helper", plugin->interface);
448 /* Start the server process */
449 plugin->server_pid = GNUNET_OS_start_process(plugin->server_stdin, plugin->server_stdout, "gnunet-transport-wlan-helper", "gnunet-transport-wlan-helper", plugin->interface, NULL);
450 if (plugin->server_pid == GNUNET_SYSERR)
453 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
454 "Failed to start gnunet-wlan-helper process\n");
456 return GNUNET_SYSERR;
458 /* Close the write end of the read pipe */
459 GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
461 /* Close the read end of the write pipe */
462 GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ);
464 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);
467 plugin->server_read_task =
468 GNUNET_SCHEDULER_add_read_file (plugin->env->sched,
469 GNUNET_TIME_UNIT_FOREVER_REL,
470 plugin->server_stdout_handle, &wlan_plugin_helper_read, plugin);
480 * Entry point for the plugin.
483 gnunet_plugin_transport_wlan_init (void *cls)
485 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
486 struct GNUNET_TRANSPORT_PluginFunctions *api;
487 struct Plugin *plugin;
489 GNUNET_assert(cls !=NULL);
491 plugin = GNUNET_malloc (sizeof (struct Plugin));
495 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
497 api->send = &wlan_plugin_send;
498 api->disconnect = &wlan_plugin_disconnect;
499 api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
500 api->check_address = &wlan_plugin_address_suggested;
501 api->address_to_string = &wlan_plugin_address_to_string;
508 * Exit point from the plugin.
511 gnunet_plugin_transport_wlan_done (void *cls)
513 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
514 struct Plugin *plugin = api->cls;
516 GNUNET_assert(cls !=NULL);
518 GNUNET_free (plugin);
523 /* end of plugin_transport_wlan.c */