2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file stream/stream_api.c
23 * @brief Implementation of the stream library
24 * @author Sree Harsha Totakura
27 #include "gnunet_common.h"
28 #include "gnunet_stream_lib.h"
29 #include "stream_protocol.h"
32 * states in the Protocol
37 * Client initialization state
42 * Listener initialization state
47 * Pre-connection establishment state
52 * State where a connection has been established
57 * State where the socket is closed on our side and waiting to be ACK'ed
59 STATE_RECEIVE_CLOSE_WAIT,
62 * State where the socket is closed for reading
67 * State where the socket is closed on our side and waiting to be ACK'ed
69 STATE_TRANSMIT_CLOSE_WAIT,
72 * State where the socket is closed for writing
74 STATE_TRANSMIT_CLOSED,
77 * State where the socket is closed on our side and waiting to be ACK'ed
82 * State where the socket is closed
89 * The STREAM Socket Handler
91 struct GNUNET_STREAM_Socket
96 struct GNUNET_MESH_Handle *mesh;
99 * The mesh tunnel handle
101 struct GNUNET_MESH_Tunnel *tunnel;
104 * The session id associated with this stream connection
109 * The peer identity of the peer at the other end of the stream
111 struct GNUNET_PeerIdentity other_peer;
114 * Stream open closure
119 * Stream open callback
121 GNUNET_STREAM_OpenCallback open_cb;
124 * Retransmission timeout
126 struct GNUNET_TIME_Relative retransmit_timeout;
129 * The state of the protocol associated with this socket
134 * The status of the socket
136 enum GNUNET_STREAM_Status status;
139 * The current transmit handle (if a pending transmit request exists)
141 struct GNUNET_MESH_TransmitHandle *transmit_handle;
144 * The current message associated with the transmit handle
146 struct GNUNET_MessageHeader *message;
151 * A socket for listening
153 struct GNUNET_STREAM_ListenSocket
159 struct GNUNET_MESH_Handle *mesh;
164 GNUNET_MESH_ApplicationType port;
167 * The callback function which is called after successful opening socket
169 GNUNET_STREAM_ListenCallback listen_cb;
172 * The call back closure
179 * Default value in seconds for various timeouts
181 static unsigned int default_timeout = 300;
185 * Callback function from send_message
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
193 send_message_notify (void *cls, size_t size, void *buf)
195 struct GNUNET_STREAM_Socket *socket = cls;
198 socket->transmit_handle = NULL; /* Remove the transmit handle */
199 if (0 == size) /* request timed out */
201 // statistics ("message timeout")
204 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
205 "Message not sent as tunnel was closed \n");
208 else /* Size is more or equal to what was requested */
210 ret = ntohs (socket->message->size);
211 GNUNET_assert (size >= ret);
212 memcpy (buf, socket->message, ret);
214 GNUNET_free (socket->message); /* Free the message memory */
215 socket->message = NULL;
221 * Sends a message using the mesh connection of a socket
223 * @param socket the socket whose mesh connection is used
224 * @param message the message to be sent
227 send_message (struct GNUNET_STREAM_Socket *socket,
228 struct GNUNET_MessageHeader *message)
230 socket->message = message;
231 socket->transmit_handle =
232 GNUNET_MESH_notify_transmit_ready (socket->tunnel,
235 socket->retransmit_timeout,
237 ntohs (message->size),
238 &send_message_notify,
243 * Makes state transition dependending on the given state
245 * @param socket the socket whose state has to be transitioned
248 make_state_transition (struct GNUNET_STREAM_Socket *socket)
255 * Client's message Handler for GNUNET_MESSAGE_TYPE_STREAM_DATA
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)
267 client_handle_data (void *cls,
268 struct GNUNET_MESH_Tunnel *tunnel,
270 const struct GNUNET_PeerIdentity *sender,
271 const struct GNUNET_MessageHeader *message,
272 const struct GNUNET_ATS_Information*atsi)
274 struct GNUNET_STREAM_Socket *socket = cls;
276 const struct GNUNET_STREAM_DataMessage *data_msg;
279 size = ntohs (message->size);
280 if (size < sizeof (struct GNUNET_STREAM_DataMessage))
283 return GNUNET_SYSERR;
285 data_msg = (const struct GNUNET_STREAM_DataMessage *) message;
286 size -= sizeof (struct GNUNET_STREAM_DataMessage);
287 payload = &data_msg[1];
294 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO
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)
306 client_handle_hello (void *cls,
307 struct GNUNET_MESH_Tunnel *tunnel,
309 const struct GNUNET_PeerIdentity *sender,
310 const struct GNUNET_MessageHeader *message,
311 const struct GNUNET_ATS_Information*atsi)
313 struct GNUNET_STREAM_Socket *socket = cls;
320 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK
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)
332 client_handle_hello_ack (void *cls,
333 struct GNUNET_MESH_Tunnel *tunnel,
335 const struct GNUNET_PeerIdentity *sender,
336 const struct GNUNET_MessageHeader *message,
337 const struct GNUNET_ATS_Information*atsi)
339 struct GNUNET_STREAM_Socket *socket = cls;
346 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_RESET
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)
358 client_handle_reset (void *cls,
359 struct GNUNET_MESH_Tunnel *tunnel,
361 const struct GNUNET_PeerIdentity *sender,
362 const struct GNUNET_MessageHeader *message,
363 const struct GNUNET_ATS_Information*atsi)
365 struct GNUNET_STREAM_Socket *socket = cls;
372 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE
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)
384 client_handle_transmit_close (void *cls,
385 struct GNUNET_MESH_Tunnel *tunnel,
387 const struct GNUNET_PeerIdentity *sender,
388 const struct GNUNET_MessageHeader *message,
389 const struct GNUNET_ATS_Information*atsi)
391 struct GNUNET_STREAM_Socket *socket = cls;
398 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK
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)
410 client_handle_transmit_close_ack (void *cls,
411 struct GNUNET_MESH_Tunnel *tunnel,
413 const struct GNUNET_PeerIdentity *sender,
414 const struct GNUNET_MessageHeader *message,
415 const struct GNUNET_ATS_Information*atsi)
417 struct GNUNET_STREAM_Socket *socket = cls;
424 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE
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)
436 client_handle_receive_close (void *cls,
437 struct GNUNET_MESH_Tunnel *tunnel,
439 const struct GNUNET_PeerIdentity *sender,
440 const struct GNUNET_MessageHeader *message,
441 const struct GNUNET_ATS_Information*atsi)
443 struct GNUNET_STREAM_Socket *socket = cls;
450 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK
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)
462 client_handle_receive_close_ack (void *cls,
463 struct GNUNET_MESH_Tunnel *tunnel,
465 const struct GNUNET_PeerIdentity *sender,
466 const struct GNUNET_MessageHeader *message,
467 const struct GNUNET_ATS_Information*atsi)
469 struct GNUNET_STREAM_Socket *socket = cls;
476 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE
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)
488 client_handle_close (void *cls,
489 struct GNUNET_MESH_Tunnel *tunnel,
491 const struct GNUNET_PeerIdentity *sender,
492 const struct GNUNET_MessageHeader *message,
493 const struct GNUNET_ATS_Information*atsi)
495 struct GNUNET_STREAM_Socket *socket = cls;
502 * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK
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)
514 client_handle_close_ack (void *cls,
515 struct GNUNET_MESH_Tunnel *tunnel,
517 const struct GNUNET_PeerIdentity *sender,
518 const struct GNUNET_MessageHeader *message,
519 const struct GNUNET_ATS_Information*atsi)
521 struct GNUNET_STREAM_Socket *socket = cls;
526 /*****************************/
527 /* Server's Message Handlers */
528 /*****************************/
531 * Server's message Handler for GNUNET_MESSAGE_TYPE_STREAM_DATA
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)
543 server_handle_data (void *cls,
544 struct GNUNET_MESH_Tunnel *tunnel,
546 const struct GNUNET_PeerIdentity *sender,
547 const struct GNUNET_MessageHeader *message,
548 const struct GNUNET_ATS_Information*atsi)
550 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
557 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO
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)
569 server_handle_hello (void *cls,
570 struct GNUNET_MESH_Tunnel *tunnel,
572 const struct GNUNET_PeerIdentity *sender,
573 const struct GNUNET_MessageHeader *message,
574 const struct GNUNET_ATS_Information*atsi)
576 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
583 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK
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)
595 server_handle_hello_ack (void *cls,
596 struct GNUNET_MESH_Tunnel *tunnel,
598 const struct GNUNET_PeerIdentity *sender,
599 const struct GNUNET_MessageHeader *message,
600 const struct GNUNET_ATS_Information*atsi)
602 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
609 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_RESET
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)
621 server_handle_reset (void *cls,
622 struct GNUNET_MESH_Tunnel *tunnel,
624 const struct GNUNET_PeerIdentity *sender,
625 const struct GNUNET_MessageHeader *message,
626 const struct GNUNET_ATS_Information*atsi)
628 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
635 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE
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)
647 server_handle_transmit_close (void *cls,
648 struct GNUNET_MESH_Tunnel *tunnel,
650 const struct GNUNET_PeerIdentity *sender,
651 const struct GNUNET_MessageHeader *message,
652 const struct GNUNET_ATS_Information*atsi)
654 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
661 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK
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)
673 server_handle_transmit_close_ack (void *cls,
674 struct GNUNET_MESH_Tunnel *tunnel,
676 const struct GNUNET_PeerIdentity *sender,
677 const struct GNUNET_MessageHeader *message,
678 const struct GNUNET_ATS_Information*atsi)
680 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
687 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE
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)
699 server_handle_receive_close (void *cls,
700 struct GNUNET_MESH_Tunnel *tunnel,
702 const struct GNUNET_PeerIdentity *sender,
703 const struct GNUNET_MessageHeader *message,
704 const struct GNUNET_ATS_Information*atsi)
706 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
713 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK
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)
725 server_handle_receive_close_ack (void *cls,
726 struct GNUNET_MESH_Tunnel *tunnel,
728 const struct GNUNET_PeerIdentity *sender,
729 const struct GNUNET_MessageHeader *message,
730 const struct GNUNET_ATS_Information*atsi)
732 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
739 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE
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)
751 server_handle_close (void *cls,
752 struct GNUNET_MESH_Tunnel *tunnel,
754 const struct GNUNET_PeerIdentity *sender,
755 const struct GNUNET_MessageHeader *message,
756 const struct GNUNET_ATS_Information*atsi)
758 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
765 * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK
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)
777 server_handle_close_ack (void *cls,
778 struct GNUNET_MESH_Tunnel *tunnel,
780 const struct GNUNET_PeerIdentity *sender,
781 const struct GNUNET_MessageHeader *message,
782 const struct GNUNET_ATS_Information*atsi)
784 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
791 * Message Handler for mesh
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)
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)
814 * Message Handler for mesh
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)
826 client_handle_ack (void *cls,
827 struct GNUNET_MESH_Tunnel *tunnel,
829 const struct GNUNET_PeerIdentity *sender,
830 const struct GNUNET_MessageHeader *message,
831 const struct GNUNET_ATS_Information*atsi)
833 struct GNUNET_STREAM_Socket *socket = cls;
834 const struct GNUNET_STREAM_AckMessage *ack = (const struct GNUNET_STREAM_AckMessage *) message;
836 return handle_ack (socket, tunnel, sender, ack, atsi);
841 * Message Handler for mesh
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)
853 server_handle_ack (void *cls,
854 struct GNUNET_MESH_Tunnel *tunnel,
856 const struct GNUNET_PeerIdentity *sender,
857 const struct GNUNET_MessageHeader *message,
858 const struct GNUNET_ATS_Information*atsi)
860 struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
861 const struct GNUNET_STREAM_AckMessage *ack = (const struct GNUNET_STREAM_AckMessage *) message;
863 return handle_ack (socket, tunnel, sender, ack, atsi);
868 * For client message handlers, the stream socket is in the
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)},
898 * For server message handlers, the stream socket is in the
899 * tunnel context, and the listen socket in the closure argument.
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)},
928 * Function called when our target peer is connected to our tunnel
930 * @param peer the peer identity of the target
931 * @param atsi performance data for the connection
934 mesh_peer_connect_callback (void *cls,
935 const struct GNUNET_PeerIdentity *peer,
936 const struct GNUNET_ATS_Information * atsi)
938 struct GNUNET_STREAM_Socket *socket = cls;
940 if (0 != memcmp (&socket->other_peer,
942 sizeof (struct GNUNET_PeerIdentity)))
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));
950 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
951 "Target peer %s connected\n", GNUNET_i2s (peer));
953 /* Set state to INIT */
954 socket->state = STATE_INIT;
956 /* Try to achieve ESTABLISHED state */
957 make_state_transition (socket);
959 /* Call open callback */
960 if (NULL == socket->open_cls)
962 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
963 "STREAM_open callback is NULL\n");
965 if (NULL != socket->open_cb)
967 socket->open_cb (socket->open_cls, socket);
973 * Function called when our target peer is disconnected from our tunnel
975 * @param peer the peer identity of the target
978 mesh_peer_disconnect_callback (void *cls,
979 const struct GNUNET_PeerIdentity *peer)
986 * Function to find the mapped socket of a tunnel
988 * @param tunnel the tunnel whose associated socket has to be retrieved
989 * @return the socket corresponding to the tunnel
991 static struct GNUNET_STREAM_Socket *
992 find_socket (const struct GNUNET_MESH_Tunnel *tunnel)
994 /* Search tunnel in a list or hashtable and retrieve the socket */
1003 * Tries to open a stream to the target peer
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
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
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,
1023 struct GNUNET_STREAM_Socket *socket;
1024 enum GNUNET_STREAM_Option option;
1025 va_list vargs; /* Variable arguments */
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;
1033 socket->retransmit_timeout =
1034 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, default_timeout);
1036 va_start (vargs, open_cb_cls); /* Parse variable args */
1038 option = va_arg (vargs, enum GNUNET_STREAM_Option);
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);
1046 case GNUNET_STREAM_OPTION_END:
1050 } while (0 != option);
1051 va_end (vargs); /* End of variable args parsing */
1053 socket->mesh = GNUNET_MESH_connect (cfg, /* the configuration handle */
1054 1, /* QUEUE size as parameter? */
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) ...
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,
1068 // FIXME: if (NULL == socket->tunnel) ...
1077 * @param socket the stream socket
1080 GNUNET_STREAM_close (struct GNUNET_STREAM_Socket *socket)
1082 /* Clear Transmit handles */
1083 if (NULL != socket->transmit_handle)
1085 GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle);
1087 /* Clear existing message queue message */
1088 if (NULL != socket->message)
1090 GNUNET_free (socket->message);
1092 /* Close associated tunnel */
1093 if (NULL != socket->tunnel)
1095 GNUNET_MESH_tunnel_destroy (socket->tunnel);
1097 /* Close mesh connection */
1098 if (NULL != socket->mesh)
1100 GNUNET_MESH_disconnect (socket->mesh);
1102 GNUNET_free (socket);
1107 * Method called whenever a peer creates a tunnel to us
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)
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)
1122 struct GNUNET_STREAM_ListenSocket *lsocket = cls;
1123 struct GNUNET_STREAM_Socket *socket;
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;
1131 if (GNUNET_SYSERR == lsocket->listen_cb (lsocket->listen_cb_cls,
1133 &socket->other_peer))
1135 socket->state = STATE_CLOSED;
1136 make_state_transition (socket);
1137 GNUNET_free (socket);
1138 GNUNET_MESH_tunnel_destroy (tunnel); /* Destroy the tunnel */
1142 make_state_transition (socket);
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
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
1161 tunnel_cleaner (void *cls,
1162 const struct GNUNET_MESH_Tunnel *tunnel,
1165 struct GNUNET_STREAM_ListenSocket *lsocket = cls;
1166 struct GNUNET_STREAM_Socket *socket = tunnel_ctx;
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));
1173 socket->status = GNUNET_STREAM_SHUTDOWN;
1174 /* Clear Transmit handles */
1175 if (NULL != socket->transmit_handle)
1177 GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle);
1178 socket->transmit_handle = NULL;
1181 /* Clear existing message queue message */
1182 if (NULL != socket->message)
1184 GNUNET_free (socket->message);
1185 socket->message = NULL;
1191 * Listens for stream connections for a specific application ports
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
1197 * @param listen_cb_cls closure for listen_cb
1198 * @return listen socket, NULL for any error
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)
1206 /* FIXME: Add variable args for passing configration options? */
1207 struct GNUNET_STREAM_ListenSocket *lsocket;
1208 GNUNET_MESH_ApplicationType app_types[2];
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 */
1221 server_message_handlers,
1228 * Closes the listen socket
1230 * @param socket the listen socket
1233 GNUNET_STREAM_listen_close (struct GNUNET_STREAM_ListenSocket *lsocket)
1235 /* Do house keeping */
1237 /* Close MESH connection */
1238 GNUNET_MESH_disconnect (lsocket->mesh);
1240 GNUNET_free (lsocket);