- remove unnecessary code
[oweals/gnunet.git] / src / mesh / mesh2_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 2011 Christian Grothoff (and other contributing authors)
4      GNUnet is free software; you can redistribute it and/or modify
5      it under the terms of the GNU General Public License as published
6      by the Free Software Foundation; either version 3, or (at your
7      option) any later version.
8      GNUnet is distributed in the hope that it will be useful, but
9      WITHOUT ANY WARRANTY; without even the implied warranty of
10      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11      General Public License for more details.
12      You should have received a copy of the GNU General Public License
13      along with GNUnet; see the file COPYING.  If not, write to the
14      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
15      Boston, MA 02111-1307, USA.
16 */
17
18 /**
19  * @file mesh/mesh2_api.c
20  * @brief mesh2 api: client implementation of new mesh service
21  * @author Bartlomiej Polot
22  *
23  * STRUCTURE:
24  * - DATA STRUCTURES
25  * - DECLARATIONS
26  * - AUXILIARY FUNCTIONS
27  * - RECEIVE HANDLERS
28  * - SEND FUNCTIONS
29  * - API CALL DEFINITIONS
30  *
31  * TODO: add regex to reconnect
32  */
33 #include "platform.h"
34 #include "gnunet_common.h"
35 #include "gnunet_client_lib.h"
36 #include "gnunet_util_lib.h"
37 #include "gnunet_peer_lib.h"
38 #include "gnunet_mesh2_service.h"
39 #include "mesh.h"
40 #include "mesh_protocol.h"
41
42 #define LOG(kind,...) GNUNET_log_from (kind, "mesh2-api",__VA_ARGS__)
43
44 #define DEBUG_ACK GNUNET_YES
45
46 /******************************************************************************/
47 /************************      DATA STRUCTURES     ****************************/
48 /******************************************************************************/
49
50 /**
51  * Transmission queue to the service
52  */
53 struct GNUNET_MESH_TransmitHandle
54 {
55
56     /**
57      * Double Linked list
58      */
59   struct GNUNET_MESH_TransmitHandle *next;
60
61     /**
62      * Double Linked list
63      */
64   struct GNUNET_MESH_TransmitHandle *prev;
65
66     /**
67      * Tunnel this message is sent on / for (may be NULL for control messages).
68      */
69   struct GNUNET_MESH_Tunnel *tunnel;
70
71     /**
72      * Callback to obtain the message to transmit, or NULL if we
73      * got the message in 'data'.  Notice that messages built
74      * by 'notify' need to be encapsulated with information about
75      * the 'target'.
76      */
77   GNUNET_CONNECTION_TransmitReadyNotify notify;
78
79     /**
80      * Closure for 'notify'
81      */
82   void *notify_cls;
83
84     /**
85      * How long is this message valid.  Once the timeout has been
86      * reached, the message must no longer be sent.  If this
87      * is a message with a 'notify' callback set, the 'notify'
88      * function should be called with 'buf' NULL and size 0.
89      */
90   struct GNUNET_TIME_Absolute timeout;
91
92     /**
93      * Task triggering a timeout, can be NO_TASK if the timeout is FOREVER.
94      */
95   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
96
97     /**
98      * Size of 'data' -- or the desired size of 'notify' if 'data' is NULL.
99      */
100   size_t size;
101 };
102
103
104 /**
105  * Opaque handle to the service.
106  */
107 struct GNUNET_MESH_Handle
108 {
109
110     /**
111      * Handle to the server connection, to send messages later
112      */
113   struct GNUNET_CLIENT_Connection *client;
114
115     /**
116      * Set of handlers used for processing incoming messages in the tunnels
117      */
118   const struct GNUNET_MESH_MessageHandler *message_handlers;
119
120     /**
121      * Double linked list of the tunnels this client is connected to, head.
122      */
123   struct GNUNET_MESH_Tunnel *tunnels_head;
124
125     /**
126      * Double linked list of the tunnels this client is connected to, tail.
127      */
128   struct GNUNET_MESH_Tunnel *tunnels_tail;
129
130     /**
131      * Callback for inbound tunnel creation
132      */
133   GNUNET_MESH_InboundTunnelNotificationHandler *new_tunnel;
134
135     /**
136      * Callback for inbound tunnel disconnection
137      */
138   GNUNET_MESH_TunnelEndHandler *cleaner;
139
140     /**
141      * Handle to cancel pending transmissions in case of disconnection
142      */
143   struct GNUNET_CLIENT_TransmitHandle *th;
144
145     /**
146      * Closure for all the handlers given by the client
147      */
148   void *cls;
149
150     /**
151      * Messages to send to the service, head.
152      */
153   struct GNUNET_MESH_TransmitHandle *th_head;
154
155     /**
156      * Messages to send to the service, tail.
157      */
158   struct GNUNET_MESH_TransmitHandle *th_tail;
159
160     /**
161      * tid of the next tunnel to create (to avoid reusing IDs often)
162      */
163   MESH_TunnelNumber next_tid;
164
165     /**
166      * Number of handlers in the handlers array.
167      */
168   unsigned int n_handlers;
169
170     /**
171      * Number of applications in the applications array.
172      */
173   unsigned int n_applications;
174
175     /**
176      * Have we started the task to receive messages from the service
177      * yet? We do this after we send the 'MESH_LOCAL_CONNECT' message.
178      */
179   int in_receive;
180
181   /**
182    * Configuration given by the client, in case of reconnection
183    */
184   const struct GNUNET_CONFIGURATION_Handle *cfg;
185
186   /**
187    * Time to the next reconnect in case one reconnect fails
188    */
189   struct GNUNET_TIME_Relative reconnect_time;
190   
191   /**
192    * Task for trying to reconnect.
193    */
194   GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
195
196   /**
197    * Monitor callback
198    */
199   GNUNET_MESH_TunnelsCB tunnels_cb;
200
201   /**
202    * Monitor callback closure.
203    */
204   void *tunnels_cls;
205
206   /**
207    * Tunnel callback.
208    */
209   GNUNET_MESH_TunnelCB tunnel_cb;
210
211   /**
212    * Tunnel callback closure.
213    */
214   void *tunnel_cls;
215
216   /**
217    * All the peer in the tunnel so far.
218    */
219   struct GNUNET_PeerIdentity *peers;
220
221   /**
222    * How many peers we have in this tunnel so far.
223    */
224   unsigned int tunnel_npeers;
225
226 #if DEBUG_ACK
227   unsigned int acks_sent;
228   unsigned int acks_recv;
229 #endif
230 };
231
232
233 /**
234  * Description of a peer
235  */
236 struct GNUNET_MESH_Peer
237 {
238     /**
239      * ID of the peer in short form
240      */
241   GNUNET_PEER_Id id;
242
243   /**
244    * Tunnel this peer belongs to
245    */
246   struct GNUNET_MESH_Tunnel *t;
247
248   /**
249    * Flag indicating whether service has informed about its connection
250    */
251   int connected;
252
253 };
254
255
256 /**
257  * Opaque handle to a tunnel.
258  */
259 struct GNUNET_MESH_Tunnel
260 {
261
262     /**
263      * DLL next
264      */
265   struct GNUNET_MESH_Tunnel *next;
266
267     /**
268      * DLL prev
269      */
270   struct GNUNET_MESH_Tunnel *prev;
271
272     /**
273      * Handle to the mesh this tunnel belongs to
274      */
275   struct GNUNET_MESH_Handle *mesh;
276
277     /**
278      * Local ID of the tunnel
279      */
280   MESH_TunnelNumber tid;
281
282     /**
283      * Owner of the tunnel. (1 if the tunnel is a local client).
284      */
285   GNUNET_PEER_Id owner;
286
287     /**
288      * Destination of the tunnel.
289      */
290   GNUNET_PEER_Id destination;
291
292     /**
293      * Next hop for the tunnel.
294      */
295   GNUNET_PEER_Id next_hop;
296
297     /**
298      * Previous hop for the tunnel.
299      */
300   GNUNET_PEER_Id prev_hop;
301
302   /**
303    * Any data the caller wants to put in here
304    */
305   void *ctx;
306
307     /**
308      * Size of packet queued in this tunnel
309      */
310   unsigned int packet_size;
311
312     /**
313      * Number of applications requested this tunnel
314      */
315   unsigned int napps;
316
317     /**
318      * Is the tunnel throttled to the slowest peer?
319      */
320   int speed_min;
321
322     /**
323      * Is the tunnel allowed to buffer?
324      */
325   int buffering;
326
327     /**
328      * Next packet ID to send.
329      */
330   uint32_t next_send_pid;
331
332     /**
333      * Maximum allowed PID to send (ACK recevied).
334      */
335   uint32_t max_send_pid;
336
337     /**
338      * Last pid received from the service.
339      */
340   uint32_t last_recv_pid;
341
342   /**
343    * Which ACK value have we last sent to the service?
344    */
345   uint32_t max_recv_pid;
346 };
347
348
349 /******************************************************************************/
350 /***********************         DECLARATIONS         *************************/
351 /******************************************************************************/
352
353 /**
354  * Function called to send a message to the service.
355  * "buf" will be NULL and "size" zero if the socket was closed for writing in
356  * the meantime.
357  *
358  * @param cls closure, the mesh handle
359  * @param size number of bytes available in buf
360  * @param buf where the callee should write the connect message
361  * @return number of bytes written to buf
362  */
363 static size_t
364 send_callback (void *cls, size_t size, void *buf);
365
366
367 /******************************************************************************/
368 /***********************     AUXILIARY FUNCTIONS      *************************/
369 /******************************************************************************/
370
371 /**
372  * Check if transmission is a payload packet.
373  *
374  * @param th Transmission handle.
375  *
376  * @return GNUNET_YES if it is a payload packet,
377  *         GNUNET_NO if it is a mesh management packet.
378  */
379 static int
380 th_is_payload (struct GNUNET_MESH_TransmitHandle *th)
381 {
382   return (th->notify != NULL) ? GNUNET_YES : GNUNET_NO;
383 }
384
385
386 /**
387  * Check whether there is any message ready in the queue and find the size.
388  * 
389  * @param h Mesh handle.
390  * 
391  * @return The size of the first ready message in the queue,
392  *         0 if there is none.
393  */
394 static size_t
395 message_ready_size (struct GNUNET_MESH_Handle *h)
396 {
397   struct GNUNET_MESH_TransmitHandle *th;
398   struct GNUNET_MESH_Tunnel *t;
399
400   for (th = h->th_head; NULL != th; th = th->next)
401   {
402     t = th->tunnel;
403     if (GNUNET_NO == th_is_payload (th))
404     {
405       LOG (GNUNET_ERROR_TYPE_DEBUG, "  message internal\n");
406       return th->size;
407     }
408     if (GNUNET_NO == GMC_is_pid_bigger(t->next_send_pid, t->max_send_pid))
409     {
410       LOG (GNUNET_ERROR_TYPE_DEBUG, "  message payload ok (%u <= %u)\n",
411            t->next_send_pid, t->max_send_pid);
412       return th->size;
413     }
414   }
415   return 0;
416 }
417
418
419 /**
420  * Get the tunnel handler for the tunnel specified by id from the given handle
421  * @param h Mesh handle
422  * @param tid ID of the wanted tunnel
423  * @return handle to the required tunnel or NULL if not found
424  */
425 static struct GNUNET_MESH_Tunnel *
426 retrieve_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelNumber tid)
427 {
428   struct GNUNET_MESH_Tunnel *t;
429
430   t = h->tunnels_head;
431   while (t != NULL)
432   {
433     if (t->tid == tid)
434       return t;
435     t = t->next;
436   }
437   return NULL;
438 }
439
440
441 /**
442  * Create a new tunnel and insert it in the tunnel list of the mesh handle
443  * @param h Mesh handle
444  * @param tid desired tid of the tunnel, 0 to assign one automatically
445  * @return handle to the created tunnel
446  */
447 static struct GNUNET_MESH_Tunnel *
448 create_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelNumber tid)
449 {
450   struct GNUNET_MESH_Tunnel *t;
451
452   t = GNUNET_malloc (sizeof (struct GNUNET_MESH_Tunnel));
453   GNUNET_CONTAINER_DLL_insert (h->tunnels_head, h->tunnels_tail, t);
454   t->mesh = h;
455   if (0 == tid)
456   {
457     t->tid = h->next_tid;
458     while (NULL != retrieve_tunnel (h, h->next_tid))
459     {
460       h->next_tid++;
461       h->next_tid &= ~GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
462       h->next_tid |= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
463     }
464   }
465   else
466   {
467     t->tid = tid;
468   }
469   t->max_send_pid = INITIAL_WINDOW_SIZE - 1;
470   t->last_recv_pid = (uint32_t) -1;
471   t->buffering = GNUNET_YES;
472   return t;
473 }
474
475
476 /**
477  * Destroy the specified tunnel.
478  * - Destroys all peers, calling the disconnect callback on each if needed
479  * - Cancels all outgoing traffic for that tunnel, calling respective notifys
480  * - Calls cleaner if tunnel was inbound
481  * - Frees all memory used
482  *
483  * @param t Pointer to the tunnel.
484  * @param call_cleaner Whether to call the cleaner handler.
485  *
486  * @return Handle to the required tunnel or NULL if not found.
487  */
488 static void
489 destroy_tunnel (struct GNUNET_MESH_Tunnel *t, int call_cleaner)
490 {
491   struct GNUNET_MESH_Handle *h;
492   struct GNUNET_PeerIdentity pi;
493   struct GNUNET_MESH_TransmitHandle *th;
494   struct GNUNET_MESH_TransmitHandle *next;
495   unsigned int i;
496
497   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroy_tunnel %X\n", t->tid);
498
499   if (NULL == t)
500   {
501     GNUNET_break (0);
502     return;
503   }
504   h = t->mesh;
505
506   /* free all peer's ID */
507   GNUNET_CONTAINER_DLL_remove (h->tunnels_head, h->tunnels_tail, t);
508   GNUNET_PEER_change_rc (t->owner, -1);
509   GNUNET_PEER_change_rc (t->destination, -1);
510   GNUNET_PEER_change_rc (t->next_hop, -1);
511   GNUNET_PEER_change_rc (t->prev_hop, -1);
512
513   /* signal tunnel destruction */
514   if ( (NULL != h->cleaner) && (0 != t->owner) && (GNUNET_YES == call_cleaner) )
515     h->cleaner (h->cls, t, t->ctx);
516
517   /* check that clients did not leave messages behind in the queue */
518   for (th = h->th_head; NULL != th; th = next)
519   {
520     next = th->next;
521     if (th->tunnel != t)
522       continue;
523     /* Clients should have aborted their requests already.
524      * Management traffic should be ok, as clients can't cancel that */
525     GNUNET_break (GNUNET_NO == th_is_payload(th));
526     GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
527
528     /* clean up request */
529     if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task)
530       GNUNET_SCHEDULER_cancel (th->timeout_task);
531     GNUNET_free (th);    
532   }
533
534   /* if there are no more pending requests with mesh service, cancel active request */
535   /* Note: this should be unnecessary... */
536   if ((0 == message_ready_size (h)) && (NULL != h->th))
537   {
538     GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
539     h->th = NULL;
540   }
541
542
543   if (t->npeers > 0)
544     GNUNET_free (t->peers);
545   if (0 != t->owner)
546     GNUNET_PEER_change_rc (t->owner, -1);
547   if (0 != t->napps && t->apps)
548     GNUNET_free (t->apps);
549   GNUNET_free (t);
550   return;
551 }
552
553
554 /**
555  * Get the peer descriptor for the peer with id from the given tunnel
556  * @param t Tunnel handle
557  * @param id Short form ID of the wanted peer
558  * @return handle to the requested peer or NULL if not found
559  */
560 static struct GNUNET_MESH_Peer *
561 retrieve_peer (struct GNUNET_MESH_Tunnel *t, GNUNET_PEER_Id id)
562 {
563   unsigned int i;
564
565   for (i = 0; i < t->npeers; i++)
566     if (t->peers[i]->id == id)
567       return t->peers[i];
568   return NULL;
569 }
570
571
572 /**
573  * Add a peer into a tunnel
574  * @param t Tunnel handle
575  * @param pi Full ID of the new peer
576  * @return handle to the newly created peer
577  */
578 static struct GNUNET_MESH_Peer *
579 add_peer_to_tunnel (struct GNUNET_MESH_Tunnel *t,
580                     const struct GNUNET_PeerIdentity *pi)
581 {
582   struct GNUNET_MESH_Peer *p;
583   GNUNET_PEER_Id id;
584
585   if (0 != t->owner)
586   {
587     GNUNET_break (0);
588     return NULL;
589   }
590   id = GNUNET_PEER_intern (pi);
591
592   p = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer));
593   p->id = id;
594   p->t = t;
595   GNUNET_array_append (t->peers, t->npeers, p);
596   return p;
597 }
598
599
600 /**
601  * Remove a peer from a tunnel
602  * @param p Peer handle
603  */
604 static void
605 remove_peer_from_tunnel (struct GNUNET_MESH_Peer *p)
606 {
607   unsigned int i;
608
609   for (i = 0; i < p->t->npeers; i++)
610   {
611     if (p->t->peers[i] == p)
612       break;
613   }
614   if (i == p->t->npeers)
615   {
616     GNUNET_break (0);
617     return;
618   }
619   p->t->peers[i] = p->t->peers[p->t->npeers - 1];
620   GNUNET_array_grow (p->t->peers, p->t->npeers, p->t->npeers - 1);
621 }
622
623
624 /**
625  * Notify client that the transmission has timed out
626  * 
627  * @param cls closure
628  * @param tc task context
629  */
630 static void
631 timeout_transmission (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
632 {
633   struct GNUNET_MESH_TransmitHandle *th = cls;
634   struct GNUNET_MESH_Handle *mesh;
635
636   mesh = th->tunnel->mesh;
637   GNUNET_CONTAINER_DLL_remove (mesh->th_head, mesh->th_tail, th);
638   th->tunnel->packet_size = 0;
639   if (GNUNET_YES == th_is_payload (th))
640     th->notify (th->notify_cls, 0, NULL);
641   GNUNET_free (th);
642   if ((0 == message_ready_size (mesh)) && (NULL != mesh->th))
643   {
644     /* nothing ready to transmit, no point in asking for transmission */
645     GNUNET_CLIENT_notify_transmit_ready_cancel (mesh->th);
646     mesh->th = NULL;
647   }
648 }
649
650
651 /**
652  * Add a transmit handle to the transmission queue and set the
653  * timeout if needed.
654  *
655  * @param h mesh handle with the queue head and tail
656  * @param th handle to the packet to be transmitted
657  */
658 static void
659 add_to_queue (struct GNUNET_MESH_Handle *h,
660               struct GNUNET_MESH_TransmitHandle *th)
661 {
662   GNUNET_CONTAINER_DLL_insert_tail (h->th_head, h->th_tail, th);
663   if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value == th->timeout.abs_value)
664     return;
665   th->timeout_task =
666       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
667                                     (th->timeout), &timeout_transmission, th);
668 }
669
670
671 /**
672  * Auxiliary function to send an already constructed packet to the service.
673  * Takes care of creating a new queue element, copying the message and
674  * calling the tmt_rdy function if necessary.
675  *
676  * @param h mesh handle
677  * @param msg message to transmit
678  * @param tunnel tunnel this send is related to (NULL if N/A)
679  */
680 static void
681 send_packet (struct GNUNET_MESH_Handle *h,
682              const struct GNUNET_MessageHeader *msg,
683              struct GNUNET_MESH_Tunnel *tunnel);
684
685
686 /**
687  * Send an ack on the tunnel to confirm the processing of a message.
688  * 
689  * @param h Mesh handle.
690  * @param t Tunnel on which to send the ACK.
691  */
692 static void
693 send_ack (struct GNUNET_MESH_Handle *h, struct GNUNET_MESH_Tunnel *t)
694 {
695   struct GNUNET_MESH_LocalAck msg;
696   uint32_t delta;
697
698   delta = t->max_recv_pid - t->last_recv_pid;
699   if (delta > ACK_THRESHOLD)
700   {
701     LOG (GNUNET_ERROR_TYPE_DEBUG,
702          "Not sending ACK on tunnel %X: ACK: %u, PID: %u, buffer %u\n",
703          t->tid, t->max_recv_pid, t->last_recv_pid, delta);
704     return;
705   }
706   if (GNUNET_YES == t->buffering)
707     t->max_recv_pid = t->last_recv_pid + INITIAL_WINDOW_SIZE;
708   else
709     t->max_recv_pid = t->last_recv_pid + 1;
710   LOG (GNUNET_ERROR_TYPE_DEBUG,
711        "Sending ACK on tunnel %X: %u\n",
712        t->tid, t->max_recv_pid);
713   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
714   msg.header.size = htons (sizeof (msg));
715   msg.tunnel_id = htonl (t->tid);
716   msg.max_pid = htonl (t->max_recv_pid);
717
718 #if DEBUG_ACK
719   t->mesh->acks_sent++;
720 #endif
721
722   send_packet (h, &msg.header, t);
723   return;
724 }
725
726
727
728 /**
729  * Reconnect callback: tries to reconnect again after a failer previous
730  * reconnecttion
731  * @param cls closure (mesh handle)
732  * @param tc task context
733  */
734 static void
735 reconnect_cbk (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
736
737
738 /**
739  * Send a connect packet to the service with the applications and types
740  * requested by the user.
741  *
742  * @param h The mesh handle.
743  *
744  */
745 static void
746 send_connect (struct GNUNET_MESH_Handle *h)
747 {
748   size_t size;
749
750   size = sizeof (struct GNUNET_MESH_ClientConnect);
751   size += h->n_handlers * sizeof (uint16_t);
752   {
753     char buf[size] GNUNET_ALIGN;
754     struct GNUNET_MESH_ClientConnect *msg;
755     uint16_t napps;
756     uint16_t *types;
757     uint16_t ntypes;
758
759     /* build connection packet */
760     msg = (struct GNUNET_MESH_ClientConnect *) buf;
761     msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT);
762     msg->header.size = htons (size);
763     types = (uint16_t *) & apps[napps];
764     for (ntypes = 0; ntypes < h->n_handlers; ntypes++)
765     {
766       types[ntypes] = htons (h->message_handlers[ntypes].type);
767       LOG (GNUNET_ERROR_TYPE_DEBUG, " type %u\n",
768            h->message_handlers[ntypes].type);
769     }
770     msg->applications = htons (napps);
771     msg->types = htons (ntypes);
772     LOG (GNUNET_ERROR_TYPE_DEBUG,
773          "Sending %lu bytes long message %d types and %d apps\n",
774          ntohs (msg->header.size), ntypes, napps);
775     send_packet (h, &msg->header, NULL);
776   }
777 }
778
779
780 /**
781  * Reconnect to the service, retransmit all infomation to try to restore the
782  * original state.
783  *
784  * @param h handle to the mesh
785  *
786  * @return GNUNET_YES in case of sucess, GNUNET_NO otherwise (service down...)
787  */
788 static int
789 do_reconnect (struct GNUNET_MESH_Handle *h)
790 {
791   struct GNUNET_MESH_Tunnel *t;
792   unsigned int i;
793
794   LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
795   LOG (GNUNET_ERROR_TYPE_DEBUG, "*******   RECONNECT   *******\n");
796   LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
797   LOG (GNUNET_ERROR_TYPE_DEBUG, "******** on %p *******\n", h);
798   LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
799
800   /* disconnect */
801   if (NULL != h->th)
802   {
803     GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
804     h->th = NULL;
805   }
806   if (NULL != h->client)
807   {
808     GNUNET_CLIENT_disconnect (h->client);
809   }
810
811   /* connect again */
812   h->client = GNUNET_CLIENT_connect ("mesh", h->cfg);
813   if (h->client == NULL)
814   {
815     h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
816                                                       &reconnect_cbk, h);
817     h->reconnect_time =
818         GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS,
819                                   GNUNET_TIME_relative_multiply
820                                   (h->reconnect_time, 2));
821     LOG (GNUNET_ERROR_TYPE_DEBUG, 
822          "Next retry in %s\n",
823          GNUNET_STRINGS_relative_time_to_string (h->reconnect_time,
824                                                  GNUNET_NO));
825     GNUNET_break (0);
826     return GNUNET_NO;
827   }
828   else
829   {
830     h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
831   }
832   send_connect (h);
833   /* Rebuild all tunnels */
834   for (t = h->tunnels_head; NULL != t; t = t->next)
835   {
836     struct GNUNET_MESH_TunnelMessage tmsg;
837     struct GNUNET_MESH_PeerControl pmsg;
838
839     if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
840     {
841       /* Tunnel was created by service (incoming tunnel) */
842       /* TODO: Notify service of missing tunnel, to request
843        * creator to recreate path (find a path to him via DHT?)
844        */
845       continue;
846     }
847     t->next_send_pid = 0;
848     t->max_send_pid = INITIAL_WINDOW_SIZE - 1;
849     t->last_recv_pid = (uint32_t) -1;
850     tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
851     tmsg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
852     tmsg.tunnel_id = htonl (t->tid);
853     send_packet (h, &tmsg.header, t);
854
855     pmsg.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
856     pmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
857     pmsg.tunnel_id = htonl (t->tid);
858
859     /* Reconnect all peers */
860     /* If the tunnel was "by type", dont connect individual peers */
861     for (i = 0; i < t->npeers && 0 == t->napps; i++)
862     {
863       GNUNET_PEER_resolve (t->peers[i]->id, &pmsg.peer);
864       if (NULL != t->disconnect_handler && t->peers[i]->connected)
865         t->disconnect_handler (t->cls, &pmsg.peer);
866       send_packet (t->mesh, &pmsg.header, t);
867     }
868     /* Reconnect all types, if any  */
869     for (i = 0; i < t->napps; i++)
870     {
871       struct GNUNET_MESH_ConnectPeerByType msg;
872
873       msg.header.size = htons (sizeof (struct GNUNET_MESH_ConnectPeerByType));
874       msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE);
875       msg.tunnel_id = htonl (t->tid);
876       msg.type = htonl (t->apps[i]);
877       send_packet (t->mesh, &msg.header, t);
878     }
879     if (GNUNET_NO == t->buffering)
880       GNUNET_MESH_tunnel_buffer (t, GNUNET_NO);
881     if (GNUNET_YES == t->speed_min)
882       GNUNET_MESH_tunnel_speed_min (t);
883   }
884   return GNUNET_YES;
885 }
886
887 /**
888  * Reconnect callback: tries to reconnect again after a failer previous
889  * reconnecttion
890  * @param cls closure (mesh handle)
891  * @param tc task context
892  */
893 static void
894 reconnect_cbk (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
895 {
896   struct GNUNET_MESH_Handle *h = cls;
897
898   h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
899   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
900     return;
901   do_reconnect (h);
902 }
903
904
905 /**
906  * Reconnect to the service, retransmit all infomation to try to restore the
907  * original state.
908  *
909  * @param h handle to the mesh
910  *
911  * @return GNUNET_YES in case of sucess, GNUNET_NO otherwise (service down...)
912  */
913 static void
914 reconnect (struct GNUNET_MESH_Handle *h)
915 {
916   LOG (GNUNET_ERROR_TYPE_DEBUG, "Requested RECONNECT\n");
917   h->in_receive = GNUNET_NO;
918   if (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task)
919     h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
920                                                       &reconnect_cbk, h);
921 }
922
923
924 /******************************************************************************/
925 /***********************      RECEIVE HANDLERS     ****************************/
926 /******************************************************************************/
927
928 /**
929  * Process the new tunnel notification and add it to the tunnels in the handle
930  *
931  * @param h     The mesh handle
932  * @param msg   A message with the details of the new incoming tunnel
933  */
934 static void
935 process_tunnel_created (struct GNUNET_MESH_Handle *h,
936                         const struct GNUNET_MESH_TunnelNotification *msg)
937 {
938   struct GNUNET_MESH_Tunnel *t;
939   MESH_TunnelNumber tid;
940
941   tid = ntohl (msg->tunnel_id);
942   LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating incoming tunnel %X\n", tid);
943   if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
944   {
945     GNUNET_break (0);
946     return;
947   }
948   if (NULL != h->new_tunnel)
949   {
950     struct GNUNET_ATS_Information atsi;
951
952     t = create_tunnel (h, tid);
953     t->owner = GNUNET_PEER_intern (&msg->peer);
954     t->npeers = 1;
955     t->peers = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer *));
956     t->peers[0] = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer));
957     t->peers[0]->t = t;
958     t->peers[0]->connected = 1;
959     t->peers[0]->id = t->owner;
960     GNUNET_PEER_change_rc (t->owner, 1);
961     t->mesh = h;
962     t->tid = tid;
963     if ((msg->opt & MESH_TUNNEL_OPT_NOBUFFER) != 0)
964       t->buffering = GNUNET_NO;
965     else
966       t->buffering = GNUNET_YES;
967     if ((msg->opt & MESH_TUNNEL_OPT_SPEED_MIN) != 0)
968       t->speed_min = GNUNET_YES;
969     atsi.type = 0;
970     atsi.value = 0;
971     LOG (GNUNET_ERROR_TYPE_DEBUG, "  created tunnel %p\n", t);
972     t->ctx = h->new_tunnel (h->cls, t, &msg->peer, &atsi);
973     LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n");
974   }
975   else
976   {
977     struct GNUNET_MESH_TunnelMessage d_msg;
978
979     LOG (GNUNET_ERROR_TYPE_DEBUG, "No handler for incoming tunnels\n");
980
981     d_msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
982     d_msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
983     d_msg.tunnel_id = msg->tunnel_id;
984
985     send_packet (h, &d_msg.header, NULL);
986   }
987   return;
988 }
989
990
991 /**
992  * Process the tunnel destroy notification and free associated resources
993  *
994  * @param h     The mesh handle
995  * @param msg   A message with the details of the tunnel being destroyed
996  */
997 static void
998 process_tunnel_destroy (struct GNUNET_MESH_Handle *h,
999                         const struct GNUNET_MESH_TunnelMessage *msg)
1000 {
1001   struct GNUNET_MESH_Tunnel *t;
1002   MESH_TunnelNumber tid;
1003
1004   tid = ntohl (msg->tunnel_id);
1005   t = retrieve_tunnel (h, tid);
1006
1007   if (NULL == t)
1008   {
1009     return;
1010   }
1011   if (0 == t->owner)
1012   {
1013     GNUNET_break (0);
1014   }
1015   LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %X destroyed\n", t->tid);
1016   destroy_tunnel (t, GNUNET_YES);
1017   return;
1018 }
1019
1020
1021 /**
1022  * Process the new peer event and notify the upper level of it
1023  *
1024  * @param h     The mesh handle
1025  * @param msg   A message with the details of the peer event
1026  */
1027 static void
1028 process_peer_event (struct GNUNET_MESH_Handle *h,
1029                     const struct GNUNET_MESH_PeerControl *msg)
1030 {
1031   struct GNUNET_MESH_Tunnel *t;
1032   struct GNUNET_MESH_Peer *p;
1033   struct GNUNET_ATS_Information atsi;
1034   GNUNET_PEER_Id id;
1035   uint16_t size;
1036
1037   LOG (GNUNET_ERROR_TYPE_DEBUG, "processig peer event\n");
1038   size = ntohs (msg->header.size);
1039   if (size != sizeof (struct GNUNET_MESH_PeerControl))
1040   {
1041     GNUNET_break (0);
1042     return;
1043   }
1044   t = retrieve_tunnel (h, ntohl (msg->tunnel_id));
1045   if (NULL == t)
1046   {
1047     GNUNET_break (0);
1048     return;
1049   }
1050   id = GNUNET_PEER_search (&msg->peer);
1051   if ((p = retrieve_peer (t, id)) == NULL)
1052     p = add_peer_to_tunnel (t, &msg->peer);
1053   if (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD == ntohs (msg->header.type))
1054   {
1055     LOG (GNUNET_ERROR_TYPE_DEBUG, "adding peer\n");
1056     if (NULL != t->connect_handler)
1057     {
1058       atsi.type = 0;
1059       atsi.value = 0;
1060       t->connect_handler (t->cls, &msg->peer, &atsi);
1061     }
1062     p->connected = 1;
1063   }
1064   else
1065   {
1066     LOG (GNUNET_ERROR_TYPE_DEBUG, "removing peer\n");
1067     if (NULL != t->disconnect_handler && p->connected)
1068     {
1069       t->disconnect_handler (t->cls, &msg->peer);
1070     }
1071     remove_peer_from_tunnel (p);
1072     GNUNET_free (p);
1073   }
1074   LOG (GNUNET_ERROR_TYPE_DEBUG, "processing peer event END\n");
1075 }
1076
1077
1078 /**
1079  * Process the incoming data packets
1080  *
1081  * @param h         The mesh handle
1082  * @param message   A message encapsulating the data
1083  * 
1084  * @return GNUNET_YES if everything went fine
1085  *         GNUNET_NO if client closed connection (h no longer valid)
1086  */
1087 static int
1088 process_incoming_data (struct GNUNET_MESH_Handle *h,
1089                        const struct GNUNET_MessageHeader *message)
1090 {
1091   const struct GNUNET_MessageHeader *payload;
1092   const struct GNUNET_MESH_MessageHandler *handler;
1093   const struct GNUNET_PeerIdentity *peer;
1094   struct GNUNET_MESH_Unicast *ucast;
1095   struct GNUNET_MESH_Multicast *mcast;
1096   struct GNUNET_MESH_ToOrigin *to_orig;
1097   struct GNUNET_MESH_Tunnel *t;
1098   unsigned int i;
1099   uint32_t pid;
1100   uint16_t type;
1101
1102   LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a data message!\n");
1103   type = ntohs (message->type);
1104   switch (type)
1105   {
1106   case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
1107     ucast = (struct GNUNET_MESH_Unicast *) message;
1108
1109     t = retrieve_tunnel (h, ntohl (ucast->tid));
1110     payload = (struct GNUNET_MessageHeader *) &ucast[1];
1111     peer = &ucast->oid;
1112     pid = ntohl (ucast->pid);
1113     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ucast on tunnel %s [%X]\n",
1114          GNUNET_i2s (peer), ntohl (ucast->tid));
1115     break;
1116   case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
1117     mcast = (struct GNUNET_MESH_Multicast *) message;
1118     t = retrieve_tunnel (h, ntohl (mcast->tid));
1119     payload = (struct GNUNET_MessageHeader *) &mcast[1];
1120     peer = &mcast->oid;
1121     pid = ntohl (mcast->pid);
1122     LOG (GNUNET_ERROR_TYPE_DEBUG, "  mcast on tunnel %s [%X]\n",
1123          GNUNET_i2s (peer), ntohl (mcast->tid));
1124     break;
1125   case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
1126     to_orig = (struct GNUNET_MESH_ToOrigin *) message;
1127     t = retrieve_tunnel (h, ntohl (to_orig->tid));
1128     payload = (struct GNUNET_MessageHeader *) &to_orig[1];
1129     peer = &to_orig->sender;
1130     pid = ntohl (to_orig->pid);
1131     LOG (GNUNET_ERROR_TYPE_DEBUG, "  torig on tunnel %s [%X]\n",
1132          GNUNET_i2s (peer), ntohl (to_orig->tid));
1133     break;
1134   default:
1135     GNUNET_break (0);
1136     return GNUNET_YES;
1137   }
1138   LOG (GNUNET_ERROR_TYPE_DEBUG, "  pid %u\n", pid);
1139   if (NULL == t)
1140   {
1141     /* Tunnel was ignored/destroyed, probably service didn't get it yet */
1142     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ignored!\n");
1143     return GNUNET_YES;
1144   }
1145   if (GNUNET_YES ==
1146       GMC_is_pid_bigger(pid, t->max_recv_pid))
1147   {
1148     GNUNET_break (0);
1149     LOG (GNUNET_ERROR_TYPE_WARNING,
1150          "  unauthorized message! (%u, max %u)\n",
1151          pid, t->max_recv_pid);
1152     // FIXME fc what now? accept? reject?
1153     return GNUNET_YES;
1154   }
1155   t->last_recv_pid = pid;
1156   type = ntohs (payload->type);
1157   send_ack (h, t);
1158   for (i = 0; i < h->n_handlers; i++)
1159   {
1160     handler = &h->message_handlers[i];
1161     if (handler->type == type)
1162     {
1163       struct GNUNET_ATS_Information atsi;
1164
1165       atsi.type = 0;
1166       atsi.value = 0;
1167       if (GNUNET_OK !=
1168           handler->callback (h->cls, t, &t->ctx, peer, payload, &atsi))
1169       {
1170         LOG (GNUNET_ERROR_TYPE_DEBUG, "callback caused disconnection\n");
1171         GNUNET_MESH_disconnect (h);
1172         return GNUNET_NO;
1173       }
1174       else
1175       {
1176         LOG (GNUNET_ERROR_TYPE_DEBUG,
1177              "callback completed successfully\n");
1178       }
1179     }
1180   }
1181   return GNUNET_YES;
1182 }
1183
1184
1185 /**
1186  * Process a local ACK message, enabling the client to send
1187  * more data to the service.
1188  * 
1189  * @param h Mesh handle.
1190  * @param message Message itself.
1191  */
1192 static void
1193 process_ack (struct GNUNET_MESH_Handle *h,
1194              const struct GNUNET_MessageHeader *message)
1195 {
1196   struct GNUNET_MESH_LocalAck *msg;
1197   struct GNUNET_MESH_Tunnel *t;
1198   uint32_t ack;
1199
1200   LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK!\n");
1201   h->acks_recv++;
1202   msg = (struct GNUNET_MESH_LocalAck *) message;
1203
1204   t = retrieve_tunnel (h, ntohl (msg->tunnel_id));
1205
1206   if (NULL == t)
1207   {
1208     LOG (GNUNET_ERROR_TYPE_WARNING,
1209          "ACK on unknown tunnel %X\n",
1210          ntohl (msg->tunnel_id));
1211     return;
1212   }
1213   ack = ntohl (msg->max_pid);
1214   LOG (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X, ack %u!\n", t->tid, ack);
1215   if (GNUNET_YES == GMC_is_pid_bigger(ack, t->max_send_pid))
1216     t->max_send_pid = ack;
1217   else
1218     return;
1219   if (NULL == h->th && 0 < t->packet_size)
1220   {
1221     LOG (GNUNET_ERROR_TYPE_DEBUG, "  tmt rdy was NULL, requesting!\n", t->tid, ack);
1222     h->th =
1223         GNUNET_CLIENT_notify_transmit_ready (h->client, t->packet_size,
1224                                              GNUNET_TIME_UNIT_FOREVER_REL,
1225                                              GNUNET_YES, &send_callback, h);
1226   }
1227 }
1228
1229
1230 /**
1231  * Process a local reply about info on all tunnels, pass info to the user.
1232  *
1233  * @param h Mesh handle.
1234  * @param message Message itself.
1235  */
1236 static void
1237 process_get_tunnels (struct GNUNET_MESH_Handle *h,
1238                      const struct GNUNET_MessageHeader *message)
1239 {
1240   struct GNUNET_MESH_LocalMonitor *msg;
1241   uint32_t npeers;
1242
1243   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Tunnels messasge received\n");
1244
1245   if (NULL == h->tunnels_cb)
1246   {
1247     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  ignored\n");
1248     return;
1249   }
1250
1251   msg = (struct GNUNET_MESH_LocalMonitor *) message;
1252   npeers = ntohl (msg->npeers);
1253   if (ntohs (message->size) !=
1254       (sizeof (struct GNUNET_MESH_LocalMonitor) +
1255        npeers * sizeof (struct GNUNET_PeerIdentity)))
1256   {
1257     GNUNET_break_op (0);
1258     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1259                 "Get tunnels message: size %hu - expected %u (%u peers)\n",
1260                 ntohs (message->size),
1261                 sizeof (struct GNUNET_MESH_LocalMonitor) +
1262                 npeers * sizeof (struct GNUNET_PeerIdentity),
1263                 npeers);
1264     return;
1265   }
1266   h->tunnels_cb (h->tunnels_cls,
1267                  &msg->owner,
1268                  ntohl (msg->tunnel_id),
1269                  (struct GNUNET_PeerIdentity *) &msg[1],
1270                  npeers);
1271 }
1272
1273
1274
1275 /**
1276  * Process a local monitor_tunnel reply, pass info to the user.
1277  *
1278  * @param h Mesh handle.
1279  * @param message Message itself.
1280  */
1281 static void
1282 process_show_tunnel (struct GNUNET_MESH_Handle *h,
1283                      const struct GNUNET_MessageHeader *message)
1284 {
1285   struct GNUNET_MESH_LocalMonitor *msg;
1286   struct GNUNET_PeerIdentity *new_peers;
1287   uint32_t *new_parents;
1288   size_t esize;
1289   uint32_t npeers;
1290   unsigned int i;
1291
1292   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Tunnel messasge received\n");
1293
1294   if (NULL == h->tunnel_cb)
1295   {
1296     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  ignored\n");
1297     return;
1298   }
1299
1300   /* Verify message sanity */
1301   msg = (struct GNUNET_MESH_LocalMonitor *) message;
1302   npeers = ntohl (msg->npeers);
1303   esize = sizeof (struct GNUNET_MESH_LocalMonitor);
1304   esize += npeers * (sizeof (struct GNUNET_PeerIdentity) + sizeof (uint32_t));
1305   if (ntohs (message->size) != esize)
1306   {
1307     GNUNET_break_op (0);
1308     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1309                 "Show tunnel message: size %hu - expected %u (%u peers)\n",
1310                 ntohs (message->size),
1311                 esize,
1312                 npeers);
1313
1314     h->tunnel_cb (h->tunnel_cls, NULL, NULL);
1315     h->tunnel_cb = NULL;
1316     h->tunnel_cls = NULL;
1317     h->tunnel_npeers = 0;
1318     GNUNET_free_non_null (h->peers);
1319     h->peers = NULL;
1320
1321     return;
1322   }
1323
1324   new_peers = (struct GNUNET_PeerIdentity *) &msg[1];
1325   new_parents = (uint32_t *) &new_peers[npeers];
1326
1327   h->peers = GNUNET_realloc (h->peers, h->tunnel_npeers + npeers);
1328   memcpy (&h->peers[h->tunnel_npeers],
1329           new_peers,
1330           npeers * sizeof (struct GNUNET_PeerIdentity));
1331   h->tunnel_npeers += npeers;
1332   for (i = 0; i < npeers; i++)
1333     h->tunnel_cb (h->tunnel_cls,
1334                   &new_peers[i],
1335                   &h->peers[new_parents[i]]);
1336 }
1337
1338
1339 /**
1340  * Function to process all messages received from the service
1341  *
1342  * @param cls closure
1343  * @param msg message received, NULL on timeout or fatal error
1344  */
1345 static void
1346 msg_received (void *cls, const struct GNUNET_MessageHeader *msg)
1347 {
1348   struct GNUNET_MESH_Handle *h = cls;
1349
1350   if (msg == NULL)
1351   {
1352     LOG (GNUNET_ERROR_TYPE_DEBUG, 
1353          "Mesh service disconnected, reconnecting\n", h);
1354     reconnect (h);
1355     return;
1356   }
1357   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n",
1358        GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
1359   LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a message: %s\n",
1360        GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
1361   switch (ntohs (msg->type))
1362   {
1363     /* Notify of a new incoming tunnel */
1364   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE:
1365     process_tunnel_created (h, (struct GNUNET_MESH_TunnelNotification *) msg);
1366     break;
1367     /* Notify of a tunnel disconnection */
1368   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY:
1369     process_tunnel_destroy (h, (struct GNUNET_MESH_TunnelMessage *) msg);
1370     break;
1371     /* Notify of a new peer or a peer disconnect in the tunnel */
1372   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD:
1373   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL:
1374     process_peer_event (h, (struct GNUNET_MESH_PeerControl *) msg);
1375     break;
1376     /* Notify of a new data packet in the tunnel */
1377   case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
1378   case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
1379   case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
1380     if (GNUNET_NO == process_incoming_data (h, msg))
1381       return;
1382     break;
1383   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
1384     process_ack (h, msg);
1385     break;
1386   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS:
1387         process_get_tunnels (h, msg);
1388     break;
1389   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL:
1390         process_show_tunnel (h, msg);
1391     break;
1392   default:
1393     /* We shouldn't get any other packages, log and ignore */
1394     LOG (GNUNET_ERROR_TYPE_WARNING,
1395          "unsolicited message form service (type %s)\n",
1396          GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
1397   }
1398   LOG (GNUNET_ERROR_TYPE_DEBUG, "message processed\n");
1399   if (GNUNET_YES == h->in_receive)
1400   {
1401     GNUNET_CLIENT_receive (h->client, &msg_received, h,
1402                            GNUNET_TIME_UNIT_FOREVER_REL);
1403   }
1404   else
1405   {
1406     LOG (GNUNET_ERROR_TYPE_DEBUG,
1407          "in receive off, not calling CLIENT_receive\n");
1408   }
1409 }
1410
1411
1412 /******************************************************************************/
1413 /************************       SEND FUNCTIONS     ****************************/
1414 /******************************************************************************/
1415
1416 /**
1417  * Function called to send a message to the service.
1418  * "buf" will be NULL and "size" zero if the socket was closed for writing in
1419  * the meantime.
1420  *
1421  * @param cls closure, the mesh handle
1422  * @param size number of bytes available in buf
1423  * @param buf where the callee should write the connect message
1424  * @return number of bytes written to buf
1425  */
1426 static size_t
1427 send_callback (void *cls, size_t size, void *buf)
1428 {
1429   struct GNUNET_MESH_Handle *h = cls;
1430   struct GNUNET_MESH_TransmitHandle *th;
1431   struct GNUNET_MESH_TransmitHandle *next;
1432   struct GNUNET_MESH_Tunnel *t;
1433   char *cbuf = buf;
1434   size_t tsize;
1435   size_t psize;
1436   size_t nsize;
1437
1438   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
1439   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send packet() Buffer %u\n", size);
1440   if ((0 == size) || (NULL == buf))
1441   {
1442     LOG (GNUNET_ERROR_TYPE_DEBUG, "Received NULL send callback on %p\n", h);
1443     reconnect (h);
1444     h->th = NULL;
1445     return 0;
1446   }
1447   tsize = 0;
1448   next = h->th_head;
1449   nsize = message_ready_size (h);
1450   while ((NULL != (th = next)) && (0 < nsize) && (size >= nsize))
1451   {
1452     t = th->tunnel;
1453     if (GNUNET_YES == th_is_payload (th))
1454     {
1455       LOG (GNUNET_ERROR_TYPE_DEBUG, " payload\n");
1456       if (GNUNET_YES == GMC_is_pid_bigger(t->next_send_pid, t->max_send_pid))
1457       {
1458         /* This tunnel is not ready to transmit yet, try next message */
1459         next = th->next;
1460         continue;
1461       }
1462       t->packet_size = 0;
1463       if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
1464       {
1465         /* traffic to origin */
1466         struct GNUNET_MESH_ToOrigin to;
1467         struct GNUNET_MessageHeader *mh;
1468
1469         GNUNET_assert (size >= th->size);
1470         mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (to)];
1471         psize = th->notify (th->notify_cls, size - sizeof (to), mh);
1472         LOG (GNUNET_ERROR_TYPE_DEBUG, "  to origin, type %s\n",
1473              GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
1474         if (psize > 0)
1475         {
1476           psize += sizeof (to);
1477           GNUNET_assert (size >= psize);
1478           to.header.size = htons (psize);
1479           to.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
1480           to.tid = htonl (t->tid);
1481           to.pid = htonl (t->next_send_pid);
1482           to.ttl = 0;
1483           memset (&to.oid, 0, sizeof (struct GNUNET_PeerIdentity));
1484           memset (&to.sender, 0, sizeof (struct GNUNET_PeerIdentity));
1485           memcpy (cbuf, &to, sizeof (to));
1486         }
1487       }
1488       else
1489       {
1490         /* unicast */
1491         struct GNUNET_MESH_Unicast uc;
1492         struct GNUNET_MessageHeader *mh;
1493
1494         GNUNET_assert (size >= th->size);
1495         mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (uc)];
1496         psize = th->notify (th->notify_cls, size - sizeof (uc), mh);
1497         LOG (GNUNET_ERROR_TYPE_DEBUG, "  unicast, type %s\n",
1498              GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
1499         if (psize > 0)
1500         {
1501           psize += sizeof (uc);
1502           GNUNET_assert (size >= psize);
1503           uc.header.size = htons (psize);
1504           uc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
1505           uc.tid = htonl (t->tid);
1506           uc.pid = htonl (t->next_send_pid);
1507           uc.ttl = 0;
1508           memset (&uc.oid, 0, sizeof (struct GNUNET_PeerIdentity));
1509           GNUNET_PEER_resolve (th->target, &uc.destination);
1510           memcpy (cbuf, &uc, sizeof (uc));
1511         }
1512       }
1513       t->next_send_pid++;
1514     }
1515     else
1516     {
1517       struct GNUNET_MessageHeader *mh = (struct GNUNET_MessageHeader *) &th[1];
1518
1519       LOG (GNUNET_ERROR_TYPE_DEBUG, "  mesh traffic, type %s\n",
1520            GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
1521       memcpy (cbuf, &th[1], th->size);
1522       psize = th->size;
1523     }
1524     if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK)
1525       GNUNET_SCHEDULER_cancel (th->timeout_task);
1526     GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
1527     GNUNET_free (th);
1528     next = h->th_head;
1529     nsize = message_ready_size (h);
1530     cbuf += psize;
1531     size -= psize;
1532     tsize += psize;
1533   }
1534   LOG (GNUNET_ERROR_TYPE_DEBUG, "  total size: %u\n", tsize);
1535   h->th = NULL;
1536   size = message_ready_size (h);
1537   if (0 != size)
1538   {
1539     LOG (GNUNET_ERROR_TYPE_DEBUG, "  next size: %u\n", size);
1540     h->th =
1541         GNUNET_CLIENT_notify_transmit_ready (h->client, size,
1542                                              GNUNET_TIME_UNIT_FOREVER_REL,
1543                                              GNUNET_YES, &send_callback, h);
1544   }
1545   else
1546   {
1547     if (NULL != h->th_head)
1548       LOG (GNUNET_ERROR_TYPE_DEBUG, "  can't transmit any more\n");
1549     else
1550       LOG (GNUNET_ERROR_TYPE_DEBUG, "  nothing left to transmit\n");
1551   }
1552   if (GNUNET_NO == h->in_receive)
1553   {
1554     LOG (GNUNET_ERROR_TYPE_DEBUG, " start receiving from service\n");
1555     h->in_receive = GNUNET_YES;
1556     GNUNET_CLIENT_receive (h->client, &msg_received, h,
1557                            GNUNET_TIME_UNIT_FOREVER_REL);
1558   }
1559   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send packet() END\n");
1560   return tsize;
1561 }
1562
1563
1564 /**
1565  * Auxiliary function to send an already constructed packet to the service.
1566  * Takes care of creating a new queue element, copying the message and
1567  * calling the tmt_rdy function if necessary.
1568  * 
1569  * @param h mesh handle
1570  * @param msg message to transmit
1571  * @param tunnel tunnel this send is related to (NULL if N/A)
1572  */
1573 static void
1574 send_packet (struct GNUNET_MESH_Handle *h,
1575              const struct GNUNET_MessageHeader *msg,
1576              struct GNUNET_MESH_Tunnel *tunnel)
1577 {
1578   struct GNUNET_MESH_TransmitHandle *th;
1579   size_t msize;
1580
1581   LOG (GNUNET_ERROR_TYPE_DEBUG, " Sending message to service: %s\n",
1582        GNUNET_MESH_DEBUG_M2S(ntohs(msg->type)));
1583   msize = ntohs (msg->size);
1584   th = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle) + msize);
1585   th->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
1586   th->size = msize;
1587   th->tunnel = tunnel;
1588   memcpy (&th[1], msg, msize);
1589   add_to_queue (h, th);
1590   LOG (GNUNET_ERROR_TYPE_DEBUG, "  queued\n");
1591   if (NULL != h->th)
1592     return;
1593   LOG (GNUNET_ERROR_TYPE_DEBUG, "  calling ntfy tmt rdy for %u bytes\n", msize);
1594   h->th =
1595       GNUNET_CLIENT_notify_transmit_ready (h->client, msize,
1596                                            GNUNET_TIME_UNIT_FOREVER_REL,
1597                                            GNUNET_YES, &send_callback, h);
1598 }
1599
1600
1601 /******************************************************************************/
1602 /**********************      API CALL DEFINITIONS     *************************/
1603 /******************************************************************************/
1604
1605 /**
1606  * Connect to the mesh service.
1607  *
1608  * @param cfg configuration to use
1609  * @param cls closure for the various callbacks that follow
1610  *            (including handlers in the handlers array)
1611  * @param new_tunnel function called when an *inbound* tunnel is created
1612  * @param cleaner function called when an *inbound* tunnel is destroyed by the
1613  *                remote peer, it is *not* called if GNUNET_MESH_tunnel_destroy
1614  *                is called on the tunnel
1615  * @param handlers callbacks for messages we care about, NULL-terminated
1616  *                note that the mesh is allowed to drop notifications about
1617  *                inbound messages if the client does not process them fast
1618  *                enough (for this notification type, a bounded queue is used)
1619  * @param stypes list of the applications that this client claims to provide
1620  * @return handle to the mesh service NULL on error
1621  *         (in this case, init is never called)
1622  */
1623 struct GNUNET_MESH_Handle *
1624 GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
1625                      GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
1626                      GNUNET_MESH_TunnelEndHandler cleaner,
1627                      const struct GNUNET_MESH_MessageHandler *handlers,
1628                      const GNUNET_MESH_ApplicationType *stypes)
1629 {
1630   struct GNUNET_MESH_Handle *h;
1631   size_t size;
1632
1633   LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_MESH_connect()\n");
1634   h = GNUNET_malloc (sizeof (struct GNUNET_MESH_Handle));
1635   LOG (GNUNET_ERROR_TYPE_DEBUG, " addr %p\n", h);
1636   h->cfg = cfg;
1637   h->new_tunnel = new_tunnel;
1638   h->cleaner = cleaner;
1639   h->client = GNUNET_CLIENT_connect ("mesh", cfg);
1640   if (h->client == NULL)
1641   {
1642     GNUNET_break (0);
1643     GNUNET_free (h);
1644     return NULL;
1645   }
1646   h->cls = cls;
1647   h->message_handlers = handlers;
1648   h->next_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
1649   h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1650   h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1651
1652   /* count apps */
1653   for (h->n_applications = 0;
1654        stypes && stypes[h->n_applications];
1655        h->n_applications++) ;
1656   if (0 < h->n_applications)
1657   {
1658     size = h->n_applications * sizeof (GNUNET_MESH_ApplicationType *);
1659     h->applications = GNUNET_malloc (size);
1660     memcpy (h->applications, stypes, size);
1661   }
1662   /* count handlers */
1663   for (h->n_handlers = 0;
1664        handlers && handlers[h->n_handlers].type;
1665        h->n_handlers++) ;
1666   send_connect (h);
1667   LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_MESH_connect() END\n");
1668   return h;
1669 }
1670
1671
1672 /**
1673  * Disconnect from the mesh service. All tunnels will be destroyed. All tunnel
1674  * disconnect callbacks will be called on any still connected peers, notifying
1675  * about their disconnection. The registered inbound tunnel cleaner will be
1676  * called should any inbound tunnels still exist.
1677  *
1678  * @param handle connection to mesh to disconnect
1679  */
1680 void
1681 GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle)
1682 {
1683   struct GNUNET_MESH_Tunnel *t;
1684   struct GNUNET_MESH_Tunnel *aux;
1685   struct GNUNET_MESH_TransmitHandle *th;
1686
1687   LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH DISCONNECT\n");
1688
1689 #if DEBUG_ACK
1690   LOG (GNUNET_ERROR_TYPE_INFO, "Sent %d ACKs\n", handle->acks_sent);
1691   LOG (GNUNET_ERROR_TYPE_INFO, "Recv %d ACKs\n\n", handle->acks_recv);
1692 #endif
1693
1694   t = handle->tunnels_head;
1695   while (NULL != t)
1696   {
1697     aux = t->next;
1698     if (t->tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
1699     {
1700       GNUNET_break (0);
1701       LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %X not destroyed\n", t->tid);
1702     }
1703     destroy_tunnel (t, GNUNET_YES);
1704     t = aux;
1705   }
1706   while ( (th = handle->th_head) != NULL)
1707   {
1708     struct GNUNET_MessageHeader *msg;
1709
1710     /* Make sure it is an allowed packet (everything else should have been
1711      * already canceled).
1712      */
1713     GNUNET_break (GNUNET_NO == th_is_payload (th));
1714     msg = (struct GNUNET_MessageHeader *) &th[1];
1715     switch (ntohs(msg->type))
1716     {
1717       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT:
1718       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY:
1719       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS:
1720       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL:
1721         break;
1722       default:
1723         GNUNET_break (0);
1724         LOG (GNUNET_ERROR_TYPE_ERROR, "unexpected msg %u\n",
1725              ntohs(msg->type));
1726     }
1727
1728     GNUNET_CONTAINER_DLL_remove (handle->th_head, handle->th_tail, th);
1729     GNUNET_free (th);
1730   }
1731
1732   if (NULL != handle->th)
1733   {
1734     GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
1735     handle->th = NULL;
1736   }
1737   if (NULL != handle->client)
1738   {
1739     GNUNET_CLIENT_disconnect (handle->client);
1740     handle->client = NULL;
1741   }
1742   if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task)
1743   {
1744     GNUNET_SCHEDULER_cancel(handle->reconnect_task);
1745     handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1746   }
1747   GNUNET_free_non_null (handle->applications);
1748   GNUNET_free (handle);
1749 }
1750
1751
1752 /**
1753  * Announce to ther peer the availability of services described by the regex,
1754  * in order to be reachable to other peers via connect_by_string.
1755  * 
1756  * Note that the first 8 characters are considered to be part of a prefix,
1757  * (for instance 'gnunet://'). If you put a variable part in there (*, +. ()),
1758  * all matching strings will be stored in the DHT.
1759  *
1760  * @param h Handle to mesh.
1761  * @param regex String with the regular expression describing local services.
1762  * @param compression_characters How many characters can be assigned to one
1763  *                               edge of the graph. The bigger the variability
1764  *                               of the data, the smaller this parameter should
1765  *                               be (down to 1).
1766  *                               For maximum compression, use strlen (regex)
1767  *                               or 0 (special value). Use with care!
1768  */
1769 void
1770 GNUNET_MESH_announce_regex (struct GNUNET_MESH_Handle *h,
1771                             const char *regex,
1772                             unsigned int compression_characters)
1773 {
1774   struct GNUNET_MESH_RegexAnnounce *msg;
1775   size_t payload;
1776   size_t len;
1777   size_t msgsize;
1778   size_t offset;
1779   char buffer[UINT16_MAX];
1780
1781   len = strlen (regex);
1782   payload = UINT16_MAX - sizeof(struct GNUNET_MESH_RegexAnnounce);
1783   msg = (struct GNUNET_MESH_RegexAnnounce *) buffer;
1784   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX);
1785   msg->compression_characters = htons (compression_characters);
1786   offset = 0;
1787   do
1788   {
1789     msgsize = (len - offset > payload) ? payload : len - offset;
1790     memcpy (&msg[1], &regex[offset], msgsize);
1791     offset += msgsize;
1792     msgsize += sizeof(struct GNUNET_MESH_RegexAnnounce);
1793
1794     msg->header.size = htons (msgsize);
1795     msg->last = htons (offset >= len);
1796
1797     send_packet (h, &msg->header, NULL);
1798   } while (len > offset);
1799 }
1800
1801 /**
1802  * Create a new tunnel (we're initiator and will be allowed to add/remove peers
1803  * and to broadcast).
1804  *
1805  * @param h mesh handle
1806  * @param tunnel_ctx client's tunnel context to associate with the tunnel
1807  * @param connect_handler function to call when peers are actually connected
1808  * @param disconnect_handler function to call when peers are disconnected
1809  * @param handler_cls closure for connect/disconnect handlers
1810  */
1811 struct GNUNET_MESH_Tunnel *
1812 GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, void *tunnel_ctx,
1813                            GNUNET_MESH_PeerConnectHandler connect_handler,
1814                            GNUNET_MESH_PeerDisconnectHandler disconnect_handler,
1815                            void *handler_cls)
1816 {
1817   struct GNUNET_MESH_Tunnel *t;
1818   struct GNUNET_MESH_TunnelMessage msg;
1819
1820   LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating new tunnel\n");
1821   t = create_tunnel (h, 0);
1822   LOG (GNUNET_ERROR_TYPE_DEBUG, "  at %p\n", t);
1823   LOG (GNUNET_ERROR_TYPE_DEBUG, "  number %X\n", t->tid);
1824   t->connect_handler = connect_handler;
1825   t->disconnect_handler = disconnect_handler;
1826   t->cls = handler_cls;
1827   t->ctx = tunnel_ctx;
1828   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
1829   msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
1830   msg.tunnel_id = htonl (t->tid);
1831   send_packet (h, &msg.header, t);
1832   return t;
1833 }
1834
1835
1836 /**
1837  * Destroy an existing tunnel. The existing callback for the tunnel will NOT
1838  * be called.
1839  *
1840  * @param tunnel tunnel handle
1841  */
1842 void
1843 GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel)
1844 {
1845   struct GNUNET_MESH_Handle *h;
1846   struct GNUNET_MESH_TunnelMessage msg;
1847   struct GNUNET_MESH_TransmitHandle *th;
1848
1849   LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying tunnel\n");
1850   h = tunnel->mesh;
1851
1852   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
1853   msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
1854   msg.tunnel_id = htonl (tunnel->tid);
1855   th = h->th_head;
1856   while (th != NULL)
1857   {
1858     struct GNUNET_MESH_TransmitHandle *aux;
1859     if (th->tunnel == tunnel)
1860     {
1861       aux = th->next;
1862       /* FIXME call the handler? */
1863       if (GNUNET_YES == th_is_payload (th))
1864         th->notify (th->notify_cls, 0, NULL);
1865       GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
1866       GNUNET_free (th);
1867       th = aux;
1868     }
1869     else
1870       th = th->next;
1871   }
1872
1873   destroy_tunnel (tunnel, GNUNET_NO);
1874   send_packet (h, &msg.header, NULL);
1875 }
1876
1877 /**
1878  * Request that the tunnel data rate is limited to the speed of the slowest
1879  * receiver.
1880  *
1881  * @param tunnel Tunnel affected.
1882  */
1883 void
1884 GNUNET_MESH_tunnel_speed_min (struct GNUNET_MESH_Tunnel *tunnel)
1885 {
1886   struct GNUNET_MESH_TunnelMessage msg;
1887   struct GNUNET_MESH_Handle *h;
1888
1889   h = tunnel->mesh;
1890   tunnel->speed_min = GNUNET_YES;
1891
1892   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MIN);
1893   msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
1894   msg.tunnel_id = htonl (tunnel->tid);
1895
1896   send_packet (h, &msg.header, NULL);
1897 }
1898
1899
1900 /**
1901  * Request that the tunnel data rate is limited to the speed of the fastest
1902  * receiver. This is the default behavior.
1903  *
1904  * @param tunnel Tunnel affected.
1905  */
1906 void
1907 GNUNET_MESH_tunnel_speed_max (struct GNUNET_MESH_Tunnel *tunnel)
1908 {
1909   struct GNUNET_MESH_TunnelMessage msg;
1910   struct GNUNET_MESH_Handle *h;
1911
1912   h = tunnel->mesh;
1913   tunnel->speed_min = GNUNET_NO;
1914
1915   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MAX);
1916   msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
1917   msg.tunnel_id = htonl (tunnel->tid);
1918
1919   send_packet (h, &msg.header, NULL);
1920 }
1921
1922 /**
1923  * Turn on/off the buffering status of the tunnel.
1924  * 
1925  * @param tunnel Tunnel affected.
1926  * @param buffer GNUNET_YES to turn buffering on (default),
1927  *               GNUNET_NO otherwise.
1928  */
1929 void
1930 GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer)
1931 {
1932   struct GNUNET_MESH_TunnelMessage msg;
1933   struct GNUNET_MESH_Handle *h;
1934
1935   h = tunnel->mesh;
1936   tunnel->buffering = buffer;
1937   tunnel->max_send_pid = tunnel->next_send_pid;
1938
1939   if (GNUNET_YES == buffer)
1940     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER);
1941   else
1942     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER);
1943   msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
1944   msg.tunnel_id = htonl (tunnel->tid);
1945
1946   send_packet (h, &msg.header, NULL);
1947 }
1948
1949
1950 struct GNUNET_MESH_TransmitHandle *
1951 GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
1952                                    struct GNUNET_TIME_Relative maxdelay,
1953                                    size_t notify_size,
1954                                    GNUNET_CONNECTION_TransmitReadyNotify notify,
1955                                    void *notify_cls)
1956 {
1957   struct GNUNET_MESH_TransmitHandle *th;
1958   size_t overhead;
1959
1960   GNUNET_assert (NULL != tunnel);
1961   LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH NOTIFY TRANSMIT READY\n");
1962   LOG (GNUNET_ERROR_TYPE_DEBUG, "    on tunnel %X\n", tunnel->tid);
1963   if (tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
1964     LOG (GNUNET_ERROR_TYPE_DEBUG, "    to origin\n");
1965   else
1966     LOG (GNUNET_ERROR_TYPE_DEBUG, "    to destination\n");
1967   LOG (GNUNET_ERROR_TYPE_DEBUG, "    payload size %u\n", notify_size);
1968   GNUNET_assert (NULL != notify);
1969   GNUNET_assert (0 == tunnel->packet_size); // Only one data packet allowed
1970   th = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle));
1971   th->tunnel = tunnel;
1972   th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
1973   if (tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
1974     overhead = sizeof (struct GNUNET_MESH_ToOrigin);
1975   else
1976     overhead = sizeof (struct GNUNET_MESH_Unicast);
1977   tunnel->packet_size = th->size = notify_size + overhead;
1978   LOG (GNUNET_ERROR_TYPE_DEBUG, "    total size %u\n", th->size);
1979   th->notify = notify;
1980   th->notify_cls = notify_cls;
1981   add_to_queue (tunnel->mesh, th);
1982   if (NULL != tunnel->mesh->th)
1983     return th;
1984   if (GMC_is_pid_bigger(tunnel->next_send_pid, tunnel->max_send_pid))
1985     return th;
1986   LOG (GNUNET_ERROR_TYPE_DEBUG, "    call notify tmt rdy\n");
1987   tunnel->mesh->th =
1988       GNUNET_CLIENT_notify_transmit_ready (tunnel->mesh->client, th->size,
1989                                            GNUNET_TIME_UNIT_FOREVER_REL,
1990                                            GNUNET_YES, &send_callback,
1991                                            tunnel->mesh);
1992   LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH NOTIFY TRANSMIT READY END\n");
1993   return th;
1994 }
1995
1996
1997 /**
1998  * Cancel the specified transmission-ready notification.
1999  *
2000  * @param th handle that was returned by "notify_transmit_ready".
2001  */
2002 void
2003 GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th)
2004 {
2005   struct GNUNET_MESH_Handle *mesh;
2006
2007   th->tunnel->packet_size = 0;
2008   mesh = th->tunnel->mesh;
2009   if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK)
2010     GNUNET_SCHEDULER_cancel (th->timeout_task);
2011   GNUNET_CONTAINER_DLL_remove (mesh->th_head, mesh->th_tail, th);
2012   GNUNET_free (th);
2013   if ((0 == message_ready_size (mesh)) && (NULL != mesh->th))
2014   {
2015     /* queue empty, no point in asking for transmission */
2016     GNUNET_CLIENT_notify_transmit_ready_cancel (mesh->th);
2017     mesh->th = NULL;
2018   }
2019 }
2020
2021
2022 /**
2023  * Request information about the running mesh peer.
2024  * The callback will be called for every tunnel known to the service,
2025  * listing all active peers that blong to the tunnel.
2026  *
2027  * If called again on the same handle, it will overwrite the previous
2028  * callback and cls. To retrieve the cls, monitor_cancel must be
2029  * called first.
2030  *
2031  * WARNING: unstable API, likely to change in the future!
2032  *
2033  * @param h Handle to the mesh peer.
2034  * @param callback Function to call with the requested data.
2035  * @param callback_cls Closure for @c callback.
2036  */
2037 void
2038 GNUNET_MESH_get_tunnels (struct GNUNET_MESH_Handle *h,
2039                          GNUNET_MESH_TunnelsCB callback,
2040                          void *callback_cls)
2041 {
2042   struct GNUNET_MessageHeader msg;
2043
2044   msg.size = htons (sizeof (msg));
2045   msg.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS);
2046   send_packet (h, &msg, NULL);
2047   h->tunnels_cb = callback;
2048   h->tunnels_cls = callback_cls;
2049
2050   return;
2051 }
2052
2053
2054 /**
2055  * Cancel a monitor request. The monitor callback will not be called.
2056  *
2057  * @param h Mesh handle.
2058  *
2059  * @return Closure given to GNUNET_MESH_monitor, if any.
2060  */
2061 void *
2062 GNUNET_MESH_get_tunnels_cancel (struct GNUNET_MESH_Handle *h)
2063 {
2064   void *cls;
2065
2066   cls = h->tunnels_cls;
2067   h->tunnels_cb = NULL;
2068   h->tunnels_cls = NULL;
2069   return cls;
2070 }
2071
2072
2073 /**
2074  * Request information about a specific tunnel of the running mesh peer.
2075  *
2076  * WARNING: unstable API, likely to change in the future!
2077  *
2078  * @param h Handle to the mesh peer.
2079  * @param initiator ID of the owner of the tunnel.
2080  * @param tunnel_number Tunnel number.
2081  * @param callback Function to call with the requested data.
2082  * @param callback_cls Closure for @c callback.
2083  */
2084 void
2085 GNUNET_MESH_show_tunnel (struct GNUNET_MESH_Handle *h,
2086                          struct GNUNET_PeerIdentity *initiator,
2087                          unsigned int tunnel_number,
2088                          GNUNET_MESH_TunnelCB callback,
2089                          void *callback_cls)
2090 {
2091   struct GNUNET_MESH_LocalMonitor msg;
2092
2093   msg.header.size = htons (sizeof (msg));
2094   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL);
2095   msg.npeers = htonl (0);
2096   msg.owner = *initiator;
2097   msg.tunnel_id = htonl (tunnel_number);
2098   msg.reserved = 0;
2099   send_packet (h, &msg.header, NULL);
2100   h->tunnel_cb = callback;
2101   h->tunnel_cls = callback_cls;
2102
2103   return;
2104 }
2105
2106
2107 /**
2108  * Transition API for tunnel ctx management
2109  */
2110 void
2111 GNUNET_MESH_tunnel_set_data (struct GNUNET_MESH_Tunnel *tunnel, void *data)
2112 {
2113   tunnel->ctx = data;
2114 }
2115
2116 /**
2117  * Transition API for tunnel ctx management
2118  */
2119 void *
2120 GNUNET_MESH_tunnel_get_data (struct GNUNET_MESH_Tunnel *tunnel)
2121 {
2122   return tunnel->ctx;
2123 }
2124
2125