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_connection_lib.h"
30 #include "gnunet_server_lib.h"
31 #include "gnunet_service_lib.h"
32 #include "gnunet_statistics_service.h"
33 #include "gnunet_transport_service.h"
34 #include "plugin_transport.h"
36 #define PROTOCOL_PREFIX "wlan"
38 #define DEBUG_wlan GNUNET_NO
41 wlan_plugin_helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
44 * After how long do we expire an address that we
45 * learned from another peer if it is not reconfirmed
48 #define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
52 * Encapsulation of all of the state of the plugin.
58 * Session handle for connections.
64 * Stored in a linked list.
69 * Pointer to the global plugin struct.
71 struct Plugin *plugin;
74 * The client (used to identify this connection)
79 * Continuation function to call once the transmission buffer
80 * has again space available. NULL if there is no
81 * continuation to call.
83 GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
86 * Closure for transmit_cont.
88 void *transmit_cont_cls;
91 * To whom are we talking to (set to our identity
92 * if we are still waiting for the welcome message)
94 struct GNUNET_PeerIdentity sender;
97 * At what time did we reset last_received last?
99 struct GNUNET_TIME_Absolute last_quota_update;
102 * How many bytes have we received since the "last_quota_update"
105 uint64_t last_received;
108 * Number of bytes per ms that this peer is allowed
116 * Encapsulation of all of the state of the plugin.
123 struct GNUNET_TRANSPORT_PluginEnvironment *env;
126 * List of open sessions.
129 struct Session *sessions;
132 * encapsulation to the local wlan server prog
135 struct GNUNET_SERVER_MessageStreamTokenizer * consoltoken;
138 * encapsulation of the data
141 struct GNUNET_SERVER_MessageStreamTokenizer * datatoken;
144 * stdout pipe handle for the gnunet-wlan-helper process
146 struct GNUNET_DISK_PipeHandle *server_stdout;
149 * stdout file handle for the gnunet-wlan-helper process
151 const struct GNUNET_DISK_FileHandle *server_stdout_handle;
154 * stdin pipe handle for the gnunet-wlan-helper process
156 struct GNUNET_DISK_PipeHandle *server_stdin;
159 * stdin file handle for the gnunet-wlan-helper process
161 const struct GNUNET_DISK_FileHandle *server_stdin_handle;
164 * ID of select gnunet-nat-server std read task
166 GNUNET_SCHEDULER_TaskIdentifier server_read_task;
169 * The process id of the server process (if behind NAT)
174 * The interface of the wlan card given to us by the user.
179 * The mac_address of the wlan card given to us by the helper.
185 struct Plugin* plugin;
188 * Function that can be used by the transport service to transmit
189 * a message using the plugin.
192 * @param target who should receive this message
193 * @param priority how important is the message
194 * @param msgbuf the message to transmit
195 * @param msgbuf_size number of bytes in 'msgbuf'
196 * @param timeout when should we time out
197 * @param session which session must be used (or NULL for "any")
198 * @param addr the address to use (can be NULL if the plugin
199 * is "on its own" (i.e. re-use existing TCP connection))
200 * @param addrlen length of the address in bytes
201 * @param force_address GNUNET_YES if the plugin MUST use the given address,
202 * otherwise the plugin may use other addresses or
203 * existing connections (if available)
204 * @param cont continuation to call once the message has
205 * been transmitted (or if the transport is ready
206 * for the next transmission call; or if the
207 * peer disconnected...)
208 * @param cont_cls closure for cont
209 * @return number of bytes used (on the physical network, with overheads);
210 * -1 on hard errors (i.e. address invalid); 0 is a legal value
211 * and does NOT mean that the message was not transmitted (DV)
214 wlan_plugin_send (void *cls,
215 const struct GNUNET_PeerIdentity *
219 unsigned int priority,
220 struct GNUNET_TIME_Relative timeout,
221 struct Session *session,
225 GNUNET_TRANSPORT_TransmitContinuation
226 cont, void *cont_cls)
229 /* struct Plugin *plugin = cls; */
236 * Function that can be used to force the plugin to disconnect
237 * from the given peer and cancel all previous transmissions
238 * (and their continuationc).
241 * @param target peer from which to disconnect
244 wlan_plugin_disconnect (void *cls,
245 const struct GNUNET_PeerIdentity *target)
247 // struct Plugin *plugin = cls;
253 * Convert the transports address to a nice, human-readable
257 * @param type name of the transport that generated the address
258 * @param addr one of the addresses of the host, NULL for the last address
259 * the specific address format depends on the transport
260 * @param addrlen length of the address
261 * @param numeric should (IP) addresses be displayed in numeric form?
262 * @param timeout after how long should we give up?
263 * @param asc function to call on each string
264 * @param asc_cls closure for asc
267 wlan_plugin_address_pretty_printer (void *cls,
272 struct GNUNET_TIME_Relative timeout,
273 GNUNET_TRANSPORT_AddressStringCallback
280 GNUNET_assert(cls !=NULL);
281 //Mac Adress has 6 bytes
284 res = GNUNET_asprintf(&ret,"%s Mac-Adress %X:%X:%X:%X:%X:%X", PROTOCOL_PREFIX, input[0], input[1],input[2],input[3],input[4],input[5]);
286 GNUNET_assert(res != 0);
288 GNUNET_free_non_null (ret);
291 /* invalid address */
301 * Another peer has suggested an address for this
302 * peer and transport plugin. Check that this could be a valid
303 * address. If so, consider adding it to the list
307 * @param addr pointer to the address
308 * @param addrlen length of addr
309 * @return GNUNET_OK if this is a plausible address for this peer
313 wlan_plugin_address_suggested (void *cls,
317 /* struct Plugin *plugin = cls; */
319 /* check if the address is plausible; if so,
320 add it to our list! */
322 GNUNET_assert(cls !=NULL);
324 //Mac Adress has 6 bytes
326 /* TODO check for bad addresses like milticast, broadcast, etc */
329 return GNUNET_SYSERR;
336 * Function called for a quick conversion of the binary address to
337 * a numeric address. Note that the caller must not free the
338 * address and that the next call to this function is allowed
339 * to override the address again.
342 * @param addr binary address
343 * @param addrlen length of the address
344 * @return string representing the same address
347 wlan_plugin_address_to_string (void *cls,
355 GNUNET_assert(cls !=NULL);
356 //Mac Adress has 6 bytes
359 res = GNUNET_asprintf(&ret,"%X:%X:%X:%X:%X:%X", input[0], input[1],input[2],input[3],input[4],input[5]);
361 GNUNET_assert(res != 0);
365 /* invalid address */
373 * Function for used to process the data from the suid process
376 wlan_process_helper (void *cls,
377 void *client_identity,
378 struct GNUNET_MessageHeader *hdr)
380 if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA){
382 } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_ADVERTISEMENT){
384 } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL){
387 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying transport of address %s\n", wlan_plugin_address_to_string(cls, plugin->mac_address, hdr->size));
388 plugin->env->notify_address (plugin->env->cls,
390 &plugin->mac_address, sizeof(plugin->mac_address), GNUNET_TIME_UNIT_FOREVER_REL);
392 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Wrong wlan mac address %s\n", plugin->mac_address);
404 * Start the gnunet-wlan-helper process for users behind NAT.
406 * @param plugin the transport plugin
408 * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
412 wlan_transport_start_wlan_helper(struct Plugin *plugin)
415 plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES);
416 if (plugin->server_stdout == NULL)
417 return GNUNET_SYSERR;
419 plugin->server_stdin = GNUNET_DISK_pipe(GNUNET_YES);
420 if (plugin->server_stdin == NULL)
421 return GNUNET_SYSERR;
424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
425 "Starting gnunet-wlan-helper process cmd: %s %s\n", "gnunet-wlan-helper", plugin->interface);
427 /* Start the server process */
428 plugin->server_pid = GNUNET_OS_start_process(plugin->server_stdin, plugin->server_stdout, "gnunet-transport-wlan-helper", "gnunet-transport-wlan-helper", plugin->interface, NULL);
429 if (plugin->server_pid == GNUNET_SYSERR)
432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
433 "Failed to start gnunet-wlan-helper process\n");
435 return GNUNET_SYSERR;
437 /* Close the write end of the read pipe */
438 GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
440 /* Close the read end of the write pipe */
441 GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ);
443 plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ);
444 plugin->server_stdin_handle = GNUNET_DISK_pipe_handle(plugin->server_stdin, GNUNET_DISK_PIPE_END_WRITE);
446 plugin->server_read_task =
447 GNUNET_SCHEDULER_add_read_file (plugin->env->sched,
448 GNUNET_TIME_UNIT_FOREVER_REL,
449 plugin->server_stdout_handle, &wlan_plugin_helper_read, plugin);
457 wlan_plugin_helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
459 struct Plugin *plugin = cls;
460 char mybuf[3000]; //max size of packet from helper
462 //memset(&mybuf, 0, sizeof(mybuf)); //?
466 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
469 bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, &mybuf, sizeof(mybuf));
474 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
475 _("Finished reading from wlan-helper stdout with code: %d\n"), bytes);
480 plugin->server_read_task =
481 GNUNET_SCHEDULER_add_read_file (plugin->env->sched,
482 GNUNET_TIME_UNIT_FOREVER_REL,
483 plugin->server_stdout_handle, &wlan_plugin_helper_read, plugin);
489 * Entry point for the plugin.
492 gnunet_plugin_transport_wlan_init (void *cls)
494 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
495 struct GNUNET_TRANSPORT_PluginFunctions *api;
496 struct Plugin *plugin;
498 GNUNET_assert(cls !=NULL);
500 plugin = GNUNET_malloc (sizeof (struct Plugin));
504 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
506 api->send = &wlan_plugin_send;
507 api->disconnect = &wlan_plugin_disconnect;
508 api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
509 api->check_address = &wlan_plugin_address_suggested;
510 api->address_to_string = &wlan_plugin_address_to_string;
517 * Exit point from the plugin.
520 gnunet_plugin_transport_wlan_done (void *cls)
522 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
523 struct Plugin *plugin = api->cls;
525 GNUNET_assert(cls !=NULL);
527 GNUNET_free (plugin);
532 /* end of plugin_transport_wlan.c */