aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_core.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-05-20 00:35:13 +0200
committerChristian Grothoff <christian@grothoff.org>2018-05-20 00:36:20 +0200
commit0be37e812d034754eb725701f237fbc81b973904 (patch)
treec50481209ec97b5dbbd075489255477c5e761d3d /src/cadet/gnunet-service-cadet_core.c
parentc227e3f00efb4b3677e9b85c0273a7bf5fbcb4a9 (diff)
downloadgnunet-0be37e812d034754eb725701f237fbc81b973904.tar.gz
gnunet-0be37e812d034754eb725701f237fbc81b973904.zip
fix off-by-one error in cadet connection construction, also enforce better timeouts for retransmissions of handshake
Diffstat (limited to 'src/cadet/gnunet-service-cadet_core.c')
-rw-r--r--src/cadet/gnunet-service-cadet_core.c117
1 files changed, 88 insertions, 29 deletions
diff --git a/src/cadet/gnunet-service-cadet_core.c b/src/cadet/gnunet-service-cadet_core.c
index 84aff1857..06d1fe3cc 100644
--- a/src/cadet/gnunet-service-cadet_core.c
+++ b/src/cadet/gnunet-service-cadet_core.c
@@ -406,6 +406,28 @@ route_message (struct CadetPeer *prev,
406 (NULL != dir->env_head) ) 406 (NULL != dir->env_head) )
407 discard_buffer (dir, 407 discard_buffer (dir,
408 dir->env_head); 408 dir->env_head);
409 /* Check for duplicates */
410 for (const struct GNUNET_MQ_Envelope *env = dir->env_head;
411 NULL != env;
412 env = GNUNET_MQ_env_next (env))
413 {
414 const struct GNUNET_MessageHeader *hdr = GNUNET_MQ_env_get_msg (env);
415
416 if ( (hdr->size == msg->size) &&
417 (0 == memcmp (hdr,
418 msg,
419 ntohs (msg->size))) )
420 {
421 LOG (GNUNET_ERROR_TYPE_DEBUG,
422 "Received duplicate of message already in buffer, dropping\n");
423 GNUNET_STATISTICS_update (stats,
424 "# messages dropped due to duplicate in buffer",
425 1,
426 GNUNET_NO);
427 return;
428 }
429 }
430
409 rung = dir->rung; 431 rung = dir->rung;
410 if (cur_buffers == max_buffers) 432 if (cur_buffers == max_buffers)
411 { 433 {
@@ -434,7 +456,7 @@ route_message (struct CadetPeer *prev,
434 GNUNET_CONTAINER_DLL_remove (rung->rd_head, 456 GNUNET_CONTAINER_DLL_remove (rung->rd_head,
435 rung->rd_tail, 457 rung->rd_tail,
436 dir); 458 dir);
437 /* make 'nxt' point to the next higher rung, creat if necessary */ 459 /* make 'nxt' point to the next higher rung, create if necessary */
438 nxt = rung->next; 460 nxt = rung->next;
439 if ( (NULL == nxt) || 461 if ( (NULL == nxt) ||
440 (rung->rung_off + 1 != nxt->rung_off) ) 462 (rung->rung_off + 1 != nxt->rung_off) )
@@ -781,31 +803,45 @@ handle_connection_create (void *cls,
781 if (0 == path_length) 803 if (0 == path_length)
782 { 804 {
783 LOG (GNUNET_ERROR_TYPE_DEBUG, 805 LOG (GNUNET_ERROR_TYPE_DEBUG,
784 "Dropping CADET_CONNECTION_CREATE with empty path\n"); 806 "Dropping CADET_CONNECTION_CREATE with empty path\n");
785 GNUNET_break_op (0); 807 GNUNET_break_op (0);
786 return; 808 return;
787 } 809 }
810 LOG (GNUNET_ERROR_TYPE_DEBUG,
811 "Handling CADET_CONNECTION_CREATE from %s for CID %s with %u hops\n",
812 GCP_2s (sender),
813 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
814 path_length);
788 /* Check for loops */ 815 /* Check for loops */
789 struct GNUNET_CONTAINER_MultiPeerMap *map; 816 {
790 map = GNUNET_CONTAINER_multipeermap_create (path_length * 2, 817 struct GNUNET_CONTAINER_MultiPeerMap *map;
791 GNUNET_YES); 818
792 GNUNET_assert (NULL != map); 819 map = GNUNET_CONTAINER_multipeermap_create (path_length * 2,
793 for (off = 0; off < path_length; off++) { 820 GNUNET_YES);
794 if (GNUNET_SYSERR == 821 GNUNET_assert (NULL != map);
795 GNUNET_CONTAINER_multipeermap_put (map, 822 for (unsigned int i=0;i<path_length;i++)
796 &pids[off], 823 {
797 NULL,
798 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) {
799 /* bogus request */
800 GNUNET_CONTAINER_multipeermap_destroy (map);
801 LOG (GNUNET_ERROR_TYPE_DEBUG, 824 LOG (GNUNET_ERROR_TYPE_DEBUG,
802 "Dropping CADET_CONNECTION_CREATE with cyclic path\n"); 825 "CADET_CONNECTION_CREATE has peer %s at offset %u\n",
803 GNUNET_break_op (0); 826 GNUNET_i2s (&pids[i]),
804 return; 827 i);
828 if (GNUNET_SYSERR ==
829 GNUNET_CONTAINER_multipeermap_put (map,
830 &pids[i],
831 NULL,
832 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
833 {
834 /* bogus request */
835 GNUNET_CONTAINER_multipeermap_destroy (map);
836 LOG (GNUNET_ERROR_TYPE_DEBUG,
837 "Dropping CADET_CONNECTION_CREATE with cyclic path\n");
838 GNUNET_break_op (0);
839 return;
840 }
805 } 841 }
842 GNUNET_CONTAINER_multipeermap_destroy (map);
806 } 843 }
807 GNUNET_CONTAINER_multipeermap_destroy (map); 844 /* Initiator is at offset 0, find us */
808 /* Initiator is at offset 0. */
809 for (off=1;off<path_length;off++) 845 for (off=1;off<path_length;off++)
810 if (0 == memcmp (&my_full_id, 846 if (0 == memcmp (&my_full_id,
811 &pids[off], 847 &pids[off],
@@ -814,7 +850,7 @@ handle_connection_create (void *cls,
814 if (off == path_length) 850 if (off == path_length)
815 { 851 {
816 LOG (GNUNET_ERROR_TYPE_DEBUG, 852 LOG (GNUNET_ERROR_TYPE_DEBUG,
817 "Dropping CADET_CONNECTION_CREATE without us in the path\n"); 853 "Dropping CADET_CONNECTION_CREATE without us in the path\n");
818 GNUNET_break_op (0); 854 GNUNET_break_op (0);
819 return; 855 return;
820 } 856 }
@@ -823,14 +859,15 @@ handle_connection_create (void *cls,
823 GNUNET_NO)) 859 GNUNET_NO))
824 { 860 {
825 LOG (GNUNET_ERROR_TYPE_DEBUG, 861 LOG (GNUNET_ERROR_TYPE_DEBUG,
826 "Dropping CADET_CONNECTION_CREATE without sender in the path\n"); 862 "Dropping CADET_CONNECTION_CREATE without sender at previous hop in the path\n");
827 GNUNET_break_op (0); 863 GNUNET_break_op (0);
828 return; 864 return;
829 } 865 }
830 if (NULL != 866 if (NULL !=
831 get_route (&msg->cid)) 867 (route = get_route (&msg->cid)))
832 { 868 {
833 /* Duplicate CREATE, pass it on, previous one might have been lost! */ 869 /* Duplicate CREATE, pass it on, previous one might have been lost! */
870
834 LOG (GNUNET_ERROR_TYPE_DEBUG, 871 LOG (GNUNET_ERROR_TYPE_DEBUG,
835 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n", 872 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n",
836 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 873 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
@@ -859,7 +896,7 @@ handle_connection_create (void *cls,
859 origin = GCP_get (&pids[0], 896 origin = GCP_get (&pids[0],
860 GNUNET_YES); 897 GNUNET_YES);
861 LOG (GNUNET_ERROR_TYPE_DEBUG, 898 LOG (GNUNET_ERROR_TYPE_DEBUG,
862 "Received CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n", 899 "I am destination for CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n",
863 GCP_2s (origin), 900 GCP_2s (origin),
864 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 901 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
865 path = GCPP_get_path_from_route (path_length - 1, 902 path = GCPP_get_path_from_route (path_length - 1,
@@ -949,6 +986,10 @@ handle_connection_create (void *cls,
949 3), 986 3),
950 &timeout_cb, 987 &timeout_cb,
951 NULL); 988 NULL);
989 /* also pass CREATE message along to next hop */
990 route_message (sender,
991 &msg->cid,
992 &msg->header);
952} 993}
953 994
954 995
@@ -970,7 +1011,9 @@ handle_connection_create_ack (void *cls,
970 if (NULL != cc) 1011 if (NULL != cc)
971 { 1012 {
972 /* verify ACK came from the right direction */ 1013 /* verify ACK came from the right direction */
973 struct CadetPeerPath *path = GCC_get_path (cc); 1014 unsigned int len;
1015 struct CadetPeerPath *path = GCC_get_path (cc,
1016 &len);
974 1017
975 if (peer != 1018 if (peer !=
976 GCPP_get_peer_at_offset (path, 1019 GCPP_get_peer_at_offset (path,
@@ -1014,7 +1057,9 @@ handle_connection_broken (void *cls,
1014 if (NULL != cc) 1057 if (NULL != cc)
1015 { 1058 {
1016 /* verify message came from the right direction */ 1059 /* verify message came from the right direction */
1017 struct CadetPeerPath *path = GCC_get_path (cc); 1060 unsigned int len;
1061 struct CadetPeerPath *path = GCC_get_path (cc,
1062 &len);
1018 1063
1019 if (peer != 1064 if (peer !=
1020 GCPP_get_peer_at_offset (path, 1065 GCPP_get_peer_at_offset (path,
@@ -1063,7 +1108,9 @@ handle_connection_destroy (void *cls,
1063 if (NULL != cc) 1108 if (NULL != cc)
1064 { 1109 {
1065 /* verify message came from the right direction */ 1110 /* verify message came from the right direction */
1066 struct CadetPeerPath *path = GCC_get_path (cc); 1111 unsigned int len;
1112 struct CadetPeerPath *path = GCC_get_path (cc,
1113 &len);
1067 1114
1068 if (peer != 1115 if (peer !=
1069 GCPP_get_peer_at_offset (path, 1116 GCPP_get_peer_at_offset (path,
@@ -1108,11 +1155,19 @@ handle_tunnel_kx (void *cls,
1108 struct CadetConnection *cc; 1155 struct CadetConnection *cc;
1109 1156
1110 /* First, check if message belongs to a connection that ends here. */ 1157 /* First, check if message belongs to a connection that ends here. */
1158 LOG (GNUNET_ERROR_TYPE_DEBUG,
1159 "Routing KX with ephemeral %s on CID %s\n",
1160 GNUNET_e2s (&msg->ephemeral_key),
1161 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1162
1163
1111 cc = GCC_lookup (&msg->cid); 1164 cc = GCC_lookup (&msg->cid);
1112 if (NULL != cc) 1165 if (NULL != cc)
1113 { 1166 {
1114 /* verify message came from the right direction */ 1167 /* verify message came from the right direction */
1115 struct CadetPeerPath *path = GCC_get_path (cc); 1168 unsigned int len;
1169 struct CadetPeerPath *path = GCC_get_path (cc,
1170 &len);
1116 1171
1117 if (peer != 1172 if (peer !=
1118 GCPP_get_peer_at_offset (path, 1173 GCPP_get_peer_at_offset (path,
@@ -1152,7 +1207,9 @@ handle_tunnel_kx_auth (void *cls,
1152 if (NULL != cc) 1207 if (NULL != cc)
1153 { 1208 {
1154 /* verify message came from the right direction */ 1209 /* verify message came from the right direction */
1155 struct CadetPeerPath *path = GCC_get_path (cc); 1210 unsigned int len;
1211 struct CadetPeerPath *path = GCC_get_path (cc,
1212 &len);
1156 1213
1157 if (peer != 1214 if (peer !=
1158 GCPP_get_peer_at_offset (path, 1215 GCPP_get_peer_at_offset (path,
@@ -1208,7 +1265,9 @@ handle_tunnel_encrypted (void *cls,
1208 if (NULL != cc) 1265 if (NULL != cc)
1209 { 1266 {
1210 /* verify message came from the right direction */ 1267 /* verify message came from the right direction */
1211 struct CadetPeerPath *path = GCC_get_path (cc); 1268 unsigned int len;
1269 struct CadetPeerPath *path = GCC_get_path (cc,
1270 &len);
1212 1271
1213 if (peer != 1272 if (peer !=
1214 GCPP_get_peer_at_offset (path, 1273 GCPP_get_peer_at_offset (path,