diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-05-20 00:35:13 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-05-20 00:36:20 +0200 |
commit | 0be37e812d034754eb725701f237fbc81b973904 (patch) | |
tree | c50481209ec97b5dbbd075489255477c5e761d3d /src/cadet/gnunet-service-cadet_core.c | |
parent | c227e3f00efb4b3677e9b85c0273a7bf5fbcb4a9 (diff) | |
download | gnunet-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.c | 117 |
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, |