aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cadet/cadet_api.c54
-rw-r--r--src/cadet/cadet_path.c7
-rw-r--r--src/cadet/gnunet-cadet.c6
-rw-r--r--src/cadet/gnunet-service-cadet_channel.c2
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c19
-rw-r--r--src/cadet/gnunet-service-cadet_dht.c2
-rw-r--r--src/cadet/gnunet-service-cadet_hello.c9
-rw-r--r--src/cadet/gnunet-service-cadet_local.c92
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c54
-rw-r--r--src/cadet/gnunet-service-cadet_peer.h48
-rw-r--r--src/include/gnunet_cadet_service.h2
11 files changed, 230 insertions, 65 deletions
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index 055682d40..aaec91ede 100644
--- a/src/cadet/cadet_api.c
+++ b/src/cadet/cadet_api.c
@@ -1058,11 +1058,17 @@ static void
1058process_get_peer (struct GNUNET_CADET_Handle *h, 1058process_get_peer (struct GNUNET_CADET_Handle *h,
1059 const struct GNUNET_MessageHeader *message) 1059 const struct GNUNET_MessageHeader *message)
1060{ 1060{
1061 struct GNUNET_CADET_LocalInfoTunnel *msg; 1061 struct GNUNET_CADET_LocalInfoPeer *msg;
1062 struct GNUNET_PeerIdentity *id;
1063 unsigned int epaths;
1064 unsigned int paths;
1065 unsigned int path_length;
1066 unsigned int i;
1067 int neighbor;
1062 size_t esize; 1068 size_t esize;
1063 size_t msize; 1069 size_t msize;
1064 1070
1065 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Get Tunnel messasge received\n"); 1071 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Info Peer messasge received\n");
1066 if (NULL == h->info_cb.peer_cb) 1072 if (NULL == h->info_cb.peer_cb)
1067 { 1073 {
1068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ignored\n"); 1074 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ignored\n");
@@ -1070,17 +1076,34 @@ process_get_peer (struct GNUNET_CADET_Handle *h,
1070 } 1076 }
1071 1077
1072 /* Verify message sanity */ 1078 /* Verify message sanity */
1073 msg = (struct GNUNET_CADET_LocalInfoTunnel *) message; 1079 msg = (struct GNUNET_CADET_LocalInfoPeer *) message;
1074 msize = ntohs (message->size); 1080 esize = ntohs (message->size);
1075 esize = sizeof (struct GNUNET_CADET_LocalInfoPeer); 1081 msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
1076 if (esize > msize) 1082 if (esize < msize)
1077 { 1083 {
1078 GNUNET_break_op (0); 1084 GNUNET_break_op (0);
1079 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL); 1085 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1080 goto clean_cls; 1086 goto clean_cls;
1081 } 1087 }
1082// esize += ch_n * sizeof (CADET_ChannelNumber); 1088 epaths = (unsigned int) ntohs (msg->paths);
1083// esize += c_n * sizeof (struct GNUNET_CADET_Hash); 1089 paths = 0;
1090 path_length = 0;
1091 neighbor = GNUNET_NO;
1092 id = (struct GNUNET_PeerIdentity *) &msg[1];
1093 for (i = 0; msize < esize; i++)
1094 {
1095 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&id[i]));
1096 msize += sizeof (struct GNUNET_PeerIdentity);
1097 path_length++;
1098 if (0 == memcmp (&id[i], &msg->destination,
1099 sizeof (struct GNUNET_PeerIdentity)))
1100 {
1101 if (1 == path_length)
1102 neighbor = GNUNET_YES;
1103 path_length = 0;
1104 paths++;
1105 }
1106 }
1084 if (msize != esize) 1107 if (msize != esize)
1085 { 1108 {
1086 GNUNET_break_op (0); 1109 GNUNET_break_op (0);
@@ -1088,9 +1111,22 @@ process_get_peer (struct GNUNET_CADET_Handle *h,
1088 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL); 1111 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1089 goto clean_cls; 1112 goto clean_cls;
1090 } 1113 }
1114 if (paths != epaths)
1115 {
1116 GNUNET_break_op (0);
1117 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "p:%u, e: %u\n", paths, epaths);
1118 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1119 goto clean_cls;
1120 }
1091 1121
1092 /* Call Callback with tunnel info. */ 1122 /* Call Callback with tunnel info. */
1093 h->info_cb.peer_cb (h->info_cls, &msg->destination, 0, 0, 0, NULL); 1123 id = (struct GNUNET_PeerIdentity *) &msg[1];
1124 h->info_cb.peer_cb (h->info_cls,
1125 &msg->destination,
1126 (int) ntohs (msg->tunnel),
1127 neighbor,
1128 paths,
1129 id);
1094 1130
1095 clean_cls: 1131 clean_cls:
1096 h->info_cb.peer_cb = NULL; 1132 h->info_cb.peer_cb = NULL;
diff --git a/src/cadet/cadet_path.c b/src/cadet/cadet_path.c
index 4177d1529..0845f5a00 100644
--- a/src/cadet/cadet_path.c
+++ b/src/cadet/cadet_path.c
@@ -50,11 +50,12 @@ path_destroy_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
50 LOG (GNUNET_ERROR_TYPE_INFO, "Destroy delayed %p (%u)\n", path, path->length); 50 LOG (GNUNET_ERROR_TYPE_INFO, "Destroy delayed %p (%u)\n", path, path->length);
51 path->path_delete = NULL; 51 path->path_delete = NULL;
52 52
53 /* During shutdown, the peers peermap might not exist anymore. */
53 if (2 < path->length && (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) == 0) 54 if (2 < path->length && (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) == 0)
54 { 55 {
55 /* During shutdown, the peers peermap might not exist anymore. */ 56 peer = GCP_get_short (path->peers[path->length - 1], GNUNET_NO);
56 peer = GCP_get_short (path->peers[path->length - 1]); 57 if (NULL != peer)
57 GCP_remove_path (peer, path); 58 GCP_remove_path (peer, path);
58 } 59 }
59 else 60 else
60 path_destroy (path); 61 path_destroy (path);
diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c
index 7e6bf3fce..f0537adc6 100644
--- a/src/cadet/gnunet-cadet.c
+++ b/src/cadet/gnunet-cadet.c
@@ -515,15 +515,17 @@ peer_callback (void *cls,
515 GNUNET_i2s_full (peer), 515 GNUNET_i2s_full (peer),
516 tunnel ? "Y" : "N", neighbor ? "Y" : "N", n_paths); 516 tunnel ? "Y" : "N", neighbor ? "Y" : "N", n_paths);
517 p = paths; 517 p = paths;
518 for (i = 0; i < n_paths && NULL != p; i++) 518 for (i = 0; i < n_paths && NULL != p;)
519 { 519 {
520 FPRINTF (stdout, "%s ", GNUNET_i2s_full (p)); 520 FPRINTF (stdout, "%s ", GNUNET_i2s (p));
521 if (0 == memcmp (p, peer, sizeof (*p))) 521 if (0 == memcmp (p, peer, sizeof (*p)))
522 { 522 {
523 FPRINTF (stdout, "\n"); 523 FPRINTF (stdout, "\n");
524 i++;
524 } 525 }
525 p++; 526 p++;
526 } 527 }
528
527 GNUNET_SCHEDULER_shutdown(); 529 GNUNET_SCHEDULER_shutdown();
528} 530}
529 531
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c
index 234785732..158fc0ea6 100644
--- a/src/cadet/gnunet-service-cadet_channel.c
+++ b/src/cadet/gnunet-service-cadet_channel.c
@@ -1863,7 +1863,7 @@ GCCH_handle_local_create (struct CadetClient *c,
1863 return GNUNET_SYSERR; 1863 return GNUNET_SYSERR;
1864 } 1864 }
1865 1865
1866 peer = GCP_get (&msg->peer); 1866 peer = GCP_get (&msg->peer, GNUNET_YES);
1867 GCP_add_tunnel (peer); 1867 GCP_add_tunnel (peer);
1868 t = GCP_get_tunnel (peer); 1868 t = GCP_get_tunnel (peer);
1869 1869
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index 97d184e8e..af1f03ee1 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -783,7 +783,7 @@ get_prev_hop (const struct CadetConnection *c)
783 LOG (GNUNET_ERROR_TYPE_DEBUG, " ID: %s (%u)\n", 783 LOG (GNUNET_ERROR_TYPE_DEBUG, " ID: %s (%u)\n",
784 GNUNET_i2s (GNUNET_PEER_resolve2 (id)), id); 784 GNUNET_i2s (GNUNET_PEER_resolve2 (id)), id);
785 785
786 return GCP_get_short (id); 786 return GCP_get_short (id, GNUNET_YES);
787} 787}
788 788
789 789
@@ -812,7 +812,7 @@ get_next_hop (const struct CadetConnection *c)
812 LOG (GNUNET_ERROR_TYPE_DEBUG, " ID: %s (%u)\n", 812 LOG (GNUNET_ERROR_TYPE_DEBUG, " ID: %s (%u)\n",
813 GNUNET_i2s (GNUNET_PEER_resolve2 (id)), id); 813 GNUNET_i2s (GNUNET_PEER_resolve2 (id)), id);
814 814
815 return GCP_get_short (id); 815 return GCP_get_short (id, GNUNET_YES);
816} 816}
817 817
818 818
@@ -1038,7 +1038,8 @@ send_broken_unknown (const struct GNUNET_CADET_Hash *connection_id,
1038 msg->peer2 = *id2; 1038 msg->peer2 = *id2;
1039 else 1039 else
1040 memset (&msg->peer2, 0, sizeof (msg->peer2)); 1040 memset (&msg->peer2, 0, sizeof (msg->peer2));
1041 neighbor = GCP_get (peer_id); 1041 neighbor = GCP_get (peer_id, GNUNET_NO); /* We MUST know neighbor. */
1042 GNUNET_assert (NULL != neighbor);
1042 GCP_queue_add (neighbor, msg, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, 1043 GCP_queue_add (neighbor, msg, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
1043 0, 2, sizeof (struct GNUNET_CADET_ConnectionBroken), 1044 0, 2, sizeof (struct GNUNET_CADET_ConnectionBroken),
1044 NULL, GNUNET_SYSERR, /* connection, fwd */ 1045 NULL, GNUNET_SYSERR, /* connection, fwd */
@@ -1777,7 +1778,9 @@ does_connection_exist (struct CadetConnection *conn)
1777 struct CadetTunnel *t; 1778 struct CadetTunnel *t;
1778 struct CadetConnection *c; 1779 struct CadetConnection *c;
1779 1780
1780 p = GCP_get_short (conn->path->peers[0]); 1781 p = GCP_get_short (conn->path->peers[0], GNUNET_NO);
1782 if (NULL == p)
1783 return GNUNET_NO;
1781 t = GCP_get_tunnel (p); 1784 t = GCP_get_tunnel (p);
1782 if (NULL == t) 1785 if (NULL == t)
1783 return GNUNET_NO; 1786 return GNUNET_NO;
@@ -1967,8 +1970,8 @@ GCC_handle_create (void *cls,
1967 connection_change_state (c, CADET_CONNECTION_SENT); 1970 connection_change_state (c, CADET_CONNECTION_SENT);
1968 1971
1969 /* Remember peers */ 1972 /* Remember peers */
1970 dest_peer = GCP_get (&id[size - 1]); 1973 dest_peer = GCP_get (&id[size - 1], GNUNET_YES);
1971 orig_peer = GCP_get (&id[0]); 1974 orig_peer = GCP_get (&id[0], GNUNET_YES);
1972 1975
1973 /* Is it a connection to us? */ 1976 /* Is it a connection to us? */
1974 if (c->own_pos == path->length - 1) 1977 if (c->own_pos == path->length - 1)
@@ -2056,7 +2059,7 @@ GCC_handle_confirm (void *cls,
2056 2059
2057 oldstate = c->state; 2060 oldstate = c->state;
2058 LOG (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n", GNUNET_i2s (peer)); 2061 LOG (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n", GNUNET_i2s (peer));
2059 pi = GCP_get (peer); 2062 pi = GCP_get (peer, GNUNET_YES);
2060 if (get_next_hop (c) == pi) 2063 if (get_next_hop (c) == pi)
2061 { 2064 {
2062 LOG (GNUNET_ERROR_TYPE_DEBUG, " SYNACK\n"); 2065 LOG (GNUNET_ERROR_TYPE_DEBUG, " SYNACK\n");
@@ -2194,7 +2197,7 @@ GCC_handle_broken (void* cls,
2194 GCC_debug (c, GNUNET_ERROR_TYPE_ERROR); 2197 GCC_debug (c, GNUNET_ERROR_TYPE_ERROR);
2195 return GNUNET_OK; 2198 return GNUNET_OK;
2196 } 2199 }
2197 endpoint = GCP_get_short (c->path->peers[c->path->length - 1]); 2200 endpoint = GCP_get_short (c->path->peers[c->path->length - 1], GNUNET_YES);
2198 if (2 < c->path->length) 2201 if (2 < c->path->length)
2199 path_invalidate (c->path); 2202 path_invalidate (c->path);
2200 GCP_notify_broken_link (endpoint, &msg->peer1, &msg->peer2); 2203 GCP_notify_broken_link (endpoint, &msg->peer1, &msg->peer2);
diff --git a/src/cadet/gnunet-service-cadet_dht.c b/src/cadet/gnunet-service-cadet_dht.c
index 81051a700..cdc1f5a7f 100644
--- a/src/cadet/gnunet-service-cadet_dht.c
+++ b/src/cadet/gnunet-service-cadet_dht.c
@@ -187,7 +187,7 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
187 s = path_2s (p); 187 s = path_2s (p);
188 LOG (GNUNET_ERROR_TYPE_INFO, "Got path from DHT: %s\n", s); 188 LOG (GNUNET_ERROR_TYPE_INFO, "Got path from DHT: %s\n", s);
189 GNUNET_free_non_null (s); 189 GNUNET_free_non_null (s);
190 peer = GCP_get_short (p->peers[p->length - 1]); 190 peer = GCP_get_short (p->peers[p->length - 1], GNUNET_YES);
191 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got HELLO for %s\n", GCP_2s (peer)); 191 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got HELLO for %s\n", GCP_2s (peer));
192 h->callback (h->cls, p); 192 h->callback (h->cls, p);
193 path_destroy (p); 193 path_destroy (p);
diff --git a/src/cadet/gnunet-service-cadet_hello.c b/src/cadet/gnunet-service-cadet_hello.c
index 9229483fe..19b45c9cd 100644
--- a/src/cadet/gnunet-service-cadet_hello.c
+++ b/src/cadet/gnunet-service-cadet_hello.c
@@ -108,7 +108,7 @@ got_hello (void *cls, const struct GNUNET_PeerIdentity *id,
108 LOG (GNUNET_ERROR_TYPE_DEBUG, " hello for %s (%d bytes), expires on %s\n", 108 LOG (GNUNET_ERROR_TYPE_DEBUG, " hello for %s (%d bytes), expires on %s\n",
109 GNUNET_i2s (id), GNUNET_HELLO_size (hello), 109 GNUNET_i2s (id), GNUNET_HELLO_size (hello),
110 GNUNET_STRINGS_absolute_time_to_string (GNUNET_HELLO_get_last_expiration(hello))); 110 GNUNET_STRINGS_absolute_time_to_string (GNUNET_HELLO_get_last_expiration(hello)));
111 peer = GCP_get (id); 111 peer = GCP_get (id, GNUNET_YES);
112 GCP_set_hello (peer, hello); 112 GCP_set_hello (peer, hello);
113 113
114 if (GCP_get_short_id (peer) == myid) 114 if (GCP_get_short_id (peer) == myid)
@@ -176,7 +176,12 @@ GCH_get_mine (void)
176const struct GNUNET_HELLO_Message * 176const struct GNUNET_HELLO_Message *
177GCH_get (const struct GNUNET_PeerIdentity *id) 177GCH_get (const struct GNUNET_PeerIdentity *id)
178{ 178{
179 return GCP_get_hello (GCP_get (id)); 179 struct CadetPeer *p;
180
181 p = GCP_get (id, GNUNET_NO);
182 if (NULL == p)
183 return NULL;
184 return GCP_get_hello (p);
180} 185}
181 186
182 187
diff --git a/src/cadet/gnunet-service-cadet_local.c b/src/cadet/gnunet-service-cadet_local.c
index f2be87dfb..9c39ac6c6 100644
--- a/src/cadet/gnunet-service-cadet_local.c
+++ b/src/cadet/gnunet-service-cadet_local.c
@@ -672,6 +672,61 @@ show_peer_iterator (void *cls,
672 672
673 673
674/** 674/**
675 * Iterator over all paths of a peer to build an InfoPeer message.
676 *
677 * Message contains blocks of peers, first not included.
678 *
679 * @param cls Closure (message to build).
680 * @param peer Peer this path is towards.
681 * @param path Path itself
682 * @return #GNUNET_YES if should keep iterating.
683 * #GNUNET_NO otherwise.
684 */
685static int
686path_info_iterator (void *cls,
687 struct CadetPeer *peer,
688 struct CadetPeerPath *path)
689{
690 struct GNUNET_CADET_LocalInfoPeer *resp = cls;
691 struct GNUNET_PeerIdentity *id;
692 uint16_t msg_size;
693 uint16_t path_size;
694 unsigned int i;
695
696 msg_size = ntohs (resp->header.size);
697 path_size = sizeof (struct GNUNET_PeerIdentity) * (path->length - 1);
698
699 LOG (GNUNET_ERROR_TYPE_DEBUG, "Info Path %u\n", path->length);
700 if (msg_size + path_size > UINT16_MAX)
701 {
702 LOG (GNUNET_ERROR_TYPE_WARNING, "path too long for info message\n");
703 return GNUNET_NO;
704 }
705
706 i = msg_size - sizeof (struct GNUNET_CADET_LocalInfoPeer);
707 i = i / sizeof (struct GNUNET_PeerIdentity);
708
709 /* Set id to the address of the first free peer slot. */
710 id = (struct GNUNET_PeerIdentity *) &resp[1];
711 id = &id[i];
712
713 /* Don't copy first peers.
714 * First peer is always the local one.
715 * Last peer is always the destination (leave as 0, EOL).
716 */
717 for (i = 0; i < path->length - 1; i++)
718 {
719 GNUNET_PEER_resolve (path->peers[i + 1], &id[i]);
720 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&id[i]));
721 }
722
723 resp->header.size = htons (msg_size + path_size);
724
725 return GNUNET_YES;
726}
727
728
729/**
675 * Handler for client's INFO PEERS request. 730 * Handler for client's INFO PEERS request.
676 * 731 *
677 * @param cls Closure (unused). 732 * @param cls Closure (unused).
@@ -723,7 +778,7 @@ handle_show_peer (void *cls, struct GNUNET_SERVER_Client *client,
723 struct GNUNET_CADET_LocalInfoPeer *resp; 778 struct GNUNET_CADET_LocalInfoPeer *resp;
724 struct CadetPeer *p; 779 struct CadetPeer *p;
725 struct CadetClient *c; 780 struct CadetClient *c;
726 size_t size; 781 unsigned char cbuf[64 * 1024];
727 782
728 /* Sanity check for client registration */ 783 /* Sanity check for client registration */
729 if (NULL == (c = GML_client_get (client))) 784 if (NULL == (c = GML_client_get (client)))
@@ -734,44 +789,37 @@ handle_show_peer (void *cls, struct GNUNET_SERVER_Client *client,
734 } 789 }
735 790
736 msg = (struct GNUNET_CADET_LocalInfo *) message; 791 msg = (struct GNUNET_CADET_LocalInfo *) message;
792 resp = (struct GNUNET_CADET_LocalInfoPeer *) cbuf;
737 LOG (GNUNET_ERROR_TYPE_INFO, 793 LOG (GNUNET_ERROR_TYPE_INFO,
738 "Received peer info request from client %u for peer %s\n", 794 "Received peer info request from client %u for peer %s\n",
739 c->id, GNUNET_i2s_full (&msg->peer)); 795 c->id, GNUNET_i2s_full (&msg->peer));
740 796
741 p = GCP_get (&msg->peer); 797 resp->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
798 resp->header.size = htons (sizeof (struct GNUNET_CADET_LocalInfoPeer));
799 resp->destination = msg->peer;
800 p = GCP_get (&msg->peer, GNUNET_NO);
742 if (NULL == p) 801 if (NULL == p)
743 { 802 {
744 /* We don't know the peer */ 803 /* We don't know the peer */
745 struct GNUNET_CADET_LocalInfoPeer warn;
746 804
747 LOG (GNUNET_ERROR_TYPE_INFO, "Peer %s unknown %u\n", 805 LOG (GNUNET_ERROR_TYPE_INFO, "Peer %s unknown\n",
748 GNUNET_i2s_full (&msg->peer), sizeof (warn)); 806 GNUNET_i2s_full (&msg->peer));
749 warn.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); 807 resp->paths = htons (0);
750 warn.header.size = htons (sizeof (warn)); 808 resp->tunnel = htons (NULL != GCP_get_tunnel (p));
751 warn.destination = msg->peer;
752 warn.paths = htons (0);
753 warn.tunnel = htons (NULL != GCP_get_tunnel (p));
754 809
755 GNUNET_SERVER_notification_context_unicast (nc, client, 810 GNUNET_SERVER_notification_context_unicast (nc, client,
756 &warn.header, 811 &resp->header,
757 GNUNET_NO); 812 GNUNET_NO);
758 GNUNET_SERVER_receive_done (client, GNUNET_OK); 813 GNUNET_SERVER_receive_done (client, GNUNET_OK);
759 return; 814 return;
760 } 815 }
761 816
762 size = sizeof (struct GNUNET_CADET_LocalInfoPeer); 817 resp->paths = htons (GCP_count_paths (p));
763// size += c_n * sizeof (struct GNUNET_CADET_Hash); 818 resp->tunnel = htons (NULL != GCP_get_tunnel (p));
764 819 GCP_iterate_paths (p, &path_info_iterator, resp);
765 resp = GNUNET_malloc (size);
766 resp->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
767 resp->header.size = htons (size);
768 resp->destination = msg->peer;
769 resp->paths = htons (0);
770 resp->tunnel = htons (0);
771 820
772 GNUNET_SERVER_notification_context_unicast (nc, c->handle, 821 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
773 &resp->header, GNUNET_NO); 822 &resp->header, GNUNET_NO);
774 GNUNET_free (resp);
775 823
776 LOG (GNUNET_ERROR_TYPE_INFO, "Show peer request from client %u completed.\n"); 824 LOG (GNUNET_ERROR_TYPE_INFO, "Show peer request from client %u completed.\n");
777 GNUNET_SERVER_receive_done (client, GNUNET_OK); 825 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -904,7 +952,7 @@ handle_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
904 "Received tunnel info request from client %u for tunnel %s\n", 952 "Received tunnel info request from client %u for tunnel %s\n",
905 c->id, GNUNET_i2s_full(&msg->peer)); 953 c->id, GNUNET_i2s_full(&msg->peer));
906 954
907 t = GCP_get_tunnel (GCP_get (&msg->peer)); 955 t = GCP_get_tunnel (GCP_get (&msg->peer, GNUNET_NO));
908 if (NULL == t) 956 if (NULL == t)
909 { 957 {
910 /* We don't know the tunnel */ 958 /* We don't know the tunnel */
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index 66b1b8ff3..4d3eccc53 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -414,7 +414,7 @@ core_connect (void *cls,
414 sizeof (own_id), 414 sizeof (own_id),
415 "%s", 415 "%s",
416 GNUNET_i2s (&my_full_id)); 416 GNUNET_i2s (&my_full_id));
417 mp = GCP_get (peer); 417 mp = GCP_get (peer, GNUNET_YES);
418 if (myid == mp->id) 418 if (myid == mp->id)
419 { 419 {
420 LOG (GNUNET_ERROR_TYPE_INFO, 420 LOG (GNUNET_ERROR_TYPE_INFO,
@@ -1817,15 +1817,18 @@ GCP_shutdown (void)
1817 1817
1818 1818
1819/** 1819/**
1820 * Retrieve the CadetPeer stucture associated with the peer, create one 1820 * Retrieve the CadetPeer stucture associated with the peer. Optionally create
1821 * and insert it in the appropriate structures if the peer is not known yet. 1821 * one and insert it in the appropriate structures if the peer is not known yet.
1822 * 1822 *
1823 * @param peer_id Full identity of the peer. 1823 * @param peer_id Full identity of the peer.
1824 * @param create #GNUNET_YES if a new peer should be created if unknown.
1825 * #GNUNET_NO otherwise.
1824 * 1826 *
1825 * @return Existing or newly created peer structure. 1827 * @return Existing or newly created peer structure.
1828 * NULL if unknown and not requested @a create
1826 */ 1829 */
1827struct CadetPeer * 1830struct CadetPeer *
1828GCP_get (const struct GNUNET_PeerIdentity *peer_id) 1831GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create)
1829{ 1832{
1830 struct CadetPeer *peer; 1833 struct CadetPeer *peer;
1831 1834
@@ -1851,17 +1854,20 @@ GCP_get (const struct GNUNET_PeerIdentity *peer_id)
1851 1854
1852 1855
1853/** 1856/**
1854 * Retrieve the CadetPeer stucture associated with the peer, create one 1857 * Retrieve the CadetPeer stucture associated with the peer. Optionally create
1855 * and insert it in the appropriate structures if the peer is not known yet. 1858 * one and insert it in the appropriate structures if the peer is not known yet.
1856 * 1859 *
1857 * @param peer Short identity of the peer. 1860 * @param peer Short identity of the peer.
1861 * @param create #GNUNET_YES if a new peer should be created if unknown.
1862 * #GNUNET_NO otherwise.
1858 * 1863 *
1859 * @return Existing or newly created peer structure. 1864 * @return Existing or newly created peer structure.
1865 * NULL if unknown and not requested @a create
1860 */ 1866 */
1861struct CadetPeer * 1867struct CadetPeer *
1862GCP_get_short (const GNUNET_PEER_Id peer) 1868GCP_get_short (const GNUNET_PEER_Id peer, int create)
1863{ 1869{
1864 return GCP_get (GNUNET_PEER_resolve2 (peer)); 1870 return GCP_get (GNUNET_PEER_resolve2 (peer), create);
1865} 1871}
1866 1872
1867 1873
@@ -2199,7 +2205,7 @@ GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed)
2199 struct CadetPeer *aux; 2205 struct CadetPeer *aux;
2200 struct CadetPeerPath *copy; 2206 struct CadetPeerPath *copy;
2201 2207
2202 aux = GCP_get_short (p->peers[i]); 2208 aux = GCP_get_short (p->peers[i], GNUNET_YES);
2203 copy = path_duplicate (p); 2209 copy = path_duplicate (p);
2204 copy->length = i + 1; 2210 copy->length = i + 1;
2205 GCP_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed); 2211 GCP_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
@@ -2417,6 +2423,8 @@ GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t)
2417struct CadetTunnel * 2423struct CadetTunnel *
2418GCP_get_tunnel (const struct CadetPeer *peer) 2424GCP_get_tunnel (const struct CadetPeer *peer)
2419{ 2425{
2426 if (NULL == peer)
2427 return NULL;
2420 return peer->tunnel; 2428 return peer->tunnel;
2421} 2429}
2422 2430
@@ -2583,6 +2591,34 @@ GCP_count_paths (const struct CadetPeer *peer)
2583 2591
2584 2592
2585/** 2593/**
2594 * Iterate over the paths to a peer.
2595 *
2596 * @param peer Peer to get path info.
2597 * @param callback Function to call for every path.
2598 * @param cls Closure for @a callback.
2599 *
2600 * @return Number of iterated paths.
2601 */
2602unsigned int
2603GCP_iterate_paths (struct CadetPeer *peer,
2604 GCP_path_iterator callback,
2605 void *cls)
2606{
2607 struct CadetPeerPath *iter;
2608 unsigned int i;
2609
2610 for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next)
2611 {
2612 i++;
2613 if (GNUNET_YES != callback (cls, peer, iter))
2614 break;
2615 }
2616
2617 return i;
2618}
2619
2620
2621/**
2586 * Iterate all known peers. 2622 * Iterate all known peers.
2587 * 2623 *
2588 * @param iter Iterator. 2624 * @param iter Iterator.
diff --git a/src/cadet/gnunet-service-cadet_peer.h b/src/cadet/gnunet-service-cadet_peer.h
index 87e828b66..7a60b33bd 100644
--- a/src/cadet/gnunet-service-cadet_peer.h
+++ b/src/cadet/gnunet-service-cadet_peer.h
@@ -39,6 +39,7 @@ extern "C"
39 39
40#include "platform.h" 40#include "platform.h"
41#include "gnunet_util_lib.h" 41#include "gnunet_util_lib.h"
42#include "cadet_path.h"
42 43
43/** 44/**
44 * Struct containing all information regarding a given peer 45 * Struct containing all information regarding a given peer
@@ -72,6 +73,20 @@ typedef int
72 uint16_t type, uint32_t pid, int fwd, size_t size, 73 uint16_t type, uint32_t pid, int fwd, size_t size,
73 struct GNUNET_TIME_Relative wait); 74 struct GNUNET_TIME_Relative wait);
74 75
76/**
77 * Peer path iterator.
78 *
79 * @param cls Closure.
80 * @param peer Peer this path is towards.
81 * @param path Path itself
82 * @return #GNUNET_YES if should keep iterating.
83 * #GNUNET_NO otherwise.
84 */
85typedef int
86(*GCP_path_iterator) (void *cls,
87 struct CadetPeer *peer,
88 struct CadetPeerPath *path);
89
75 90
76/******************************************************************************/ 91/******************************************************************************/
77/******************************** API ***********************************/ 92/******************************** API ***********************************/
@@ -93,27 +108,32 @@ GCP_shutdown (void);
93 108
94 109
95/** 110/**
96 * Retrieve the CadetPeer stucture associated with the peer, create one 111 * Retrieve the CadetPeer stucture associated with the peer. Optionally create
97 * and insert it in the appropriate structures if the peer is not known yet. 112 * one and insert it in the appropriate structures if the peer is not known yet.
98 * 113 *
99 * @param peer_id Full identity of the peer. 114 * @param peer_id Full identity of the peer.
115 * @param create #GNUNET_YES if a new peer should be created if unknown.
116 * #GNUNET_NO otherwise.
100 * 117 *
101 * @return Existing or newly created peer structure. 118 * @return Existing or newly created peer structure.
119 * NULL if unknown and not requested @a create
102 */ 120 */
103struct CadetPeer * 121struct CadetPeer *
104GCP_get (const struct GNUNET_PeerIdentity *peer_id); 122GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create);
105
106 123
107/** 124/**
108 * Retrieve the CadetPeer stucture associated with the peer, create one 125 * Retrieve the CadetPeer stucture associated with the peer. Optionally create
109 * and insert it in the appropriate structures if the peer is not known yet. 126 * one and insert it in the appropriate structures if the peer is not known yet.
110 * 127 *
111 * @param peer Short identity of the peer. 128 * @param peer Short identity of the peer.
129 * @param create #GNUNET_YES if a new peer should be created if unknown.
130 * #GNUNET_NO otherwise.
112 * 131 *
113 * @return Existing or newly created peer structure. 132 * @return Existing or newly created peer structure.
133 * NULL if unknown and not requested @a create
114 */ 134 */
115struct CadetPeer * 135struct CadetPeer *
116GCP_get_short (const GNUNET_PEER_Id peer); 136GCP_get_short (const GNUNET_PEER_Id peer, int create);
117 137
118/** 138/**
119 * Try to establish a new connection to this peer (in its tunnel). 139 * Try to establish a new connection to this peer (in its tunnel).
@@ -444,6 +464,20 @@ GCP_notify_broken_link (struct CadetPeer *peer,
444unsigned int 464unsigned int
445GCP_count_paths (const struct CadetPeer *peer); 465GCP_count_paths (const struct CadetPeer *peer);
446 466
467/**
468 * Iterate over the paths to a peer.
469 *
470 * @param peer Peer to get path info.
471 * @param callback Function to call for every path.
472 * @param cls Closure for @a callback.
473 *
474 * @return Number of iterated paths.
475 */
476unsigned int
477GCP_iterate_paths (struct CadetPeer *peer,
478 GCP_path_iterator callback,
479 void *cls);
480
447 481
448/** 482/**
449 * Iterate all known peers. 483 * Iterate all known peers.
diff --git a/src/include/gnunet_cadet_service.h b/src/include/gnunet_cadet_service.h
index d2d41b3ce..a0d28b531 100644
--- a/src/include/gnunet_cadet_service.h
+++ b/src/include/gnunet_cadet_service.h
@@ -420,7 +420,7 @@ typedef void
420 * @param neighbor Is this a direct neighbor? #GNUNET_YES/#GNUNET_NO 420 * @param neighbor Is this a direct neighbor? #GNUNET_YES/#GNUNET_NO
421 * @param n_paths Number of paths known towards peer. 421 * @param n_paths Number of paths known towards peer.
422 * @param paths Array of PEER_IDs representing all paths to reach the peer. 422 * @param paths Array of PEER_IDs representing all paths to reach the peer.
423 * Each path starts with the local peer. 423 * Each path starts with the first hop (local peer not included).
424 * Each path ends with the destination peer (given in @c peer). 424 * Each path ends with the destination peer (given in @c peer).
425 */ 425 */
426typedef void 426typedef void