aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-02-03 18:46:22 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-02-03 18:46:22 +0000
commit5d1bc37b4b364d593e53a7e17038dca722ee3b6f (patch)
tree8e773396b4f49f721344f096fc951ac5e31c7739 /src/dht
parentb26ee701eb12e7664fc0f158e5f38bfbd4149b10 (diff)
downloadgnunet-5d1bc37b4b364d593e53a7e17038dca722ee3b6f.tar.gz
gnunet-5d1bc37b4b364d593e53a7e17038dca722ee3b6f.zip
1. Adding an entry in routing table.
2. Peer arithmetic to get finger id.
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c167
-rw-r--r--src/dht/gnunet-service-xdht_routing.c15
2 files changed, 139 insertions, 43 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index d15c43105..c6de372f1 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -51,6 +51,7 @@
51 51
52/*TODO 52/*TODO
53 * 1. Remove extra comments - FIXME,TODO,SUPU 53 * 1. Remove extra comments - FIXME,TODO,SUPU
54 * 2. Use GNUNET_Log to debug
54 */ 55 */
55 56
56/** 57/**
@@ -81,7 +82,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
81 * Keep the field now but remove it when implementing PUT/GET. 82 * Keep the field now but remove it when implementing PUT/GET.
82 * 2) also, check the field of put/get/result if all are required for 83 * 2) also, check the field of put/get/result if all are required for
83 * x-vine or not. */ 84 * x-vine or not. */
84 85
85/** 86/**
86 * P2P PUT message 87 * P2P PUT message
87 */ 88 */
@@ -482,9 +483,9 @@ static struct GNUNET_ATS_PerformanceHandle *atsAPI;
482static struct GNUNET_CORE_Handle *core_api; 483static struct GNUNET_CORE_Handle *core_api;
483 484
484/** 485/**
485 * The highest finger_id that we have found trail to. 486 * The current finger index that we have found trail to.
486 */ 487 */
487static unsigned int highest_finger_id; 488static unsigned int current_finger_id;
488 489
489 490
490/** 491/**
@@ -615,8 +616,11 @@ GDS_NEIGHBOURS_trail_setup(struct GNUNET_PeerIdentity *finger_id,
615 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), 616 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
616 1, GNUNET_NO); 617 1, GNUNET_NO);
617 } 618 }
618 619
620 /* SUPU: Verify if this copy between pending message, tsm is correct? */
619 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage)); 621 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage));
622 /*SUPU: What does this code do? Does this intialize pending with
623 values of tsm? */
620 tsm = (struct PeerTrailSetupMessage *) &pending[1]; 624 tsm = (struct PeerTrailSetupMessage *) &pending[1];
621 pending->msg = &tsm->header; 625 pending->msg = &tsm->header;
622 tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); 626 tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
@@ -775,7 +779,9 @@ get_random_friend()
775 779
776 780
777/** 781/**
778 * TODO: Complete this function. 782 * TODO: Check the logic of using current_finger_id again.
783 * This code is not correct. I need to check the pointers and
784 * correct use of memcpy and all the data type.
779 * Use Chord formula finger[i]=(n+2^(i-1))mod m, 785 * Use Chord formula finger[i]=(n+2^(i-1))mod m,
780 * where i = current finger map index - max. 256 bits 786 * where i = current finger map index - max. 256 bits
781 * n = own peer identity - 256 bits 787 * n = own peer identity - 256 bits
@@ -787,20 +793,48 @@ struct GNUNET_PeerIdentity *
787finger_id_to_search() 793finger_id_to_search()
788{ 794{
789 795
790 //struct GNUNET_PeerIdentity *finger_peer_id; 796 struct GNUNET_PeerIdentity *finger_peer_id;
791 797 uint32_t peer_id;
792 /*TODO: Add a wrapper in crypto_ecc.c to add an integer do mod operation on integer 798 uint32_t finger_id;
793 to find peer id. Take care of parameters. You should work on the value of 799
794 finger_id not on its pointer. 800 finger_peer_id = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
795 Increment the value of finger_id. */ 801
796 802 /* Copy unsigned char array into peer_id. */
797 //return finger_peer_id; 803 if (0 == memcpy(&peer_id,&my_identity.public_key.q_y,sizeof(uint32_t)))
798 return NULL; 804 return NULL;
805
806
807 /* We do all the arithmetic operation on peer_id to get finger_id*/
808 finger_id = (uint32_t)(peer_id + pow(2,current_finger_id)) % MAX_FINGERS;
809
810
811 /* Copy the finger_id to finger_peer_id. */
812 if (0 == memcpy(&finger_peer_id->public_key.q_y,&finger_id,sizeof(uint32_t)))
813 return NULL;
814
815 /* FIXME: Here I increment the index so that next time when we enter this
816 function, then we begin the search from current index. Is it possible
817 to set this value when we add the finger id to our finger table. No, because
818 even there is a call going on to find the finger, we can start another call
819 to search another peer. */
820 current_finger_id = (current_finger_id+1) % MAX_FINGERS;
821
822 /* Check if you already have an entry in finger_peers for this finger_id.
823 If yes then again look for a new finger_id. */
824 if(NULL == GNUNET_CONTAINER_multipeermap_get(finger_peers,finger_peer_id))
825 {
826 /* Is the recursion safe here? */
827 finger_peer_id = finger_id_to_search();
828 }
829
830 return finger_peer_id;
799} 831}
800 832
801 833
802/** 834/**
803 * FIXME: Implement after testing friend/finger map. 835 * TODO: Implement after testing friend/finger map.
836 * TODO: Handle the case when we already have a trail to our predecessor in
837 * the network.
804 * This function will be needed when we are handling node joins/fails 838 * This function will be needed when we are handling node joins/fails
805 * to maintain correct pointer to our predecessor and successor in the network. 839 * to maintain correct pointer to our predecessor and successor in the network.
806 * Find immediate predecessor in the network. 840 * Find immediate predecessor in the network.
@@ -813,7 +847,9 @@ find_immediate_predecessor()
813{ 847{
814 /* Using your own peer identity, calculate your predecessor 848 /* Using your own peer identity, calculate your predecessor
815 in the network. Try to setup path to this predecessor using 849 in the network. Try to setup path to this predecessor using
816 the same logic as used for other fingers. */ 850 the same logic as used for other fingers.
851 If we already have a trail to our predecessor then send NULL and
852 calling function should be able to handle that case. */
817 return NULL; 853 return NULL;
818} 854}
819 855
@@ -838,27 +874,34 @@ send_find_finger_trail_message (void *cls,
838 { 874 {
839 /* We can find trail to our immediate predecessor in the network. */ 875 /* We can find trail to our immediate predecessor in the network. */
840 finger_peer_id = find_immediate_predecessor(); 876 finger_peer_id = find_immediate_predecessor();
877 if(NULL == finger_peer_id)
878 {
879 /* We already have a trail to reach to immediate predecessor. */
880 goto new_find_trail_request;
881 }
841 } 882 }
842 else 883 else
843 { 884 {
844 /* Find the finger_peer_id for which we want to setup the trial */ 885 /* Find the finger_peer_id for which we want to setup the trail */
845 finger_peer_id = finger_id_to_search(); 886 finger_peer_id = finger_id_to_search();
846 } 887 }
847 888
848 /* Choose a friend randomly from your friend_peers map. */ 889 /* Choose a friend randomly from your friend_peers map. */
849 friend_peer_id = get_random_friend(); 890 friend_peer_id = get_random_friend();
850 891
851 /* Check if we found a friend or not. */ 892 /* We found a friend.*/
852 if(NULL != friend_peer_id) 893 if(NULL != friend_peer_id)
853 GDS_NEIGHBOURS_trail_setup(finger_peer_id, friend_peer_id); 894 GDS_NEIGHBOURS_trail_setup(finger_peer_id, friend_peer_id);
854 895
855 896
897 new_find_trail_request:
898
856 next_send_time.rel_value_us = 899 next_send_time.rel_value_us =
857 DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + 900 DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
858 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 901 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
859 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us / 902 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
860 (highest_finger_id + 1)); 903 (current_finger_id + 1));
861 904
862 find_finger_trail_task = 905 find_finger_trail_task =
863 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message, 906 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
864 NULL); 907 NULL);
@@ -906,7 +949,7 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
906 949
907 /* got a first connection, good time to start with FIND FINGER TRAIL requests... */ 950 /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
908 if (1 == GNUNET_CONTAINER_multipeermap_size(friend_peers)) 951 if (1 == GNUNET_CONTAINER_multipeermap_size(friend_peers))
909 find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL); 952 find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
910} 953}
911 954
912 955
@@ -932,7 +975,6 @@ handle_core_disconnect (void *cls,
932 * 6. Here is case where we started put operation but a peer got disconnected and 975 * 6. Here is case where we started put operation but a peer got disconnected and
933 we removed the entry from the table. How to handle such a case. 976 we removed the entry from the table. How to handle such a case.
934 */ 977 */
935
936} 978}
937 979
938 980
@@ -1076,11 +1118,25 @@ find_successor(struct GNUNET_PeerIdentity *destination)
1076 */ 1118 */
1077 } 1119 }
1078 } 1120 }
1079 1121
1080
1081 /* Check between friend and finger value to decide which is the predecessor. 1122 /* Check between friend and finger value to decide which is the predecessor.
1082 If friend, then send the friend id. 1123 If friend, then send the friend id.
1083 If finger, then send the next hop. */ 1124 If finger, then send the next hop.
1125 Also set the current_destination = friend, if friend
1126 or else current_destination = finger. */
1127 return NULL;
1128}
1129
1130
1131/* Traverse the trail list to find the prev hop to store in routing table. */
1132static
1133struct GNUNET_PeerIdentity *
1134find_trail_list_prev_hop(struct PeerTrailSetupMessage *trail_result)
1135{
1136 /*FIXME: I don't see any function in existing dll implementation, to
1137 just read the dll backward or forward. So, I would implement one here.
1138 * As no one else uses this functionality so I guess its okay to just
1139 * implement it here. */
1084 return NULL; 1140 return NULL;
1085} 1141}
1086 1142
@@ -1090,7 +1146,7 @@ find_successor(struct GNUNET_PeerIdentity *destination)
1090 * 1. Check if we are maintaining the 64k size of struct PeerTrailSetupMessage. 1146 * 1. Check if we are maintaining the 64k size of struct PeerTrailSetupMessage.
1091 * when we add ourself to the trail list. 1147 * when we add ourself to the trail list.
1092 * 2. Ensure every case is handled for current_destination. 1148 * 2. Ensure every case is handled for current_destination.
1093 * 3. When should you call GDS_Routing_Add? 1149 * 3. When should you call GDS_Routing_Add?
1094 * Core handler for P2P trail setup message. 1150 * Core handler for P2P trail setup message.
1095 * @param cls closure 1151 * @param cls closure
1096 * @param message message 1152 * @param message message
@@ -1101,8 +1157,9 @@ static int
1101handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, 1157handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1102 const struct GNUNET_MessageHeader *message) 1158 const struct GNUNET_MessageHeader *message)
1103{ 1159{
1104 const struct PeerTrailSetupMessage *trail_setup; 1160 struct PeerTrailSetupMessage *trail_setup;
1105 struct GNUNET_PeerIdentity *next_hop; 1161 struct GNUNET_PeerIdentity *next_hop;
1162 struct GNUNET_PeerIdentity *prev_hop;
1106 struct FriendInfo *friend; 1163 struct FriendInfo *friend;
1107 struct TrailPeerList *peer_entry; 1164 struct TrailPeerList *peer_entry;
1108 struct P2PPendingMessage *pending; 1165 struct P2PPendingMessage *pending;
@@ -1116,7 +1173,7 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1116 return GNUNET_YES; 1173 return GNUNET_YES;
1117 } 1174 }
1118 1175
1119 trail_setup = (const struct PeerTrailSetupMessage *) message; 1176 trail_setup = (struct PeerTrailSetupMessage *) message;
1120 1177
1121 GNUNET_STATISTICS_update (GDS_stats, 1178 GNUNET_STATISTICS_update (GDS_stats,
1122 gettext_noop ("# TRAIL SETUP requests received"), 1, 1179 gettext_noop ("# TRAIL SETUP requests received"), 1,
@@ -1135,10 +1192,7 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1135 else if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(trail_setup->current_destination,&my_identity))) 1192 else if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(trail_setup->current_destination,&my_identity)))
1136 { 1193 {
1137 /* I am current destination, find the next peer to pass the trail setup message. */ 1194 /* I am current destination, find the next peer to pass the trail setup message. */
1138 next_hop = find_successor(trail_setup->destination_finger); 1195 next_hop = find_successor(trail_setup->destination_finger);
1139 /* Here we have not reached to final destination, but we found the closest
1140 predecessor. routing table should have an entry only if its a finger. */
1141 //GDS_Routing_add();
1142 } 1196 }
1143 else 1197 else
1144 { 1198 {
@@ -1150,7 +1204,7 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1150 if(0 == (GNUNET_CRYPTO_cmp_peer_identity(next_hop,&my_identity))) 1204 if(0 == (GNUNET_CRYPTO_cmp_peer_identity(next_hop,&my_identity)))
1151 { 1205 {
1152 /* I am the closest successor of the destination finger in the network. */ 1206 /* I am the closest successor of the destination finger in the network. */
1153 /*SUPU:: 1207 /*TODO::
1154 1. Prepare a trail setup result message. 1208 1. Prepare a trail setup result message.
1155 2. Add yourself to trail list. 1209 2. Add yourself to trail list.
1156 3. send packet to last element in the list. 1210 3. send packet to last element in the list.
@@ -1158,7 +1212,24 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1158 return GNUNET_YES; 1212 return GNUNET_YES;
1159 } 1213 }
1160 1214
1161 /* Insert next hop into trial list. */ 1215 /* FIXME:
1216 * Do we really need to pass the whole trail_setup? I guess
1217 * we can just pass the double linked list.
1218 */
1219 prev_hop = find_trail_list_prev_hop(trail_setup);
1220
1221 /* Add an entry in the routing table.
1222 SUPU: Here we are adding an entry to our routing table because we are not final
1223 destination.So, it means we are part of a routing trail. It may happen
1224 that we found next_hop from searching the routing table. So, in GDS_ROUTING_Add,
1225 we should first check if there is already an entry for current_destination. If yes
1226 then don't add.*/
1227 GDS_ROUTING_add(trail_setup->source_peer,trail_setup->current_destination,prev_hop,next_hop);
1228
1229 /* FIXME:
1230 * 1. Insert next hop into trail list.
1231 * 2. I don't see any function to just read the DLL. Need to see again if there is
1232 * one. If not then need to write something. */
1162 peer_entry = GNUNET_malloc (sizeof (struct TrailPeerList)); 1233 peer_entry = GNUNET_malloc (sizeof (struct TrailPeerList));
1163 peer_entry->peer = &my_identity; 1234 peer_entry->peer = &my_identity;
1164 peer_entry->next = NULL; 1235 peer_entry->next = NULL;
@@ -1170,10 +1241,16 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1170 /* Find the struct FriendInfo for next_hop peer id. */ 1241 /* Find the struct FriendInfo for next_hop peer id. */
1171 friend = GNUNET_CONTAINER_multipeermap_get(friend_peers,next_hop); 1242 friend = GNUNET_CONTAINER_multipeermap_get(friend_peers,next_hop);
1172 1243
1244 if (friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1245 {
1246 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1247 1, GNUNET_NO);
1248 }
1249
1173 /* Send trail setup message to next hop friend. */ 1250 /* Send trail setup message to next hop friend. */
1174 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage)); 1251 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage));
1175 /*FIXME: This is wrong. Where do you copy the new trail_setup message to 1252 trail_setup = (struct PeerTrailSetupMessage *) &pending[1];
1176 pending.*/ 1253 pending->msg = &trail_setup->header;
1177 GNUNET_CONTAINER_DLL_insert_tail (friend->head, friend->tail, pending); 1254 GNUNET_CONTAINER_DLL_insert_tail (friend->head, friend->tail, pending);
1178 friend->pending_count++; 1255 friend->pending_count++;
1179 process_friend_queue(friend); 1256 process_friend_queue(friend);
@@ -1185,7 +1262,9 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1185static 1262static
1186void finger_table_add(struct PeerTrailSetupResultMessage *result) 1263void finger_table_add(struct PeerTrailSetupResultMessage *result)
1187{ 1264{
1188 /* Add the whole trail in your finger table, 1265 /* 1. create a struct FingerInfo and copy respective members
1266 * of result into this struct.
1267 * Add the whole trail in your finger table,
1189 also add interval. */ 1268 also add interval. */
1190} 1269}
1191 1270
@@ -1234,9 +1313,9 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
1234 /* Am I the destination ? */ 1313 /* Am I the destination ? */
1235 if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(trail_result->destination_peer,&my_identity))) 1314 if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(trail_result->destination_peer,&my_identity)))
1236 { 1315 {
1237 /* I am the destination. Add the trail to my finger table. */ 1316 /* I am the destination. Add the trail to my finger table. */
1238 finger_table_add(trail_result); 1317 finger_table_add(trail_result);
1239 return GNUNET_YES; 1318 return GNUNET_YES;
1240 } 1319 }
1241 else 1320 else
1242 { 1321 {
@@ -1246,6 +1325,11 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
1246 /* Find the struct FriendInfo for next_hop peer id. */ 1325 /* Find the struct FriendInfo for next_hop peer id. */
1247 friend = GNUNET_CONTAINER_multipeermap_get(friend_peers,next_hop); 1326 friend = GNUNET_CONTAINER_multipeermap_get(friend_peers,next_hop);
1248 1327
1328 if (friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1329 {
1330 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1331 1, GNUNET_NO);
1332 }
1249 /* Send trail setup result message to next hop friend. */ 1333 /* Send trail setup result message to next hop friend. */
1250 /*FIXME: 1334 /*FIXME:
1251 I have not yet written the code to copy struct trail message to 1335 I have not yet written the code to copy struct trail message to
@@ -1253,6 +1337,8 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
1253 the MAXIMUM_PENDNIG_PEER limit is not crossed. Modify the same part 1337 the MAXIMUM_PENDNIG_PEER limit is not crossed. Modify the same part
1254 of code for handle_dht_p2p_trail_setup. */ 1338 of code for handle_dht_p2p_trail_setup. */
1255 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage)); 1339 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage));
1340 trail_result = (struct PeerTrailSetupResultMessage *) &pending[1];
1341 pending->msg = &trail_result->header;
1256 GNUNET_CONTAINER_DLL_insert_tail (friend->head, friend->tail, pending); 1342 GNUNET_CONTAINER_DLL_insert_tail (friend->head, friend->tail, pending);
1257 friend->pending_count++; 1343 friend->pending_count++;
1258 process_friend_queue(friend); 1344 process_friend_queue(friend);
@@ -1281,6 +1367,7 @@ GDS_NEIGHBOURS_init()
1281 {NULL, 0, 0} 1367 {NULL, 0, 0}
1282 }; 1368 };
1283 1369
1370 /*ASK: What is ATS? Why do we need it? */
1284 atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL); 1371 atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL);
1285 core_api = 1372 core_api =
1286 GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect, 1373 GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c
index 6d14ce029..15a492dc5 100644
--- a/src/dht/gnunet-service-xdht_routing.c
+++ b/src/dht/gnunet-service-xdht_routing.c
@@ -100,10 +100,19 @@ GDS_ROUTING_add (struct GNUNET_PeerIdentity *source,
100 new_routing_entry->next_hop = next_hop; 100 new_routing_entry->next_hop = next_hop;
101 new_routing_entry->destination = dest; 101 new_routing_entry->destination = dest;
102 102
103 /* If dest is already present in the routing table, then exit.*/
104 if (GNUNET_YES ==
105 GNUNET_CONTAINER_multipeermap_contains (routing_table,
106 dest))
107 {
108 GNUNET_break (0);
109 return;
110 }
111
103 GNUNET_assert (GNUNET_OK == 112 GNUNET_assert (GNUNET_OK ==
104 GNUNET_CONTAINER_multipeermap_put (routing_table, 113 GNUNET_CONTAINER_multipeermap_put (routing_table,
105 dest, new_routing_entry, 114 dest, new_routing_entry,
106 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 115 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
107} 116}
108 117
109 118