-fixed compilation errors
[oweals/gnunet.git] / src / stream / stream_api.c
1 /*
2   This file is part of GNUnet.
3   (C) 2012 Christian Grothoff (and other contributing authors)
4
5   GNUnet is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published
7   by the Free Software Foundation; either version 3, or (at your
8   option) any later version.
9
10   GNUnet is distributed in the hope that it will be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with GNUnet; see the file COPYING.  If not, write to the
17   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18   Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file stream/stream_api.c
23  * @brief Implementation of the stream library
24  * @author Sree Harsha Totakura
25  */
26 #include "platform.h"
27 #include "gnunet_common.h"
28 #include "gnunet_stream_lib.h"
29 #include "stream_protocol.h"
30
31 /**
32  * states in the Protocol
33  */
34 enum State
35   {
36     /**
37      * Client initialization state
38      */
39     STATE_INIT,
40
41     /**
42      * Listener initialization state 
43      */
44     STATE_LISTEN,
45
46     /**
47      * Pre-connection establishment state
48      */
49     STATE_HELLO_WAIT,
50
51     /**
52      * State where a connection has been established
53      */
54     STATE_ESTABLISHED,
55
56     /**
57      * State where the socket is closed on our side and waiting to be ACK'ed
58      */
59     STATE_RECEIVE_CLOSE_WAIT,
60
61     /**
62      * State where the socket is closed for reading
63      */
64     STATE_RECEIVE_CLOSED,
65
66     /**
67      * State where the socket is closed on our side and waiting to be ACK'ed
68      */
69     STATE_TRANSMIT_CLOSE_WAIT,
70
71     /**
72      * State where the socket is closed for writing
73      */
74     STATE_TRANSMIT_CLOSED,
75
76     /**
77      * State where the socket is closed on our side and waiting to be ACK'ed
78      */
79     STATE_CLOSE_WAIT,
80
81     /**
82      * State where the socket is closed
83      */
84     STATE_CLOSED 
85   };
86
87
88 /**
89  * The STREAM Socket Handler
90  */
91 struct GNUNET_STREAM_Socket
92 {
93   /**
94    * The mesh handle
95    */
96   struct GNUNET_MESH_Handle *mesh;
97
98   /**
99    * The mesh tunnel handle
100    */
101   struct GNUNET_MESH_Tunnel *tunnel;
102
103   /**
104    * The session id associated with this stream connection
105    */
106   uint32_t session_id;
107
108   /**
109    * The peer identity of the peer at the other end of the stream
110    */
111   struct GNUNET_PeerIdentity other_peer;
112
113   /**
114    * Stream open closure
115    */
116   void *open_cls;
117
118   /**
119    * Stream open callback
120    */
121   GNUNET_STREAM_OpenCallback open_cb;
122
123   /**
124    * Retransmission timeout
125    */
126   struct GNUNET_TIME_Relative retransmit_timeout;
127
128   /**
129    * The state of the protocol associated with this socket
130    */
131   enum State state;
132
133   /**
134    * The status of the socket
135    */
136   enum GNUNET_STREAM_Status status;
137
138   /**
139    * The current transmit handle (if a pending transmit request exists)
140    */
141   struct GNUNET_MESH_TransmitHandle *transmit_handle;
142
143   /**
144    * The current message associated with the transmit handle
145    */
146   struct GNUNET_MessageHeader *message;
147 };
148
149
150 /**
151  * A socket for listening
152  */
153 struct GNUNET_STREAM_ListenSocket
154 {
155
156   /**
157    * The mesh handle
158    */
159   struct GNUNET_MESH_Handle *mesh;
160
161   /**
162    * The service port
163    */
164   GNUNET_MESH_ApplicationType port;
165
166   /**
167    * The callback function which is called after successful opening socket
168    */
169   GNUNET_STREAM_ListenCallback listen_cb;
170
171   /**
172    * The call back closure
173    */
174   void *listen_cb_cls;
175
176 };
177
178 /**
179  * Default value in seconds for various timeouts
180  */
181 static unsigned int default_timeout = 300;
182
183
184 /**
185  * Callback function from send_message
186  *
187  * @param cls closure the socket on which the send message was called
188  * @param size number of bytes available in buf
189  * @param buf where the callee should write the message
190  * @return number of bytes written to buf
191  */
192 static size_t
193 send_message_notify (void *cls, size_t size, void *buf)
194 {
195   struct GNUNET_STREAM_Socket *socket = cls;
196   size_t ret;
197
198   socket->transmit_handle = NULL; /* Remove the transmit handle */
199   if (0 == size)                /* request timed out */
200     {
201       // statistics ("message timeout")
202       
203       
204       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
205                   "Message not sent as tunnel was closed \n");
206       ret = 0;
207     }
208   else                          /* Size is more or equal to what was requested */
209     {
210       ret = ntohs (socket->message->size);
211       GNUNET_assert (size >= ret);
212       memcpy (buf, socket->message, ret);
213     }
214   GNUNET_free (socket->message); /* Free the message memory */
215   socket->message = NULL;
216   return ret;
217 }
218
219
220 /**
221  * Sends a message using the mesh connection of a socket
222  *
223  * @param socket the socket whose mesh connection is used
224  * @param message the message to be sent
225  */
226 static void
227 send_message (struct GNUNET_STREAM_Socket *socket,
228               struct GNUNET_MessageHeader *message)
229 {
230   socket->message = message;
231   socket->transmit_handle = 
232     GNUNET_MESH_notify_transmit_ready (socket->tunnel,
233                                        0, /* Corking */
234                                        1, /* Priority */
235                                        socket->retransmit_timeout,
236                                        &socket->other_peer,
237                                        ntohs (message->size),
238                                        &send_message_notify,
239                                        socket);
240 }
241
242 /**
243  * Makes state transition dependending on the given state
244  *
245  * @param socket the socket whose state has to be transitioned
246  */
247 static void
248 make_state_transition (struct GNUNET_STREAM_Socket *socket)
249 {
250
251 }
252
253
254 /**
255  * Client's message Handler for GNUNET_MESSAGE_TYPE_STREAM_DATA
256  *
257  * @param cls the socket (set from GNUNET_MESH_connect)
258  * @param tunnel connection to the other end
259  * @param tunnel_ctx place to store local state associated with the tunnel
260  * @param sender who sent the message
261  * @param message the actual message
262  * @param atsi performance data for the connection
263  * @return GNUNET_OK to keep the connection open,
264  *         GNUNET_SYSERR to close it (signal serious error)
265  */
266 static int
267 client_handle_data (void *cls,
268              struct GNUNET_MESH_Tunnel *tunnel,
269              void **tunnel_ctx,
270              const struct GNUNET_PeerIdentity *sender,
271              const struct GNUNET_MessageHeader *message,
272              const struct GNUNET_ATS_Information*atsi)
273 {
274   struct GNUNET_STREAM_Socket *socket = cls;
275   uint16_t size;
276   const struct GNUNET_STREAM_DataMessage *data_msg;
277   const void *payload;
278
279   size = ntohs (message->size);
280   if (size < sizeof (struct GNUNET_STREAM_DataMessage))
281   {
282     GNUNET_break_op (0);
283     return GNUNET_SYSERR;
284   }
285   data_msg = (const struct GNUNET_STREAM_DataMessage *) message;
286   size -= sizeof (struct GNUNET_STREAM_DataMessage);
287   payload = &data_msg[1];
288   /* ... */
289   
290   return GNUNET_OK;
291 }
292
293 /**
294  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO
295  *
296  * @param cls the socket (set from GNUNET_MESH_connect)
297  * @param tunnel connection to the other end
298  * @param tunnel_ctx this is NULL
299  * @param sender who sent the message
300  * @param message the actual message
301  * @param atsi performance data for the connection
302  * @return GNUNET_OK to keep the connection open,
303  *         GNUNET_SYSERR to close it (signal serious error)
304  */
305 static int
306 client_handle_hello (void *cls,
307                      struct GNUNET_MESH_Tunnel *tunnel,
308                      void **tunnel_ctx,
309                      const struct GNUNET_PeerIdentity *sender,
310                      const struct GNUNET_MessageHeader *message,
311                      const struct GNUNET_ATS_Information*atsi)
312 {
313   struct GNUNET_STREAM_Socket *socket = cls;
314
315   return GNUNET_OK;
316 }
317
318
319 /**
320  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK
321  *
322  * @param cls the socket (set from GNUNET_MESH_connect)
323  * @param tunnel connection to the other end
324  * @param tunnel_ctx this is NULL
325  * @param sender who sent the message
326  * @param message the actual message
327  * @param atsi performance data for the connection
328  * @return GNUNET_OK to keep the connection open,
329  *         GNUNET_SYSERR to close it (signal serious error)
330  */
331 static int
332 client_handle_hello_ack (void *cls,
333                          struct GNUNET_MESH_Tunnel *tunnel,
334                          void **tunnel_ctx,
335                          const struct GNUNET_PeerIdentity *sender,
336                          const struct GNUNET_MessageHeader *message,
337                          const struct GNUNET_ATS_Information*atsi)
338 {
339   struct GNUNET_STREAM_Socket *socket = cls;
340
341   return GNUNET_OK;
342 }
343
344
345 /**
346  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_RESET
347  *
348  * @param cls the socket (set from GNUNET_MESH_connect)
349  * @param tunnel connection to the other end
350  * @param tunnel_ctx this is NULL
351  * @param sender who sent the message
352  * @param message the actual message
353  * @param atsi performance data for the connection
354  * @return GNUNET_OK to keep the connection open,
355  *         GNUNET_SYSERR to close it (signal serious error)
356  */
357 static int
358 client_handle_reset (void *cls,
359                      struct GNUNET_MESH_Tunnel *tunnel,
360                      void **tunnel_ctx,
361                      const struct GNUNET_PeerIdentity *sender,
362                      const struct GNUNET_MessageHeader *message,
363                      const struct GNUNET_ATS_Information*atsi)
364 {
365   struct GNUNET_STREAM_Socket *socket = cls;
366
367   return GNUNET_OK;
368 }
369
370
371 /**
372  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE
373  *
374  * @param cls the socket (set from GNUNET_MESH_connect)
375  * @param tunnel connection to the other end
376  * @param tunnel_ctx this is NULL
377  * @param sender who sent the message
378  * @param message the actual message
379  * @param atsi performance data for the connection
380  * @return GNUNET_OK to keep the connection open,
381  *         GNUNET_SYSERR to close it (signal serious error)
382  */
383 static int
384 client_handle_transmit_close (void *cls,
385                               struct GNUNET_MESH_Tunnel *tunnel,
386                               void **tunnel_ctx,
387                               const struct GNUNET_PeerIdentity *sender,
388                               const struct GNUNET_MessageHeader *message,
389                               const struct GNUNET_ATS_Information*atsi)
390 {
391   struct GNUNET_STREAM_Socket *socket = cls;
392
393   return GNUNET_OK;
394 }
395
396
397 /**
398  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK
399  *
400  * @param cls the socket (set from GNUNET_MESH_connect)
401  * @param tunnel connection to the other end
402  * @param tunnel_ctx this is NULL
403  * @param sender who sent the message
404  * @param message the actual message
405  * @param atsi performance data for the connection
406  * @return GNUNET_OK to keep the connection open,
407  *         GNUNET_SYSERR to close it (signal serious error)
408  */
409 static int
410 client_handle_transmit_close_ack (void *cls,
411                                   struct GNUNET_MESH_Tunnel *tunnel,
412                                   void **tunnel_ctx,
413                                   const struct GNUNET_PeerIdentity *sender,
414                                   const struct GNUNET_MessageHeader *message,
415                                   const struct GNUNET_ATS_Information*atsi)
416 {
417   struct GNUNET_STREAM_Socket *socket = cls;
418
419   return GNUNET_OK;
420 }
421
422
423 /**
424  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE
425  *
426  * @param cls the socket (set from GNUNET_MESH_connect)
427  * @param tunnel connection to the other end
428  * @param tunnel_ctx this is NULL
429  * @param sender who sent the message
430  * @param message the actual message
431  * @param atsi performance data for the connection
432  * @return GNUNET_OK to keep the connection open,
433  *         GNUNET_SYSERR to close it (signal serious error)
434  */
435 static int
436 client_handle_receive_close (void *cls,
437                              struct GNUNET_MESH_Tunnel *tunnel,
438                              void **tunnel_ctx,
439                              const struct GNUNET_PeerIdentity *sender,
440                              const struct GNUNET_MessageHeader *message,
441                              const struct GNUNET_ATS_Information*atsi)
442 {
443   struct GNUNET_STREAM_Socket *socket = cls;
444
445   return GNUNET_OK;
446 }
447
448
449 /**
450  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK
451  *
452  * @param cls the socket (set from GNUNET_MESH_connect)
453  * @param tunnel connection to the other end
454  * @param tunnel_ctx this is NULL
455  * @param sender who sent the message
456  * @param message the actual message
457  * @param atsi performance data for the connection
458  * @return GNUNET_OK to keep the connection open,
459  *         GNUNET_SYSERR to close it (signal serious error)
460  */
461 static int
462 client_handle_receive_close_ack (void *cls,
463                                  struct GNUNET_MESH_Tunnel *tunnel,
464                                  void **tunnel_ctx,
465                                  const struct GNUNET_PeerIdentity *sender,
466                                  const struct GNUNET_MessageHeader *message,
467                                  const struct GNUNET_ATS_Information*atsi)
468 {
469   struct GNUNET_STREAM_Socket *socket = cls;
470
471   return GNUNET_OK;
472 }
473
474
475 /**
476  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE
477  *
478  * @param cls the socket (set from GNUNET_MESH_connect)
479  * @param tunnel connection to the other end
480  * @param tunnel_ctx this is NULL
481  * @param sender who sent the message
482  * @param message the actual message
483  * @param atsi performance data for the connection
484  * @return GNUNET_OK to keep the connection open,
485  *         GNUNET_SYSERR to close it (signal serious error)
486  */
487 static int
488 client_handle_close (void *cls,
489                      struct GNUNET_MESH_Tunnel *tunnel,
490                      void **tunnel_ctx,
491                      const struct GNUNET_PeerIdentity *sender,
492                      const struct GNUNET_MessageHeader *message,
493                      const struct GNUNET_ATS_Information*atsi)
494 {
495   struct GNUNET_STREAM_Socket *socket = cls;
496
497   return GNUNET_OK;
498 }
499
500
501 /**
502  * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK
503  *
504  * @param cls the socket (set from GNUNET_MESH_connect)
505  * @param tunnel connection to the other end
506  * @param tunnel_ctx this is NULL
507  * @param sender who sent the message
508  * @param message the actual message
509  * @param atsi performance data for the connection
510  * @return GNUNET_OK to keep the connection open,
511  *         GNUNET_SYSERR to close it (signal serious error)
512  */
513 static int
514 client_handle_close_ack (void *cls,
515                          struct GNUNET_MESH_Tunnel *tunnel,
516                          void **tunnel_ctx,
517                          const struct GNUNET_PeerIdentity *sender,
518                          const struct GNUNET_MessageHeader *message,
519                          const struct GNUNET_ATS_Information*atsi)
520 {
521   struct GNUNET_STREAM_Socket *socket = cls;
522
523   return GNUNET_OK;
524 }
525
526 /*****************************/
527 /* Server's Message Handlers */
528 /*****************************/
529
530 /**
531  * Server's message Handler for GNUNET_MESSAGE_TYPE_STREAM_DATA
532  *
533  * @param cls the closure
534  * @param tunnel connection to the other end
535  * @param tunnel_ctx the socket
536  * @param sender who sent the message
537  * @param message the actual message
538  * @param atsi performance data for the connection
539  * @return GNUNET_OK to keep the connection open,
540  *         GNUNET_SYSERR to close it (signal serious error)
541  */
542 static int
543 server_handle_data (void *cls,
544                     struct GNUNET_MESH_Tunnel *tunnel,
545                     void **tunnel_ctx,
546                     const struct GNUNET_PeerIdentity *sender,
547                     const struct GNUNET_MessageHeader *message,
548                     const struct GNUNET_ATS_Information*atsi)
549 {
550   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
551
552   return GNUNET_OK;
553 }
554
555
556 /**
557  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO
558  *
559  * @param cls the closure
560  * @param tunnel connection to the other end
561  * @param tunnel_ctx the socket
562  * @param sender who sent the message
563  * @param message the actual message
564  * @param atsi performance data for the connection
565  * @return GNUNET_OK to keep the connection open,
566  *         GNUNET_SYSERR to close it (signal serious error)
567  */
568 static int
569 server_handle_hello (void *cls,
570                      struct GNUNET_MESH_Tunnel *tunnel,
571                      void **tunnel_ctx,
572                      const struct GNUNET_PeerIdentity *sender,
573                      const struct GNUNET_MessageHeader *message,
574                      const struct GNUNET_ATS_Information*atsi)
575 {
576   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
577
578   return GNUNET_OK;
579 }
580
581
582 /**
583  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK
584  *
585  * @param cls the closure
586  * @param tunnel connection to the other end
587  * @param tunnel_ctx the socket
588  * @param sender who sent the message
589  * @param message the actual message
590  * @param atsi performance data for the connection
591  * @return GNUNET_OK to keep the connection open,
592  *         GNUNET_SYSERR to close it (signal serious error)
593  */
594 static int
595 server_handle_hello_ack (void *cls,
596                          struct GNUNET_MESH_Tunnel *tunnel,
597                          void **tunnel_ctx,
598                          const struct GNUNET_PeerIdentity *sender,
599                          const struct GNUNET_MessageHeader *message,
600                          const struct GNUNET_ATS_Information*atsi)
601 {
602   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
603
604   return GNUNET_OK;
605 }
606
607
608 /**
609  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_RESET
610  *
611  * @param cls the closure
612  * @param tunnel connection to the other end
613  * @param tunnel_ctx the socket
614  * @param sender who sent the message
615  * @param message the actual message
616  * @param atsi performance data for the connection
617  * @return GNUNET_OK to keep the connection open,
618  *         GNUNET_SYSERR to close it (signal serious error)
619  */
620 static int
621 server_handle_reset (void *cls,
622                      struct GNUNET_MESH_Tunnel *tunnel,
623                      void **tunnel_ctx,
624                      const struct GNUNET_PeerIdentity *sender,
625                      const struct GNUNET_MessageHeader *message,
626                      const struct GNUNET_ATS_Information*atsi)
627 {
628   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
629
630   return GNUNET_OK;
631 }
632
633
634 /**
635  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE
636  *
637  * @param cls the closure
638  * @param tunnel connection to the other end
639  * @param tunnel_ctx the socket
640  * @param sender who sent the message
641  * @param message the actual message
642  * @param atsi performance data for the connection
643  * @return GNUNET_OK to keep the connection open,
644  *         GNUNET_SYSERR to close it (signal serious error)
645  */
646 static int
647 server_handle_transmit_close (void *cls,
648                               struct GNUNET_MESH_Tunnel *tunnel,
649                               void **tunnel_ctx,
650                               const struct GNUNET_PeerIdentity *sender,
651                               const struct GNUNET_MessageHeader *message,
652                               const struct GNUNET_ATS_Information*atsi)
653 {
654   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
655
656   return GNUNET_OK;
657 }
658
659
660 /**
661  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK
662  *
663  * @param cls the closure
664  * @param tunnel connection to the other end
665  * @param tunnel_ctx the socket
666  * @param sender who sent the message
667  * @param message the actual message
668  * @param atsi performance data for the connection
669  * @return GNUNET_OK to keep the connection open,
670  *         GNUNET_SYSERR to close it (signal serious error)
671  */
672 static int
673 server_handle_transmit_close_ack (void *cls,
674                                   struct GNUNET_MESH_Tunnel *tunnel,
675                                   void **tunnel_ctx,
676                                   const struct GNUNET_PeerIdentity *sender,
677                                   const struct GNUNET_MessageHeader *message,
678                                   const struct GNUNET_ATS_Information*atsi)
679 {
680   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
681
682   return GNUNET_OK;
683 }
684
685
686 /**
687  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE
688  *
689  * @param cls the closure
690  * @param tunnel connection to the other end
691  * @param tunnel_ctx the socket
692  * @param sender who sent the message
693  * @param message the actual message
694  * @param atsi performance data for the connection
695  * @return GNUNET_OK to keep the connection open,
696  *         GNUNET_SYSERR to close it (signal serious error)
697  */
698 static int
699 server_handle_receive_close (void *cls,
700                              struct GNUNET_MESH_Tunnel *tunnel,
701                              void **tunnel_ctx,
702                              const struct GNUNET_PeerIdentity *sender,
703                              const struct GNUNET_MessageHeader *message,
704                              const struct GNUNET_ATS_Information*atsi)
705 {
706   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
707
708   return GNUNET_OK;
709 }
710
711
712 /**
713  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK
714  *
715  * @param cls the closure
716  * @param tunnel connection to the other end
717  * @param tunnel_ctx the socket
718  * @param sender who sent the message
719  * @param message the actual message
720  * @param atsi performance data for the connection
721  * @return GNUNET_OK to keep the connection open,
722  *         GNUNET_SYSERR to close it (signal serious error)
723  */
724 static int
725 server_handle_receive_close_ack (void *cls,
726                                  struct GNUNET_MESH_Tunnel *tunnel,
727                                  void **tunnel_ctx,
728                                  const struct GNUNET_PeerIdentity *sender,
729                                  const struct GNUNET_MessageHeader *message,
730                                  const struct GNUNET_ATS_Information*atsi)
731 {
732   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
733
734   return GNUNET_OK;
735 }
736
737
738 /**
739  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE
740  *
741  * @param cls the closure
742  * @param tunnel connection to the other end
743  * @param tunnel_ctx the socket
744  * @param sender who sent the message
745  * @param message the actual message
746  * @param atsi performance data for the connection
747  * @return GNUNET_OK to keep the connection open,
748  *         GNUNET_SYSERR to close it (signal serious error)
749  */
750 static int
751 server_handle_close (void *cls,
752                      struct GNUNET_MESH_Tunnel *tunnel,
753                      void **tunnel_ctx,
754                      const struct GNUNET_PeerIdentity *sender,
755                      const struct GNUNET_MessageHeader *message,
756                      const struct GNUNET_ATS_Information*atsi)
757 {
758   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
759
760   return GNUNET_OK;
761 }
762
763
764 /**
765  * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK
766  *
767  * @param cls the closure
768  * @param tunnel connection to the other end
769  * @param tunnel_ctx the socket
770  * @param sender who sent the message
771  * @param message the actual message
772  * @param atsi performance data for the connection
773  * @return GNUNET_OK to keep the connection open,
774  *         GNUNET_SYSERR to close it (signal serious error)
775  */
776 static int
777 server_handle_close_ack (void *cls,
778                          struct GNUNET_MESH_Tunnel *tunnel,
779                          void **tunnel_ctx,
780                          const struct GNUNET_PeerIdentity *sender,
781                          const struct GNUNET_MessageHeader *message,
782                          const struct GNUNET_ATS_Information*atsi)
783 {
784   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
785
786   return GNUNET_OK;
787 }
788
789
790 /**
791  * Message Handler for mesh
792  *
793  * @param cls closure (set from GNUNET_MESH_connect)
794  * @param tunnel connection to the other end
795  * @param tunnel_ctx place to store local state associated with the tunnel
796  * @param sender who sent the message
797  * @param ack the actual message
798  * @param atsi performance data for the connection
799  * @return GNUNET_OK to keep the connection open,
800  *         GNUNET_SYSERR to close it (signal serious error)
801  */
802 static int
803 handle_ack (struct GNUNET_STREAM_Socket *socket,
804             struct GNUNET_MESH_Tunnel *tunnel,
805             const struct GNUNET_PeerIdentity *sender,
806             const struct GNUNET_STREAM_AckMessage *ack,
807             const struct GNUNET_ATS_Information*atsi)
808 {
809   return GNUNET_OK;
810 }
811
812
813 /**
814  * Message Handler for mesh
815  *
816  * @param cls the 'struct GNUNET_STREAM_Socket'
817  * @param tunnel connection to the other end
818  * @param tunnel_ctx unused
819  * @param sender who sent the message
820  * @param message the actual message
821  * @param atsi performance data for the connection
822  * @return GNUNET_OK to keep the connection open,
823  *         GNUNET_SYSERR to close it (signal serious error)
824  */
825 static int
826 client_handle_ack (void *cls,
827                    struct GNUNET_MESH_Tunnel *tunnel,
828                    void **tunnel_ctx,
829                    const struct GNUNET_PeerIdentity *sender,
830                    const struct GNUNET_MessageHeader *message,
831                    const struct GNUNET_ATS_Information*atsi)
832 {
833   struct GNUNET_STREAM_Socket *socket = cls;
834   const struct GNUNET_STREAM_AckMessage *ack = (const struct GNUNET_STREAM_AckMessage *) message;
835  
836   return handle_ack (socket, tunnel, sender, ack, atsi);
837 }
838
839
840 /**
841  * Message Handler for mesh
842  *
843  * @param cls the server's listen socket
844  * @param tunnel connection to the other end
845  * @param tunnel_ctx pointer to the 'struct GNUNET_STREAM_Socket*'
846  * @param sender who sent the message
847  * @param message the actual message
848  * @param atsi performance data for the connection
849  * @return GNUNET_OK to keep the connection open,
850  *         GNUNET_SYSERR to close it (signal serious error)
851  */
852 static int
853 server_handle_ack (void *cls,
854                    struct GNUNET_MESH_Tunnel *tunnel,
855                    void **tunnel_ctx,
856                    const struct GNUNET_PeerIdentity *sender,
857                    const struct GNUNET_MessageHeader *message,
858                    const struct GNUNET_ATS_Information*atsi)
859 {
860   struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
861   const struct GNUNET_STREAM_AckMessage *ack = (const struct GNUNET_STREAM_AckMessage *) message;
862  
863   return handle_ack (socket, tunnel, sender, ack, atsi);
864 }
865
866
867 /**
868  * For client message handlers, the stream socket is in the
869  * closure argument.
870  */
871 static struct GNUNET_MESH_MessageHandler client_message_handlers[] = {
872   {&client_handle_data, GNUNET_MESSAGE_TYPE_STREAM_DATA, 0},
873   {&client_handle_ack, GNUNET_MESSAGE_TYPE_STREAM_ACK, 
874    sizeof (struct GNUNET_STREAM_AckMessage) },
875   {&client_handle_hello, GNUNET_MESSAGE_TYPE_STREAM_HELLO, 
876    sizeof (struct GNUNET_STREAM_MessageHeader)},
877   {&client_handle_hello_ack, GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK,
878    sizeof (struct GNUNET_STREAM_MessageHeader)},
879   {&client_handle_reset, GNUNET_MESSAGE_TYPE_STREAM_RESET,
880    sizeof (struct GNUNET_STREAM_MessageHeader)},
881   {&client_handle_transmit_close, GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE,
882    sizeof (struct GNUNET_STREAM_MessageHeader)},
883   {&client_handle_transmit_close_ack, GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK,
884    sizeof (struct GNUNET_STREAM_MessageHeader)},
885   {&client_handle_receive_close, GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE,
886    sizeof (struct GNUNET_STREAM_MessageHeader)},
887   {&client_handle_receive_close_ack, GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK,
888    sizeof (struct GNUNET_STREAM_MessageHeader)},
889   {&client_handle_close, GNUNET_MESSAGE_TYPE_STREAM_CLOSE,
890    sizeof (struct GNUNET_STREAM_MessageHeader)},
891   {&client_handle_close_ack, GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK,
892    sizeof (struct GNUNET_STREAM_MessageHeader)},
893   {NULL, 0, 0}
894 };
895
896
897 /**
898  * For server message handlers, the stream socket is in the
899  * tunnel context, and the listen socket in the closure argument.
900  */
901 static struct GNUNET_MESH_MessageHandler server_message_handlers[] = {
902   {&server_handle_data, GNUNET_MESSAGE_TYPE_STREAM_DATA, 0},
903   {&server_handle_ack, GNUNET_MESSAGE_TYPE_STREAM_ACK, 
904    sizeof (struct GNUNET_STREAM_AckMessage) },
905   {&server_handle_hello, GNUNET_MESSAGE_TYPE_STREAM_HELLO, 
906    sizeof (struct GNUNET_STREAM_MessageHeader)},
907   {&server_handle_hello_ack, GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK,
908    sizeof (struct GNUNET_STREAM_MessageHeader)},
909   {&server_handle_reset, GNUNET_MESSAGE_TYPE_STREAM_RESET,
910    sizeof (struct GNUNET_STREAM_MessageHeader)},
911   {&server_handle_transmit_close, GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE,
912    sizeof (struct GNUNET_STREAM_MessageHeader)},
913   {&server_handle_transmit_close_ack, GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK,
914    sizeof (struct GNUNET_STREAM_MessageHeader)},
915   {&server_handle_receive_close, GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE,
916    sizeof (struct GNUNET_STREAM_MessageHeader)},
917   {&server_handle_receive_close_ack, GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK,
918    sizeof (struct GNUNET_STREAM_MessageHeader)},
919   {&server_handle_close, GNUNET_MESSAGE_TYPE_STREAM_CLOSE,
920    sizeof (struct GNUNET_STREAM_MessageHeader)},
921   {&server_handle_close_ack, GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK,
922    sizeof (struct GNUNET_STREAM_MessageHeader)},
923   {NULL, 0, 0}
924 };
925
926
927 /**
928  * Function called when our target peer is connected to our tunnel
929  *
930  * @param peer the peer identity of the target
931  * @param atsi performance data for the connection
932  */
933 static void
934 mesh_peer_connect_callback (void *cls,
935                             const struct GNUNET_PeerIdentity *peer,
936                             const struct GNUNET_ATS_Information * atsi)
937 {
938   struct GNUNET_STREAM_Socket *socket = cls;
939
940   if (0 != memcmp (&socket->other_peer, 
941                    peer, 
942                    sizeof (struct GNUNET_PeerIdentity)))
943     {
944       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
945                   "A peer (%s) which is not our target has\
946   connected to our tunnel", GNUNET_i2s (peer));
947       return;
948     }
949   
950   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
951               "Target peer %s connected\n", GNUNET_i2s (peer));
952   
953   /* Set state to INIT */
954   socket->state = STATE_INIT;
955
956   /* Try to achieve ESTABLISHED state */
957   make_state_transition (socket);
958
959   /* Call open callback */
960   if (NULL == socket->open_cls)
961     {
962       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
963                   "STREAM_open callback is NULL\n");
964     }
965   if (NULL != socket->open_cb)
966     {
967       socket->open_cb (socket->open_cls, socket);
968     }
969 }
970
971
972 /**
973  * Function called when our target peer is disconnected from our tunnel
974  *
975  * @param peer the peer identity of the target
976  */
977 static void
978 mesh_peer_disconnect_callback (void *cls,
979                                const struct GNUNET_PeerIdentity *peer)
980 {
981
982 }
983
984
985 /**
986  * Function to find the mapped socket of a tunnel
987  *
988  * @param tunnel the tunnel whose associated socket has to be retrieved
989  * @return the socket corresponding to the tunnel
990  */
991 static struct GNUNET_STREAM_Socket *
992 find_socket (const struct GNUNET_MESH_Tunnel *tunnel)
993 {
994   /* Search tunnel in a list or hashtable and retrieve the socket */
995 }
996
997 /*****************/
998 /* API functions */
999 /*****************/
1000
1001
1002 /**
1003  * Tries to open a stream to the target peer
1004  *
1005  * @param cfg configuration to use
1006  * @param target the target peer to which the stream has to be opened
1007  * @param app_port the application port number which uniquely identifies this
1008  *            stream
1009  * @param open_cb this function will be called after stream has be established 
1010  * @param open_cb_cls the closure for open_cb
1011  * @param ... options to the stream, terminated by GNUNET_STREAM_OPTION_END
1012  * @return if successful it returns the stream socket; NULL if stream cannot be
1013  *         opened 
1014  */
1015 struct GNUNET_STREAM_Socket *
1016 GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg,
1017                     const struct GNUNET_PeerIdentity *target,
1018                     GNUNET_MESH_ApplicationType app_port,
1019                     GNUNET_STREAM_OpenCallback open_cb,
1020                     void *open_cb_cls,
1021                     ...)
1022 {
1023   struct GNUNET_STREAM_Socket *socket;
1024   enum GNUNET_STREAM_Option option;
1025   va_list vargs;                /* Variable arguments */
1026
1027   socket = GNUNET_malloc (sizeof (struct GNUNET_STREAM_Socket));
1028   socket->other_peer = *target;
1029   socket->open_cb = open_cb;
1030   socket->open_cls = open_cb_cls;
1031
1032   /* Set defaults */
1033   socket->retransmit_timeout = 
1034     GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, default_timeout);
1035
1036   va_start (vargs, open_cb_cls); /* Parse variable args */
1037   do {
1038     option = va_arg (vargs, enum GNUNET_STREAM_Option);
1039     switch (option)
1040       {
1041       case GNUNET_STREAM_OPTION_INITIAL_RETRANSMIT_TIMEOUT:
1042         /* Expect struct GNUNET_TIME_Relative */
1043         socket->retransmit_timeout = va_arg (vargs,
1044                                              struct GNUNET_TIME_Relative);
1045         break;
1046       case GNUNET_STREAM_OPTION_END:
1047         break;
1048       }
1049
1050   } while (0 != option);
1051   va_end (vargs);               /* End of variable args parsing */
1052
1053   socket->mesh = GNUNET_MESH_connect (cfg, /* the configuration handle */
1054                                       1,  /* QUEUE size as parameter? */
1055                                       socket, /* cls */
1056                                       NULL, /* No inbound tunnel handler */
1057                                       NULL, /* No inbound tunnel cleaner */
1058                                       client_message_handlers,
1059                                       NULL); /* We don't get inbound tunnels */
1060   // FIXME: if (NULL == socket->mesh) ...
1061
1062   /* Now create the mesh tunnel to target */
1063   socket->tunnel = GNUNET_MESH_tunnel_create (socket->mesh,
1064                                               NULL, /* Tunnel context */
1065                                               &mesh_peer_connect_callback,
1066                                               &mesh_peer_disconnect_callback,
1067                                               (void *) socket);
1068   // FIXME: if (NULL == socket->tunnel) ...
1069
1070   return socket;
1071 }
1072
1073
1074 /**
1075  * Closes the stream
1076  *
1077  * @param socket the stream socket
1078  */
1079 void
1080 GNUNET_STREAM_close (struct GNUNET_STREAM_Socket *socket)
1081 {
1082   /* Clear Transmit handles */
1083   if (NULL != socket->transmit_handle)
1084     {
1085       GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle);
1086     }
1087   /* Clear existing message queue message */
1088   if (NULL != socket->message)
1089     {
1090       GNUNET_free (socket->message);
1091     }
1092   /* Close associated tunnel */
1093   if (NULL != socket->tunnel)
1094     {
1095       GNUNET_MESH_tunnel_destroy (socket->tunnel);
1096     }
1097   /* Close mesh connection */
1098   if (NULL != socket->mesh)
1099     {
1100       GNUNET_MESH_disconnect (socket->mesh);
1101     }
1102   GNUNET_free (socket);
1103 }
1104
1105
1106 /**
1107  * Method called whenever a peer creates a tunnel to us
1108  *
1109  * @param cls closure
1110  * @param tunnel new handle to the tunnel
1111  * @param initiator peer that started the tunnel
1112  * @param atsi performance information for the tunnel
1113  * @return initial tunnel context for the tunnel
1114  *         (can be NULL -- that's not an error)
1115  */
1116 static void *
1117 new_tunnel_notify (void *cls,
1118                    struct GNUNET_MESH_Tunnel *tunnel,
1119                    const struct GNUNET_PeerIdentity *initiator,
1120                    const struct GNUNET_ATS_Information *atsi)
1121 {
1122   struct GNUNET_STREAM_ListenSocket *lsocket = cls;
1123   struct GNUNET_STREAM_Socket *socket;
1124
1125   socket = GNUNET_malloc (sizeof (struct GNUNET_STREAM_Socket));
1126   socket->tunnel = tunnel;
1127   socket->session_id = 0;       /* FIXME */
1128   socket->other_peer = *initiator;
1129   socket->state = STATE_LISTEN;
1130
1131   if (GNUNET_SYSERR == lsocket->listen_cb (lsocket->listen_cb_cls,
1132                                            socket,
1133                                            &socket->other_peer))
1134     {
1135       socket->state = STATE_CLOSED;
1136       make_state_transition (socket);
1137       GNUNET_free (socket);
1138       GNUNET_MESH_tunnel_destroy (tunnel); /* Destroy the tunnel */
1139     }
1140   else
1141     {
1142       make_state_transition (socket);
1143     }
1144   return socket;
1145 }
1146
1147
1148 /**
1149  * Function called whenever an inbound tunnel is destroyed.  Should clean up
1150  * any associated state.  This function is NOT called if the client has
1151  * explicitly asked for the tunnel to be destroyed using
1152  * GNUNET_MESH_tunnel_destroy. It must NOT call GNUNET_MESH_tunnel_destroy on
1153  * the tunnel.
1154  *
1155  * @param cls closure (set from GNUNET_MESH_connect)
1156  * @param tunnel connection to the other end (henceforth invalid)
1157  * @param tunnel_ctx place where local state associated
1158  *                   with the tunnel is stored
1159  */
1160 static void 
1161 tunnel_cleaner (void *cls,
1162                 const struct GNUNET_MESH_Tunnel *tunnel,
1163                 void *tunnel_ctx)
1164 {
1165   struct GNUNET_STREAM_ListenSocket *lsocket = cls;
1166   struct GNUNET_STREAM_Socket *socket = tunnel_ctx;
1167
1168   socket = find_socket (tunnel);
1169   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1170               "Peer %s has terminated connection abruptly\n",
1171               GNUNET_i2s (&socket->other_peer));
1172
1173   socket->status = GNUNET_STREAM_SHUTDOWN;
1174   /* Clear Transmit handles */
1175   if (NULL != socket->transmit_handle)
1176     {
1177       GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle);
1178       socket->transmit_handle = NULL;
1179     }
1180    
1181   /* Clear existing message queue message */
1182   if (NULL != socket->message)
1183     {
1184       GNUNET_free (socket->message);
1185       socket->message = NULL;
1186     }
1187 }
1188
1189
1190 /**
1191  * Listens for stream connections for a specific application ports
1192  *
1193  * @param cfg the configuration to use
1194  * @param app_port the application port for which new streams will be accepted
1195  * @param listen_cb this function will be called when a peer tries to establish
1196  *            a stream with us
1197  * @param listen_cb_cls closure for listen_cb
1198  * @return listen socket, NULL for any error
1199  */
1200 struct GNUNET_STREAM_ListenSocket *
1201 GNUNET_STREAM_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
1202                       GNUNET_MESH_ApplicationType app_port,
1203                       GNUNET_STREAM_ListenCallback listen_cb,
1204                       void *listen_cb_cls)
1205 {
1206   /* FIXME: Add variable args for passing configration options? */
1207   struct GNUNET_STREAM_ListenSocket *lsocket;
1208   GNUNET_MESH_ApplicationType app_types[2];
1209
1210   app_types[0] = app_port;
1211   app_types[1] = NULL;
1212   lsocket = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ListenSocket));
1213   lsocket->port = app_port;
1214   lsocket->listen_cb = listen_cb;
1215   lsocket->listen_cb_cls = listen_cb_cls;
1216   lsocket->mesh = GNUNET_MESH_connect (cfg,
1217                                        10, /* FIXME: QUEUE size as parameter? */
1218                                        lsocket, /* Closure */
1219                                        &new_tunnel_notify,
1220                                        &tunnel_cleaner,
1221                                        server_message_handlers,
1222                                        app_types);
1223   return lsocket;
1224 }
1225
1226
1227 /**
1228  * Closes the listen socket
1229  *
1230  * @param socket the listen socket
1231  */
1232 void
1233 GNUNET_STREAM_listen_close (struct GNUNET_STREAM_ListenSocket *lsocket)
1234 {
1235   /* Do house keeping */
1236
1237   /* Close MESH connection */
1238   GNUNET_MESH_disconnect (lsocket->mesh);
1239   
1240   GNUNET_free (lsocket);
1241 }