aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-06-24 08:04:56 +0000
committerBart Polot <bart@net.in.tum.de>2011-06-24 08:04:56 +0000
commit8153b07b74e4fc34992dee4360173389656bb366 (patch)
treed631ae5946b893a5276d73fc51847a2d1a306252
parentb734352920d1731a739800549b0281421fe7b98c (diff)
downloadgnunet-8153b07b74e4fc34992dee4360173389656bb366.tar.gz
gnunet-8153b07b74e4fc34992dee4360173389656bb366.zip
WiP (mesh data handling and connection ACKs)
-rw-r--r--src/include/gnunet_protocols.h2
-rw-r--r--src/mesh/gnunet-service-mesh.c225
-rw-r--r--src/mesh/mesh.h2
3 files changed, 209 insertions, 20 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 598d566bf..000b71f3b 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -835,7 +835,7 @@ extern "C"
835/** 835/**
836 * We need flow control 836 * We need flow control
837 */ 837 */
838#define GNUNET_MESSAGE_TYPE_MESH_SPEED_NOTIFY 263 838#define GNUNET_MESSAGE_TYPE_MESH_SPEED_NOTIFY 270
839 839
840/** 840/**
841 * Connect to the mesh service, specifying subscriptions 841 * Connect to the mesh service, specifying subscriptions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 6cf01b6d4..afa9aec03 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -468,6 +468,29 @@ add_path_to_peer(struct MeshPeerInfo *peer_info, struct MeshPath *path)
468 468
469 469
470/** 470/**
471 * Add the path to the peer and update the path used to reach it in case this
472 * is the shortest. The path is given in reverse, the destination peer is
473 * path[0]. The function modifies the path, inverting it to use the origin as
474 * destination.
475 * @param peer_info Destination peer to add the path to.
476 * @param path New path to add. First peer must be the peer in arg 1.
477 */
478static void
479add_path_to_origin(struct MeshPeerInfo *peer_info, struct MeshPath *path)
480{
481 GNUNET_PEER_Id aux;
482 unsigned int i;
483
484 for (i = 0; i < path->length/2; i++) {
485 aux = path->peers[i];
486 path->peers[i] = path->peers[path->length - i - 1];
487 path->peers[path->length - i - 1] = aux;
488 }
489 add_path_to_peer(peer_info, path);
490}
491
492
493/**
471 * Check if client has registered with the service and has not disconnected 494 * Check if client has registered with the service and has not disconnected
472 * @param client the client to check 495 * @param client the client to check
473 * @return non-NULL if client exists in the global DLL 496 * @return non-NULL if client exists in the global DLL
@@ -672,13 +695,116 @@ send_core_create_path_for_peer (void *cls, size_t size, void *buf)
672 GNUNET_PEER_resolve(p->peers[i], peer_ptr++); 695 GNUNET_PEER_resolve(p->peers[i], peer_ptr++);
673 } 696 }
674 697
675 peer_info->state = MESH_PEER_WAITING; // TODO maybe already ready? 698 peer_info->state = MESH_PEER_WAITING;
676 699
677 return size_needed; 700 return size_needed;
678} 701}
679 702
703/**
704 * FIXME / COMMENT
705 * There are several options to send a "data to origin" or similar packet.
706 * The core callback function needs to know at least: ID of tunnel and the
707 * data itself, so one parameter (cls) is not enough.
708 * 1. Build the message inside the original funtction, call core_ntfy_trnsmt_rdy
709 * passing the created message as cls
710 * - # memcpy: 2 (function X: to message struct, callback: from cls to buf)
711 * - Very messy, original function becomes huge and ugly
712 * (see "handle_mesh_path_create" for example)
713 * 2. Create a helper function to build the packet, then call
714 * core_ntfy_trnsmt_rdy with message as cls.
715 * - # memcpy: 2 (in helper function data->msg and in callback cls->buf)
716 * 3- Define new container, pass container with pointers
717 * - # memcpy = 1 (in callback, cls->buf)
718 * - Noise: extra containers defined per type of message
719 */
720 struct info_for_data_to_origin
721{
722 struct MESH_TunnelID *origin;
723 void *data;
724 size_t size;
725};
726
727/**
728 * Function called to notify a client about the socket
729 * being ready to queue more data. "buf" will be
730 * NULL and "size" zero if the socket was closed for
731 * writing in the meantime.
732 *
733 * @param cls closure (data itself)
734 * @param size number of bytes available in buf
735 * @param buf where the callee should write the message
736 * @return number of bytes written to buf
737 */
738static size_t
739send_core_data_to_origin (void *cls, size_t size, void *buf)
740{
741 struct info_for_data_to_origin *info = cls;
742 struct GNUNET_MESH_DataMessageToOrigin *msg = buf;
743 size_t total_size;
744
745 GNUNET_assert(NULL != info);
746 total_size = sizeof(struct GNUNET_MESH_DataMessageToOrigin) + info->size;
747 GNUNET_assert(total_size < (uint16_t) -1); /* FIXME */
748
749 if (total_size > size) {
750 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
751 "not enough buffer to send data to origin\n");
752 return 0;
753 }
754 msg->header.size = htons(total_size);
755 msg->header.type = htons(GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN);
756 GNUNET_PEER_resolve(info->origin->oid, &msg->oid);
757 msg->tid = htonl(info->origin->tid);
758 if (0 != info->size && NULL != info->data) {
759 memcpy(&msg[1], info->data, info->size);
760 }
761 GNUNET_free(info);
762 return total_size;
763}
764
765
680#if LATER 766#if LATER
681/** 767/**
768 * Function called to notify a client about the socket
769 * being ready to queue more data. "buf" will be
770 * NULL and "size" zero if the socket was closed for
771 * writing in the meantime.
772 *
773 * @param cls closure (data itself)
774 * @param size number of bytes available in buf
775 * @param buf where the callee should write the message
776 * @return number of bytes written to buf
777 */
778static size_t
779send_core_data_to_peer (void *cls, size_t size, void *buf)
780{
781 struct info_for_data_to_origin *info = cls;
782 struct GNUNET_MESH_DataMessageToOrigin *msg = buf;
783 size_t total_size;
784
785 GNUNET_assert(NULL != info);
786 total_size = sizeof(struct GNUNET_MESH_DataMessageToOrigin) + info->size;
787 /* FIXME better constant? short >= 16 bits, not == 16 bits... */
788 GNUNET_assert(total_size < USHRT_MAX);
789
790 if (total_size > size) {
791 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
792 "not enough buffer to send data to origin\n");
793 return 0;
794 }
795 msg->header.size = htons(total_size);
796 msg->header.type = htons(GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN);
797 GNUNET_PEER_resolve(info->origin->oid, &msg->oid);
798 msg->tid = htonl(info->origin->tid);
799 if (0 != info->size && NULL != info->data) {
800 memcpy(&msg[1], info->data, info->size);
801 }
802 GNUNET_free(info);
803 return total_size;
804}
805
806
807/**
682 * Send another peer a notification to destroy a tunnel 808 * Send another peer a notification to destroy a tunnel
683 * @param cls The tunnel to destroy 809 * @param cls The tunnel to destroy
684 * @param size Size in the buffer 810 * @param size Size in the buffer
@@ -734,9 +860,11 @@ handle_mesh_path_create (void *cls,
734 MESH_TunnelNumber tid; 860 MESH_TunnelNumber tid;
735 struct GNUNET_MESH_ManipulatePath *msg; 861 struct GNUNET_MESH_ManipulatePath *msg;
736 struct GNUNET_PeerIdentity *pi; 862 struct GNUNET_PeerIdentity *pi;
863 struct GNUNET_PeerIdentity id;
737 GNUNET_HashCode hash; 864 GNUNET_HashCode hash;
738 struct MeshPath *path; 865 struct MeshPath *path;
739 struct MeshPeerInfo *peer_info; 866 struct MeshPeerInfo *dest_peer_info;
867 struct MeshPeerInfo *orig_peer_info;
740 struct MeshTunnel *t; 868 struct MeshTunnel *t;
741 869
742 870
@@ -786,17 +914,28 @@ handle_mesh_path_create (void *cls,
786 } 914 }
787 915
788 } 916 }
789 peer_info = GNUNET_CONTAINER_multihashmap_get(peers, 917 dest_peer_info = GNUNET_CONTAINER_multihashmap_get(peers,
790 &pi[size - 1].hashPubKey); 918 &pi[size - 1].hashPubKey);
791 if (NULL == peer_info) { 919 if (NULL == dest_peer_info) {
792 peer_info = GNUNET_malloc(sizeof(struct MeshPeerInfo)); 920 dest_peer_info = GNUNET_malloc(sizeof(struct MeshPeerInfo));
793 peer_info->id = GNUNET_PEER_intern(&pi[size - 1]); 921 dest_peer_info->id = GNUNET_PEER_intern(&pi[size - 1]);
794 peer_info->state = MESH_PEER_WAITING; 922 dest_peer_info->state = MESH_PEER_WAITING;
795 GNUNET_CONTAINER_multihashmap_put(peers, 923 GNUNET_CONTAINER_multihashmap_put(peers,
796 &pi[size - 1].hashPubKey, 924 &pi[size - 1].hashPubKey,
797 peer_info, 925 dest_peer_info,
798 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 926 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
799 } 927 }
928 orig_peer_info = GNUNET_CONTAINER_multihashmap_get(peers, &pi->hashPubKey);
929 if (NULL == orig_peer_info) {
930 orig_peer_info = GNUNET_malloc(sizeof(struct MeshPeerInfo));
931 orig_peer_info->id = GNUNET_PEER_intern(pi);
932 orig_peer_info->state = MESH_PEER_WAITING;
933 GNUNET_CONTAINER_multihashmap_put(peers,
934 &pi->hashPubKey,
935 orig_peer_info,
936 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
937 }
938
800 939
801 path = GNUNET_malloc(sizeof(struct MeshPath)); 940 path = GNUNET_malloc(sizeof(struct MeshPath));
802 path->length = size; 941 path->length = size;
@@ -810,15 +949,42 @@ handle_mesh_path_create (void *cls,
810 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 949 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
811 "create path: self not found in path through self\n"); 950 "create path: self not found in path through self\n");
812 destroy_path(path); 951 destroy_path(path);
813 /* FIXME destroy tunnel? leave for timeout? */ 952 /* FIXME error. destroy tunnel? leave for timeout? */
814 return 0; 953 return 0;
815 } 954 }
816 if (own_pos == size - 1) { /* it is for us! */ 955 if (own_pos == size - 1) { /* it is for us! */
817 destroy_path(path); /* not needed anymore */ 956 add_path_to_origin(orig_peer_info, path); /* inverts path! */
818 /* TODO: send ack? new meesage type? */ 957 GNUNET_PEER_resolve(get_first_hop(path), &id); /* path is inverted :) */
958 /* FIXME / COMMENT
959 * is it allowed/desired to declare variables this way?
960 * (style, best bractices, etc)
961 * This variable is short lived and completely irrelevant for the rest
962 * of the function
963 */
964 struct info_for_data_to_origin *info =
965 GNUNET_malloc(sizeof(struct info_for_data_to_origin));
966 info->origin = &t->id;
967 info->data = NULL;
968 info->size = 0;
969 GNUNET_CORE_notify_transmit_ready(core_handle,
970 0,
971 0,
972 GNUNET_TIME_UNIT_FOREVER_REL,
973 &id,
974 sizeof(struct GNUNET_MessageHeader),
975 &send_core_data_to_origin,
976 info);
819 } else { 977 } else {
820 add_path_to_peer(peer_info, path); 978 add_path_to_peer(dest_peer_info, path);
821 /* TODO: Retransmit to next link in chain, if any (core_notify + callback) */ 979 GNUNET_PEER_resolve(get_first_hop(path), &id);
980 GNUNET_CORE_notify_transmit_ready(core_handle,
981 0,
982 0,
983 GNUNET_TIME_UNIT_FOREVER_REL,
984 &id,
985 sizeof(struct GNUNET_MessageHeader),
986 &send_core_create_path_for_peer,
987 dest_peer_info);
822 } 988 }
823 return GNUNET_OK; 989 return GNUNET_OK;
824} 990}
@@ -1540,7 +1706,9 @@ handle_local_network_traffic (void *cls,
1540{ 1706{
1541 struct MeshClient *c; 1707 struct MeshClient *c;
1542 struct MeshTunnel *t; 1708 struct MeshTunnel *t;
1709 struct MeshPeerInfo *pi;
1543 struct GNUNET_MESH_Data *data_msg; 1710 struct GNUNET_MESH_Data *data_msg;
1711 struct GNUNET_PeerIdentity next_hop;
1544 MESH_TunnelNumber tid; 1712 MESH_TunnelNumber tid;
1545 1713
1546 /* Sanity check for client registration */ 1714 /* Sanity check for client registration */
@@ -1568,16 +1736,37 @@ handle_local_network_traffic (void *cls,
1568 return; 1736 return;
1569 } 1737 }
1570 1738
1571 /* Does client own tunnel? */ 1739 /* Is it a local tunnel? Then, does client own the tunnel? */
1572 if (t->client->handle != client) { 1740 if (t->client->handle != NULL && t->client->handle != client) {
1573 GNUNET_break(0); 1741 GNUNET_break(0);
1574 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); 1742 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1575 return; 1743 return;
1576 } 1744 }
1577 1745
1578 /* TODO */ 1746 pi = GNUNET_CONTAINER_multihashmap_get(t->peers,
1579 1747 &data_msg->peer_id.hashPubKey);
1580 GNUNET_SERVER_receive_done(client, GNUNET_OK); 1748 /* Is the selected peer in the tunnel? */
1749 if (NULL == pi) {
1750 /* TODO
1751 * Are we SO nice that we automatically try to add him to the tunnel?
1752 */
1753 GNUNET_break(0);
1754 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1755 return;
1756 }
1757 GNUNET_PEER_resolve(get_first_hop(pi->path), &next_hop);
1758 GNUNET_CORE_notify_transmit_ready(core_handle,
1759 0,
1760 0,
1761 GNUNET_TIME_UNIT_FOREVER_REL,
1762 &next_hop,
1763 /* FIXME re-check types */
1764 message->size - sizeof(struct GNUNET_MESH_Data)
1765 + sizeof(struct GNUNET_MESH_DataMessageFromOrigin),
1766 &send_core_data_to_origin, /* FIXME re-check */
1767 NULL);
1768
1769 GNUNET_SERVER_receive_done(client, GNUNET_OK); /* FIXME not yet */
1581 return; 1770 return;
1582} 1771}
1583 1772
diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h
index bbfad3225..38f0486fb 100644
--- a/src/mesh/mesh.h
+++ b/src/mesh/mesh.h
@@ -206,7 +206,7 @@ struct GNUNET_MESH_Data {
206 struct GNUNET_MessageHeader header; 206 struct GNUNET_MessageHeader header;
207 207
208 /** 208 /**
209 * ID of a tunnel controlled by this client. 209 * ID of a tunnel in which this client participates.
210 */ 210 */
211 MESH_TunnelNumber tunnel_id GNUNET_PACKED; 211 MESH_TunnelNumber tunnel_id GNUNET_PACKED;
212 212