diff options
Diffstat (limited to 'src')
76 files changed, 2675 insertions, 2712 deletions
diff --git a/src/arm/Makefile.am b/src/arm/Makefile.am index 373847fde..b1706a479 100644 --- a/src/arm/Makefile.am +++ b/src/arm/Makefile.am | |||
@@ -92,7 +92,8 @@ test_gnunet_service_arm_SOURCES = \ | |||
92 | 92 | ||
93 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' | 93 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' |
94 | 94 | ||
95 | %.py: %.py.in Makefile | 95 | SUFFIXES = .py.in .py |
96 | .py.in.py: | ||
96 | $(do_subst) < $(srcdir)/$< > $@ | 97 | $(do_subst) < $(srcdir)/$< > $@ |
97 | chmod +x $@ | 98 | chmod +x $@ |
98 | 99 | ||
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index 2db2ba0d1..bf5982d10 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -1915,7 +1915,6 @@ setup_service (void *cls, | |||
1915 | struct sockaddr **addrs; | 1915 | struct sockaddr **addrs; |
1916 | socklen_t *addr_lens; | 1916 | socklen_t *addr_lens; |
1917 | int ret; | 1917 | int ret; |
1918 | unsigned int i; | ||
1919 | 1918 | ||
1920 | if (0 == strcasecmp (section, | 1919 | if (0 == strcasecmp (section, |
1921 | "arm")) | 1920 | "arm")) |
@@ -2027,7 +2026,7 @@ setup_service (void *cls, | |||
2027 | &addr_lens))) | 2026 | &addr_lens))) |
2028 | return; | 2027 | return; |
2029 | /* this will free (or capture) addrs[i] */ | 2028 | /* this will free (or capture) addrs[i] */ |
2030 | for (i = 0; i < ret; i++) | 2029 | for (unsigned int i = 0; i < ret; i++) |
2031 | create_listen_socket (addrs[i], | 2030 | create_listen_socket (addrs[i], |
2032 | addr_lens[i], | 2031 | addr_lens[i], |
2033 | sl); | 2032 | sl); |
diff --git a/src/ats-tool/gnunet-ats.c b/src/ats-tool/gnunet-ats.c index 5ec7693b1..d88e6d523 100644 --- a/src/ats-tool/gnunet-ats.c +++ b/src/ats-tool/gnunet-ats.c | |||
@@ -872,8 +872,8 @@ run (void *cls, | |||
872 | 872 | ||
873 | for (c = 0; c < strlen (opt_type_str); c++) | 873 | for (c = 0; c < strlen (opt_type_str); c++) |
874 | { | 874 | { |
875 | if (isupper (opt_type_str[c])) | 875 | if (isupper ((unsigned char) opt_type_str[c])) |
876 | opt_type_str[c] = tolower (opt_type_str[c]); | 876 | opt_type_str[c] = tolower ((unsigned char) opt_type_str[c]); |
877 | } | 877 | } |
878 | 878 | ||
879 | if (0 == strcasecmp ("latency", opt_type_str)) | 879 | if (0 == strcasecmp ("latency", opt_type_str)) |
@@ -974,7 +974,7 @@ main (int argc, | |||
974 | gettext_noop ("set preference for the given peer"), | 974 | gettext_noop ("set preference for the given peer"), |
975 | &opt_set_pref), | 975 | &opt_set_pref), |
976 | 976 | ||
977 | GNUNET_GETOPT_option_flag ('q', | 977 | GNUNET_GETOPT_option_flag ('q', |
978 | "quotas", | 978 | "quotas", |
979 | gettext_noop ("print all configured quotas"), | 979 | gettext_noop ("print all configured quotas"), |
980 | &opt_print_quotas), | 980 | &opt_print_quotas), |
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c index 00a482452..366e31405 100644 --- a/src/cadet/cadet_api.c +++ b/src/cadet/cadet_api.c | |||
@@ -824,6 +824,29 @@ handle_mq_error (void *cls, | |||
824 | 824 | ||
825 | 825 | ||
826 | /** | 826 | /** |
827 | * Check that message received from CADET service is well-formed. | ||
828 | * | ||
829 | * @param cls the `struct GNUNET_CADET_Handle` | ||
830 | * @param message the message we got | ||
831 | * @return #GNUNET_OK if the message is well-formed, | ||
832 | * #GNUNET_SYSERR otherwise | ||
833 | */ | ||
834 | static int | ||
835 | check_get_peers (void *cls, | ||
836 | const struct GNUNET_MessageHeader *message) | ||
837 | { | ||
838 | size_t esize; | ||
839 | |||
840 | esize = ntohs (message->size); | ||
841 | if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == esize) | ||
842 | return GNUNET_OK; | ||
843 | if (sizeof (struct GNUNET_MessageHeader) == esize) | ||
844 | return GNUNET_OK; | ||
845 | return GNUNET_SYSERR; | ||
846 | } | ||
847 | |||
848 | |||
849 | /** | ||
827 | * Process a local reply about info on all tunnels, pass info to the user. | 850 | * Process a local reply about info on all tunnels, pass info to the user. |
828 | * | 851 | * |
829 | * @param cls Closure (Cadet handle). | 852 | * @param cls Closure (Cadet handle). |
@@ -831,17 +854,26 @@ handle_mq_error (void *cls, | |||
831 | */ | 854 | */ |
832 | static void | 855 | static void |
833 | handle_get_peers (void *cls, | 856 | handle_get_peers (void *cls, |
834 | const struct GNUNET_CADET_LocalInfoPeer *msg) | 857 | const struct GNUNET_MessageHeader *msg) |
835 | { | 858 | { |
836 | struct GNUNET_CADET_Handle *h = cls; | 859 | struct GNUNET_CADET_Handle *h = cls; |
860 | const struct GNUNET_CADET_LocalInfoPeer *info = | ||
861 | (const struct GNUNET_CADET_LocalInfoPeer *) msg; | ||
837 | 862 | ||
838 | if (NULL == h->info_cb.peers_cb) | 863 | if (NULL == h->info_cb.peers_cb) |
839 | return; | 864 | return; |
840 | h->info_cb.peers_cb (h->info_cls, | 865 | if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == ntohs (msg->size)) |
841 | &msg->destination, | 866 | h->info_cb.peers_cb (h->info_cls, |
842 | (int) ntohs (msg->tunnel), | 867 | &info->destination, |
843 | (unsigned int) ntohs (msg->paths), | 868 | (int) ntohs (info->tunnel), |
844 | 0); | 869 | (unsigned int) ntohs (info->paths), |
870 | 0); | ||
871 | else | ||
872 | h->info_cb.peers_cb (h->info_cls, | ||
873 | NULL, | ||
874 | 0, | ||
875 | 0, | ||
876 | 0); | ||
845 | } | 877 | } |
846 | 878 | ||
847 | 879 | ||
@@ -946,6 +978,29 @@ handle_get_peer (void *cls, | |||
946 | 978 | ||
947 | 979 | ||
948 | /** | 980 | /** |
981 | * Check that message received from CADET service is well-formed. | ||
982 | * | ||
983 | * @param cls the `struct GNUNET_CADET_Handle` | ||
984 | * @param message the message we got | ||
985 | * @return #GNUNET_OK if the message is well-formed, | ||
986 | * #GNUNET_SYSERR otherwise | ||
987 | */ | ||
988 | static int | ||
989 | check_get_tunnels (void *cls, | ||
990 | const struct GNUNET_MessageHeader *message) | ||
991 | { | ||
992 | size_t esize; | ||
993 | |||
994 | esize = ntohs (message->size); | ||
995 | if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) == esize) | ||
996 | return GNUNET_OK; | ||
997 | if (sizeof (struct GNUNET_MessageHeader) == esize) | ||
998 | return GNUNET_OK; | ||
999 | return GNUNET_SYSERR; | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | /** | ||
949 | * Process a local reply about info on all tunnels, pass info to the user. | 1004 | * Process a local reply about info on all tunnels, pass info to the user. |
950 | * | 1005 | * |
951 | * @param cls Closure (Cadet handle). | 1006 | * @param cls Closure (Cadet handle). |
@@ -953,19 +1008,28 @@ handle_get_peer (void *cls, | |||
953 | */ | 1008 | */ |
954 | static void | 1009 | static void |
955 | handle_get_tunnels (void *cls, | 1010 | handle_get_tunnels (void *cls, |
956 | const struct GNUNET_CADET_LocalInfoTunnel *msg) | 1011 | const struct GNUNET_MessageHeader *msg) |
957 | { | 1012 | { |
958 | struct GNUNET_CADET_Handle *h = cls; | 1013 | struct GNUNET_CADET_Handle *h = cls; |
1014 | const struct GNUNET_CADET_LocalInfoTunnel *info = | ||
1015 | (const struct GNUNET_CADET_LocalInfoTunnel *) msg; | ||
959 | 1016 | ||
960 | if (NULL == h->info_cb.tunnels_cb) | 1017 | if (NULL == h->info_cb.tunnels_cb) |
961 | return; | 1018 | return; |
962 | h->info_cb.tunnels_cb (h->info_cls, | 1019 | if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) == ntohs (msg->size)) |
963 | &msg->destination, | 1020 | h->info_cb.tunnels_cb (h->info_cls, |
964 | ntohl (msg->channels), | 1021 | &info->destination, |
965 | ntohl (msg->connections), | 1022 | ntohl (info->channels), |
966 | ntohs (msg->estate), | 1023 | ntohl (info->connections), |
967 | ntohs (msg->cstate)); | 1024 | ntohs (info->estate), |
968 | 1025 | ntohs (info->cstate)); | |
1026 | else | ||
1027 | h->info_cb.tunnels_cb (h->info_cls, | ||
1028 | NULL, | ||
1029 | 0, | ||
1030 | 0, | ||
1031 | 0, | ||
1032 | 0); | ||
969 | } | 1033 | } |
970 | 1034 | ||
971 | 1035 | ||
@@ -1075,18 +1139,18 @@ reconnect (struct GNUNET_CADET_Handle *h) | |||
1075 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, | 1139 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, |
1076 | struct GNUNET_CADET_LocalAck, | 1140 | struct GNUNET_CADET_LocalAck, |
1077 | h), | 1141 | h), |
1078 | GNUNET_MQ_hd_fixed_size (get_peers, | 1142 | GNUNET_MQ_hd_var_size (get_peers, |
1079 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS, | 1143 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS, |
1080 | struct GNUNET_CADET_LocalInfoPeer, | 1144 | struct GNUNET_MessageHeader, |
1081 | h), | 1145 | h), |
1082 | GNUNET_MQ_hd_var_size (get_peer, | 1146 | GNUNET_MQ_hd_var_size (get_peer, |
1083 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER, | 1147 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER, |
1084 | struct GNUNET_CADET_LocalInfoPeer, | 1148 | struct GNUNET_CADET_LocalInfoPeer, |
1085 | h), | 1149 | h), |
1086 | GNUNET_MQ_hd_fixed_size (get_tunnels, | 1150 | GNUNET_MQ_hd_var_size (get_tunnels, |
1087 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS, | 1151 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS, |
1088 | struct GNUNET_CADET_LocalInfoTunnel, | 1152 | struct GNUNET_MessageHeader, |
1089 | h), | 1153 | h), |
1090 | GNUNET_MQ_hd_var_size (get_tunnel, | 1154 | GNUNET_MQ_hd_var_size (get_tunnel, |
1091 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL, | 1155 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL, |
1092 | struct GNUNET_CADET_LocalInfoTunnel, | 1156 | struct GNUNET_CADET_LocalInfoTunnel, |
@@ -1094,6 +1158,7 @@ reconnect (struct GNUNET_CADET_Handle *h) | |||
1094 | GNUNET_MQ_handler_end () | 1158 | GNUNET_MQ_handler_end () |
1095 | }; | 1159 | }; |
1096 | 1160 | ||
1161 | GNUNET_assert (NULL == h->mq); | ||
1097 | h->mq = GNUNET_CLIENT_connect (h->cfg, | 1162 | h->mq = GNUNET_CLIENT_connect (h->cfg, |
1098 | "cadet", | 1163 | "cadet", |
1099 | handlers, | 1164 | handlers, |
@@ -1600,7 +1665,10 @@ GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h, | |||
1600 | 1665 | ||
1601 | GNUNET_assert (NULL != connects); | 1666 | GNUNET_assert (NULL != connects); |
1602 | GNUNET_assert (NULL != disconnects); | 1667 | GNUNET_assert (NULL != disconnects); |
1603 | 1668 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | |
1669 | "Listening to CADET port %s\n", | ||
1670 | GNUNET_h2s (port)); | ||
1671 | |||
1604 | p = GNUNET_new (struct GNUNET_CADET_Port); | 1672 | p = GNUNET_new (struct GNUNET_CADET_Port); |
1605 | p->cadet = h; | 1673 | p->cadet = h; |
1606 | p->id = *port; | 1674 | p->id = *port; |
@@ -1663,6 +1731,10 @@ GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h, | |||
1663 | struct GNUNET_MQ_Envelope *env; | 1731 | struct GNUNET_MQ_Envelope *env; |
1664 | 1732 | ||
1665 | GNUNET_assert (NULL != disconnects); | 1733 | GNUNET_assert (NULL != disconnects); |
1734 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1735 | "Creating channel to peer %s at port %s\n", | ||
1736 | GNUNET_i2s (destination), | ||
1737 | GNUNET_h2s (port)); | ||
1666 | ch = create_channel (h, | 1738 | ch = create_channel (h, |
1667 | NULL); | 1739 | NULL); |
1668 | ch->ctx = channel_cls; | 1740 | ch->ctx = channel_cls; |
diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c index 675e7faf0..a9b02714b 100644 --- a/src/cadet/gnunet-cadet.c +++ b/src/cadet/gnunet-cadet.c | |||
@@ -693,6 +693,7 @@ show_tunnel (void *cls) | |||
693 | { | 693 | { |
694 | struct GNUNET_PeerIdentity pid; | 694 | struct GNUNET_PeerIdentity pid; |
695 | 695 | ||
696 | job = NULL; | ||
696 | if (GNUNET_OK != | 697 | if (GNUNET_OK != |
697 | GNUNET_CRYPTO_eddsa_public_key_from_string (tunnel_id, | 698 | GNUNET_CRYPTO_eddsa_public_key_from_string (tunnel_id, |
698 | strlen (tunnel_id), | 699 | strlen (tunnel_id), |
diff --git a/src/cadet/gnunet-service-cadet_core.c b/src/cadet/gnunet-service-cadet_core.c index ae03b4f35..99957d8a1 100644 --- a/src/cadet/gnunet-service-cadet_core.c +++ b/src/cadet/gnunet-service-cadet_core.c | |||
@@ -771,6 +771,33 @@ handle_connection_create (void *cls, | |||
771 | 771 | ||
772 | options = (enum GNUNET_CADET_ChannelOption) ntohl (msg->options); | 772 | options = (enum GNUNET_CADET_ChannelOption) ntohl (msg->options); |
773 | path_length = size / sizeof (struct GNUNET_PeerIdentity); | 773 | path_length = size / sizeof (struct GNUNET_PeerIdentity); |
774 | if (0 == path_length) | ||
775 | { | ||
776 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
777 | "Dropping CADET_CONNECTION_CREATE with empty path\n"); | ||
778 | GNUNET_break_op (0); | ||
779 | return; | ||
780 | } | ||
781 | /* Check for loops */ | ||
782 | struct GNUNET_CONTAINER_MultiPeerMap *map; | ||
783 | map = GNUNET_CONTAINER_multipeermap_create (path_length * 2, | ||
784 | GNUNET_YES); | ||
785 | GNUNET_assert (NULL != map); | ||
786 | for (off = 0; off < path_length; off++) { | ||
787 | if (GNUNET_SYSERR == | ||
788 | GNUNET_CONTAINER_multipeermap_put (map, | ||
789 | &pids[off], | ||
790 | NULL, | ||
791 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) { | ||
792 | /* bogus request */ | ||
793 | GNUNET_CONTAINER_multipeermap_destroy (map); | ||
794 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
795 | "Dropping CADET_CONNECTION_CREATE with cyclic path\n"); | ||
796 | GNUNET_break_op (0); | ||
797 | return; | ||
798 | } | ||
799 | } | ||
800 | GNUNET_CONTAINER_multipeermap_destroy (map); | ||
774 | /* Initiator is at offset 0. */ | 801 | /* Initiator is at offset 0. */ |
775 | for (off=1;off<path_length;off++) | 802 | for (off=1;off<path_length;off++) |
776 | if (0 == memcmp (&my_full_id, | 803 | if (0 == memcmp (&my_full_id, |
@@ -779,7 +806,8 @@ handle_connection_create (void *cls, | |||
779 | break; | 806 | break; |
780 | if (off == path_length) | 807 | if (off == path_length) |
781 | { | 808 | { |
782 | /* We are not on the path, bogus request */ | 809 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
810 | "Dropping CADET_CONNECTION_CREATE without us in the path\n"); | ||
783 | GNUNET_break_op (0); | 811 | GNUNET_break_op (0); |
784 | return; | 812 | return; |
785 | } | 813 | } |
@@ -787,7 +815,8 @@ handle_connection_create (void *cls, | |||
787 | if (sender != GCP_get (&pids[off - 1], | 815 | if (sender != GCP_get (&pids[off - 1], |
788 | GNUNET_NO)) | 816 | GNUNET_NO)) |
789 | { | 817 | { |
790 | /* sender is not on the path, not allowed */ | 818 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
819 | "Dropping CADET_CONNECTION_CREATE without sender in the path\n"); | ||
791 | GNUNET_break_op (0); | 820 | GNUNET_break_op (0); |
792 | return; | 821 | return; |
793 | } | 822 | } |
diff --git a/src/cadet/gnunet-service-cadet_paths.c b/src/cadet/gnunet-service-cadet_paths.c index 13752643c..9dd6f1ddd 100644 --- a/src/cadet/gnunet-service-cadet_paths.c +++ b/src/cadet/gnunet-service-cadet_paths.c | |||
@@ -187,33 +187,51 @@ GCPP_del_connection (struct CadetPeerPath *path, | |||
187 | 187 | ||
188 | 188 | ||
189 | /** | 189 | /** |
190 | * This path is no longer needed, free resources. | 190 | * Tries to attach @a path to a peer, working backwards from the end |
191 | * and stopping at @a stop_at. If path->hn is NULL on return then the | ||
192 | * path was not attached and you can assume that path->entries_length | ||
193 | * is equal to @a stop_at. | ||
191 | * | 194 | * |
192 | * @param path path resources to free | 195 | * @param path the path to attach |
196 | * @param stop_at the path length at which to stop trying | ||
193 | */ | 197 | */ |
194 | static void | 198 | static void |
195 | path_destroy (struct CadetPeerPath *path) | 199 | attach_path (struct CadetPeerPath *path, unsigned int stop_at) |
196 | { | 200 | { |
197 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 201 | GNUNET_assert (NULL == path->hn); |
198 | "Destroying path %s\n", | 202 | |
199 | GCPP_2s (path)); | 203 | /* Try to attach this path to a peer, working backwards from the end. */ |
200 | for (unsigned int i=0;i<path->entries_length;i++) | 204 | while (path->entries_length > stop_at) |
201 | { | 205 | { |
202 | struct CadetPeerPathEntry *entry = path->entries[i]; | 206 | unsigned int end = path->entries_length - 1; |
207 | struct CadetPeerPathEntry *entry = path->entries[end]; | ||
208 | int force = GNUNET_NO; | ||
203 | 209 | ||
210 | recalculate_path_desirability (path); | ||
211 | /* If the entry already has a connection using it, force attach. */ | ||
204 | if (NULL != entry->cc) | 212 | if (NULL != entry->cc) |
205 | { | 213 | force = GNUNET_YES; |
206 | struct CadetTConnection *ct; | 214 | path->hn = GCP_attach_path (entry->peer, |
215 | path, | ||
216 | end, | ||
217 | force); | ||
218 | if (NULL != path->hn) | ||
219 | break; | ||
207 | 220 | ||
208 | ct = GCC_get_ct (entry->cc); | 221 | /* Attach failed, trim this entry from the path. */ |
209 | if (NULL != ct) | 222 | GNUNET_assert (NULL == entry->cc); |
210 | GCT_connection_lost (ct); | 223 | GCP_path_entry_remove (entry->peer, |
211 | GCC_destroy_without_tunnel (entry->cc); | 224 | entry, |
212 | } | 225 | end); |
213 | GNUNET_free (entry); | 226 | GNUNET_free (entry); |
227 | path->entries[end] = NULL; | ||
228 | path->entries_length--; | ||
214 | } | 229 | } |
215 | GNUNET_free (path->entries); | 230 | |
216 | GNUNET_free (path); | 231 | /* Shrink array to actual path length. */ |
232 | GNUNET_array_grow (path->entries, | ||
233 | path->entries_length, | ||
234 | path->entries_length); | ||
217 | } | 235 | } |
218 | 236 | ||
219 | 237 | ||
@@ -228,7 +246,6 @@ void | |||
228 | GCPP_release (struct CadetPeerPath *path) | 246 | GCPP_release (struct CadetPeerPath *path) |
229 | { | 247 | { |
230 | struct CadetPeerPathEntry *entry; | 248 | struct CadetPeerPathEntry *entry; |
231 | int force; | ||
232 | 249 | ||
233 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 250 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
234 | "Owner releases path %s\n", | 251 | "Owner releases path %s\n", |
@@ -236,34 +253,23 @@ GCPP_release (struct CadetPeerPath *path) | |||
236 | path->hn = NULL; | 253 | path->hn = NULL; |
237 | entry = path->entries[path->entries_length - 1]; | 254 | entry = path->entries[path->entries_length - 1]; |
238 | GNUNET_assert (path == entry->path); | 255 | GNUNET_assert (path == entry->path); |
239 | while (1) | 256 | GNUNET_assert (NULL == entry->cc); |
257 | /* cut 'off' end of path */ | ||
258 | GCP_path_entry_remove (entry->peer, | ||
259 | entry, | ||
260 | path->entries_length - 1); | ||
261 | GNUNET_free (entry); | ||
262 | path->entries[path->entries_length - 1] = NULL; | ||
263 | path->entries_length--; | ||
264 | /* see if new peer at the end likes this path any better */ | ||
265 | attach_path (path, 0); | ||
266 | if (NULL == path->hn) | ||
240 | { | 267 | { |
241 | /* cut 'off' end of path */ | 268 | /* nobody wants us, discard the path */ |
242 | GNUNET_assert (NULL == entry->cc); | 269 | GNUNET_assert (0 == path->entries_length); |
243 | GCP_path_entry_remove (entry->peer, | 270 | GNUNET_assert (NULL == path->entries); |
244 | entry, | 271 | GNUNET_free (path); |
245 | path->entries_length - 1); | ||
246 | path->entries_length--; /* We don't bother shrinking the 'entries' array, | ||
247 | as it's probably not worth it. */ | ||
248 | GNUNET_free (entry); | ||
249 | if (0 == path->entries_length) | ||
250 | break; /* the end */ | ||
251 | |||
252 | /* see if new peer at the end likes this path any better */ | ||
253 | entry = path->entries[path->entries_length - 1]; | ||
254 | GNUNET_assert (path == entry->path); | ||
255 | force = (NULL == entry->cc) ? GNUNET_NO : GNUNET_YES; | ||
256 | path->hn = GCP_attach_path (entry->peer, | ||
257 | path, | ||
258 | path->entries_length - 1, | ||
259 | force); | ||
260 | if (NULL != path->hn) | ||
261 | return; /* yep, got attached, we are done. */ | ||
262 | GNUNET_assert (GNUNET_NO == force); | ||
263 | } | 272 | } |
264 | |||
265 | /* nobody wants us, discard the path */ | ||
266 | path_destroy (path); | ||
267 | } | 273 | } |
268 | 274 | ||
269 | 275 | ||
@@ -422,32 +428,13 @@ extend_path (struct CadetPeerPath *path, | |||
422 | path, | 428 | path, |
423 | path->hn); | 429 | path->hn); |
424 | path->hn = NULL; | 430 | path->hn = NULL; |
425 | for (i=num_peers-1;i>=0;i--) | 431 | path->entries_length = old_len + num_peers; |
426 | { | 432 | attach_path (path, old_len); |
427 | struct CadetPeerPathEntry *entry = path->entries[old_len + i]; | ||
428 | |||
429 | path->entries_length = old_len + i + 1; | ||
430 | recalculate_path_desirability (path); | ||
431 | path->hn = GCP_attach_path (peers[i], | ||
432 | path, | ||
433 | old_len + (unsigned int) i, | ||
434 | force); | ||
435 | if (NULL != path->hn) | ||
436 | break; | ||
437 | GNUNET_assert (NULL == entry->cc); | ||
438 | GCP_path_entry_remove (entry->peer, | ||
439 | entry, | ||
440 | old_len + i); | ||
441 | GNUNET_free (entry); | ||
442 | path->entries[old_len + i] = NULL; | ||
443 | } | ||
444 | if (NULL == path->hn) | 433 | if (NULL == path->hn) |
445 | { | 434 | { |
446 | /* none of the peers is interested in this path; | 435 | /* none of the peers is interested in this path; |
447 | shrink path back and re-attach. */ | 436 | re-attach. */ |
448 | GNUNET_array_grow (path->entries, | 437 | GNUNET_assert (old_len == path->entries_length); |
449 | path->entries_length, | ||
450 | old_len); | ||
451 | path->hn = GCP_attach_path (path->entries[old_len - 1]->peer, | 438 | path->hn = GCP_attach_path (path->entries[old_len - 1]->peer, |
452 | path, | 439 | path, |
453 | old_len - 1, | 440 | old_len - 1, |
@@ -482,7 +469,6 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
482 | struct CadetPeer *cpath[get_path_length + put_path_length]; | 469 | struct CadetPeer *cpath[get_path_length + put_path_length]; |
483 | struct CheckMatchContext cm_ctx; | 470 | struct CheckMatchContext cm_ctx; |
484 | struct CadetPeerPath *path; | 471 | struct CadetPeerPath *path; |
485 | struct GNUNET_CONTAINER_HeapNode *hn; | ||
486 | int i; | 472 | int i; |
487 | unsigned int skip; | 473 | unsigned int skip; |
488 | unsigned int total_len; | 474 | unsigned int total_len; |
@@ -498,8 +484,16 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
498 | const struct GNUNET_PeerIdentity *pid; | 484 | const struct GNUNET_PeerIdentity *pid; |
499 | 485 | ||
500 | pid = (off < get_path_length) | 486 | pid = (off < get_path_length) |
501 | ? &get_path[get_path_length - off] | 487 | ? &get_path[get_path_length - off - 1] |
502 | : &put_path[get_path_length + put_path_length - off]; | 488 | : &put_path[get_path_length + put_path_length - off - 1]; |
489 | /* Check that I am not in the path */ | ||
490 | if (0 == memcmp (&my_full_id, | ||
491 | pid, | ||
492 | sizeof (struct GNUNET_PeerIdentity))) | ||
493 | { | ||
494 | skip = off + 1; | ||
495 | continue; | ||
496 | } | ||
503 | cpath[off - skip] = GCP_get (pid, | 497 | cpath[off - skip] = GCP_get (pid, |
504 | GNUNET_YES); | 498 | GNUNET_YES); |
505 | /* Check that no peer is twice on the path */ | 499 | /* Check that no peer is twice on the path */ |
@@ -512,6 +506,12 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
512 | } | 506 | } |
513 | } | 507 | } |
514 | } | 508 | } |
509 | if (skip >= total_len) | ||
510 | { | ||
511 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
512 | "Path discovered from DHT is one big cycle?\n"); | ||
513 | return; | ||
514 | } | ||
515 | total_len -= skip; | 515 | total_len -= skip; |
516 | 516 | ||
517 | /* First figure out if this path is a subset of an existing path, an | 517 | /* First figure out if this path is a subset of an existing path, an |
@@ -572,39 +572,17 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
572 | } | 572 | } |
573 | 573 | ||
574 | /* Finally, try to attach it */ | 574 | /* Finally, try to attach it */ |
575 | hn = NULL; | 575 | attach_path (path, 0); |
576 | for (i=total_len-1;i>=0;i--) | 576 | if (NULL == path->hn) |
577 | { | ||
578 | struct CadetPeerPathEntry *entry = path->entries[i]; | ||
579 | |||
580 | path->entries_length = i + 1; | ||
581 | recalculate_path_desirability (path); | ||
582 | hn = GCP_attach_path (cpath[i], | ||
583 | path, | ||
584 | (unsigned int) i, | ||
585 | GNUNET_NO); | ||
586 | if (NULL != hn) | ||
587 | break; | ||
588 | GCP_path_entry_remove (entry->peer, | ||
589 | entry, | ||
590 | i); | ||
591 | GNUNET_free (entry); | ||
592 | path->entries[i] = NULL; | ||
593 | } | ||
594 | if (NULL == hn) | ||
595 | { | 577 | { |
596 | /* None of the peers on the path care about it. */ | 578 | /* None of the peers on the path care about it. */ |
597 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 579 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
598 | "Path discovered from DHT is not interesting to us\n"); | 580 | "Path discovered from DHT is not interesting to us\n"); |
599 | GNUNET_free (path->entries); | 581 | GNUNET_assert (0 == path->entries_length); |
582 | GNUNET_assert (NULL == path->entries); | ||
600 | GNUNET_free (path); | 583 | GNUNET_free (path); |
601 | return; | 584 | return; |
602 | } | 585 | } |
603 | path->hn = hn; | ||
604 | /* Shrink path to actual useful length */ | ||
605 | GNUNET_array_grow (path->entries, | ||
606 | path->entries_length, | ||
607 | i + 1); | ||
608 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 586 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
609 | "Created new path %s based on information from DHT\n", | 587 | "Created new path %s based on information from DHT\n", |
610 | GCPP_2s (path)); | 588 | GCPP_2s (path)); |
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c index 71c7c67d0..da78a03c4 100644 --- a/src/cadet/gnunet-service-cadet_peer.c +++ b/src/cadet/gnunet-service-cadet_peer.c | |||
@@ -979,7 +979,7 @@ GCP_attach_path (struct CadetPeer *cp, | |||
979 | (desirability < root_desirability) ) | 979 | (desirability < root_desirability) ) |
980 | { | 980 | { |
981 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 981 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
982 | "Decided to not attach path %p to peer %s due to undesirability\n", | 982 | "Decided to not attach path %s to peer %s due to undesirability\n", |
983 | GCPP_2s (path), | 983 | GCPP_2s (path), |
984 | GCP_2s (cp)); | 984 | GCP_2s (cp)); |
985 | return NULL; | 985 | return NULL; |
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c index 72df2203c..6691a0573 100644 --- a/src/cadet/test_cadet.c +++ b/src/cadet/test_cadet.c | |||
@@ -960,16 +960,16 @@ main (int argc, char *argv[]) | |||
960 | char port_id[] = "test port"; | 960 | char port_id[] = "test port"; |
961 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 961 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
962 | GNUNET_GETOPT_option_relative_time ('t', | 962 | GNUNET_GETOPT_option_relative_time ('t', |
963 | "time", | 963 | "time", |
964 | "short_time", | 964 | "short_time", |
965 | gettext_noop ("set short timeout"), | 965 | gettext_noop ("set short timeout"), |
966 | &short_time), | 966 | &short_time), |
967 | 967 | ||
968 | GNUNET_GETOPT_option_uint ('m', | 968 | GNUNET_GETOPT_option_uint ('m', |
969 | "messages", | 969 | "messages", |
970 | "NUM_MESSAGES", | 970 | "NUM_MESSAGES", |
971 | gettext_noop ("set number of messages to send"), | 971 | gettext_noop ("set number of messages to send"), |
972 | &total_packets), | 972 | &total_packets), |
973 | 973 | ||
974 | GNUNET_GETOPT_OPTION_END | 974 | GNUNET_GETOPT_OPTION_END |
975 | }; | 975 | }; |
diff --git a/src/conversation/gnunet-conversation.c b/src/conversation/gnunet-conversation.c index 8f9ddec25..00ab65680 100644 --- a/src/conversation/gnunet-conversation.c +++ b/src/conversation/gnunet-conversation.c | |||
@@ -1091,7 +1091,7 @@ handle_command_string (char *message, | |||
1091 | strlen (commands[i].command)))) | 1091 | strlen (commands[i].command)))) |
1092 | i++; | 1092 | i++; |
1093 | ptr = &message[strlen (commands[i].command)]; | 1093 | ptr = &message[strlen (commands[i].command)]; |
1094 | while (isspace ((int) *ptr)) | 1094 | while (isspace ((unsigned char) *ptr)) |
1095 | ptr++; | 1095 | ptr++; |
1096 | if ('\0' == *ptr) | 1096 | if ('\0' == *ptr) |
1097 | ptr = NULL; | 1097 | ptr = NULL; |
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index ae0ae508f..944d1e692 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c | |||
@@ -953,7 +953,7 @@ handle_ephemeral_key (void *cls, | |||
953 | kx->peer, | 953 | kx->peer, |
954 | sizeof (struct GNUNET_PeerIdentity))) | 954 | sizeof (struct GNUNET_PeerIdentity))) |
955 | { | 955 | { |
956 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 956 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
957 | "Received EPHEMERAL_KEY from %s, but expected %s\n", | 957 | "Received EPHEMERAL_KEY from %s, but expected %s\n", |
958 | GNUNET_i2s (&m->origin_identity), | 958 | GNUNET_i2s (&m->origin_identity), |
959 | GNUNET_i2s_full (kx->peer)); | 959 | GNUNET_i2s_full (kx->peer)); |
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index 034f2e883..5d34b7c26 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c | |||
@@ -975,6 +975,7 @@ GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer, | |||
975 | session = find_session (peer); | 975 | session = find_session (peer); |
976 | if (NULL == session) | 976 | if (NULL == session) |
977 | { | 977 | { |
978 | GSC_TYPEMAP_destroy (nmap); | ||
978 | GNUNET_break (0); | 979 | GNUNET_break (0); |
979 | return; | 980 | return; |
980 | } | 981 | } |
diff --git a/src/core/test_core_api_reliability.c b/src/core/test_core_api_reliability.c index 900c9f732..528093c99 100644 --- a/src/core/test_core_api_reliability.c +++ b/src/core/test_core_api_reliability.c | |||
@@ -381,6 +381,7 @@ process_hello (void *cls, | |||
381 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 381 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
382 | "Received (my) `%s' from transport service\n", "HELLO"); | 382 | "Received (my) `%s' from transport service\n", "HELLO"); |
383 | GNUNET_assert (message != NULL); | 383 | GNUNET_assert (message != NULL); |
384 | GNUNET_free_non_null (p->hello); | ||
384 | p->hello = GNUNET_copy_message (message); | 385 | p->hello = GNUNET_copy_message (message); |
385 | if ((p == &p1) && (NULL == p2.oh)) | 386 | if ((p == &p1) && (NULL == p2.oh)) |
386 | p2.oh = GNUNET_TRANSPORT_offer_hello (p2.cfg, | 387 | p2.oh = GNUNET_TRANSPORT_offer_hello (p2.cfg, |
@@ -518,6 +519,8 @@ main (int argc, | |||
518 | &ok); | 519 | &ok); |
519 | stop_arm (&p1); | 520 | stop_arm (&p1); |
520 | stop_arm (&p2); | 521 | stop_arm (&p2); |
522 | GNUNET_free_non_null (p1.hello); | ||
523 | GNUNET_free_non_null (p2.hello); | ||
521 | GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-1"); | 524 | GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-1"); |
522 | GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-2"); | 525 | GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-2"); |
523 | 526 | ||
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c index 31f7a997f..2ad864987 100644 --- a/src/datastore/datastore_api.c +++ b/src/datastore/datastore_api.c | |||
@@ -651,6 +651,46 @@ process_queue (struct GNUNET_DATASTORE_Handle *h) | |||
651 | } | 651 | } |
652 | 652 | ||
653 | 653 | ||
654 | /** | ||
655 | * Get the entry at the head of the message queue. | ||
656 | * | ||
657 | * @param h handle to the datastore | ||
658 | * @param response_type the expected response type | ||
659 | * @return the queue entry | ||
660 | */ | ||
661 | static struct GNUNET_DATASTORE_QueueEntry * | ||
662 | get_queue_head (struct GNUNET_DATASTORE_Handle *h, | ||
663 | uint16_t response_type) | ||
664 | { | ||
665 | struct GNUNET_DATASTORE_QueueEntry *qe; | ||
666 | |||
667 | if (h->skip_next_messages > 0) | ||
668 | { | ||
669 | h->skip_next_messages--; | ||
670 | process_queue (h); | ||
671 | return NULL; | ||
672 | } | ||
673 | qe = h->queue_head; | ||
674 | if (NULL == qe) | ||
675 | { | ||
676 | GNUNET_break (0); | ||
677 | do_disconnect (h); | ||
678 | return NULL; | ||
679 | } | ||
680 | if (NULL != qe->env) | ||
681 | { | ||
682 | GNUNET_break (0); | ||
683 | do_disconnect (h); | ||
684 | return NULL; | ||
685 | } | ||
686 | if (response_type != qe->response_type) | ||
687 | { | ||
688 | GNUNET_break (0); | ||
689 | do_disconnect (h); | ||
690 | return NULL; | ||
691 | } | ||
692 | return qe; | ||
693 | } | ||
654 | 694 | ||
655 | 695 | ||
656 | /** | 696 | /** |
@@ -702,30 +742,10 @@ handle_status (void *cls, | |||
702 | const char *emsg; | 742 | const char *emsg; |
703 | int32_t status = ntohl (sm->status); | 743 | int32_t status = ntohl (sm->status); |
704 | 744 | ||
705 | if (h->skip_next_messages > 0) | 745 | qe = get_queue_head (h, |
706 | { | 746 | GNUNET_MESSAGE_TYPE_DATASTORE_STATUS); |
707 | h->skip_next_messages--; | 747 | if (NULL == qe) |
708 | process_queue (h); | ||
709 | return; | ||
710 | } | ||
711 | if (NULL == (qe = h->queue_head)) | ||
712 | { | ||
713 | GNUNET_break (0); | ||
714 | do_disconnect (h); | ||
715 | return; | ||
716 | } | ||
717 | if (NULL != qe->env) | ||
718 | { | ||
719 | GNUNET_break (0); | ||
720 | do_disconnect (h); | ||
721 | return; | ||
722 | } | ||
723 | if (GNUNET_MESSAGE_TYPE_DATASTORE_STATUS != qe->response_type) | ||
724 | { | ||
725 | GNUNET_break (0); | ||
726 | do_disconnect (h); | ||
727 | return; | 748 | return; |
728 | } | ||
729 | rc = qe->qc.sc; | 749 | rc = qe->qc.sc; |
730 | free_queue_entry (qe); | 750 | free_queue_entry (qe); |
731 | if (ntohs (sm->header.size) > sizeof (struct StatusMessage)) | 751 | if (ntohs (sm->header.size) > sizeof (struct StatusMessage)) |
@@ -785,30 +805,10 @@ handle_data (void *cls, | |||
785 | struct GNUNET_DATASTORE_QueueEntry *qe; | 805 | struct GNUNET_DATASTORE_QueueEntry *qe; |
786 | struct ResultContext rc; | 806 | struct ResultContext rc; |
787 | 807 | ||
788 | if (h->skip_next_messages > 0) | 808 | qe = get_queue_head (h, |
789 | { | 809 | GNUNET_MESSAGE_TYPE_DATASTORE_DATA); |
790 | process_queue (h); | ||
791 | return; | ||
792 | } | ||
793 | qe = h->queue_head; | ||
794 | if (NULL == qe) | 810 | if (NULL == qe) |
795 | { | ||
796 | GNUNET_break (0); | ||
797 | do_disconnect (h); | ||
798 | return; | ||
799 | } | ||
800 | if (NULL != qe->env) | ||
801 | { | ||
802 | GNUNET_break (0); | ||
803 | do_disconnect (h); | ||
804 | return; | ||
805 | } | ||
806 | if (GNUNET_MESSAGE_TYPE_DATASTORE_DATA != qe->response_type) | ||
807 | { | ||
808 | GNUNET_break (0); | ||
809 | do_disconnect (h); | ||
810 | return; | 811 | return; |
811 | } | ||
812 | #if INSANE_STATISTICS | 812 | #if INSANE_STATISTICS |
813 | GNUNET_STATISTICS_update (h->stats, | 813 | GNUNET_STATISTICS_update (h->stats, |
814 | gettext_noop ("# Results received"), | 814 | gettext_noop ("# Results received"), |
@@ -854,31 +854,10 @@ handle_data_end (void *cls, | |||
854 | struct GNUNET_DATASTORE_QueueEntry *qe; | 854 | struct GNUNET_DATASTORE_QueueEntry *qe; |
855 | struct ResultContext rc; | 855 | struct ResultContext rc; |
856 | 856 | ||
857 | if (h->skip_next_messages > 0) | 857 | qe = get_queue_head (h, |
858 | { | 858 | GNUNET_MESSAGE_TYPE_DATASTORE_DATA); |
859 | h->skip_next_messages--; | ||
860 | process_queue (h); | ||
861 | return; | ||
862 | } | ||
863 | qe = h->queue_head; | ||
864 | if (NULL == qe) | 859 | if (NULL == qe) |
865 | { | ||
866 | GNUNET_break (0); | ||
867 | do_disconnect (h); | ||
868 | return; | 860 | return; |
869 | } | ||
870 | if (NULL != qe->env) | ||
871 | { | ||
872 | GNUNET_break (0); | ||
873 | do_disconnect (h); | ||
874 | return; | ||
875 | } | ||
876 | if (GNUNET_MESSAGE_TYPE_DATASTORE_DATA != qe->response_type) | ||
877 | { | ||
878 | GNUNET_break (0); | ||
879 | do_disconnect (h); | ||
880 | return; | ||
881 | } | ||
882 | rc = qe->qc.rc; | 861 | rc = qe->qc.rc; |
883 | free_queue_entry (qe); | 862 | free_queue_entry (qe); |
884 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 863 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c index 77b8409cd..cc56f5959 100644 --- a/src/datastore/plugin_datastore_sqlite.c +++ b/src/datastore/plugin_datastore_sqlite.c | |||
@@ -185,21 +185,22 @@ static void | |||
185 | create_indices (sqlite3 * dbh) | 185 | create_indices (sqlite3 * dbh) |
186 | { | 186 | { |
187 | /* create indices */ | 187 | /* create indices */ |
188 | if ((SQLITE_OK != | 188 | if (0 != |
189 | (SQLITE_OK != | ||
189 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS idx_hash ON gn091 (hash)", | 190 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS idx_hash ON gn091 (hash)", |
190 | NULL, NULL, NULL)) || | 191 | NULL, NULL, NULL)) + |
191 | (SQLITE_OK != | 192 | (SQLITE_OK != |
192 | sqlite3_exec (dbh, | 193 | sqlite3_exec (dbh, |
193 | "CREATE INDEX IF NOT EXISTS idx_anon_type ON gn091 (anonLevel ASC,type)", | 194 | "CREATE INDEX IF NOT EXISTS idx_anon_type ON gn091 (anonLevel ASC,type)", |
194 | NULL, NULL, NULL)) || | 195 | NULL, NULL, NULL)) + |
195 | (SQLITE_OK != | 196 | (SQLITE_OK != |
196 | sqlite3_exec (dbh, | 197 | sqlite3_exec (dbh, |
197 | "CREATE INDEX IF NOT EXISTS idx_expire ON gn091 (expire ASC)", | 198 | "CREATE INDEX IF NOT EXISTS idx_expire ON gn091 (expire ASC)", |
198 | NULL, NULL, NULL)) || | 199 | NULL, NULL, NULL)) + |
199 | (SQLITE_OK != | 200 | (SQLITE_OK != |
200 | sqlite3_exec (dbh, | 201 | sqlite3_exec (dbh, |
201 | "CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn091 (repl,rvalue)", | 202 | "CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn091 (repl,rvalue)", |
202 | NULL, NULL, NULL))) | 203 | NULL, NULL, NULL)) ) |
203 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite", | 204 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite", |
204 | "Failed to create indices: %s\n", sqlite3_errmsg (dbh)); | 205 | "Failed to create indices: %s\n", sqlite3_errmsg (dbh)); |
205 | } | 206 | } |
@@ -354,40 +355,24 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
354 | (SQLITE_OK != | 355 | (SQLITE_OK != |
355 | sq_prepare (plugin->dbh, | 356 | sq_prepare (plugin->dbh, |
356 | "SELECT " RESULT_COLUMNS " FROM gn091 " | 357 | "SELECT " RESULT_COLUMNS " FROM gn091 " |
357 | #if SQLITE_VERSION_NUMBER >= 3007000 | ||
358 | "INDEXED BY idx_repl_rvalue " | ||
359 | #endif | ||
360 | "WHERE repl=?2 AND " " (rvalue>=?1 OR " | 358 | "WHERE repl=?2 AND " " (rvalue>=?1 OR " |
361 | " NOT EXISTS (SELECT 1 FROM gn091 " | 359 | " NOT EXISTS (SELECT 1 FROM gn091 " |
362 | #if SQLITE_VERSION_NUMBER >= 3007000 | ||
363 | "INDEXED BY idx_repl_rvalue " | ||
364 | #endif | ||
365 | "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) " | 360 | "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) " |
366 | "ORDER BY rvalue ASC LIMIT 1", | 361 | "ORDER BY rvalue ASC LIMIT 1", |
367 | &plugin->selRepl)) || | 362 | &plugin->selRepl)) || |
368 | (SQLITE_OK != | 363 | (SQLITE_OK != |
369 | sq_prepare (plugin->dbh, | 364 | sq_prepare (plugin->dbh, |
370 | "SELECT MAX(repl) FROM gn091" | 365 | "SELECT MAX(repl) FROM gn091", |
371 | #if SQLITE_VERSION_NUMBER >= 3007000 | ||
372 | " INDEXED BY idx_repl_rvalue" | ||
373 | #endif | ||
374 | "", | ||
375 | &plugin->maxRepl)) || | 366 | &plugin->maxRepl)) || |
376 | (SQLITE_OK != | 367 | (SQLITE_OK != |
377 | sq_prepare (plugin->dbh, | 368 | sq_prepare (plugin->dbh, |
378 | "SELECT " RESULT_COLUMNS " FROM gn091 " | 369 | "SELECT " RESULT_COLUMNS " FROM gn091 " |
379 | #if SQLITE_VERSION_NUMBER >= 3007000 | ||
380 | "INDEXED BY idx_expire " | ||
381 | #endif | ||
382 | "WHERE NOT EXISTS (SELECT 1 FROM gn091 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) " | 370 | "WHERE NOT EXISTS (SELECT 1 FROM gn091 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) " |
383 | "ORDER BY expire ASC LIMIT 1", | 371 | "ORDER BY expire ASC LIMIT 1", |
384 | &plugin->selExpi)) || | 372 | &plugin->selExpi)) || |
385 | (SQLITE_OK != | 373 | (SQLITE_OK != |
386 | sq_prepare (plugin->dbh, | 374 | sq_prepare (plugin->dbh, |
387 | "SELECT " RESULT_COLUMNS " FROM gn091 " | 375 | "SELECT " RESULT_COLUMNS " FROM gn091 " |
388 | #if SQLITE_VERSION_NUMBER >= 3007000 | ||
389 | "INDEXED BY idx_anon_type " | ||
390 | #endif | ||
391 | "WHERE _ROWID_ >= ? AND " | 376 | "WHERE _ROWID_ >= ? AND " |
392 | "anonLevel = 0 AND " | 377 | "anonLevel = 0 AND " |
393 | "type = ? " | 378 | "type = ? " |
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index 00ce0e934..4a78ea4c7 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am | |||
@@ -213,7 +213,8 @@ endif | |||
213 | 213 | ||
214 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' -e 's,[@]bindir[@],$(bindir),g' | 214 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' -e 's,[@]bindir[@],$(bindir),g' |
215 | 215 | ||
216 | %.py: %.py.in Makefile | 216 | SUFFIXES = .py.in .py |
217 | .py.in.py: | ||
217 | $(do_subst) < $(srcdir)/$< > $@ | 218 | $(do_subst) < $(srcdir)/$< > $@ |
218 | chmod +x $@ | 219 | chmod +x $@ |
219 | 220 | ||
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index 36b4c36f1..30d9245ff 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c | |||
@@ -1278,8 +1278,8 @@ GNUNET_DNSPARSER_hex_to_bin (const char *hex, | |||
1278 | in[2] = '\0'; | 1278 | in[2] = '\0'; |
1279 | for (off = 0; off < data_size; off++) | 1279 | for (off = 0; off < data_size; off++) |
1280 | { | 1280 | { |
1281 | in[0] = tolower ((int) hex[off * 2]); | 1281 | in[0] = tolower ((unsigned char) hex[off * 2]); |
1282 | in[1] = tolower ((int) hex[off * 2 + 1]); | 1282 | in[1] = tolower ((unsigned char) hex[off * 2 + 1]); |
1283 | if (1 != sscanf (in, "%x", &h)) | 1283 | if (1 != sscanf (in, "%x", &h)) |
1284 | return off; | 1284 | return off; |
1285 | idata[off] = (uint8_t) h; | 1285 | idata[off] = (uint8_t) h; |
diff --git a/src/fs/fs_misc.c b/src/fs/fs_misc.c index bcb8620cf..b26de431c 100644 --- a/src/fs/fs_misc.c +++ b/src/fs/fs_misc.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010, 2011 GNUnet e.V. | 3 | Copyright (C) 2010, 2011, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -43,6 +43,8 @@ GNUNET_FS_meta_data_suggest_filename (const struct GNUNET_CONTAINER_MetaData | |||
43 | {"application/gnunet-directory", ".gnd"}, | 43 | {"application/gnunet-directory", ".gnd"}, |
44 | {"application/java", ".class"}, | 44 | {"application/java", ".class"}, |
45 | {"application/msword", ".doc"}, | 45 | {"application/msword", ".doc"}, |
46 | {"application/nar", ".nar"}, | ||
47 | {"application/narinfo", ".narinfo"}, | ||
46 | {"application/ogg", ".ogg"}, | 48 | {"application/ogg", ".ogg"}, |
47 | {"application/pdf", ".pdf"}, | 49 | {"application/pdf", ".pdf"}, |
48 | {"application/pgp-keys", ".key"}, | 50 | {"application/pgp-keys", ".key"}, |
@@ -53,8 +55,8 @@ GNUNET_FS_meta_data_suggest_filename (const struct GNUNET_CONTAINER_MetaData | |||
53 | {"application/xml", ".xml"}, | 55 | {"application/xml", ".xml"}, |
54 | {"application/x-debian-package", ".deb"}, | 56 | {"application/x-debian-package", ".deb"}, |
55 | {"application/x-dvi", ".dvi"}, | 57 | {"application/x-dvi", ".dvi"}, |
56 | {"applixation/x-flac", ".flac"}, | 58 | {"application/x-flac", ".flac"}, |
57 | {"applixation/x-gzip", ".gz"}, | 59 | {"application/x-gzip", ".gz"}, |
58 | {"application/x-java-archive", ".jar"}, | 60 | {"application/x-java-archive", ".jar"}, |
59 | {"application/x-java-vm", ".class"}, | 61 | {"application/x-java-vm", ".class"}, |
60 | {"application/x-python-code", ".pyc"}, | 62 | {"application/x-python-code", ".pyc"}, |
diff --git a/src/fs/fs_publish_ublock.c b/src/fs/fs_publish_ublock.c index e21443ccb..189a6909a 100644 --- a/src/fs/fs_publish_ublock.c +++ b/src/fs/fs_publish_ublock.c | |||
@@ -301,6 +301,7 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, | |||
301 | uc->task = GNUNET_SCHEDULER_add_now (&run_cont, | 301 | uc->task = GNUNET_SCHEDULER_add_now (&run_cont, |
302 | uc); | 302 | uc); |
303 | } | 303 | } |
304 | GNUNET_free (ub_enc); | ||
304 | return uc; | 305 | return uc; |
305 | } | 306 | } |
306 | 307 | ||
diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c index 902519f15..c762835ce 100644 --- a/src/fs/plugin_block_fs.c +++ b/src/fs/plugin_block_fs.c | |||
@@ -71,17 +71,22 @@ block_plugin_fs_create_group (void *cls, | |||
71 | return NULL; | 71 | return NULL; |
72 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: | 72 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: |
73 | guard = va_arg (va, const char *); | 73 | guard = va_arg (va, const char *); |
74 | if (0 != strcmp (guard, | 74 | if (0 == strcmp (guard, |
75 | "seen-set-size")) | 75 | "seen-set-size")) |
76 | { | 76 | { |
77 | /* va-args invalid! bad bug, complain! */ | 77 | size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), |
78 | GNUNET_break (0); | 78 | BLOOMFILTER_K); |
79 | size = 8; | 79 | } |
80 | else if (0 == strcmp (guard, | ||
81 | "filter-size")) | ||
82 | { | ||
83 | size = va_arg (va, unsigned int); | ||
80 | } | 84 | } |
81 | else | 85 | else |
82 | { | 86 | { |
83 | size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), | 87 | /* va-args invalid! bad bug, complain! */ |
84 | BLOOMFILTER_K); | 88 | GNUNET_break (0); |
89 | size = 8; | ||
85 | } | 90 | } |
86 | if (0 == size) | 91 | if (0 == size) |
87 | size = raw_data_size; /* not for us to determine, use what we got! */ | 92 | size = raw_data_size; /* not for us to determine, use what we got! */ |
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c index 2a6de1c30..3af571eba 100644 --- a/src/gns/gnunet-gns-proxy.c +++ b/src/gns/gnunet-gns-proxy.c | |||
@@ -786,6 +786,8 @@ cleanup_s5r (struct Socks5Request *s5r) | |||
786 | 786 | ||
787 | /* ************************* HTTP handling with cURL *********************** */ | 787 | /* ************************* HTTP handling with cURL *********************** */ |
788 | 788 | ||
789 | static void | ||
790 | curl_download_prepare (); | ||
789 | 791 | ||
790 | /** | 792 | /** |
791 | * Callback for MHD response generation. This function is called from | 793 | * Callback for MHD response generation. This function is called from |
@@ -824,6 +826,11 @@ mhd_content_cb (void *cls, | |||
824 | { | 826 | { |
825 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 827 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
826 | "Pausing MHD download, no data available\n"); | 828 | "Pausing MHD download, no data available\n"); |
829 | if (NULL != s5r->curl) | ||
830 | { | ||
831 | curl_easy_pause (s5r->curl, CURLPAUSE_CONT); | ||
832 | curl_download_prepare (); | ||
833 | } | ||
827 | return 0; /* more data later */ | 834 | return 0; /* more data later */ |
828 | } | 835 | } |
829 | if ( (0 == bytes_to_copy) && | 836 | if ( (0 == bytes_to_copy) && |
@@ -833,6 +840,8 @@ mhd_content_cb (void *cls, | |||
833 | "Completed MHD download\n"); | 840 | "Completed MHD download\n"); |
834 | return MHD_CONTENT_READER_END_OF_STREAM; | 841 | return MHD_CONTENT_READER_END_OF_STREAM; |
835 | } | 842 | } |
843 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
844 | "Writing %lu/%lu bytes\n", bytes_to_copy, s5r->io_len); | ||
836 | GNUNET_memcpy (buf, s5r->io_buf, bytes_to_copy); | 845 | GNUNET_memcpy (buf, s5r->io_buf, bytes_to_copy); |
837 | memmove (s5r->io_buf, | 846 | memmove (s5r->io_buf, |
838 | &s5r->io_buf[bytes_to_copy], | 847 | &s5r->io_buf[bytes_to_copy], |
@@ -865,7 +874,7 @@ check_ssl_certificate (struct Socks5Request *s5r) | |||
865 | const char *name; | 874 | const char *name; |
866 | 875 | ||
867 | s5r->ssl_checked = GNUNET_YES; | 876 | s5r->ssl_checked = GNUNET_YES; |
868 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 877 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
869 | "Checking SSL certificate\n"); | 878 | "Checking SSL certificate\n"); |
870 | if (CURLE_OK != | 879 | if (CURLE_OK != |
871 | curl_easy_getinfo (s5r->curl, | 880 | curl_easy_getinfo (s5r->curl, |
@@ -1249,7 +1258,8 @@ curl_download_cb (void *ptr, size_t size, size_t nmemb, void* ctx) | |||
1249 | if (sizeof (s5r->io_buf) - s5r->io_len < total) | 1258 | if (sizeof (s5r->io_buf) - s5r->io_len < total) |
1250 | { | 1259 | { |
1251 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1260 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1252 | "Pausing CURL download, not enough space\n"); | 1261 | "Pausing CURL download, not enough space %lu %lu %lu\n", sizeof (s5r->io_buf), |
1262 | s5r->io_len, total); | ||
1253 | return CURL_WRITEFUNC_PAUSE; /* not enough space */ | 1263 | return CURL_WRITEFUNC_PAUSE; /* not enough space */ |
1254 | } | 1264 | } |
1255 | GNUNET_memcpy (&s5r->io_buf[s5r->io_len], | 1265 | GNUNET_memcpy (&s5r->io_buf[s5r->io_len], |
@@ -1833,7 +1843,7 @@ mhd_completed_cb (void *cls, | |||
1833 | for (header = s5r->header_head; header != NULL; header = s5r->header_head) | 1843 | for (header = s5r->header_head; header != NULL; header = s5r->header_head) |
1834 | { | 1844 | { |
1835 | GNUNET_CONTAINER_DLL_remove (s5r->header_head, | 1845 | GNUNET_CONTAINER_DLL_remove (s5r->header_head, |
1836 | s5r->header_head, | 1846 | s5r->header_tail, |
1837 | header); | 1847 | header); |
1838 | GNUNET_free (header->type); | 1848 | GNUNET_free (header->type); |
1839 | GNUNET_free (header->value); | 1849 | GNUNET_free (header->value); |
@@ -2414,6 +2424,8 @@ do_write (void *cls) | |||
2414 | if (len <= 0) | 2424 | if (len <= 0) |
2415 | { | 2425 | { |
2416 | /* write error: connection closed, shutdown, etc.; just clean up */ | 2426 | /* write error: connection closed, shutdown, etc.; just clean up */ |
2427 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2428 | "Write Error\n"); | ||
2417 | cleanup_s5r (s5r); | 2429 | cleanup_s5r (s5r); |
2418 | return; | 2430 | return; |
2419 | } | 2431 | } |
diff --git a/src/hello/hello.c b/src/hello/hello.c index 27580275f..690a0961a 100644 --- a/src/hello/hello.c +++ b/src/hello/hello.c | |||
@@ -271,7 +271,10 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg, | |||
271 | msize = GNUNET_HELLO_size (msg); | 271 | msize = GNUNET_HELLO_size (msg); |
272 | if ((msize < sizeof (struct GNUNET_HELLO_Message)) || | 272 | if ((msize < sizeof (struct GNUNET_HELLO_Message)) || |
273 | (ntohs (msg->header.type) != GNUNET_MESSAGE_TYPE_HELLO)) | 273 | (ntohs (msg->header.type) != GNUNET_MESSAGE_TYPE_HELLO)) |
274 | { | ||
275 | GNUNET_break_op (0); | ||
274 | return NULL; | 276 | return NULL; |
277 | } | ||
275 | ret = NULL; | 278 | ret = NULL; |
276 | if (return_modified) | 279 | if (return_modified) |
277 | { | 280 | { |
@@ -285,6 +288,10 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg, | |||
285 | wpos = 0; | 288 | wpos = 0; |
286 | woff = (NULL != ret) ? (char *) &ret[1] : NULL; | 289 | woff = (NULL != ret) ? (char *) &ret[1] : NULL; |
287 | address.peer.public_key = msg->publicKey; | 290 | address.peer.public_key = msg->publicKey; |
291 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
292 | "HELLO has %u bytes of address data\n", | ||
293 | (unsigned int) insize); | ||
294 | |||
288 | while (insize > 0) | 295 | while (insize > 0) |
289 | { | 296 | { |
290 | esize = get_hello_address_size (inptr, | 297 | esize = get_hello_address_size (inptr, |
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 07cade0e3..e886a561c 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -1110,6 +1110,16 @@ GNUNET_CRYPTO_ecdsa_public_key_to_string (const struct GNUNET_CRYPTO_EcdsaPublic | |||
1110 | 1110 | ||
1111 | 1111 | ||
1112 | /** | 1112 | /** |
1113 | * Convert a private key to a string. | ||
1114 | * | ||
1115 | * @param priv key to convert | ||
1116 | * @return string representing @a pub | ||
1117 | */ | ||
1118 | char * | ||
1119 | GNUNET_CRYPTO_eddsa_private_key_to_string (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv); | ||
1120 | |||
1121 | |||
1122 | /** | ||
1113 | * Convert a public key to a string. | 1123 | * Convert a public key to a string. |
1114 | * | 1124 | * |
1115 | * @param pub key to convert | 1125 | * @param pub key to convert |
@@ -2016,13 +2026,14 @@ GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1, | |||
2016 | * @param pkey the public key of the signer | 2026 | * @param pkey the public key of the signer |
2017 | * @param[out] buf set to a buffer with the blinded message to be signed | 2027 | * @param[out] buf set to a buffer with the blinded message to be signed |
2018 | * @param[out] buf_size number of bytes stored in @a buf | 2028 | * @param[out] buf_size number of bytes stored in @a buf |
2019 | * @return GNUNET_YES if successful, GNUNET_NO if RSA key is malicious | 2029 | * @return #GNUNET_YES if successful, #GNUNET_NO if RSA key is malicious |
2020 | */ | 2030 | */ |
2021 | int | 2031 | int |
2022 | GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, | 2032 | GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, |
2023 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, | 2033 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, |
2024 | struct GNUNET_CRYPTO_RsaPublicKey *pkey, | 2034 | struct GNUNET_CRYPTO_RsaPublicKey *pkey, |
2025 | char **buf, size_t *buf_size); | 2035 | char **buf, |
2036 | size_t *buf_size); | ||
2026 | 2037 | ||
2027 | 2038 | ||
2028 | /** | 2039 | /** |
@@ -2035,7 +2046,8 @@ GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, | |||
2035 | */ | 2046 | */ |
2036 | struct GNUNET_CRYPTO_RsaSignature * | 2047 | struct GNUNET_CRYPTO_RsaSignature * |
2037 | GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key, | 2048 | GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key, |
2038 | const void *msg, size_t msg_len); | 2049 | const void *msg, |
2050 | size_t msg_len); | ||
2039 | 2051 | ||
2040 | 2052 | ||
2041 | /** | 2053 | /** |
@@ -2105,7 +2117,7 @@ GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig); | |||
2105 | * @return unblinded signature on success, NULL if RSA key is bad or malicious. | 2117 | * @return unblinded signature on success, NULL if RSA key is bad or malicious. |
2106 | */ | 2118 | */ |
2107 | struct GNUNET_CRYPTO_RsaSignature * | 2119 | struct GNUNET_CRYPTO_RsaSignature * |
2108 | GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig, | 2120 | GNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig, |
2109 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, | 2121 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, |
2110 | struct GNUNET_CRYPTO_RsaPublicKey *pkey); | 2122 | struct GNUNET_CRYPTO_RsaPublicKey *pkey); |
2111 | 2123 | ||
diff --git a/src/include/gnunet_getopt_lib.h b/src/include/gnunet_getopt_lib.h index f707bb091..e38925f14 100644 --- a/src/include/gnunet_getopt_lib.h +++ b/src/include/gnunet_getopt_lib.h | |||
@@ -230,11 +230,11 @@ GNUNET_GETOPT_option_filename (char shortName, | |||
230 | */ | 230 | */ |
231 | struct GNUNET_GETOPT_CommandLineOption | 231 | struct GNUNET_GETOPT_CommandLineOption |
232 | GNUNET_GETOPT_option_base32_fixed_size (char shortName, | 232 | GNUNET_GETOPT_option_base32_fixed_size (char shortName, |
233 | const char *name, | 233 | const char *name, |
234 | const char *argumentHelp, | 234 | const char *argumentHelp, |
235 | const char *description, | 235 | const char *description, |
236 | void *val, | 236 | void *val, |
237 | size_t val_size); | 237 | size_t val_size); |
238 | 238 | ||
239 | 239 | ||
240 | /** | 240 | /** |
@@ -264,9 +264,9 @@ GNUNET_GETOPT_option_base32_fixed_size (char shortName, | |||
264 | */ | 264 | */ |
265 | struct GNUNET_GETOPT_CommandLineOption | 265 | struct GNUNET_GETOPT_CommandLineOption |
266 | GNUNET_GETOPT_option_flag (char shortName, | 266 | GNUNET_GETOPT_option_flag (char shortName, |
267 | const char *name, | 267 | const char *name, |
268 | const char *description, | 268 | const char *description, |
269 | int *val); | 269 | int *val); |
270 | 270 | ||
271 | 271 | ||
272 | /** | 272 | /** |
@@ -280,10 +280,10 @@ GNUNET_GETOPT_option_flag (char shortName, | |||
280 | */ | 280 | */ |
281 | struct GNUNET_GETOPT_CommandLineOption | 281 | struct GNUNET_GETOPT_CommandLineOption |
282 | GNUNET_GETOPT_option_uint (char shortName, | 282 | GNUNET_GETOPT_option_uint (char shortName, |
283 | const char *name, | 283 | const char *name, |
284 | const char *argumentHelp, | 284 | const char *argumentHelp, |
285 | const char *description, | 285 | const char *description, |
286 | unsigned int *val); | 286 | unsigned int *val); |
287 | 287 | ||
288 | 288 | ||
289 | /** | 289 | /** |
@@ -297,10 +297,10 @@ GNUNET_GETOPT_option_uint (char shortName, | |||
297 | */ | 297 | */ |
298 | struct GNUNET_GETOPT_CommandLineOption | 298 | struct GNUNET_GETOPT_CommandLineOption |
299 | GNUNET_GETOPT_option_ulong (char shortName, | 299 | GNUNET_GETOPT_option_ulong (char shortName, |
300 | const char *name, | 300 | const char *name, |
301 | const char *argumentHelp, | 301 | const char *argumentHelp, |
302 | const char *description, | 302 | const char *description, |
303 | unsigned long long *val); | 303 | unsigned long long *val); |
304 | 304 | ||
305 | 305 | ||
306 | /** | 306 | /** |
@@ -315,10 +315,10 @@ GNUNET_GETOPT_option_ulong (char shortName, | |||
315 | */ | 315 | */ |
316 | struct GNUNET_GETOPT_CommandLineOption | 316 | struct GNUNET_GETOPT_CommandLineOption |
317 | GNUNET_GETOPT_option_relative_time (char shortName, | 317 | GNUNET_GETOPT_option_relative_time (char shortName, |
318 | const char *name, | 318 | const char *name, |
319 | const char *argumentHelp, | 319 | const char *argumentHelp, |
320 | const char *description, | 320 | const char *description, |
321 | struct GNUNET_TIME_Relative *val); | 321 | struct GNUNET_TIME_Relative *val); |
322 | 322 | ||
323 | 323 | ||
324 | /** | 324 | /** |
@@ -333,10 +333,10 @@ GNUNET_GETOPT_option_relative_time (char shortName, | |||
333 | */ | 333 | */ |
334 | struct GNUNET_GETOPT_CommandLineOption | 334 | struct GNUNET_GETOPT_CommandLineOption |
335 | GNUNET_GETOPT_option_absolute_time (char shortName, | 335 | GNUNET_GETOPT_option_absolute_time (char shortName, |
336 | const char *name, | 336 | const char *name, |
337 | const char *argumentHelp, | 337 | const char *argumentHelp, |
338 | const char *description, | 338 | const char *description, |
339 | struct GNUNET_TIME_Absolute *val); | 339 | struct GNUNET_TIME_Absolute *val); |
340 | 340 | ||
341 | 341 | ||
342 | /** | 342 | /** |
@@ -350,9 +350,9 @@ GNUNET_GETOPT_option_absolute_time (char shortName, | |||
350 | */ | 350 | */ |
351 | struct GNUNET_GETOPT_CommandLineOption | 351 | struct GNUNET_GETOPT_CommandLineOption |
352 | GNUNET_GETOPT_option_increment_uint (char shortName, | 352 | GNUNET_GETOPT_option_increment_uint (char shortName, |
353 | const char *name, | 353 | const char *name, |
354 | const char *description, | 354 | const char *description, |
355 | unsigned int *val); | 355 | unsigned int *val); |
356 | 356 | ||
357 | 357 | ||
358 | /** | 358 | /** |
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h index f2682bea7..c12badcd9 100644 --- a/src/include/gnunet_json_lib.h +++ b/src/include/gnunet_json_lib.h | |||
@@ -343,6 +343,16 @@ GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp); | |||
343 | 343 | ||
344 | 344 | ||
345 | /** | 345 | /** |
346 | * Convert absolute timestamp to a json string. | ||
347 | * | ||
348 | * @param stamp the time stamp | ||
349 | * @return a json string with the timestamp in @a stamp | ||
350 | */ | ||
351 | json_t * | ||
352 | GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp); | ||
353 | |||
354 | |||
355 | /** | ||
346 | * Convert relative timestamp to a json string. | 356 | * Convert relative timestamp to a json string. |
347 | * | 357 | * |
348 | * @param stamp the time stamp | 358 | * @param stamp the time stamp |
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h index 875f5043a..a855ab8ab 100644 --- a/src/include/gnunet_scheduler_lib.h +++ b/src/include/gnunet_scheduler_lib.h | |||
@@ -400,6 +400,22 @@ void | |||
400 | GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, | 400 | GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, |
401 | void *task_cls); | 401 | void *task_cls); |
402 | 402 | ||
403 | /** | ||
404 | * Initialize and run scheduler. This function will return when all | ||
405 | * tasks have completed. When @ install_signals is GNUNET_YES, then | ||
406 | * this function behaves in the same was as GNUNET_SCHEDULER_run does. | ||
407 | * If @ install_signals is GNUNET_NO then no signal handlers are | ||
408 | * installed. | ||
409 | * | ||
410 | * @param install_signals whether to install signals (GNUNET_YES/NO) | ||
411 | * @param task task to run first (and immediately) | ||
412 | * @param task_cls closure of @a task | ||
413 | */ | ||
414 | void | ||
415 | GNUNET_SCHEDULER_run_with_optional_signals (int install_signals, | ||
416 | GNUNET_SCHEDULER_TaskCallback task, | ||
417 | void *task_cls); | ||
418 | |||
403 | 419 | ||
404 | /** | 420 | /** |
405 | * Request the shutdown of a scheduler. Marks all tasks | 421 | * Request the shutdown of a scheduler. Marks all tasks |
diff --git a/src/include/gnunet_set_service.h b/src/include/gnunet_set_service.h index 6e822d82e..a2999aebc 100644 --- a/src/include/gnunet_set_service.h +++ b/src/include/gnunet_set_service.h | |||
@@ -452,6 +452,8 @@ GNUNET_SET_listen (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
452 | /** | 452 | /** |
453 | * Cancel the given listen operation. After calling cancel, the | 453 | * Cancel the given listen operation. After calling cancel, the |
454 | * listen callback for this listen handle will not be called again. | 454 | * listen callback for this listen handle will not be called again. |
455 | * Note that cancelling a listen operation will automatically reject | ||
456 | * all operations that have not yet been accepted. | ||
455 | * | 457 | * |
456 | * @param lh handle for the listen operation | 458 | * @param lh handle for the listen operation |
457 | */ | 459 | */ |
@@ -556,7 +558,8 @@ GNUNET_SET_element_dup (const struct GNUNET_SET_Element *element); | |||
556 | * should be stored | 558 | * should be stored |
557 | */ | 559 | */ |
558 | void | 560 | void |
559 | GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash); | 561 | GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element, |
562 | struct GNUNET_HashCode *ret_hash); | ||
560 | 563 | ||
561 | 564 | ||
562 | #if 0 /* keep Emacsens' auto-indent happy */ | 565 | #if 0 /* keep Emacsens' auto-indent happy */ |
diff --git a/src/integration-tests/Makefile.am b/src/integration-tests/Makefile.am index 6fff0b407..368980064 100644 --- a/src/integration-tests/Makefile.am +++ b/src/integration-tests/Makefile.am | |||
@@ -42,7 +42,8 @@ endif | |||
42 | 42 | ||
43 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' | 43 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' |
44 | 44 | ||
45 | %.py: %.py.in Makefile | 45 | SUFFIXES = .py.in .py |
46 | .py.in.py: | ||
46 | $(do_subst) < $(srcdir)/$< > $@ | 47 | $(do_subst) < $(srcdir)/$< > $@ |
47 | chmod +x $@ | 48 | chmod +x $@ |
48 | 49 | ||
diff --git a/src/json/json_generator.c b/src/json/json_generator.c index e660e10c5..98f7163bc 100644 --- a/src/json/json_generator.c +++ b/src/json/json_generator.c | |||
@@ -73,6 +73,19 @@ GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp) | |||
73 | 73 | ||
74 | 74 | ||
75 | /** | 75 | /** |
76 | * Convert absolute timestamp to a json string. | ||
77 | * | ||
78 | * @param stamp the time stamp | ||
79 | * @return a json string with the timestamp in @a stamp | ||
80 | */ | ||
81 | json_t * | ||
82 | GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp) | ||
83 | { | ||
84 | return GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (stamp)); | ||
85 | } | ||
86 | |||
87 | |||
88 | /** | ||
76 | * Convert relative timestamp to a json string. | 89 | * Convert relative timestamp to a json string. |
77 | * | 90 | * |
78 | * @param stamp the time stamp | 91 | * @param stamp the time stamp |
diff --git a/src/multicast/.gitignore b/src/multicast/.gitignore index 43752ec4b..a97844e81 100644 --- a/src/multicast/.gitignore +++ b/src/multicast/.gitignore | |||
@@ -3,3 +3,5 @@ gnunet-multicast | |||
3 | test_multicast | 3 | test_multicast |
4 | test_multicast_multipeer | 4 | test_multicast_multipeer |
5 | test_multicast_2peers | 5 | test_multicast_2peers |
6 | test_multicast_multipeer_line | ||
7 | test_multicast_multipeer_star | ||
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c index 731c24bf1..af1eb2d1d 100644 --- a/src/peerinfo/gnunet-service-peerinfo.c +++ b/src/peerinfo/gnunet-service-peerinfo.c | |||
@@ -987,9 +987,13 @@ discard_hosts_helper (void *cls, | |||
987 | int write_pos; | 987 | int write_pos; |
988 | unsigned int cnt; | 988 | unsigned int cnt; |
989 | char *writebuffer; | 989 | char *writebuffer; |
990 | uint64_t fsize; | ||
990 | 991 | ||
992 | GNUNET_DISK_file_size (fn, &fsize, GNUNET_YES, GNUNET_YES); | ||
991 | read_size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); | 993 | read_size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); |
992 | if (read_size < (int) sizeof (struct GNUNET_MessageHeader)) | 994 | |
995 | if ((read_size < (int) sizeof (struct GNUNET_MessageHeader)) || | ||
996 | (fsize > GNUNET_MAX_MESSAGE_SIZE)) | ||
993 | { | 997 | { |
994 | if (0 != UNLINK (fn)) | 998 | if (0 != UNLINK (fn)) |
995 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | | 999 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | |
diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c index b75d4e291..8b47ed444 100644 --- a/src/peerinfo/peerinfo_api.c +++ b/src/peerinfo/peerinfo_api.c | |||
@@ -334,11 +334,12 @@ handle_info (void *cls, | |||
334 | { | 334 | { |
335 | struct GNUNET_PEERINFO_Handle *h = cls; | 335 | struct GNUNET_PEERINFO_Handle *h = cls; |
336 | struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head; | 336 | struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head; |
337 | const struct GNUNET_HELLO_Message *hello; | 337 | const struct GNUNET_HELLO_Message *hello = NULL; |
338 | uint16_t ms; | 338 | uint16_t ms; |
339 | 339 | ||
340 | ms = ntohs (im->header.size); | 340 | ms = ntohs (im->header.size); |
341 | hello = (0 == ms) ? NULL : (const struct GNUNET_HELLO_Message *) &im[1]; | 341 | if (ms > sizeof (struct InfoMessage)) |
342 | hello = (const struct GNUNET_HELLO_Message *) &im[1]; | ||
342 | if (NULL != ic->callback) | 343 | if (NULL != ic->callback) |
343 | ic->callback (ic->callback_cls, | 344 | ic->callback (ic->callback_cls, |
344 | &im->peer, | 345 | &im->peer, |
diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c index 9d077f874..8281e9a16 100644 --- a/src/revocation/gnunet-service-revocation.c +++ b/src/revocation/gnunet-service-revocation.c | |||
@@ -509,6 +509,7 @@ transmit_task_cb (void *cls) | |||
509 | "Starting set exchange with peer `%s'\n", | 509 | "Starting set exchange with peer `%s'\n", |
510 | GNUNET_i2s (&peer_entry->id)); | 510 | GNUNET_i2s (&peer_entry->id)); |
511 | peer_entry->transmit_task = NULL; | 511 | peer_entry->transmit_task = NULL; |
512 | GNUNET_assert (NULL == peer_entry->so); | ||
512 | peer_entry->so = GNUNET_SET_prepare (&peer_entry->id, | 513 | peer_entry->so = GNUNET_SET_prepare (&peer_entry->id, |
513 | &revocation_set_union_app_id, | 514 | &revocation_set_union_app_id, |
514 | NULL, | 515 | NULL, |
@@ -758,6 +759,7 @@ handle_revocation_union_request (void *cls, | |||
758 | { | 759 | { |
759 | peer_entry = new_peer_entry (other_peer); | 760 | peer_entry = new_peer_entry (other_peer); |
760 | } | 761 | } |
762 | GNUNET_assert (NULL == peer_entry->so); | ||
761 | peer_entry->so = GNUNET_SET_accept (request, | 763 | peer_entry->so = GNUNET_SET_accept (request, |
762 | GNUNET_SET_RESULT_ADDED, | 764 | GNUNET_SET_RESULT_ADDED, |
763 | (struct GNUNET_SET_Option[]) {{ 0 }}, | 765 | (struct GNUNET_SET_Option[]) {{ 0 }}, |
diff --git a/src/rps/.gitignore b/src/rps/.gitignore index 0d460e62c..c8068912b 100644 --- a/src/rps/.gitignore +++ b/src/rps/.gitignore | |||
@@ -1,3 +1,14 @@ | |||
1 | gnunet-service-rps | 1 | gnunet-service-rps |
2 | gnunet-rps | 2 | gnunet-rps |
3 | gnunet-rps-profiler | 3 | gnunet-rps-profiler |
4 | test_rps_malicious_1 | ||
5 | test_rps_malicious_2 | ||
6 | test_rps_malicious_3 | ||
7 | test_rps_req_cancel | ||
8 | test_rps_seed_big | ||
9 | test_rps_seed_request | ||
10 | test_rps_single_req | ||
11 | test_service_rps_custommap | ||
12 | test_service_rps_sampler_elem | ||
13 | test_service_rps_view | ||
14 | test_rps_churn | ||
diff --git a/src/rps/Makefile.am b/src/rps/Makefile.am index e6c8cd929..de3469254 100644 --- a/src/rps/Makefile.am +++ b/src/rps/Makefile.am | |||
@@ -49,7 +49,6 @@ endif | |||
49 | gnunet_service_rps_SOURCES = \ | 49 | gnunet_service_rps_SOURCES = \ |
50 | gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \ | 50 | gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \ |
51 | gnunet-service-rps_sampler.h gnunet-service-rps_sampler.c \ | 51 | gnunet-service-rps_sampler.h gnunet-service-rps_sampler.c \ |
52 | gnunet-service-rps_peers.h gnunet-service-rps_peers.c \ | ||
53 | gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \ | 52 | gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \ |
54 | gnunet-service-rps_view.h gnunet-service-rps_view.c \ | 53 | gnunet-service-rps_view.h gnunet-service-rps_view.c \ |
55 | rps-test_util.h rps-test_util.c \ | 54 | rps-test_util.h rps-test_util.c \ |
@@ -73,7 +72,6 @@ if HAVE_TESTING | |||
73 | check_PROGRAMS = \ | 72 | check_PROGRAMS = \ |
74 | test_service_rps_view \ | 73 | test_service_rps_view \ |
75 | test_service_rps_custommap \ | 74 | test_service_rps_custommap \ |
76 | test_service_rps_peers \ | ||
77 | test_service_rps_sampler_elem \ | 75 | test_service_rps_sampler_elem \ |
78 | test_rps_malicious_1 \ | 76 | test_rps_malicious_1 \ |
79 | test_rps_malicious_2 \ | 77 | test_rps_malicious_2 \ |
@@ -81,7 +79,8 @@ check_PROGRAMS = \ | |||
81 | test_rps_seed_request \ | 79 | test_rps_seed_request \ |
82 | test_rps_single_req \ | 80 | test_rps_single_req \ |
83 | test_rps_req_cancel \ | 81 | test_rps_req_cancel \ |
84 | test_rps_seed_big | 82 | test_rps_seed_big \ |
83 | test_rps_churn | ||
85 | endif | 84 | endif |
86 | 85 | ||
87 | ld_rps_test_lib = \ | 86 | ld_rps_test_lib = \ |
@@ -105,13 +104,6 @@ test_service_rps_view_SOURCES = \ | |||
105 | test_service_rps_view.c | 104 | test_service_rps_view.c |
106 | test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la | 105 | test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la |
107 | 106 | ||
108 | test_service_rps_peers_SOURCES = \ | ||
109 | gnunet-service-rps_peers.h gnunet-service-rps_peers.c \ | ||
110 | test_service_rps_peers.c | ||
111 | test_service_rps_peers_LDADD = \ | ||
112 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
113 | $(top_builddir)/src/cadet/libgnunetcadet.la | ||
114 | |||
115 | test_service_rps_custommap_SOURCES = \ | 107 | test_service_rps_custommap_SOURCES = \ |
116 | gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \ | 108 | gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \ |
117 | test_service_rps_custommap.c | 109 | test_service_rps_custommap.c |
@@ -145,6 +137,9 @@ test_rps_req_cancel_LDADD = $(ld_rps_test_lib) | |||
145 | test_rps_seed_big_SOURCES = $(rps_test_src) | 137 | test_rps_seed_big_SOURCES = $(rps_test_src) |
146 | test_rps_seed_big_LDADD = $(ld_rps_test_lib) | 138 | test_rps_seed_big_LDADD = $(ld_rps_test_lib) |
147 | 139 | ||
140 | test_rps_churn_SOURCES = $(rps_test_src) | ||
141 | test_rps_churn_LDADD = $(ld_rps_test_lib) | ||
142 | |||
148 | gnunet_rps_profiler_SOURCES = $(rps_test_src) | 143 | gnunet_rps_profiler_SOURCES = $(rps_test_src) |
149 | gnunet_rps_profiler_LDADD = $(ld_rps_test_lib) | 144 | gnunet_rps_profiler_LDADD = $(ld_rps_test_lib) |
150 | 145 | ||
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 0a4543b30..ec70075cf 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "rps-test_util.h" | 33 | #include "rps-test_util.h" |
34 | #include "gnunet-service-rps_sampler.h" | 34 | #include "gnunet-service-rps_sampler.h" |
35 | #include "gnunet-service-rps_custommap.h" | 35 | #include "gnunet-service-rps_custommap.h" |
36 | #include "gnunet-service-rps_peers.h" | ||
37 | #include "gnunet-service-rps_view.h" | 36 | #include "gnunet-service-rps_view.h" |
38 | 37 | ||
39 | #include <math.h> | 38 | #include <math.h> |
@@ -66,6 +65,1728 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
66 | static struct GNUNET_PeerIdentity own_identity; | 65 | static struct GNUNET_PeerIdentity own_identity; |
67 | 66 | ||
68 | 67 | ||
68 | |||
69 | /*********************************************************************** | ||
70 | * Old gnunet-service-rps_peers.c | ||
71 | ***********************************************************************/ | ||
72 | |||
73 | /** | ||
74 | * Set a peer flag of given peer context. | ||
75 | */ | ||
76 | #define set_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) |= (mask)) | ||
77 | |||
78 | /** | ||
79 | * Get peer flag of given peer context. | ||
80 | */ | ||
81 | #define check_peer_flag_set(peer_ctx, mask)\ | ||
82 | ((peer_ctx->peer_flags) & (mask) ? GNUNET_YES : GNUNET_NO) | ||
83 | |||
84 | /** | ||
85 | * Unset flag of given peer context. | ||
86 | */ | ||
87 | #define unset_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) &= ~(mask)) | ||
88 | |||
89 | /** | ||
90 | * Set a channel flag of given channel context. | ||
91 | */ | ||
92 | #define set_channel_flag(channel_flags, mask) ((*channel_flags) |= (mask)) | ||
93 | |||
94 | /** | ||
95 | * Get channel flag of given channel context. | ||
96 | */ | ||
97 | #define check_channel_flag_set(channel_flags, mask)\ | ||
98 | ((*channel_flags) & (mask) ? GNUNET_YES : GNUNET_NO) | ||
99 | |||
100 | /** | ||
101 | * Unset flag of given channel context. | ||
102 | */ | ||
103 | #define unset_channel_flag(channel_flags, mask) ((*channel_flags) &= ~(mask)) | ||
104 | |||
105 | |||
106 | |||
107 | /** | ||
108 | * Pending operation on peer consisting of callback and closure | ||
109 | * | ||
110 | * When an operation cannot be executed right now this struct is used to store | ||
111 | * the callback and closure for later execution. | ||
112 | */ | ||
113 | struct PeerPendingOp | ||
114 | { | ||
115 | /** | ||
116 | * Callback | ||
117 | */ | ||
118 | PeerOp op; | ||
119 | |||
120 | /** | ||
121 | * Closure | ||
122 | */ | ||
123 | void *op_cls; | ||
124 | }; | ||
125 | |||
126 | /** | ||
127 | * List containing all messages that are yet to be send | ||
128 | * | ||
129 | * This is used to keep track of all messages that have not been sent yet. When | ||
130 | * a peer is to be removed the pending messages can be removed properly. | ||
131 | */ | ||
132 | struct PendingMessage | ||
133 | { | ||
134 | /** | ||
135 | * DLL next, prev | ||
136 | */ | ||
137 | struct PendingMessage *next; | ||
138 | struct PendingMessage *prev; | ||
139 | |||
140 | /** | ||
141 | * The envelope to the corresponding message | ||
142 | */ | ||
143 | struct GNUNET_MQ_Envelope *ev; | ||
144 | |||
145 | /** | ||
146 | * The corresponding context | ||
147 | */ | ||
148 | struct PeerContext *peer_ctx; | ||
149 | |||
150 | /** | ||
151 | * The message type | ||
152 | */ | ||
153 | const char *type; | ||
154 | }; | ||
155 | |||
156 | /** | ||
157 | * Struct used to keep track of other peer's status | ||
158 | * | ||
159 | * This is stored in a multipeermap. | ||
160 | * It contains information such as cadet channels, a message queue for sending, | ||
161 | * status about the channels, the pending operations on this peer and some flags | ||
162 | * about the status of the peer itself. (live, valid, ...) | ||
163 | */ | ||
164 | struct PeerContext | ||
165 | { | ||
166 | /** | ||
167 | * Message queue open to client | ||
168 | */ | ||
169 | struct GNUNET_MQ_Handle *mq; | ||
170 | |||
171 | /** | ||
172 | * Channel open to client. | ||
173 | */ | ||
174 | struct GNUNET_CADET_Channel *send_channel; | ||
175 | |||
176 | /** | ||
177 | * Flags to the sending channel | ||
178 | */ | ||
179 | uint32_t *send_channel_flags; | ||
180 | |||
181 | /** | ||
182 | * Channel open from client. | ||
183 | */ | ||
184 | struct GNUNET_CADET_Channel *recv_channel; // unneeded? | ||
185 | |||
186 | /** | ||
187 | * Flags to the receiving channel | ||
188 | */ | ||
189 | uint32_t *recv_channel_flags; | ||
190 | |||
191 | /** | ||
192 | * Array of pending operations on this peer. | ||
193 | */ | ||
194 | struct PeerPendingOp *pending_ops; | ||
195 | |||
196 | /** | ||
197 | * Handle to the callback given to cadet_ntfy_tmt_rdy() | ||
198 | * | ||
199 | * To be canceled on shutdown. | ||
200 | */ | ||
201 | struct PendingMessage *liveliness_check_pending; | ||
202 | |||
203 | /** | ||
204 | * Number of pending operations. | ||
205 | */ | ||
206 | unsigned int num_pending_ops; | ||
207 | |||
208 | /** | ||
209 | * Identity of the peer | ||
210 | */ | ||
211 | struct GNUNET_PeerIdentity peer_id; | ||
212 | |||
213 | /** | ||
214 | * Flags indicating status of peer | ||
215 | */ | ||
216 | uint32_t peer_flags; | ||
217 | |||
218 | /** | ||
219 | * Last time we received something from that peer. | ||
220 | */ | ||
221 | struct GNUNET_TIME_Absolute last_message_recv; | ||
222 | |||
223 | /** | ||
224 | * Last time we received a keepalive message. | ||
225 | */ | ||
226 | struct GNUNET_TIME_Absolute last_keepalive; | ||
227 | |||
228 | /** | ||
229 | * DLL with all messages that are yet to be sent | ||
230 | */ | ||
231 | struct PendingMessage *pending_messages_head; | ||
232 | struct PendingMessage *pending_messages_tail; | ||
233 | |||
234 | /** | ||
235 | * This is pobably followed by 'statistical' data (when we first saw | ||
236 | * him, how did we get his ID, how many pushes (in a timeinterval), | ||
237 | * ...) | ||
238 | */ | ||
239 | }; | ||
240 | |||
241 | /** | ||
242 | * @brief Closure to #valid_peer_iterator | ||
243 | */ | ||
244 | struct PeersIteratorCls | ||
245 | { | ||
246 | /** | ||
247 | * Iterator function | ||
248 | */ | ||
249 | PeersIterator iterator; | ||
250 | |||
251 | /** | ||
252 | * Closure to iterator | ||
253 | */ | ||
254 | void *cls; | ||
255 | }; | ||
256 | |||
257 | /** | ||
258 | * @brief Hashmap of valid peers. | ||
259 | */ | ||
260 | static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers; | ||
261 | |||
262 | /** | ||
263 | * @brief Maximum number of valid peers to keep. | ||
264 | * TODO read from config | ||
265 | */ | ||
266 | static uint32_t num_valid_peers_max = UINT32_MAX; | ||
267 | |||
268 | /** | ||
269 | * @brief Filename of the file that stores the valid peers persistently. | ||
270 | */ | ||
271 | static char *filename_valid_peers; | ||
272 | |||
273 | /** | ||
274 | * Set of all peers to keep track of them. | ||
275 | */ | ||
276 | static struct GNUNET_CONTAINER_MultiPeerMap *peer_map; | ||
277 | |||
278 | /** | ||
279 | * Cadet handle. | ||
280 | */ | ||
281 | static struct GNUNET_CADET_Handle *cadet_handle; | ||
282 | |||
283 | |||
284 | |||
285 | /** | ||
286 | * @brief Get the #PeerContext associated with a peer | ||
287 | * | ||
288 | * @param peer the peer id | ||
289 | * | ||
290 | * @return the #PeerContext | ||
291 | */ | ||
292 | static struct PeerContext * | ||
293 | get_peer_ctx (const struct GNUNET_PeerIdentity *peer) | ||
294 | { | ||
295 | struct PeerContext *ctx; | ||
296 | int ret; | ||
297 | |||
298 | ret = GNUNET_CONTAINER_multipeermap_contains (peer_map, peer); | ||
299 | GNUNET_assert (GNUNET_YES == ret); | ||
300 | ctx = GNUNET_CONTAINER_multipeermap_get (peer_map, peer); | ||
301 | GNUNET_assert (NULL != ctx); | ||
302 | return ctx; | ||
303 | } | ||
304 | |||
305 | int | ||
306 | Peers_check_peer_known (const struct GNUNET_PeerIdentity *peer); | ||
307 | |||
308 | /** | ||
309 | * @brief Create a new #PeerContext and insert it into the peer map | ||
310 | * | ||
311 | * @param peer the peer to create the #PeerContext for | ||
312 | * | ||
313 | * @return the #PeerContext | ||
314 | */ | ||
315 | static struct PeerContext * | ||
316 | create_peer_ctx (const struct GNUNET_PeerIdentity *peer) | ||
317 | { | ||
318 | struct PeerContext *ctx; | ||
319 | int ret; | ||
320 | |||
321 | GNUNET_assert (GNUNET_NO == Peers_check_peer_known (peer)); | ||
322 | |||
323 | ctx = GNUNET_new (struct PeerContext); | ||
324 | ctx->peer_id = *peer; | ||
325 | ctx->send_channel_flags = GNUNET_new (uint32_t); | ||
326 | ctx->recv_channel_flags = GNUNET_new (uint32_t); | ||
327 | ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx, | ||
328 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
329 | GNUNET_assert (GNUNET_OK == ret); | ||
330 | return ctx; | ||
331 | } | ||
332 | |||
333 | |||
334 | /** | ||
335 | * @brief Create or get a #PeerContext | ||
336 | * | ||
337 | * @param peer the peer to get the associated context to | ||
338 | * | ||
339 | * @return the context | ||
340 | */ | ||
341 | static struct PeerContext * | ||
342 | create_or_get_peer_ctx (const struct GNUNET_PeerIdentity *peer) | ||
343 | { | ||
344 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
345 | { | ||
346 | return create_peer_ctx (peer); | ||
347 | } | ||
348 | return get_peer_ctx (peer); | ||
349 | } | ||
350 | |||
351 | void | ||
352 | Peers_unset_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags); | ||
353 | |||
354 | void | ||
355 | Peers_set_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags); | ||
356 | |||
357 | /** | ||
358 | * @brief Check whether we have a connection to this @a peer | ||
359 | * | ||
360 | * Also sets the #Peers_ONLINE flag accordingly | ||
361 | * | ||
362 | * @param peer the peer in question | ||
363 | * | ||
364 | * @return #GNUNET_YES if we are connected | ||
365 | * #GNUNET_NO otherwise | ||
366 | */ | ||
367 | int | ||
368 | Peers_check_connected (const struct GNUNET_PeerIdentity *peer) | ||
369 | { | ||
370 | const struct PeerContext *peer_ctx; | ||
371 | |||
372 | /* If we don't know about this peer we don't know whether it's online */ | ||
373 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
374 | { | ||
375 | return GNUNET_NO; | ||
376 | } | ||
377 | /* Get the context */ | ||
378 | peer_ctx = get_peer_ctx (peer); | ||
379 | /* If we have no channel to this peer we don't know whether it's online */ | ||
380 | if ( (NULL == peer_ctx->send_channel) && | ||
381 | (NULL == peer_ctx->recv_channel) ) | ||
382 | { | ||
383 | Peers_unset_peer_flag (peer, Peers_ONLINE); | ||
384 | return GNUNET_NO; | ||
385 | } | ||
386 | /* Otherwise (if we have a channel, we know that it's online */ | ||
387 | Peers_set_peer_flag (peer, Peers_ONLINE); | ||
388 | return GNUNET_YES; | ||
389 | } | ||
390 | |||
391 | |||
392 | /** | ||
393 | * @brief The closure to #get_rand_peer_iterator. | ||
394 | */ | ||
395 | struct GetRandPeerIteratorCls | ||
396 | { | ||
397 | /** | ||
398 | * @brief The index of the peer to return. | ||
399 | * Will be decreased until 0. | ||
400 | * Then current peer is returned. | ||
401 | */ | ||
402 | uint32_t index; | ||
403 | |||
404 | /** | ||
405 | * @brief Pointer to peer to return. | ||
406 | */ | ||
407 | const struct GNUNET_PeerIdentity *peer; | ||
408 | }; | ||
409 | |||
410 | |||
411 | /** | ||
412 | * @brief Iterator function for #get_random_peer_from_peermap. | ||
413 | * | ||
414 | * Implements #GNUNET_CONTAINER_PeerMapIterator. | ||
415 | * Decreases the index until the index is null. | ||
416 | * Then returns the current peer. | ||
417 | * | ||
418 | * @param cls the #GetRandPeerIteratorCls containing index and peer | ||
419 | * @param peer current peer | ||
420 | * @param value unused | ||
421 | * | ||
422 | * @return #GNUNET_YES if we should continue to | ||
423 | * iterate, | ||
424 | * #GNUNET_NO if not. | ||
425 | */ | ||
426 | static int | ||
427 | get_rand_peer_iterator (void *cls, | ||
428 | const struct GNUNET_PeerIdentity *peer, | ||
429 | void *value) | ||
430 | { | ||
431 | struct GetRandPeerIteratorCls *iterator_cls = cls; | ||
432 | if (0 >= iterator_cls->index) | ||
433 | { | ||
434 | iterator_cls->peer = peer; | ||
435 | return GNUNET_NO; | ||
436 | } | ||
437 | iterator_cls->index--; | ||
438 | return GNUNET_YES; | ||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
443 | * @brief Get a random peer from @a peer_map | ||
444 | * | ||
445 | * @param peer_map the peer_map to get the peer from | ||
446 | * | ||
447 | * @return a random peer | ||
448 | */ | ||
449 | static const struct GNUNET_PeerIdentity * | ||
450 | get_random_peer_from_peermap (const struct | ||
451 | GNUNET_CONTAINER_MultiPeerMap *peer_map) | ||
452 | { | ||
453 | struct GetRandPeerIteratorCls *iterator_cls; | ||
454 | const struct GNUNET_PeerIdentity *ret; | ||
455 | |||
456 | iterator_cls = GNUNET_new (struct GetRandPeerIteratorCls); | ||
457 | iterator_cls->index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
458 | GNUNET_CONTAINER_multipeermap_size (peer_map)); | ||
459 | (void) GNUNET_CONTAINER_multipeermap_iterate (valid_peers, | ||
460 | get_rand_peer_iterator, | ||
461 | iterator_cls); | ||
462 | ret = iterator_cls->peer; | ||
463 | GNUNET_free (iterator_cls); | ||
464 | return ret; | ||
465 | } | ||
466 | |||
467 | |||
468 | /** | ||
469 | * @brief Add a given @a peer to valid peers. | ||
470 | * | ||
471 | * If valid peers are already #num_valid_peers_max, delete a peer previously. | ||
472 | * | ||
473 | * @param peer the peer that is added to the valid peers. | ||
474 | * | ||
475 | * @return #GNUNET_YES if no other peer had to be removed | ||
476 | * #GNUNET_NO otherwise | ||
477 | */ | ||
478 | static int | ||
479 | add_valid_peer (const struct GNUNET_PeerIdentity *peer) | ||
480 | { | ||
481 | const struct GNUNET_PeerIdentity *rand_peer; | ||
482 | int ret; | ||
483 | |||
484 | ret = GNUNET_YES; | ||
485 | while (GNUNET_CONTAINER_multipeermap_size (valid_peers) >= num_valid_peers_max) | ||
486 | { | ||
487 | rand_peer = get_random_peer_from_peermap (valid_peers); | ||
488 | GNUNET_CONTAINER_multipeermap_remove_all (valid_peers, rand_peer); | ||
489 | ret = GNUNET_NO; | ||
490 | } | ||
491 | (void) GNUNET_CONTAINER_multipeermap_put (valid_peers, peer, NULL, | ||
492 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
493 | return ret; | ||
494 | } | ||
495 | |||
496 | |||
497 | /** | ||
498 | * @brief Set the peer flag to living and | ||
499 | * call the pending operations on this peer. | ||
500 | * | ||
501 | * Also adds peer to #valid_peers. | ||
502 | * | ||
503 | * @param peer_ctx the #PeerContext of the peer to set live | ||
504 | */ | ||
505 | static void | ||
506 | set_peer_live (struct PeerContext *peer_ctx) | ||
507 | { | ||
508 | struct GNUNET_PeerIdentity *peer; | ||
509 | unsigned int i; | ||
510 | |||
511 | peer = &peer_ctx->peer_id; | ||
512 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
513 | "Peer %s is live and valid, calling %i pending operations on it\n", | ||
514 | GNUNET_i2s (peer), | ||
515 | peer_ctx->num_pending_ops); | ||
516 | |||
517 | if (NULL != peer_ctx->liveliness_check_pending) | ||
518 | { | ||
519 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
520 | "Removing pending liveliness check for peer %s\n", | ||
521 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
522 | // TODO wait until cadet sets mq->cancel_impl | ||
523 | //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev); | ||
524 | GNUNET_free (peer_ctx->liveliness_check_pending); | ||
525 | peer_ctx->liveliness_check_pending = NULL; | ||
526 | } | ||
527 | |||
528 | (void) add_valid_peer (peer); | ||
529 | set_peer_flag (peer_ctx, Peers_ONLINE); | ||
530 | |||
531 | /* Call pending operations */ | ||
532 | for (i = 0; i < peer_ctx->num_pending_ops; i++) | ||
533 | { | ||
534 | peer_ctx->pending_ops[i].op (peer_ctx->pending_ops[i].op_cls, peer); | ||
535 | } | ||
536 | GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0); | ||
537 | } | ||
538 | |||
539 | static void | ||
540 | cleanup_destroyed_channel (void *cls, | ||
541 | const struct GNUNET_CADET_Channel *channel); | ||
542 | |||
543 | /* Declaration of handlers */ | ||
544 | static void | ||
545 | handle_peer_check (void *cls, | ||
546 | const struct GNUNET_MessageHeader *msg); | ||
547 | |||
548 | static void | ||
549 | handle_peer_push (void *cls, | ||
550 | const struct GNUNET_MessageHeader *msg); | ||
551 | |||
552 | static void | ||
553 | handle_peer_pull_request (void *cls, | ||
554 | const struct GNUNET_MessageHeader *msg); | ||
555 | |||
556 | static int | ||
557 | check_peer_pull_reply (void *cls, | ||
558 | const struct GNUNET_RPS_P2P_PullReplyMessage *msg); | ||
559 | |||
560 | static void | ||
561 | handle_peer_pull_reply (void *cls, | ||
562 | const struct GNUNET_RPS_P2P_PullReplyMessage *msg); | ||
563 | |||
564 | /* End declaration of handlers */ | ||
565 | |||
566 | |||
567 | /** | ||
568 | * @brief Get the channel of a peer. If not existing, create. | ||
569 | * | ||
570 | * @param peer the peer id | ||
571 | * @return the #GNUNET_CADET_Channel used to send data to @a peer | ||
572 | */ | ||
573 | struct GNUNET_CADET_Channel * | ||
574 | get_channel (const struct GNUNET_PeerIdentity *peer) | ||
575 | { | ||
576 | struct PeerContext *peer_ctx; | ||
577 | struct GNUNET_HashCode port; | ||
578 | /* There exists a copy-paste-clone in run() */ | ||
579 | struct GNUNET_MQ_MessageHandler cadet_handlers[] = { | ||
580 | GNUNET_MQ_hd_fixed_size (peer_check, | ||
581 | GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE, | ||
582 | struct GNUNET_MessageHeader, | ||
583 | NULL), | ||
584 | GNUNET_MQ_hd_fixed_size (peer_push, | ||
585 | GNUNET_MESSAGE_TYPE_RPS_PP_PUSH, | ||
586 | struct GNUNET_MessageHeader, | ||
587 | NULL), | ||
588 | GNUNET_MQ_hd_fixed_size (peer_pull_request, | ||
589 | GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST, | ||
590 | struct GNUNET_MessageHeader, | ||
591 | NULL), | ||
592 | GNUNET_MQ_hd_var_size (peer_pull_reply, | ||
593 | GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY, | ||
594 | struct GNUNET_RPS_P2P_PullReplyMessage, | ||
595 | NULL), | ||
596 | GNUNET_MQ_handler_end () | ||
597 | }; | ||
598 | |||
599 | |||
600 | peer_ctx = get_peer_ctx (peer); | ||
601 | if (NULL == peer_ctx->send_channel) | ||
602 | { | ||
603 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
604 | "Trying to establish channel to peer %s\n", | ||
605 | GNUNET_i2s (peer)); | ||
606 | GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS, | ||
607 | strlen (GNUNET_APPLICATION_PORT_RPS), | ||
608 | &port); | ||
609 | peer_ctx->send_channel = | ||
610 | GNUNET_CADET_channel_create (cadet_handle, | ||
611 | (struct GNUNET_PeerIdentity *) peer, /* context */ | ||
612 | peer, | ||
613 | &port, | ||
614 | GNUNET_CADET_OPTION_RELIABLE, | ||
615 | NULL, /* WindowSize handler */ | ||
616 | cleanup_destroyed_channel, /* Disconnect handler */ | ||
617 | cadet_handlers); | ||
618 | } | ||
619 | GNUNET_assert (NULL != peer_ctx->send_channel); | ||
620 | return peer_ctx->send_channel; | ||
621 | } | ||
622 | |||
623 | |||
624 | /** | ||
625 | * Get the message queue (#GNUNET_MQ_Handle) of a specific peer. | ||
626 | * | ||
627 | * If we already have a message queue open to this client, | ||
628 | * simply return it, otherways create one. | ||
629 | * | ||
630 | * @param peer the peer to get the mq to | ||
631 | * @return the #GNUNET_MQ_Handle | ||
632 | */ | ||
633 | static struct GNUNET_MQ_Handle * | ||
634 | get_mq (const struct GNUNET_PeerIdentity *peer) | ||
635 | { | ||
636 | struct PeerContext *peer_ctx; | ||
637 | |||
638 | peer_ctx = get_peer_ctx (peer); | ||
639 | |||
640 | if (NULL == peer_ctx->mq) | ||
641 | { | ||
642 | (void) get_channel (peer); | ||
643 | peer_ctx->mq = GNUNET_CADET_get_mq (peer_ctx->send_channel); | ||
644 | } | ||
645 | return peer_ctx->mq; | ||
646 | } | ||
647 | |||
648 | |||
649 | /** | ||
650 | * @brief This is called in response to the first message we sent as a | ||
651 | * liveliness check. | ||
652 | * | ||
653 | * @param cls #PeerContext of peer with pending liveliness check | ||
654 | */ | ||
655 | static void | ||
656 | mq_liveliness_check_successful (void *cls) | ||
657 | { | ||
658 | struct PeerContext *peer_ctx = cls; | ||
659 | |||
660 | if (NULL != peer_ctx->liveliness_check_pending) | ||
661 | { | ||
662 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
663 | "Liveliness check for peer %s was successfull\n", | ||
664 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
665 | GNUNET_free (peer_ctx->liveliness_check_pending); | ||
666 | peer_ctx->liveliness_check_pending = NULL; | ||
667 | set_peer_live (peer_ctx); | ||
668 | } | ||
669 | } | ||
670 | |||
671 | /** | ||
672 | * Issue a check whether peer is live | ||
673 | * | ||
674 | * @param peer_ctx the context of the peer | ||
675 | */ | ||
676 | static void | ||
677 | check_peer_live (struct PeerContext *peer_ctx) | ||
678 | { | ||
679 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
680 | "Get informed about peer %s getting live\n", | ||
681 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
682 | |||
683 | struct GNUNET_MQ_Handle *mq; | ||
684 | struct GNUNET_MQ_Envelope *ev; | ||
685 | |||
686 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE); | ||
687 | peer_ctx->liveliness_check_pending = GNUNET_new (struct PendingMessage); | ||
688 | peer_ctx->liveliness_check_pending->ev = ev; | ||
689 | peer_ctx->liveliness_check_pending->peer_ctx = peer_ctx; | ||
690 | peer_ctx->liveliness_check_pending->type = "Check liveliness"; | ||
691 | mq = get_mq (&peer_ctx->peer_id); | ||
692 | GNUNET_MQ_notify_sent (ev, | ||
693 | mq_liveliness_check_successful, | ||
694 | peer_ctx); | ||
695 | GNUNET_MQ_send (mq, ev); | ||
696 | } | ||
697 | |||
698 | /** | ||
699 | * @brief Add an envelope to a message passed to mq to list of pending messages | ||
700 | * | ||
701 | * @param peer peer the message was sent to | ||
702 | * @param ev envelope to the message | ||
703 | * @param type type of the message to be sent | ||
704 | * @return pointer to pending message | ||
705 | */ | ||
706 | static struct PendingMessage * | ||
707 | insert_pending_message (const struct GNUNET_PeerIdentity *peer, | ||
708 | struct GNUNET_MQ_Envelope *ev, | ||
709 | const char *type) | ||
710 | { | ||
711 | struct PendingMessage *pending_msg; | ||
712 | struct PeerContext *peer_ctx; | ||
713 | |||
714 | peer_ctx = get_peer_ctx (peer); | ||
715 | pending_msg = GNUNET_new (struct PendingMessage); | ||
716 | pending_msg->ev = ev; | ||
717 | pending_msg->peer_ctx = peer_ctx; | ||
718 | pending_msg->type = type; | ||
719 | GNUNET_CONTAINER_DLL_insert (peer_ctx->pending_messages_head, | ||
720 | peer_ctx->pending_messages_tail, | ||
721 | pending_msg); | ||
722 | return pending_msg; | ||
723 | } | ||
724 | |||
725 | |||
726 | /** | ||
727 | * @brief Remove a pending message from the respective DLL | ||
728 | * | ||
729 | * @param pending_msg the pending message to remove | ||
730 | * @param cancel cancel the pending message, too | ||
731 | */ | ||
732 | static void | ||
733 | remove_pending_message (struct PendingMessage *pending_msg, int cancel) | ||
734 | { | ||
735 | struct PeerContext *peer_ctx; | ||
736 | |||
737 | peer_ctx = pending_msg->peer_ctx; | ||
738 | GNUNET_assert (NULL != peer_ctx); | ||
739 | GNUNET_CONTAINER_DLL_remove (peer_ctx->pending_messages_head, | ||
740 | peer_ctx->pending_messages_tail, | ||
741 | pending_msg); | ||
742 | // TODO wait for the cadet implementation of message cancellation | ||
743 | //if (GNUNET_YES == cancel) | ||
744 | //{ | ||
745 | // GNUNET_MQ_send_cancel (pending_msg->ev); | ||
746 | //} | ||
747 | GNUNET_free (pending_msg); | ||
748 | } | ||
749 | |||
750 | |||
751 | /** | ||
752 | * @brief Check whether function of type #PeerOp was already scheduled | ||
753 | * | ||
754 | * The array with pending operations will probably never grow really big, so | ||
755 | * iterating over it should be ok. | ||
756 | * | ||
757 | * @param peer the peer to check | ||
758 | * @param peer_op the operation (#PeerOp) on the peer | ||
759 | * | ||
760 | * @return #GNUNET_YES if this operation is scheduled on that peer | ||
761 | * #GNUNET_NO otherwise | ||
762 | */ | ||
763 | static int | ||
764 | check_operation_scheduled (const struct GNUNET_PeerIdentity *peer, | ||
765 | const PeerOp peer_op) | ||
766 | { | ||
767 | const struct PeerContext *peer_ctx; | ||
768 | unsigned int i; | ||
769 | |||
770 | peer_ctx = get_peer_ctx (peer); | ||
771 | for (i = 0; i < peer_ctx->num_pending_ops; i++) | ||
772 | if (peer_op == peer_ctx->pending_ops[i].op) | ||
773 | return GNUNET_YES; | ||
774 | return GNUNET_NO; | ||
775 | } | ||
776 | |||
777 | int | ||
778 | Peers_remove_peer (const struct GNUNET_PeerIdentity *peer); | ||
779 | |||
780 | /** | ||
781 | * Iterator over hash map entries. Deletes all contexts of peers. | ||
782 | * | ||
783 | * @param cls closure | ||
784 | * @param key current public key | ||
785 | * @param value value in the hash map | ||
786 | * @return #GNUNET_YES if we should continue to iterate, | ||
787 | * #GNUNET_NO if not. | ||
788 | */ | ||
789 | static int | ||
790 | peermap_clear_iterator (void *cls, | ||
791 | const struct GNUNET_PeerIdentity *key, | ||
792 | void *value) | ||
793 | { | ||
794 | Peers_remove_peer (key); | ||
795 | return GNUNET_YES; | ||
796 | } | ||
797 | |||
798 | |||
799 | /** | ||
800 | * @brief This is called once a message is sent. | ||
801 | * | ||
802 | * Removes the pending message | ||
803 | * | ||
804 | * @param cls type of the message that was sent | ||
805 | */ | ||
806 | static void | ||
807 | mq_notify_sent_cb (void *cls) | ||
808 | { | ||
809 | struct PendingMessage *pending_msg = (struct PendingMessage *) cls; | ||
810 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
811 | "%s was sent.\n", | ||
812 | pending_msg->type); | ||
813 | /* Do not cancle message */ | ||
814 | remove_pending_message (pending_msg, GNUNET_NO); | ||
815 | } | ||
816 | |||
817 | |||
818 | /** | ||
819 | * @brief Iterator function for #store_valid_peers. | ||
820 | * | ||
821 | * Implements #GNUNET_CONTAINER_PeerMapIterator. | ||
822 | * Writes single peer to disk. | ||
823 | * | ||
824 | * @param cls the file handle to write to. | ||
825 | * @param peer current peer | ||
826 | * @param value unused | ||
827 | * | ||
828 | * @return #GNUNET_YES if we should continue to | ||
829 | * iterate, | ||
830 | * #GNUNET_NO if not. | ||
831 | */ | ||
832 | static int | ||
833 | store_peer_presistently_iterator (void *cls, | ||
834 | const struct GNUNET_PeerIdentity *peer, | ||
835 | void *value) | ||
836 | { | ||
837 | const struct GNUNET_DISK_FileHandle *fh = cls; | ||
838 | char peer_string[128]; | ||
839 | int size; | ||
840 | ssize_t ret; | ||
841 | |||
842 | if (NULL == peer) | ||
843 | { | ||
844 | return GNUNET_YES; | ||
845 | } | ||
846 | size = GNUNET_snprintf (peer_string, | ||
847 | sizeof (peer_string), | ||
848 | "%s\n", | ||
849 | GNUNET_i2s_full (peer)); | ||
850 | GNUNET_assert (53 == size); | ||
851 | ret = GNUNET_DISK_file_write (fh, | ||
852 | peer_string, | ||
853 | size); | ||
854 | GNUNET_assert (size == ret); | ||
855 | return GNUNET_YES; | ||
856 | } | ||
857 | |||
858 | |||
859 | /** | ||
860 | * @brief Store the peers currently in #valid_peers to disk. | ||
861 | */ | ||
862 | static void | ||
863 | store_valid_peers () | ||
864 | { | ||
865 | struct GNUNET_DISK_FileHandle *fh; | ||
866 | uint32_t number_written_peers; | ||
867 | int ret; | ||
868 | |||
869 | if (0 == strncmp ("DISABLE", filename_valid_peers, 7)) | ||
870 | { | ||
871 | return; | ||
872 | } | ||
873 | |||
874 | ret = GNUNET_DISK_directory_create_for_file (filename_valid_peers); | ||
875 | if (GNUNET_SYSERR == ret) | ||
876 | { | ||
877 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
878 | "Not able to create directory for file `%s'\n", | ||
879 | filename_valid_peers); | ||
880 | GNUNET_break (0); | ||
881 | } | ||
882 | else if (GNUNET_NO == ret) | ||
883 | { | ||
884 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
885 | "Directory for file `%s' exists but is not writable for us\n", | ||
886 | filename_valid_peers); | ||
887 | GNUNET_break (0); | ||
888 | } | ||
889 | fh = GNUNET_DISK_file_open (filename_valid_peers, | ||
890 | GNUNET_DISK_OPEN_WRITE | | ||
891 | GNUNET_DISK_OPEN_CREATE, | ||
892 | GNUNET_DISK_PERM_USER_READ | | ||
893 | GNUNET_DISK_PERM_USER_WRITE); | ||
894 | if (NULL == fh) | ||
895 | { | ||
896 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
897 | "Not able to write valid peers to file `%s'\n", | ||
898 | filename_valid_peers); | ||
899 | return; | ||
900 | } | ||
901 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
902 | "Writing %u valid peers to disk\n", | ||
903 | GNUNET_CONTAINER_multipeermap_size (valid_peers)); | ||
904 | number_written_peers = | ||
905 | GNUNET_CONTAINER_multipeermap_iterate (valid_peers, | ||
906 | store_peer_presistently_iterator, | ||
907 | fh); | ||
908 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); | ||
909 | GNUNET_assert (number_written_peers == | ||
910 | GNUNET_CONTAINER_multipeermap_size (valid_peers)); | ||
911 | } | ||
912 | |||
913 | |||
914 | /** | ||
915 | * @brief Convert string representation of peer id to peer id. | ||
916 | * | ||
917 | * Counterpart to #GNUNET_i2s_full. | ||
918 | * | ||
919 | * @param string_repr The string representation of the peer id | ||
920 | * | ||
921 | * @return The peer id | ||
922 | */ | ||
923 | static const struct GNUNET_PeerIdentity * | ||
924 | s2i_full (const char *string_repr) | ||
925 | { | ||
926 | struct GNUNET_PeerIdentity *peer; | ||
927 | size_t len; | ||
928 | int ret; | ||
929 | |||
930 | peer = GNUNET_new (struct GNUNET_PeerIdentity); | ||
931 | len = strlen (string_repr); | ||
932 | if (52 > len) | ||
933 | { | ||
934 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
935 | "Not able to convert string representation of PeerID to PeerID\n" | ||
936 | "Sting representation: %s (len %lu) - too short\n", | ||
937 | string_repr, | ||
938 | len); | ||
939 | GNUNET_break (0); | ||
940 | } | ||
941 | else if (52 < len) | ||
942 | { | ||
943 | len = 52; | ||
944 | } | ||
945 | ret = GNUNET_CRYPTO_eddsa_public_key_from_string (string_repr, | ||
946 | len, | ||
947 | &peer->public_key); | ||
948 | if (GNUNET_OK != ret) | ||
949 | { | ||
950 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
951 | "Not able to convert string representation of PeerID to PeerID\n" | ||
952 | "Sting representation: %s\n", | ||
953 | string_repr); | ||
954 | GNUNET_break (0); | ||
955 | } | ||
956 | return peer; | ||
957 | } | ||
958 | |||
959 | |||
960 | /** | ||
961 | * @brief Restore the peers on disk to #valid_peers. | ||
962 | */ | ||
963 | static void | ||
964 | restore_valid_peers () | ||
965 | { | ||
966 | off_t file_size; | ||
967 | uint32_t num_peers; | ||
968 | struct GNUNET_DISK_FileHandle *fh; | ||
969 | char *buf; | ||
970 | ssize_t size_read; | ||
971 | char *iter_buf; | ||
972 | char *str_repr; | ||
973 | const struct GNUNET_PeerIdentity *peer; | ||
974 | |||
975 | if (0 == strncmp ("DISABLE", filename_valid_peers, 7)) | ||
976 | { | ||
977 | return; | ||
978 | } | ||
979 | |||
980 | if (GNUNET_OK != GNUNET_DISK_file_test (filename_valid_peers)) | ||
981 | { | ||
982 | return; | ||
983 | } | ||
984 | fh = GNUNET_DISK_file_open (filename_valid_peers, | ||
985 | GNUNET_DISK_OPEN_READ, | ||
986 | GNUNET_DISK_PERM_NONE); | ||
987 | GNUNET_assert (NULL != fh); | ||
988 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &file_size)); | ||
989 | num_peers = file_size / 53; | ||
990 | buf = GNUNET_malloc (file_size); | ||
991 | size_read = GNUNET_DISK_file_read (fh, buf, file_size); | ||
992 | GNUNET_assert (size_read == file_size); | ||
993 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
994 | "Restoring %" PRIu32 " peers from file `%s'\n", | ||
995 | num_peers, | ||
996 | filename_valid_peers); | ||
997 | for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53) | ||
998 | { | ||
999 | str_repr = GNUNET_strndup (iter_buf, 53); | ||
1000 | peer = s2i_full (str_repr); | ||
1001 | GNUNET_free (str_repr); | ||
1002 | add_valid_peer (peer); | ||
1003 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1004 | "Restored valid peer %s from disk\n", | ||
1005 | GNUNET_i2s_full (peer)); | ||
1006 | } | ||
1007 | iter_buf = NULL; | ||
1008 | GNUNET_free (buf); | ||
1009 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1010 | "num_peers: %" PRIu32 ", _size (valid_peers): %u\n", | ||
1011 | num_peers, | ||
1012 | GNUNET_CONTAINER_multipeermap_size (valid_peers)); | ||
1013 | if (num_peers != GNUNET_CONTAINER_multipeermap_size (valid_peers)) | ||
1014 | { | ||
1015 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1016 | "Number of restored peers does not match file size. Have probably duplicates.\n"); | ||
1017 | } | ||
1018 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); | ||
1019 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1020 | "Restored %u valid peers from disk\n", | ||
1021 | GNUNET_CONTAINER_multipeermap_size (valid_peers)); | ||
1022 | } | ||
1023 | |||
1024 | |||
1025 | /** | ||
1026 | * @brief Initialise storage of peers | ||
1027 | * | ||
1028 | * @param fn_valid_peers filename of the file used to store valid peer ids | ||
1029 | * @param cadet_h cadet handle | ||
1030 | * @param disconnect_handler Disconnect handler | ||
1031 | * @param own_id own peer identity | ||
1032 | */ | ||
1033 | void | ||
1034 | Peers_initialise (char* fn_valid_peers, | ||
1035 | struct GNUNET_CADET_Handle *cadet_h, | ||
1036 | GNUNET_CADET_DisconnectEventHandler disconnect_handler, | ||
1037 | const struct GNUNET_PeerIdentity *own_id) | ||
1038 | { | ||
1039 | filename_valid_peers = GNUNET_strdup (fn_valid_peers); | ||
1040 | cadet_handle = cadet_h; | ||
1041 | own_identity = *own_id; | ||
1042 | peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); | ||
1043 | valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); | ||
1044 | restore_valid_peers (); | ||
1045 | } | ||
1046 | |||
1047 | |||
1048 | /** | ||
1049 | * @brief Delete storage of peers that was created with #Peers_initialise () | ||
1050 | */ | ||
1051 | void | ||
1052 | Peers_terminate () | ||
1053 | { | ||
1054 | if (GNUNET_SYSERR == | ||
1055 | GNUNET_CONTAINER_multipeermap_iterate (peer_map, | ||
1056 | peermap_clear_iterator, | ||
1057 | NULL)) | ||
1058 | { | ||
1059 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1060 | "Iteration destroying peers was aborted.\n"); | ||
1061 | } | ||
1062 | GNUNET_CONTAINER_multipeermap_destroy (peer_map); | ||
1063 | store_valid_peers (); | ||
1064 | GNUNET_free (filename_valid_peers); | ||
1065 | GNUNET_CONTAINER_multipeermap_destroy (valid_peers); | ||
1066 | } | ||
1067 | |||
1068 | |||
1069 | /** | ||
1070 | * Iterator over #valid_peers hash map entries. | ||
1071 | * | ||
1072 | * @param cls closure - unused | ||
1073 | * @param peer current peer id | ||
1074 | * @param value value in the hash map - unused | ||
1075 | * @return #GNUNET_YES if we should continue to | ||
1076 | * iterate, | ||
1077 | * #GNUNET_NO if not. | ||
1078 | */ | ||
1079 | static int | ||
1080 | valid_peer_iterator (void *cls, | ||
1081 | const struct GNUNET_PeerIdentity *peer, | ||
1082 | void *value) | ||
1083 | { | ||
1084 | struct PeersIteratorCls *it_cls = cls; | ||
1085 | |||
1086 | return it_cls->iterator (it_cls->cls, | ||
1087 | peer); | ||
1088 | } | ||
1089 | |||
1090 | |||
1091 | /** | ||
1092 | * @brief Get all currently known, valid peer ids. | ||
1093 | * | ||
1094 | * @param it function to call on each peer id | ||
1095 | * @param it_cls extra argument to @a it | ||
1096 | * @return the number of key value pairs processed, | ||
1097 | * #GNUNET_SYSERR if it aborted iteration | ||
1098 | */ | ||
1099 | int | ||
1100 | Peers_get_valid_peers (PeersIterator iterator, | ||
1101 | void *it_cls) | ||
1102 | { | ||
1103 | struct PeersIteratorCls *cls; | ||
1104 | int ret; | ||
1105 | |||
1106 | cls = GNUNET_new (struct PeersIteratorCls); | ||
1107 | cls->iterator = iterator; | ||
1108 | cls->cls = it_cls; | ||
1109 | ret = GNUNET_CONTAINER_multipeermap_iterate (valid_peers, | ||
1110 | valid_peer_iterator, | ||
1111 | cls); | ||
1112 | GNUNET_free (cls); | ||
1113 | return ret; | ||
1114 | } | ||
1115 | |||
1116 | |||
1117 | /** | ||
1118 | * @brief Add peer to known peers. | ||
1119 | * | ||
1120 | * This function is called on new peer_ids from 'external' sources | ||
1121 | * (client seed, cadet get_peers(), ...) | ||
1122 | * | ||
1123 | * @param peer the new #GNUNET_PeerIdentity | ||
1124 | * | ||
1125 | * @return #GNUNET_YES if peer was inserted | ||
1126 | * #GNUNET_NO otherwise (if peer was already known or | ||
1127 | * peer was #own_identity) | ||
1128 | */ | ||
1129 | int | ||
1130 | Peers_insert_peer (const struct GNUNET_PeerIdentity *peer) | ||
1131 | { | ||
1132 | if ( (GNUNET_YES == Peers_check_peer_known (peer)) || | ||
1133 | (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity)) ) | ||
1134 | { | ||
1135 | return GNUNET_NO; /* We already know this peer - nothing to do */ | ||
1136 | } | ||
1137 | (void) create_peer_ctx (peer); | ||
1138 | return GNUNET_YES; | ||
1139 | } | ||
1140 | |||
1141 | int | ||
1142 | Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags); | ||
1143 | |||
1144 | /** | ||
1145 | * @brief Try connecting to a peer to see whether it is online | ||
1146 | * | ||
1147 | * If not known yet, insert into known peers | ||
1148 | * | ||
1149 | * @param peer the peer whose liveliness is to be checked | ||
1150 | * @return #GNUNET_YES if peer had to be inserted | ||
1151 | * #GNUNET_NO otherwise (if peer was already known or | ||
1152 | * peer was #own_identity) | ||
1153 | */ | ||
1154 | int | ||
1155 | Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer) | ||
1156 | { | ||
1157 | struct PeerContext *peer_ctx; | ||
1158 | int ret; | ||
1159 | |||
1160 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity)) | ||
1161 | { | ||
1162 | return GNUNET_NO; | ||
1163 | } | ||
1164 | ret = Peers_insert_peer (peer); | ||
1165 | peer_ctx = get_peer_ctx (peer); | ||
1166 | if (GNUNET_NO == Peers_check_peer_flag (peer, Peers_ONLINE)) | ||
1167 | { | ||
1168 | check_peer_live (peer_ctx); | ||
1169 | } | ||
1170 | return ret; | ||
1171 | } | ||
1172 | |||
1173 | |||
1174 | /** | ||
1175 | * @brief Check if peer is removable. | ||
1176 | * | ||
1177 | * Check if | ||
1178 | * - a recv channel exists | ||
1179 | * - there are pending messages | ||
1180 | * - there is no pending pull reply | ||
1181 | * | ||
1182 | * @param peer the peer in question | ||
1183 | * @return #GNUNET_YES if peer is removable | ||
1184 | * #GNUNET_NO if peer is NOT removable | ||
1185 | * #GNUNET_SYSERR if peer is not known | ||
1186 | */ | ||
1187 | int | ||
1188 | Peers_check_removable (const struct GNUNET_PeerIdentity *peer) | ||
1189 | { | ||
1190 | struct PeerContext *peer_ctx; | ||
1191 | |||
1192 | if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) | ||
1193 | { | ||
1194 | return GNUNET_SYSERR; | ||
1195 | } | ||
1196 | |||
1197 | peer_ctx = get_peer_ctx (peer); | ||
1198 | if ( (NULL != peer_ctx->recv_channel) || | ||
1199 | (NULL != peer_ctx->pending_messages_head) || | ||
1200 | (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) ) | ||
1201 | { | ||
1202 | return GNUNET_NO; | ||
1203 | } | ||
1204 | return GNUNET_YES; | ||
1205 | } | ||
1206 | |||
1207 | uint32_t * | ||
1208 | Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer, | ||
1209 | enum Peers_ChannelRole role); | ||
1210 | |||
1211 | int | ||
1212 | Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags); | ||
1213 | |||
1214 | /** | ||
1215 | * @brief Remove peer | ||
1216 | * | ||
1217 | * @param peer the peer to clean | ||
1218 | * @return #GNUNET_YES if peer was removed | ||
1219 | * #GNUNET_NO otherwise | ||
1220 | */ | ||
1221 | int | ||
1222 | Peers_remove_peer (const struct GNUNET_PeerIdentity *peer) | ||
1223 | { | ||
1224 | struct PeerContext *peer_ctx; | ||
1225 | uint32_t *channel_flag; | ||
1226 | |||
1227 | if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) | ||
1228 | { | ||
1229 | return GNUNET_NO; | ||
1230 | } | ||
1231 | |||
1232 | peer_ctx = get_peer_ctx (peer); | ||
1233 | set_peer_flag (peer_ctx, Peers_TO_DESTROY); | ||
1234 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1235 | "Going to remove peer %s\n", | ||
1236 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
1237 | Peers_unset_peer_flag (peer, Peers_ONLINE); | ||
1238 | |||
1239 | GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0); | ||
1240 | while (NULL != peer_ctx->pending_messages_head) | ||
1241 | { | ||
1242 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1243 | "Removing unsent %s\n", | ||
1244 | peer_ctx->pending_messages_head->type); | ||
1245 | /* Cancle pending message, too */ | ||
1246 | remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES); | ||
1247 | } | ||
1248 | /* If we are still waiting for notification whether this peer is live | ||
1249 | * cancel the according task */ | ||
1250 | if (NULL != peer_ctx->liveliness_check_pending) | ||
1251 | { | ||
1252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1253 | "Removing pending liveliness check for peer %s\n", | ||
1254 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
1255 | // TODO wait until cadet sets mq->cancel_impl | ||
1256 | //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev); | ||
1257 | GNUNET_free (peer_ctx->liveliness_check_pending); | ||
1258 | peer_ctx->liveliness_check_pending = NULL; | ||
1259 | } | ||
1260 | channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING); | ||
1261 | if (NULL != peer_ctx->send_channel && | ||
1262 | GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING)) | ||
1263 | { | ||
1264 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1265 | "Destroying send channel\n"); | ||
1266 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | ||
1267 | peer_ctx->send_channel = NULL; | ||
1268 | } | ||
1269 | channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING); | ||
1270 | if (NULL != peer_ctx->recv_channel && | ||
1271 | GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING)) | ||
1272 | { | ||
1273 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1274 | "Destroying recv channel\n"); | ||
1275 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); | ||
1276 | peer_ctx->recv_channel = NULL; | ||
1277 | } | ||
1278 | |||
1279 | GNUNET_free (peer_ctx->send_channel_flags); | ||
1280 | GNUNET_free (peer_ctx->recv_channel_flags); | ||
1281 | |||
1282 | if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, &peer_ctx->peer_id)) | ||
1283 | { | ||
1284 | LOG (GNUNET_ERROR_TYPE_WARNING, "removing peer from peer_map failed\n"); | ||
1285 | } | ||
1286 | GNUNET_free (peer_ctx); | ||
1287 | return GNUNET_YES; | ||
1288 | } | ||
1289 | |||
1290 | |||
1291 | /** | ||
1292 | * @brief set flags on a given peer. | ||
1293 | * | ||
1294 | * @param peer the peer to set flags on | ||
1295 | * @param flags the flags | ||
1296 | */ | ||
1297 | void | ||
1298 | Peers_set_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags) | ||
1299 | { | ||
1300 | struct PeerContext *peer_ctx; | ||
1301 | |||
1302 | peer_ctx = get_peer_ctx (peer); | ||
1303 | set_peer_flag (peer_ctx, flags); | ||
1304 | } | ||
1305 | |||
1306 | |||
1307 | /** | ||
1308 | * @brief unset flags on a given peer. | ||
1309 | * | ||
1310 | * @param peer the peer to unset flags on | ||
1311 | * @param flags the flags | ||
1312 | */ | ||
1313 | void | ||
1314 | Peers_unset_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags) | ||
1315 | { | ||
1316 | struct PeerContext *peer_ctx; | ||
1317 | |||
1318 | peer_ctx = get_peer_ctx (peer); | ||
1319 | unset_peer_flag (peer_ctx, flags); | ||
1320 | } | ||
1321 | |||
1322 | |||
1323 | /** | ||
1324 | * @brief Check whether flags on a peer are set. | ||
1325 | * | ||
1326 | * @param peer the peer to check the flag of | ||
1327 | * @param flags the flags to check | ||
1328 | * | ||
1329 | * @return #GNUNET_SYSERR if peer is not known | ||
1330 | * #GNUNET_YES if all given flags are set | ||
1331 | * #GNUNET_NO otherwise | ||
1332 | */ | ||
1333 | int | ||
1334 | Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags) | ||
1335 | { | ||
1336 | struct PeerContext *peer_ctx; | ||
1337 | |||
1338 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1339 | { | ||
1340 | return GNUNET_SYSERR; | ||
1341 | } | ||
1342 | peer_ctx = get_peer_ctx (peer); | ||
1343 | return check_peer_flag_set (peer_ctx, flags); | ||
1344 | } | ||
1345 | |||
1346 | |||
1347 | /** | ||
1348 | * @brief set flags on a given channel. | ||
1349 | * | ||
1350 | * @param channel the channel to set flags on | ||
1351 | * @param flags the flags | ||
1352 | */ | ||
1353 | void | ||
1354 | Peers_set_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags) | ||
1355 | { | ||
1356 | set_channel_flag (channel_flags, flags); | ||
1357 | } | ||
1358 | |||
1359 | |||
1360 | /** | ||
1361 | * @brief unset flags on a given channel. | ||
1362 | * | ||
1363 | * @param channel the channel to unset flags on | ||
1364 | * @param flags the flags | ||
1365 | */ | ||
1366 | void | ||
1367 | Peers_unset_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags) | ||
1368 | { | ||
1369 | unset_channel_flag (channel_flags, flags); | ||
1370 | } | ||
1371 | |||
1372 | |||
1373 | /** | ||
1374 | * @brief Check whether flags on a channel are set. | ||
1375 | * | ||
1376 | * @param channel the channel to check the flag of | ||
1377 | * @param flags the flags to check | ||
1378 | * | ||
1379 | * @return #GNUNET_YES if all given flags are set | ||
1380 | * #GNUNET_NO otherwise | ||
1381 | */ | ||
1382 | int | ||
1383 | Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags) | ||
1384 | { | ||
1385 | return check_channel_flag_set (channel_flags, flags); | ||
1386 | } | ||
1387 | |||
1388 | /** | ||
1389 | * @brief Get the flags for the channel in @a role for @a peer. | ||
1390 | * | ||
1391 | * @param peer Peer to get the channel flags for. | ||
1392 | * @param role Role of channel to get flags for | ||
1393 | * | ||
1394 | * @return The flags. | ||
1395 | */ | ||
1396 | uint32_t * | ||
1397 | Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer, | ||
1398 | enum Peers_ChannelRole role) | ||
1399 | { | ||
1400 | const struct PeerContext *peer_ctx; | ||
1401 | |||
1402 | peer_ctx = get_peer_ctx (peer); | ||
1403 | if (Peers_CHANNEL_ROLE_SENDING == role) | ||
1404 | { | ||
1405 | return peer_ctx->send_channel_flags; | ||
1406 | } | ||
1407 | else if (Peers_CHANNEL_ROLE_RECEIVING == role) | ||
1408 | { | ||
1409 | return peer_ctx->recv_channel_flags; | ||
1410 | } | ||
1411 | else | ||
1412 | { | ||
1413 | GNUNET_assert (0); | ||
1414 | } | ||
1415 | } | ||
1416 | |||
1417 | /** | ||
1418 | * @brief Check whether we have information about the given peer. | ||
1419 | * | ||
1420 | * FIXME probably deprecated. Make this the new _online. | ||
1421 | * | ||
1422 | * @param peer peer in question | ||
1423 | * | ||
1424 | * @return #GNUNET_YES if peer is known | ||
1425 | * #GNUNET_NO if peer is not knwon | ||
1426 | */ | ||
1427 | int | ||
1428 | Peers_check_peer_known (const struct GNUNET_PeerIdentity *peer) | ||
1429 | { | ||
1430 | return GNUNET_CONTAINER_multipeermap_contains (peer_map, peer); | ||
1431 | } | ||
1432 | |||
1433 | |||
1434 | /** | ||
1435 | * @brief Check whether @a peer is actually a peer. | ||
1436 | * | ||
1437 | * A valid peer is a peer that we know exists eg. we were connected to once. | ||
1438 | * | ||
1439 | * @param peer peer in question | ||
1440 | * | ||
1441 | * @return #GNUNET_YES if peer is valid | ||
1442 | * #GNUNET_NO if peer is not valid | ||
1443 | */ | ||
1444 | int | ||
1445 | Peers_check_peer_valid (const struct GNUNET_PeerIdentity *peer) | ||
1446 | { | ||
1447 | return GNUNET_CONTAINER_multipeermap_contains (valid_peers, peer); | ||
1448 | } | ||
1449 | |||
1450 | |||
1451 | /** | ||
1452 | * @brief Indicate that we want to send to the other peer | ||
1453 | * | ||
1454 | * This establishes a sending channel | ||
1455 | * | ||
1456 | * @param peer the peer to establish channel to | ||
1457 | */ | ||
1458 | void | ||
1459 | Peers_indicate_sending_intention (const struct GNUNET_PeerIdentity *peer) | ||
1460 | { | ||
1461 | GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); | ||
1462 | (void) get_channel (peer); | ||
1463 | } | ||
1464 | |||
1465 | |||
1466 | /** | ||
1467 | * @brief Check whether other peer has the intention to send/opened channel | ||
1468 | * towars us | ||
1469 | * | ||
1470 | * @param peer the peer in question | ||
1471 | * | ||
1472 | * @return #GNUNET_YES if peer has the intention to send | ||
1473 | * #GNUNET_NO otherwise | ||
1474 | */ | ||
1475 | int | ||
1476 | Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer) | ||
1477 | { | ||
1478 | const struct PeerContext *peer_ctx; | ||
1479 | |||
1480 | peer_ctx = get_peer_ctx (peer); | ||
1481 | if (NULL != peer_ctx->recv_channel) | ||
1482 | { | ||
1483 | return GNUNET_YES; | ||
1484 | } | ||
1485 | return GNUNET_NO; | ||
1486 | } | ||
1487 | |||
1488 | |||
1489 | /** | ||
1490 | * Handle the channel a peer opens to us. | ||
1491 | * | ||
1492 | * @param cls The closure | ||
1493 | * @param channel The channel the peer wants to establish | ||
1494 | * @param initiator The peer's peer ID | ||
1495 | * | ||
1496 | * @return initial channel context for the channel | ||
1497 | * (can be NULL -- that's not an error) | ||
1498 | */ | ||
1499 | void * | ||
1500 | Peers_handle_inbound_channel (void *cls, | ||
1501 | struct GNUNET_CADET_Channel *channel, | ||
1502 | const struct GNUNET_PeerIdentity *initiator) | ||
1503 | { | ||
1504 | struct PeerContext *peer_ctx; | ||
1505 | |||
1506 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1507 | "New channel was established to us (Peer %s).\n", | ||
1508 | GNUNET_i2s (initiator)); | ||
1509 | GNUNET_assert (NULL != channel); /* according to cadet API */ | ||
1510 | /* Make sure we 'know' about this peer */ | ||
1511 | peer_ctx = create_or_get_peer_ctx (initiator); | ||
1512 | set_peer_live (peer_ctx); | ||
1513 | /* We only accept one incoming channel per peer */ | ||
1514 | if (GNUNET_YES == Peers_check_peer_send_intention (initiator)) | ||
1515 | { | ||
1516 | set_channel_flag (peer_ctx->recv_channel_flags, | ||
1517 | Peers_CHANNEL_ESTABLISHED_TWICE); | ||
1518 | GNUNET_CADET_channel_destroy (channel); | ||
1519 | /* return the channel context */ | ||
1520 | return &peer_ctx->peer_id; | ||
1521 | } | ||
1522 | peer_ctx->recv_channel = channel; | ||
1523 | return &peer_ctx->peer_id; | ||
1524 | } | ||
1525 | |||
1526 | |||
1527 | /** | ||
1528 | * @brief Check whether a sending channel towards the given peer exists | ||
1529 | * | ||
1530 | * @param peer the peer to check for | ||
1531 | * | ||
1532 | * @return #GNUNET_YES if a sending channel towards that peer exists | ||
1533 | * #GNUNET_NO otherwise | ||
1534 | */ | ||
1535 | int | ||
1536 | Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer) | ||
1537 | { | ||
1538 | struct PeerContext *peer_ctx; | ||
1539 | |||
1540 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1541 | { /* If no such peer exists, there is no channel */ | ||
1542 | return GNUNET_NO; | ||
1543 | } | ||
1544 | peer_ctx = get_peer_ctx (peer); | ||
1545 | if (NULL == peer_ctx->send_channel) | ||
1546 | { | ||
1547 | return GNUNET_NO; | ||
1548 | } | ||
1549 | return GNUNET_YES; | ||
1550 | } | ||
1551 | |||
1552 | |||
1553 | /** | ||
1554 | * @brief check whether the given channel is the sending channel of the given | ||
1555 | * peer | ||
1556 | * | ||
1557 | * @param peer the peer in question | ||
1558 | * @param channel the channel to check for | ||
1559 | * @param role either #Peers_CHANNEL_ROLE_SENDING, or | ||
1560 | * #Peers_CHANNEL_ROLE_RECEIVING | ||
1561 | * | ||
1562 | * @return #GNUNET_YES if the given chennel is the sending channel of the peer | ||
1563 | * #GNUNET_NO otherwise | ||
1564 | */ | ||
1565 | int | ||
1566 | Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer, | ||
1567 | const struct GNUNET_CADET_Channel *channel, | ||
1568 | enum Peers_ChannelRole role) | ||
1569 | { | ||
1570 | const struct PeerContext *peer_ctx; | ||
1571 | |||
1572 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1573 | { | ||
1574 | return GNUNET_NO; | ||
1575 | } | ||
1576 | peer_ctx = get_peer_ctx (peer); | ||
1577 | if ( (Peers_CHANNEL_ROLE_SENDING == role) && | ||
1578 | (channel == peer_ctx->send_channel) ) | ||
1579 | { | ||
1580 | return GNUNET_YES; | ||
1581 | } | ||
1582 | if ( (Peers_CHANNEL_ROLE_RECEIVING == role) && | ||
1583 | (channel == peer_ctx->recv_channel) ) | ||
1584 | { | ||
1585 | return GNUNET_YES; | ||
1586 | } | ||
1587 | return GNUNET_NO; | ||
1588 | } | ||
1589 | |||
1590 | |||
1591 | /** | ||
1592 | * @brief Destroy the send channel of a peer e.g. stop indicating a sending | ||
1593 | * intention to another peer | ||
1594 | * | ||
1595 | * If there is also no channel to receive messages from that peer, remove it | ||
1596 | * from the peermap. | ||
1597 | * TODO really? | ||
1598 | * | ||
1599 | * @peer the peer identity of the peer whose sending channel to destroy | ||
1600 | * @return #GNUNET_YES if channel was destroyed | ||
1601 | * #GNUNET_NO otherwise | ||
1602 | */ | ||
1603 | int | ||
1604 | Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer) | ||
1605 | { | ||
1606 | struct PeerContext *peer_ctx; | ||
1607 | |||
1608 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1609 | { | ||
1610 | return GNUNET_NO; | ||
1611 | } | ||
1612 | peer_ctx = get_peer_ctx (peer); | ||
1613 | if (NULL != peer_ctx->send_channel) | ||
1614 | { | ||
1615 | set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_CLEAN); | ||
1616 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | ||
1617 | peer_ctx->send_channel = NULL; | ||
1618 | (void) Peers_check_connected (peer); | ||
1619 | return GNUNET_YES; | ||
1620 | } | ||
1621 | return GNUNET_NO; | ||
1622 | } | ||
1623 | |||
1624 | /** | ||
1625 | * This is called when a channel is destroyed. | ||
1626 | * | ||
1627 | * @param cls The closure | ||
1628 | * @param channel The channel being closed | ||
1629 | * @param channel_ctx The context associated with this channel | ||
1630 | */ | ||
1631 | void | ||
1632 | Peers_cleanup_destroyed_channel (void *cls, | ||
1633 | const struct GNUNET_CADET_Channel *channel) | ||
1634 | { | ||
1635 | struct GNUNET_PeerIdentity *peer = cls; | ||
1636 | struct PeerContext *peer_ctx; | ||
1637 | |||
1638 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1639 | {/* We don't want to implicitly create a context that we're about to kill */ | ||
1640 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1641 | "channel (%s) without associated context was destroyed\n", | ||
1642 | GNUNET_i2s (peer)); | ||
1643 | return; | ||
1644 | } | ||
1645 | peer_ctx = get_peer_ctx (peer); | ||
1646 | |||
1647 | /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY | ||
1648 | * flag will be set. In this case simply make sure that the channels are | ||
1649 | * cleaned. */ | ||
1650 | /* FIXME This distinction seems to be redundant */ | ||
1651 | if (Peers_check_peer_flag (peer, Peers_TO_DESTROY)) | ||
1652 | {/* We initiatad the destruction of this particular peer */ | ||
1653 | if (channel == peer_ctx->send_channel) | ||
1654 | peer_ctx->send_channel = NULL; | ||
1655 | else if (channel == peer_ctx->recv_channel) | ||
1656 | peer_ctx->recv_channel = NULL; | ||
1657 | |||
1658 | if (NULL != peer_ctx->send_channel) | ||
1659 | { | ||
1660 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | ||
1661 | peer_ctx->send_channel = NULL; | ||
1662 | } | ||
1663 | if (NULL != peer_ctx->recv_channel) | ||
1664 | { | ||
1665 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); | ||
1666 | peer_ctx->recv_channel = NULL; | ||
1667 | } | ||
1668 | /* Set the #Peers_ONLINE flag accordingly */ | ||
1669 | (void) Peers_check_connected (peer); | ||
1670 | return; | ||
1671 | } | ||
1672 | |||
1673 | else | ||
1674 | { /* We did not initiate the destruction of this peer */ | ||
1675 | if (channel == peer_ctx->send_channel) | ||
1676 | { /* Something (but us) killd the channel - clean up peer */ | ||
1677 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1678 | "send channel (%s) was destroyed - cleaning up\n", | ||
1679 | GNUNET_i2s (peer)); | ||
1680 | peer_ctx->send_channel = NULL; | ||
1681 | } | ||
1682 | else if (channel == peer_ctx->recv_channel) | ||
1683 | { /* Other peer doesn't want to send us messages anymore */ | ||
1684 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1685 | "Peer %s destroyed recv channel - cleaning up channel\n", | ||
1686 | GNUNET_i2s (peer)); | ||
1687 | peer_ctx->recv_channel = NULL; | ||
1688 | } | ||
1689 | else | ||
1690 | { | ||
1691 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1692 | "unknown channel (%s) was destroyed\n", | ||
1693 | GNUNET_i2s (peer)); | ||
1694 | } | ||
1695 | } | ||
1696 | (void) Peers_check_connected (peer); | ||
1697 | } | ||
1698 | |||
1699 | /** | ||
1700 | * @brief Send a message to another peer. | ||
1701 | * | ||
1702 | * Keeps track about pending messages so they can be properly removed when the | ||
1703 | * peer is destroyed. | ||
1704 | * | ||
1705 | * @param peer receeiver of the message | ||
1706 | * @param ev envelope of the message | ||
1707 | * @param type type of the message | ||
1708 | */ | ||
1709 | void | ||
1710 | Peers_send_message (const struct GNUNET_PeerIdentity *peer, | ||
1711 | struct GNUNET_MQ_Envelope *ev, | ||
1712 | const char *type) | ||
1713 | { | ||
1714 | struct PendingMessage *pending_msg; | ||
1715 | struct GNUNET_MQ_Handle *mq; | ||
1716 | |||
1717 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1718 | "Sending message to %s of type %s\n", | ||
1719 | GNUNET_i2s (peer), | ||
1720 | type); | ||
1721 | pending_msg = insert_pending_message (peer, ev, type); | ||
1722 | mq = get_mq (peer); | ||
1723 | GNUNET_MQ_notify_sent (ev, | ||
1724 | mq_notify_sent_cb, | ||
1725 | pending_msg); | ||
1726 | GNUNET_MQ_send (mq, ev); | ||
1727 | } | ||
1728 | |||
1729 | /** | ||
1730 | * @brief Schedule a operation on given peer | ||
1731 | * | ||
1732 | * Avoids scheduling an operation twice. | ||
1733 | * | ||
1734 | * @param peer the peer we want to schedule the operation for once it gets live | ||
1735 | * | ||
1736 | * @return #GNUNET_YES if the operation was scheduled | ||
1737 | * #GNUNET_NO otherwise | ||
1738 | */ | ||
1739 | int | ||
1740 | Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer, | ||
1741 | const PeerOp peer_op) | ||
1742 | { | ||
1743 | struct PeerPendingOp pending_op; | ||
1744 | struct PeerContext *peer_ctx; | ||
1745 | |||
1746 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity)) | ||
1747 | { | ||
1748 | return GNUNET_NO; | ||
1749 | } | ||
1750 | GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); | ||
1751 | |||
1752 | //TODO if LIVE/ONLINE execute immediately | ||
1753 | |||
1754 | if (GNUNET_NO == check_operation_scheduled (peer, peer_op)) | ||
1755 | { | ||
1756 | peer_ctx = get_peer_ctx (peer); | ||
1757 | pending_op.op = peer_op; | ||
1758 | pending_op.op_cls = NULL; | ||
1759 | GNUNET_array_append (peer_ctx->pending_ops, | ||
1760 | peer_ctx->num_pending_ops, | ||
1761 | pending_op); | ||
1762 | return GNUNET_YES; | ||
1763 | } | ||
1764 | return GNUNET_NO; | ||
1765 | } | ||
1766 | |||
1767 | /** | ||
1768 | * @brief Get the recv_channel of @a peer. | ||
1769 | * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming | ||
1770 | * messages. | ||
1771 | * | ||
1772 | * @param peer The peer to get the recv_channel from. | ||
1773 | * | ||
1774 | * @return The recv_channel. | ||
1775 | */ | ||
1776 | struct GNUNET_CADET_Channel * | ||
1777 | Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer) | ||
1778 | { | ||
1779 | struct PeerContext *peer_ctx; | ||
1780 | |||
1781 | GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); | ||
1782 | peer_ctx = get_peer_ctx (peer); | ||
1783 | return peer_ctx->recv_channel; | ||
1784 | } | ||
1785 | /*********************************************************************** | ||
1786 | * /Old gnunet-service-rps_peers.c | ||
1787 | ***********************************************************************/ | ||
1788 | |||
1789 | |||
69 | /*********************************************************************** | 1790 | /*********************************************************************** |
70 | * Housekeeping with clients | 1791 | * Housekeeping with clients |
71 | ***********************************************************************/ | 1792 | ***********************************************************************/ |
@@ -847,6 +2568,7 @@ cleanup_destroyed_channel (void *cls, | |||
847 | { | 2568 | { |
848 | struct GNUNET_PeerIdentity *peer = cls; | 2569 | struct GNUNET_PeerIdentity *peer = cls; |
849 | uint32_t *channel_flag; | 2570 | uint32_t *channel_flag; |
2571 | struct PeerContext *peer_ctx; | ||
850 | 2572 | ||
851 | if (GNUNET_NO == Peers_check_peer_known (peer)) | 2573 | if (GNUNET_NO == Peers_check_peer_known (peer)) |
852 | { /* We don't know a context to that peer */ | 2574 | { /* We don't know a context to that peer */ |
@@ -856,6 +2578,15 @@ cleanup_destroyed_channel (void *cls, | |||
856 | return; | 2578 | return; |
857 | } | 2579 | } |
858 | 2580 | ||
2581 | peer_ctx = get_peer_ctx (peer); | ||
2582 | if (GNUNET_YES == Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_RECEIVING)) | ||
2583 | { | ||
2584 | set_channel_flag (peer_ctx->recv_channel_flags, Peers_CHANNEL_DESTROING); | ||
2585 | } else if (GNUNET_YES == Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_SENDING)) | ||
2586 | { | ||
2587 | set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_DESTROING); | ||
2588 | } | ||
2589 | |||
859 | if (GNUNET_YES == Peers_check_peer_flag (peer, Peers_TO_DESTROY)) | 2590 | if (GNUNET_YES == Peers_check_peer_flag (peer, Peers_TO_DESTROY)) |
860 | { /* We are in the middle of removing that peer from our knowledge. In this | 2591 | { /* We are in the middle of removing that peer from our knowledge. In this |
861 | case simply make sure that the channels are cleaned. */ | 2592 | case simply make sure that the channels are cleaned. */ |
@@ -1121,7 +2852,6 @@ handle_client_request_cancel (void *cls, | |||
1121 | (rep_cls->id != ntohl (msg->id)) ) | 2852 | (rep_cls->id != ntohl (msg->id)) ) |
1122 | rep_cls = rep_cls->next; | 2853 | rep_cls = rep_cls->next; |
1123 | GNUNET_assert (rep_cls->id == ntohl (msg->id)); | 2854 | GNUNET_assert (rep_cls->id == ntohl (msg->id)); |
1124 | RPS_sampler_request_cancel (rep_cls->req_handle); | ||
1125 | destroy_reply_cls (rep_cls); | 2855 | destroy_reply_cls (rep_cls); |
1126 | GNUNET_SERVICE_client_continue (cli_ctx->client); | 2856 | GNUNET_SERVICE_client_continue (cli_ctx->client); |
1127 | } | 2857 | } |
@@ -1239,24 +2969,24 @@ handle_peer_push (void *cls, | |||
1239 | (3 == mal_type) ) | 2969 | (3 == mal_type) ) |
1240 | { /* Try to maximise representation */ | 2970 | { /* Try to maximise representation */ |
1241 | tmp_att_peer = GNUNET_new (struct AttackedPeer); | 2971 | tmp_att_peer = GNUNET_new (struct AttackedPeer); |
1242 | GNUNET_memcpy (&tmp_att_peer->peer_id, peer, sizeof (struct GNUNET_PeerIdentity)); | 2972 | tmp_att_peer->peer_id = *peer; |
1243 | if (NULL == att_peer_set) | 2973 | if (NULL == att_peer_set) |
1244 | att_peer_set = GNUNET_CONTAINER_multipeermap_create (1, GNUNET_NO); | 2974 | att_peer_set = GNUNET_CONTAINER_multipeermap_create (1, GNUNET_NO); |
1245 | if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (att_peer_set, | 2975 | if (GNUNET_NO == |
1246 | peer)) | 2976 | GNUNET_CONTAINER_multipeermap_contains (att_peer_set, |
2977 | peer)) | ||
1247 | { | 2978 | { |
1248 | GNUNET_CONTAINER_DLL_insert (att_peers_head, | 2979 | GNUNET_CONTAINER_DLL_insert (att_peers_head, |
1249 | att_peers_tail, | 2980 | att_peers_tail, |
1250 | tmp_att_peer); | 2981 | tmp_att_peer); |
1251 | add_peer_array_to_set (peer, 1, att_peer_set); | 2982 | add_peer_array_to_set (peer, 1, att_peer_set); |
1252 | } | 2983 | } |
1253 | GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); | ||
1254 | } | 2984 | } |
1255 | 2985 | ||
1256 | 2986 | ||
1257 | else if (2 == mal_type) | 2987 | else if (2 == mal_type) |
1258 | { /* We attack one single well-known peer - simply ignore */ | 2988 | { |
1259 | GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); | 2989 | /* We attack one single well-known peer - simply ignore */ |
1260 | } | 2990 | } |
1261 | #endif /* ENABLE_MALICIOUS */ | 2991 | #endif /* ENABLE_MALICIOUS */ |
1262 | 2992 | ||
@@ -1289,7 +3019,6 @@ handle_peer_pull_request (void *cls, | |||
1289 | || 3 == mal_type) | 3019 | || 3 == mal_type) |
1290 | { /* Try to maximise representation */ | 3020 | { /* Try to maximise representation */ |
1291 | send_pull_reply (peer, mal_peers, num_mal_peers); | 3021 | send_pull_reply (peer, mal_peers, num_mal_peers); |
1292 | GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); | ||
1293 | } | 3022 | } |
1294 | 3023 | ||
1295 | else if (2 == mal_type) | 3024 | else if (2 == mal_type) |
@@ -1298,7 +3027,6 @@ handle_peer_pull_request (void *cls, | |||
1298 | { | 3027 | { |
1299 | send_pull_reply (peer, mal_peers, num_mal_peers); | 3028 | send_pull_reply (peer, mal_peers, num_mal_peers); |
1300 | } | 3029 | } |
1301 | GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); | ||
1302 | } | 3030 | } |
1303 | #endif /* ENABLE_MALICIOUS */ | 3031 | #endif /* ENABLE_MALICIOUS */ |
1304 | 3032 | ||
@@ -1360,7 +3088,7 @@ static void | |||
1360 | handle_peer_pull_reply (void *cls, | 3088 | handle_peer_pull_reply (void *cls, |
1361 | const struct GNUNET_RPS_P2P_PullReplyMessage *msg) | 3089 | const struct GNUNET_RPS_P2P_PullReplyMessage *msg) |
1362 | { | 3090 | { |
1363 | struct GNUNET_PeerIdentity *peers; | 3091 | const struct GNUNET_PeerIdentity *peers; |
1364 | struct GNUNET_PeerIdentity *sender = cls; | 3092 | struct GNUNET_PeerIdentity *sender = cls; |
1365 | uint32_t i; | 3093 | uint32_t i; |
1366 | #ifdef ENABLE_MALICIOUS | 3094 | #ifdef ENABLE_MALICIOUS |
@@ -1373,12 +3101,11 @@ handle_peer_pull_reply (void *cls, | |||
1373 | // We shouldn't even receive pull replies as we're not sending | 3101 | // We shouldn't even receive pull replies as we're not sending |
1374 | if (2 == mal_type) | 3102 | if (2 == mal_type) |
1375 | { | 3103 | { |
1376 | GNUNET_CADET_receive_done (Peers_get_recv_channel (sender)); | ||
1377 | } | 3104 | } |
1378 | #endif /* ENABLE_MALICIOUS */ | 3105 | #endif /* ENABLE_MALICIOUS */ |
1379 | 3106 | ||
1380 | /* Do actual logic */ | 3107 | /* Do actual logic */ |
1381 | peers = (struct GNUNET_PeerIdentity *) &msg[1]; | 3108 | peers = (const struct GNUNET_PeerIdentity *) &msg[1]; |
1382 | 3109 | ||
1383 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 3110 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1384 | "PULL REPLY received, got following %u peers:\n", | 3111 | "PULL REPLY received, got following %u peers:\n", |
@@ -2132,7 +3859,6 @@ shutdown_task (void *cls) | |||
2132 | reply_cls); | 3859 | reply_cls); |
2133 | GNUNET_free (reply_cls); | 3860 | GNUNET_free (reply_cls); |
2134 | } | 3861 | } |
2135 | GNUNET_MQ_destroy (client_ctx->mq); | ||
2136 | GNUNET_CONTAINER_DLL_remove (cli_ctx_head, cli_ctx_tail, client_ctx); | 3862 | GNUNET_CONTAINER_DLL_remove (cli_ctx_head, cli_ctx_tail, client_ctx); |
2137 | GNUNET_free (client_ctx); | 3863 | GNUNET_free (client_ctx); |
2138 | } | 3864 | } |
@@ -2150,6 +3876,7 @@ shutdown_task (void *cls) | |||
2150 | GNUNET_NSE_disconnect (nse); | 3876 | GNUNET_NSE_disconnect (nse); |
2151 | RPS_sampler_destroy (prot_sampler); | 3877 | RPS_sampler_destroy (prot_sampler); |
2152 | RPS_sampler_destroy (client_sampler); | 3878 | RPS_sampler_destroy (client_sampler); |
3879 | GNUNET_CADET_close_port (cadet_port); | ||
2153 | GNUNET_CADET_disconnect (cadet_handle); | 3880 | GNUNET_CADET_disconnect (cadet_handle); |
2154 | View_destroy (); | 3881 | View_destroy (); |
2155 | CustomPeerMap_destroy (push_map); | 3882 | CustomPeerMap_destroy (push_map); |
@@ -2240,26 +3967,6 @@ run (void *cls, | |||
2240 | const struct GNUNET_CONFIGURATION_Handle *c, | 3967 | const struct GNUNET_CONFIGURATION_Handle *c, |
2241 | struct GNUNET_SERVICE_Handle *service) | 3968 | struct GNUNET_SERVICE_Handle *service) |
2242 | { | 3969 | { |
2243 | struct GNUNET_MQ_MessageHandler cadet_handlers[] = { | ||
2244 | GNUNET_MQ_hd_fixed_size (peer_check, | ||
2245 | GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE, | ||
2246 | struct GNUNET_MessageHeader, | ||
2247 | NULL), | ||
2248 | GNUNET_MQ_hd_fixed_size (peer_push, | ||
2249 | GNUNET_MESSAGE_TYPE_RPS_PP_PUSH, | ||
2250 | struct GNUNET_MessageHeader, | ||
2251 | NULL), | ||
2252 | GNUNET_MQ_hd_fixed_size (peer_pull_request, | ||
2253 | GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST, | ||
2254 | struct GNUNET_MessageHeader, | ||
2255 | NULL), | ||
2256 | GNUNET_MQ_hd_var_size (peer_pull_reply, | ||
2257 | GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY, | ||
2258 | struct GNUNET_RPS_P2P_PullReplyMessage, | ||
2259 | NULL), | ||
2260 | GNUNET_MQ_handler_end () | ||
2261 | }; | ||
2262 | |||
2263 | int size; | 3970 | int size; |
2264 | int out_size; | 3971 | int out_size; |
2265 | char* fn_valid_peers; | 3972 | char* fn_valid_peers; |
@@ -2349,6 +4056,27 @@ run (void *cls, | |||
2349 | 4056 | ||
2350 | 4057 | ||
2351 | /* Initialise cadet */ | 4058 | /* Initialise cadet */ |
4059 | /* There exists a copy-paste-clone in get_channel() */ | ||
4060 | struct GNUNET_MQ_MessageHandler cadet_handlers[] = { | ||
4061 | GNUNET_MQ_hd_fixed_size (peer_check, | ||
4062 | GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE, | ||
4063 | struct GNUNET_MessageHeader, | ||
4064 | NULL), | ||
4065 | GNUNET_MQ_hd_fixed_size (peer_push, | ||
4066 | GNUNET_MESSAGE_TYPE_RPS_PP_PUSH, | ||
4067 | struct GNUNET_MessageHeader, | ||
4068 | NULL), | ||
4069 | GNUNET_MQ_hd_fixed_size (peer_pull_request, | ||
4070 | GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST, | ||
4071 | struct GNUNET_MessageHeader, | ||
4072 | NULL), | ||
4073 | GNUNET_MQ_hd_var_size (peer_pull_reply, | ||
4074 | GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY, | ||
4075 | struct GNUNET_RPS_P2P_PullReplyMessage, | ||
4076 | NULL), | ||
4077 | GNUNET_MQ_handler_end () | ||
4078 | }; | ||
4079 | |||
2352 | cadet_handle = GNUNET_CADET_connect (cfg); | 4080 | cadet_handle = GNUNET_CADET_connect (cfg); |
2353 | GNUNET_assert (NULL != cadet_handle); | 4081 | GNUNET_assert (NULL != cadet_handle); |
2354 | GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS, | 4082 | GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS, |
@@ -2365,7 +4093,7 @@ run (void *cls, | |||
2365 | 4093 | ||
2366 | peerinfo_handle = GNUNET_PEERINFO_connect (cfg); | 4094 | peerinfo_handle = GNUNET_PEERINFO_connect (cfg); |
2367 | Peers_initialise (fn_valid_peers, cadet_handle, cleanup_destroyed_channel, | 4095 | Peers_initialise (fn_valid_peers, cadet_handle, cleanup_destroyed_channel, |
2368 | cadet_handlers, &own_identity); | 4096 | &own_identity); |
2369 | GNUNET_free (fn_valid_peers); | 4097 | GNUNET_free (fn_valid_peers); |
2370 | 4098 | ||
2371 | /* Initialise sampler */ | 4099 | /* Initialise sampler */ |
diff --git a/src/rps/gnunet-service-rps_peers.c b/src/rps/gnunet-service-rps_peers.c deleted file mode 100644 index 58aa84ccf..000000000 --- a/src/rps/gnunet-service-rps_peers.c +++ /dev/null | |||
@@ -1,1694 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file rps/gnunet-service-rps_peers.c | ||
23 | * @brief utilities for managing (information about) peers | ||
24 | * @author Julius Bünger | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_applications.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_cadet_service.h" | ||
30 | #include <inttypes.h> | ||
31 | #include "rps.h" | ||
32 | #include "gnunet-service-rps_peers.h" | ||
33 | |||
34 | |||
35 | |||
36 | #define LOG(kind, ...) GNUNET_log_from(kind,"rps-peers",__VA_ARGS__) | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Set a peer flag of given peer context. | ||
41 | */ | ||
42 | #define set_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) |= (mask)) | ||
43 | |||
44 | /** | ||
45 | * Get peer flag of given peer context. | ||
46 | */ | ||
47 | #define check_peer_flag_set(peer_ctx, mask)\ | ||
48 | ((peer_ctx->peer_flags) & (mask) ? GNUNET_YES : GNUNET_NO) | ||
49 | |||
50 | /** | ||
51 | * Unset flag of given peer context. | ||
52 | */ | ||
53 | #define unset_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) &= ~(mask)) | ||
54 | |||
55 | /** | ||
56 | * Set a channel flag of given channel context. | ||
57 | */ | ||
58 | #define set_channel_flag(channel_flags, mask) ((*channel_flags) |= (mask)) | ||
59 | |||
60 | /** | ||
61 | * Get channel flag of given channel context. | ||
62 | */ | ||
63 | #define check_channel_flag_set(channel_flags, mask)\ | ||
64 | ((*channel_flags) & (mask) ? GNUNET_YES : GNUNET_NO) | ||
65 | |||
66 | /** | ||
67 | * Unset flag of given channel context. | ||
68 | */ | ||
69 | #define unset_channel_flag(channel_flags, mask) ((*channel_flags) &= ~(mask)) | ||
70 | |||
71 | |||
72 | |||
73 | /** | ||
74 | * Pending operation on peer consisting of callback and closure | ||
75 | * | ||
76 | * When an operation cannot be executed right now this struct is used to store | ||
77 | * the callback and closure for later execution. | ||
78 | */ | ||
79 | struct PeerPendingOp | ||
80 | { | ||
81 | /** | ||
82 | * Callback | ||
83 | */ | ||
84 | PeerOp op; | ||
85 | |||
86 | /** | ||
87 | * Closure | ||
88 | */ | ||
89 | void *op_cls; | ||
90 | }; | ||
91 | |||
92 | /** | ||
93 | * List containing all messages that are yet to be send | ||
94 | * | ||
95 | * This is used to keep track of all messages that have not been sent yet. When | ||
96 | * a peer is to be removed the pending messages can be removed properly. | ||
97 | */ | ||
98 | struct PendingMessage | ||
99 | { | ||
100 | /** | ||
101 | * DLL next, prev | ||
102 | */ | ||
103 | struct PendingMessage *next; | ||
104 | struct PendingMessage *prev; | ||
105 | |||
106 | /** | ||
107 | * The envelope to the corresponding message | ||
108 | */ | ||
109 | struct GNUNET_MQ_Envelope *ev; | ||
110 | |||
111 | /** | ||
112 | * The corresponding context | ||
113 | */ | ||
114 | struct PeerContext *peer_ctx; | ||
115 | |||
116 | /** | ||
117 | * The message type | ||
118 | */ | ||
119 | const char *type; | ||
120 | }; | ||
121 | |||
122 | /** | ||
123 | * Struct used to keep track of other peer's status | ||
124 | * | ||
125 | * This is stored in a multipeermap. | ||
126 | * It contains information such as cadet channels, a message queue for sending, | ||
127 | * status about the channels, the pending operations on this peer and some flags | ||
128 | * about the status of the peer itself. (live, valid, ...) | ||
129 | */ | ||
130 | struct PeerContext | ||
131 | { | ||
132 | /** | ||
133 | * Message queue open to client | ||
134 | */ | ||
135 | struct GNUNET_MQ_Handle *mq; | ||
136 | |||
137 | /** | ||
138 | * Channel open to client. | ||
139 | */ | ||
140 | struct GNUNET_CADET_Channel *send_channel; | ||
141 | |||
142 | /** | ||
143 | * Flags to the sending channel | ||
144 | */ | ||
145 | uint32_t *send_channel_flags; | ||
146 | |||
147 | /** | ||
148 | * Channel open from client. | ||
149 | */ | ||
150 | struct GNUNET_CADET_Channel *recv_channel; // unneeded? | ||
151 | |||
152 | /** | ||
153 | * Flags to the receiving channel | ||
154 | */ | ||
155 | uint32_t *recv_channel_flags; | ||
156 | |||
157 | /** | ||
158 | * Array of pending operations on this peer. | ||
159 | */ | ||
160 | struct PeerPendingOp *pending_ops; | ||
161 | |||
162 | /** | ||
163 | * Handle to the callback given to cadet_ntfy_tmt_rdy() | ||
164 | * | ||
165 | * To be canceled on shutdown. | ||
166 | */ | ||
167 | struct PendingMessage *liveliness_check_pending; | ||
168 | |||
169 | /** | ||
170 | * Number of pending operations. | ||
171 | */ | ||
172 | unsigned int num_pending_ops; | ||
173 | |||
174 | /** | ||
175 | * Identity of the peer | ||
176 | */ | ||
177 | struct GNUNET_PeerIdentity peer_id; | ||
178 | |||
179 | /** | ||
180 | * Flags indicating status of peer | ||
181 | */ | ||
182 | uint32_t peer_flags; | ||
183 | |||
184 | /** | ||
185 | * Last time we received something from that peer. | ||
186 | */ | ||
187 | struct GNUNET_TIME_Absolute last_message_recv; | ||
188 | |||
189 | /** | ||
190 | * Last time we received a keepalive message. | ||
191 | */ | ||
192 | struct GNUNET_TIME_Absolute last_keepalive; | ||
193 | |||
194 | /** | ||
195 | * DLL with all messages that are yet to be sent | ||
196 | */ | ||
197 | struct PendingMessage *pending_messages_head; | ||
198 | struct PendingMessage *pending_messages_tail; | ||
199 | |||
200 | /** | ||
201 | * This is pobably followed by 'statistical' data (when we first saw | ||
202 | * him, how did we get his ID, how many pushes (in a timeinterval), | ||
203 | * ...) | ||
204 | */ | ||
205 | }; | ||
206 | |||
207 | /** | ||
208 | * @brief Closure to #valid_peer_iterator | ||
209 | */ | ||
210 | struct PeersIteratorCls | ||
211 | { | ||
212 | /** | ||
213 | * Iterator function | ||
214 | */ | ||
215 | PeersIterator iterator; | ||
216 | |||
217 | /** | ||
218 | * Closure to iterator | ||
219 | */ | ||
220 | void *cls; | ||
221 | }; | ||
222 | |||
223 | /** | ||
224 | * @brief Hashmap of valid peers. | ||
225 | */ | ||
226 | static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers; | ||
227 | |||
228 | /** | ||
229 | * @brief Maximum number of valid peers to keep. | ||
230 | * TODO read from config | ||
231 | */ | ||
232 | static uint32_t num_valid_peers_max = UINT32_MAX; | ||
233 | |||
234 | /** | ||
235 | * @brief Filename of the file that stores the valid peers persistently. | ||
236 | */ | ||
237 | static char *filename_valid_peers; | ||
238 | |||
239 | /** | ||
240 | * Set of all peers to keep track of them. | ||
241 | */ | ||
242 | static struct GNUNET_CONTAINER_MultiPeerMap *peer_map; | ||
243 | |||
244 | /** | ||
245 | * Own #GNUNET_PeerIdentity. | ||
246 | */ | ||
247 | static const struct GNUNET_PeerIdentity *own_identity; | ||
248 | |||
249 | /** | ||
250 | * Cadet handle. | ||
251 | */ | ||
252 | static struct GNUNET_CADET_Handle *cadet_handle; | ||
253 | |||
254 | /** | ||
255 | * @brief Disconnect handler | ||
256 | */ | ||
257 | static GNUNET_CADET_DisconnectEventHandler cleanup_destroyed_channel; | ||
258 | |||
259 | /** | ||
260 | * @brief cadet handlers | ||
261 | */ | ||
262 | static const struct GNUNET_MQ_MessageHandler *cadet_handlers; | ||
263 | |||
264 | |||
265 | |||
266 | /** | ||
267 | * @brief Get the #PeerContext associated with a peer | ||
268 | * | ||
269 | * @param peer the peer id | ||
270 | * | ||
271 | * @return the #PeerContext | ||
272 | */ | ||
273 | static struct PeerContext * | ||
274 | get_peer_ctx (const struct GNUNET_PeerIdentity *peer) | ||
275 | { | ||
276 | struct PeerContext *ctx; | ||
277 | int ret; | ||
278 | |||
279 | ret = GNUNET_CONTAINER_multipeermap_contains (peer_map, peer); | ||
280 | GNUNET_assert (GNUNET_YES == ret); | ||
281 | ctx = GNUNET_CONTAINER_multipeermap_get (peer_map, peer); | ||
282 | GNUNET_assert (NULL != ctx); | ||
283 | return ctx; | ||
284 | } | ||
285 | |||
286 | |||
287 | /** | ||
288 | * @brief Create a new #PeerContext and insert it into the peer map | ||
289 | * | ||
290 | * @param peer the peer to create the #PeerContext for | ||
291 | * | ||
292 | * @return the #PeerContext | ||
293 | */ | ||
294 | static struct PeerContext * | ||
295 | create_peer_ctx (const struct GNUNET_PeerIdentity *peer) | ||
296 | { | ||
297 | struct PeerContext *ctx; | ||
298 | int ret; | ||
299 | |||
300 | GNUNET_assert (GNUNET_NO == Peers_check_peer_known (peer)); | ||
301 | |||
302 | ctx = GNUNET_new (struct PeerContext); | ||
303 | ctx->peer_id = *peer; | ||
304 | ctx->send_channel_flags = GNUNET_new (uint32_t); | ||
305 | ctx->recv_channel_flags = GNUNET_new (uint32_t); | ||
306 | ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx, | ||
307 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
308 | GNUNET_assert (GNUNET_OK == ret); | ||
309 | return ctx; | ||
310 | } | ||
311 | |||
312 | |||
313 | /** | ||
314 | * @brief Create or get a #PeerContext | ||
315 | * | ||
316 | * @param peer the peer to get the associated context to | ||
317 | * | ||
318 | * @return the context | ||
319 | */ | ||
320 | static struct PeerContext * | ||
321 | create_or_get_peer_ctx (const struct GNUNET_PeerIdentity *peer) | ||
322 | { | ||
323 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
324 | { | ||
325 | return create_peer_ctx (peer); | ||
326 | } | ||
327 | return get_peer_ctx (peer); | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * @brief Check whether we have a connection to this @a peer | ||
333 | * | ||
334 | * Also sets the #Peers_ONLINE flag accordingly | ||
335 | * | ||
336 | * @param peer the peer in question | ||
337 | * | ||
338 | * @return #GNUNET_YES if we are connected | ||
339 | * #GNUNET_NO otherwise | ||
340 | */ | ||
341 | int | ||
342 | Peers_check_connected (const struct GNUNET_PeerIdentity *peer) | ||
343 | { | ||
344 | const struct PeerContext *peer_ctx; | ||
345 | |||
346 | /* If we don't know about this peer we don't know whether it's online */ | ||
347 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
348 | { | ||
349 | return GNUNET_NO; | ||
350 | } | ||
351 | /* Get the context */ | ||
352 | peer_ctx = get_peer_ctx (peer); | ||
353 | /* If we have no channel to this peer we don't know whether it's online */ | ||
354 | if ( (NULL == peer_ctx->send_channel) && | ||
355 | (NULL == peer_ctx->recv_channel) ) | ||
356 | { | ||
357 | Peers_unset_peer_flag (peer, Peers_ONLINE); | ||
358 | return GNUNET_NO; | ||
359 | } | ||
360 | /* Otherwise (if we have a channel, we know that it's online */ | ||
361 | Peers_set_peer_flag (peer, Peers_ONLINE); | ||
362 | return GNUNET_YES; | ||
363 | } | ||
364 | |||
365 | |||
366 | /** | ||
367 | * @brief The closure to #get_rand_peer_iterator. | ||
368 | */ | ||
369 | struct GetRandPeerIteratorCls | ||
370 | { | ||
371 | /** | ||
372 | * @brief The index of the peer to return. | ||
373 | * Will be decreased until 0. | ||
374 | * Then current peer is returned. | ||
375 | */ | ||
376 | uint32_t index; | ||
377 | |||
378 | /** | ||
379 | * @brief Pointer to peer to return. | ||
380 | */ | ||
381 | const struct GNUNET_PeerIdentity *peer; | ||
382 | }; | ||
383 | |||
384 | |||
385 | /** | ||
386 | * @brief Iterator function for #get_random_peer_from_peermap. | ||
387 | * | ||
388 | * Implements #GNUNET_CONTAINER_PeerMapIterator. | ||
389 | * Decreases the index until the index is null. | ||
390 | * Then returns the current peer. | ||
391 | * | ||
392 | * @param cls the #GetRandPeerIteratorCls containing index and peer | ||
393 | * @param peer current peer | ||
394 | * @param value unused | ||
395 | * | ||
396 | * @return #GNUNET_YES if we should continue to | ||
397 | * iterate, | ||
398 | * #GNUNET_NO if not. | ||
399 | */ | ||
400 | static int | ||
401 | get_rand_peer_iterator (void *cls, | ||
402 | const struct GNUNET_PeerIdentity *peer, | ||
403 | void *value) | ||
404 | { | ||
405 | struct GetRandPeerIteratorCls *iterator_cls = cls; | ||
406 | if (0 >= iterator_cls->index) | ||
407 | { | ||
408 | iterator_cls->peer = peer; | ||
409 | return GNUNET_NO; | ||
410 | } | ||
411 | iterator_cls->index--; | ||
412 | return GNUNET_YES; | ||
413 | } | ||
414 | |||
415 | |||
416 | /** | ||
417 | * @brief Get a random peer from @a peer_map | ||
418 | * | ||
419 | * @param peer_map the peer_map to get the peer from | ||
420 | * | ||
421 | * @return a random peer | ||
422 | */ | ||
423 | static const struct GNUNET_PeerIdentity * | ||
424 | get_random_peer_from_peermap (const struct | ||
425 | GNUNET_CONTAINER_MultiPeerMap *peer_map) | ||
426 | { | ||
427 | struct GetRandPeerIteratorCls *iterator_cls; | ||
428 | const struct GNUNET_PeerIdentity *ret; | ||
429 | |||
430 | iterator_cls = GNUNET_new (struct GetRandPeerIteratorCls); | ||
431 | iterator_cls->index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
432 | GNUNET_CONTAINER_multipeermap_size (peer_map)); | ||
433 | (void) GNUNET_CONTAINER_multipeermap_iterate (valid_peers, | ||
434 | get_rand_peer_iterator, | ||
435 | iterator_cls); | ||
436 | ret = iterator_cls->peer; | ||
437 | GNUNET_free (iterator_cls); | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
443 | * @brief Add a given @a peer to valid peers. | ||
444 | * | ||
445 | * If valid peers are already #num_valid_peers_max, delete a peer previously. | ||
446 | * | ||
447 | * @param peer the peer that is added to the valid peers. | ||
448 | * | ||
449 | * @return #GNUNET_YES if no other peer had to be removed | ||
450 | * #GNUNET_NO otherwise | ||
451 | */ | ||
452 | static int | ||
453 | add_valid_peer (const struct GNUNET_PeerIdentity *peer) | ||
454 | { | ||
455 | const struct GNUNET_PeerIdentity *rand_peer; | ||
456 | int ret; | ||
457 | |||
458 | ret = GNUNET_YES; | ||
459 | while (GNUNET_CONTAINER_multipeermap_size (valid_peers) >= num_valid_peers_max) | ||
460 | { | ||
461 | rand_peer = get_random_peer_from_peermap (valid_peers); | ||
462 | GNUNET_CONTAINER_multipeermap_remove_all (valid_peers, rand_peer); | ||
463 | ret = GNUNET_NO; | ||
464 | } | ||
465 | (void) GNUNET_CONTAINER_multipeermap_put (valid_peers, peer, NULL, | ||
466 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
467 | return ret; | ||
468 | } | ||
469 | |||
470 | |||
471 | /** | ||
472 | * @brief Set the peer flag to living and | ||
473 | * call the pending operations on this peer. | ||
474 | * | ||
475 | * Also adds peer to #valid_peers. | ||
476 | * | ||
477 | * @param peer_ctx the #PeerContext of the peer to set live | ||
478 | */ | ||
479 | static void | ||
480 | set_peer_live (struct PeerContext *peer_ctx) | ||
481 | { | ||
482 | struct GNUNET_PeerIdentity *peer; | ||
483 | unsigned int i; | ||
484 | |||
485 | peer = &peer_ctx->peer_id; | ||
486 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
487 | "Peer %s is live and valid, calling %i pending operations on it\n", | ||
488 | GNUNET_i2s (peer), | ||
489 | peer_ctx->num_pending_ops); | ||
490 | |||
491 | if (NULL != peer_ctx->liveliness_check_pending) | ||
492 | { | ||
493 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
494 | "Removing pending liveliness check for peer %s\n", | ||
495 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
496 | // TODO wait until cadet sets mq->cancel_impl | ||
497 | //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev); | ||
498 | GNUNET_free (peer_ctx->liveliness_check_pending); | ||
499 | peer_ctx->liveliness_check_pending = NULL; | ||
500 | } | ||
501 | |||
502 | (void) add_valid_peer (peer); | ||
503 | set_peer_flag (peer_ctx, Peers_ONLINE); | ||
504 | |||
505 | /* Call pending operations */ | ||
506 | for (i = 0; i < peer_ctx->num_pending_ops; i++) | ||
507 | { | ||
508 | peer_ctx->pending_ops[i].op (peer_ctx->pending_ops[i].op_cls, peer); | ||
509 | } | ||
510 | GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0); | ||
511 | } | ||
512 | |||
513 | |||
514 | /** | ||
515 | * @brief Get the channel of a peer. If not existing, create. | ||
516 | * | ||
517 | * @param peer the peer id | ||
518 | * @return the #GNUNET_CADET_Channel used to send data to @a peer | ||
519 | */ | ||
520 | struct GNUNET_CADET_Channel * | ||
521 | get_channel (const struct GNUNET_PeerIdentity *peer) | ||
522 | { | ||
523 | struct PeerContext *peer_ctx; | ||
524 | struct GNUNET_HashCode port; | ||
525 | |||
526 | peer_ctx = get_peer_ctx (peer); | ||
527 | if (NULL == peer_ctx->send_channel) | ||
528 | { | ||
529 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
530 | "Trying to establish channel to peer %s\n", | ||
531 | GNUNET_i2s (peer)); | ||
532 | GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS, | ||
533 | strlen (GNUNET_APPLICATION_PORT_RPS), | ||
534 | &port); | ||
535 | peer_ctx->send_channel = | ||
536 | GNUNET_CADET_channel_create (cadet_handle, | ||
537 | (struct GNUNET_PeerIdentity *) peer, /* context */ | ||
538 | peer, | ||
539 | &port, | ||
540 | GNUNET_CADET_OPTION_RELIABLE, | ||
541 | NULL, /* WindowSize handler */ | ||
542 | cleanup_destroyed_channel, /* Disconnect handler */ | ||
543 | cadet_handlers); | ||
544 | } | ||
545 | GNUNET_assert (NULL != peer_ctx->send_channel); | ||
546 | return peer_ctx->send_channel; | ||
547 | } | ||
548 | |||
549 | |||
550 | /** | ||
551 | * Get the message queue (#GNUNET_MQ_Handle) of a specific peer. | ||
552 | * | ||
553 | * If we already have a message queue open to this client, | ||
554 | * simply return it, otherways create one. | ||
555 | * | ||
556 | * @param peer the peer to get the mq to | ||
557 | * @return the #GNUNET_MQ_Handle | ||
558 | */ | ||
559 | static struct GNUNET_MQ_Handle * | ||
560 | get_mq (const struct GNUNET_PeerIdentity *peer) | ||
561 | { | ||
562 | struct PeerContext *peer_ctx; | ||
563 | |||
564 | peer_ctx = get_peer_ctx (peer); | ||
565 | |||
566 | if (NULL == peer_ctx->mq) | ||
567 | { | ||
568 | (void) get_channel (peer); | ||
569 | peer_ctx->mq = GNUNET_CADET_get_mq (peer_ctx->send_channel); | ||
570 | } | ||
571 | return peer_ctx->mq; | ||
572 | } | ||
573 | |||
574 | |||
575 | /** | ||
576 | * @brief This is called in response to the first message we sent as a | ||
577 | * liveliness check. | ||
578 | * | ||
579 | * @param cls #PeerContext of peer with pending liveliness check | ||
580 | */ | ||
581 | static void | ||
582 | mq_liveliness_check_successful (void *cls) | ||
583 | { | ||
584 | struct PeerContext *peer_ctx = cls; | ||
585 | |||
586 | if (NULL != peer_ctx->liveliness_check_pending) | ||
587 | { | ||
588 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
589 | "Liveliness check for peer %s was successfull\n", | ||
590 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
591 | GNUNET_free (peer_ctx->liveliness_check_pending); | ||
592 | peer_ctx->liveliness_check_pending = NULL; | ||
593 | set_peer_live (peer_ctx); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | /** | ||
598 | * Issue a check whether peer is live | ||
599 | * | ||
600 | * @param peer_ctx the context of the peer | ||
601 | */ | ||
602 | static void | ||
603 | check_peer_live (struct PeerContext *peer_ctx) | ||
604 | { | ||
605 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
606 | "Get informed about peer %s getting live\n", | ||
607 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
608 | |||
609 | struct GNUNET_MQ_Handle *mq; | ||
610 | struct GNUNET_MQ_Envelope *ev; | ||
611 | |||
612 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE); | ||
613 | peer_ctx->liveliness_check_pending = GNUNET_new (struct PendingMessage); | ||
614 | peer_ctx->liveliness_check_pending->ev = ev; | ||
615 | peer_ctx->liveliness_check_pending->peer_ctx = peer_ctx; | ||
616 | peer_ctx->liveliness_check_pending->type = "Check liveliness"; | ||
617 | mq = get_mq (&peer_ctx->peer_id); | ||
618 | GNUNET_MQ_notify_sent (ev, | ||
619 | mq_liveliness_check_successful, | ||
620 | peer_ctx); | ||
621 | GNUNET_MQ_send (mq, ev); | ||
622 | } | ||
623 | |||
624 | /** | ||
625 | * @brief Add an envelope to a message passed to mq to list of pending messages | ||
626 | * | ||
627 | * @param peer peer the message was sent to | ||
628 | * @param ev envelope to the message | ||
629 | * @param type type of the message to be sent | ||
630 | * @return pointer to pending message | ||
631 | */ | ||
632 | static struct PendingMessage * | ||
633 | insert_pending_message (const struct GNUNET_PeerIdentity *peer, | ||
634 | struct GNUNET_MQ_Envelope *ev, | ||
635 | const char *type) | ||
636 | { | ||
637 | struct PendingMessage *pending_msg; | ||
638 | struct PeerContext *peer_ctx; | ||
639 | |||
640 | peer_ctx = get_peer_ctx (peer); | ||
641 | pending_msg = GNUNET_new (struct PendingMessage); | ||
642 | pending_msg->ev = ev; | ||
643 | pending_msg->peer_ctx = peer_ctx; | ||
644 | pending_msg->type = type; | ||
645 | GNUNET_CONTAINER_DLL_insert (peer_ctx->pending_messages_head, | ||
646 | peer_ctx->pending_messages_tail, | ||
647 | pending_msg); | ||
648 | return pending_msg; | ||
649 | } | ||
650 | |||
651 | |||
652 | /** | ||
653 | * @brief Remove a pending message from the respective DLL | ||
654 | * | ||
655 | * @param pending_msg the pending message to remove | ||
656 | */ | ||
657 | static void | ||
658 | remove_pending_message (struct PendingMessage *pending_msg) | ||
659 | { | ||
660 | struct PeerContext *peer_ctx; | ||
661 | |||
662 | peer_ctx = pending_msg->peer_ctx; | ||
663 | GNUNET_CONTAINER_DLL_remove (peer_ctx->pending_messages_head, | ||
664 | peer_ctx->pending_messages_tail, | ||
665 | pending_msg); | ||
666 | GNUNET_MQ_send_cancel (peer_ctx->pending_messages_head->ev); | ||
667 | GNUNET_free (pending_msg); | ||
668 | } | ||
669 | |||
670 | |||
671 | /** | ||
672 | * @brief Check whether function of type #PeerOp was already scheduled | ||
673 | * | ||
674 | * The array with pending operations will probably never grow really big, so | ||
675 | * iterating over it should be ok. | ||
676 | * | ||
677 | * @param peer the peer to check | ||
678 | * @param peer_op the operation (#PeerOp) on the peer | ||
679 | * | ||
680 | * @return #GNUNET_YES if this operation is scheduled on that peer | ||
681 | * #GNUNET_NO otherwise | ||
682 | */ | ||
683 | static int | ||
684 | check_operation_scheduled (const struct GNUNET_PeerIdentity *peer, | ||
685 | const PeerOp peer_op) | ||
686 | { | ||
687 | const struct PeerContext *peer_ctx; | ||
688 | unsigned int i; | ||
689 | |||
690 | peer_ctx = get_peer_ctx (peer); | ||
691 | for (i = 0; i < peer_ctx->num_pending_ops; i++) | ||
692 | if (peer_op == peer_ctx->pending_ops[i].op) | ||
693 | return GNUNET_YES; | ||
694 | return GNUNET_NO; | ||
695 | } | ||
696 | |||
697 | |||
698 | /** | ||
699 | * Iterator over hash map entries. Deletes all contexts of peers. | ||
700 | * | ||
701 | * @param cls closure | ||
702 | * @param key current public key | ||
703 | * @param value value in the hash map | ||
704 | * @return #GNUNET_YES if we should continue to iterate, | ||
705 | * #GNUNET_NO if not. | ||
706 | */ | ||
707 | static int | ||
708 | peermap_clear_iterator (void *cls, | ||
709 | const struct GNUNET_PeerIdentity *key, | ||
710 | void *value) | ||
711 | { | ||
712 | Peers_remove_peer (key); | ||
713 | return GNUNET_YES; | ||
714 | } | ||
715 | |||
716 | |||
717 | /** | ||
718 | * @brief This is called once a message is sent. | ||
719 | * | ||
720 | * Removes the pending message | ||
721 | * | ||
722 | * @param cls type of the message that was sent | ||
723 | */ | ||
724 | static void | ||
725 | mq_notify_sent_cb (void *cls) | ||
726 | { | ||
727 | struct PendingMessage *pending_msg = (struct PendingMessage *) cls; | ||
728 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
729 | "%s was sent.\n", | ||
730 | pending_msg->type); | ||
731 | remove_pending_message (pending_msg); | ||
732 | } | ||
733 | |||
734 | |||
735 | /** | ||
736 | * @brief Iterator function for #store_valid_peers. | ||
737 | * | ||
738 | * Implements #GNUNET_CONTAINER_PeerMapIterator. | ||
739 | * Writes single peer to disk. | ||
740 | * | ||
741 | * @param cls the file handle to write to. | ||
742 | * @param peer current peer | ||
743 | * @param value unused | ||
744 | * | ||
745 | * @return #GNUNET_YES if we should continue to | ||
746 | * iterate, | ||
747 | * #GNUNET_NO if not. | ||
748 | */ | ||
749 | static int | ||
750 | store_peer_presistently_iterator (void *cls, | ||
751 | const struct GNUNET_PeerIdentity *peer, | ||
752 | void *value) | ||
753 | { | ||
754 | const struct GNUNET_DISK_FileHandle *fh = cls; | ||
755 | char peer_string[128]; | ||
756 | int size; | ||
757 | ssize_t ret; | ||
758 | |||
759 | if (NULL == peer) | ||
760 | { | ||
761 | return GNUNET_YES; | ||
762 | } | ||
763 | size = GNUNET_snprintf (peer_string, | ||
764 | sizeof (peer_string), | ||
765 | "%s\n", | ||
766 | GNUNET_i2s_full (peer)); | ||
767 | GNUNET_assert (53 == size); | ||
768 | ret = GNUNET_DISK_file_write (fh, | ||
769 | peer_string, | ||
770 | size); | ||
771 | GNUNET_assert (size == ret); | ||
772 | return GNUNET_YES; | ||
773 | } | ||
774 | |||
775 | |||
776 | /** | ||
777 | * @brief Store the peers currently in #valid_peers to disk. | ||
778 | */ | ||
779 | static void | ||
780 | store_valid_peers () | ||
781 | { | ||
782 | struct GNUNET_DISK_FileHandle *fh; | ||
783 | uint32_t number_written_peers; | ||
784 | int ret; | ||
785 | |||
786 | if (0 == strncmp ("DISABLE", filename_valid_peers, 7)) | ||
787 | { | ||
788 | return; | ||
789 | } | ||
790 | |||
791 | ret = GNUNET_DISK_directory_create_for_file (filename_valid_peers); | ||
792 | if (GNUNET_SYSERR == ret) | ||
793 | { | ||
794 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
795 | "Not able to create directory for file `%s'\n", | ||
796 | filename_valid_peers); | ||
797 | GNUNET_break (0); | ||
798 | } | ||
799 | else if (GNUNET_NO == ret) | ||
800 | { | ||
801 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
802 | "Directory for file `%s' exists but is not writable for us\n", | ||
803 | filename_valid_peers); | ||
804 | GNUNET_break (0); | ||
805 | } | ||
806 | fh = GNUNET_DISK_file_open (filename_valid_peers, | ||
807 | GNUNET_DISK_OPEN_WRITE | | ||
808 | GNUNET_DISK_OPEN_CREATE, | ||
809 | GNUNET_DISK_PERM_USER_READ | | ||
810 | GNUNET_DISK_PERM_USER_WRITE); | ||
811 | if (NULL == fh) | ||
812 | { | ||
813 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
814 | "Not able to write valid peers to file `%s'\n", | ||
815 | filename_valid_peers); | ||
816 | return; | ||
817 | } | ||
818 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
819 | "Writing %u valid peers to disk\n", | ||
820 | GNUNET_CONTAINER_multipeermap_size (valid_peers)); | ||
821 | number_written_peers = | ||
822 | GNUNET_CONTAINER_multipeermap_iterate (valid_peers, | ||
823 | store_peer_presistently_iterator, | ||
824 | fh); | ||
825 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); | ||
826 | GNUNET_assert (number_written_peers == | ||
827 | GNUNET_CONTAINER_multipeermap_size (valid_peers)); | ||
828 | } | ||
829 | |||
830 | |||
831 | /** | ||
832 | * @brief Convert string representation of peer id to peer id. | ||
833 | * | ||
834 | * Counterpart to #GNUNET_i2s_full. | ||
835 | * | ||
836 | * @param string_repr The string representation of the peer id | ||
837 | * | ||
838 | * @return The peer id | ||
839 | */ | ||
840 | static const struct GNUNET_PeerIdentity * | ||
841 | s2i_full (const char *string_repr) | ||
842 | { | ||
843 | struct GNUNET_PeerIdentity *peer; | ||
844 | size_t len; | ||
845 | int ret; | ||
846 | |||
847 | peer = GNUNET_new (struct GNUNET_PeerIdentity); | ||
848 | len = strlen (string_repr); | ||
849 | if (52 > len) | ||
850 | { | ||
851 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
852 | "Not able to convert string representation of PeerID to PeerID\n" | ||
853 | "Sting representation: %s (len %u) - too short\n", | ||
854 | string_repr, | ||
855 | len); | ||
856 | GNUNET_break (0); | ||
857 | } | ||
858 | else if (52 < len) | ||
859 | { | ||
860 | len = 52; | ||
861 | } | ||
862 | ret = GNUNET_CRYPTO_eddsa_public_key_from_string (string_repr, | ||
863 | len, | ||
864 | &peer->public_key); | ||
865 | if (GNUNET_OK != ret) | ||
866 | { | ||
867 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
868 | "Not able to convert string representation of PeerID to PeerID\n" | ||
869 | "Sting representation: %s\n", | ||
870 | string_repr); | ||
871 | GNUNET_break (0); | ||
872 | } | ||
873 | return peer; | ||
874 | } | ||
875 | |||
876 | |||
877 | /** | ||
878 | * @brief Restore the peers on disk to #valid_peers. | ||
879 | */ | ||
880 | static void | ||
881 | restore_valid_peers () | ||
882 | { | ||
883 | off_t file_size; | ||
884 | uint32_t num_peers; | ||
885 | struct GNUNET_DISK_FileHandle *fh; | ||
886 | char *buf; | ||
887 | ssize_t size_read; | ||
888 | char *iter_buf; | ||
889 | char *str_repr; | ||
890 | const struct GNUNET_PeerIdentity *peer; | ||
891 | |||
892 | if (0 == strncmp ("DISABLE", filename_valid_peers, 7)) | ||
893 | { | ||
894 | return; | ||
895 | } | ||
896 | |||
897 | if (GNUNET_OK != GNUNET_DISK_file_test (filename_valid_peers)) | ||
898 | { | ||
899 | return; | ||
900 | } | ||
901 | fh = GNUNET_DISK_file_open (filename_valid_peers, | ||
902 | GNUNET_DISK_OPEN_READ, | ||
903 | GNUNET_DISK_PERM_NONE); | ||
904 | GNUNET_assert (NULL != fh); | ||
905 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &file_size)); | ||
906 | num_peers = file_size / 53; | ||
907 | buf = GNUNET_malloc (file_size); | ||
908 | size_read = GNUNET_DISK_file_read (fh, buf, file_size); | ||
909 | GNUNET_assert (size_read == file_size); | ||
910 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
911 | "Restoring %" PRIu32 " peers from file `%s'\n", | ||
912 | num_peers, | ||
913 | filename_valid_peers); | ||
914 | for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53) | ||
915 | { | ||
916 | str_repr = GNUNET_strndup (iter_buf, 53); | ||
917 | peer = s2i_full (str_repr); | ||
918 | GNUNET_free (str_repr); | ||
919 | add_valid_peer (peer); | ||
920 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
921 | "Restored valid peer %s from disk\n", | ||
922 | GNUNET_i2s_full (peer)); | ||
923 | } | ||
924 | iter_buf = NULL; | ||
925 | GNUNET_free (buf); | ||
926 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
927 | "num_peers: %" PRIu32 ", _size (valid_peers): %u\n", | ||
928 | num_peers, | ||
929 | GNUNET_CONTAINER_multipeermap_size (valid_peers)); | ||
930 | if (num_peers != GNUNET_CONTAINER_multipeermap_size (valid_peers)) | ||
931 | { | ||
932 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
933 | "Number of restored peers does not match file size. Have probably duplicates.\n"); | ||
934 | } | ||
935 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); | ||
936 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
937 | "Restored %u valid peers from disk\n", | ||
938 | GNUNET_CONTAINER_multipeermap_size (valid_peers)); | ||
939 | } | ||
940 | |||
941 | |||
942 | /** | ||
943 | * @brief Initialise storage of peers | ||
944 | * | ||
945 | * @param fn_valid_peers filename of the file used to store valid peer ids | ||
946 | * @param cadet_h cadet handle | ||
947 | * @param disconnect_handler Disconnect handler | ||
948 | * @param c_handlers cadet handlers | ||
949 | * @param own_id own peer identity | ||
950 | */ | ||
951 | void | ||
952 | Peers_initialise (char* fn_valid_peers, | ||
953 | struct GNUNET_CADET_Handle *cadet_h, | ||
954 | GNUNET_CADET_DisconnectEventHandler disconnect_handler, | ||
955 | const struct GNUNET_MQ_MessageHandler *c_handlers, | ||
956 | const struct GNUNET_PeerIdentity *own_id) | ||
957 | { | ||
958 | filename_valid_peers = GNUNET_strdup (fn_valid_peers); | ||
959 | cadet_handle = cadet_h; | ||
960 | cleanup_destroyed_channel = disconnect_handler; | ||
961 | cadet_handlers = c_handlers; | ||
962 | own_identity = own_id; | ||
963 | peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); | ||
964 | valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); | ||
965 | restore_valid_peers (); | ||
966 | } | ||
967 | |||
968 | |||
969 | /** | ||
970 | * @brief Delete storage of peers that was created with #Peers_initialise () | ||
971 | */ | ||
972 | void | ||
973 | Peers_terminate () | ||
974 | { | ||
975 | if (GNUNET_SYSERR == | ||
976 | GNUNET_CONTAINER_multipeermap_iterate (peer_map, | ||
977 | peermap_clear_iterator, | ||
978 | NULL)) | ||
979 | { | ||
980 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
981 | "Iteration destroying peers was aborted.\n"); | ||
982 | } | ||
983 | GNUNET_CONTAINER_multipeermap_destroy (peer_map); | ||
984 | store_valid_peers (); | ||
985 | GNUNET_free (filename_valid_peers); | ||
986 | GNUNET_CONTAINER_multipeermap_destroy (valid_peers); | ||
987 | } | ||
988 | |||
989 | |||
990 | /** | ||
991 | * Iterator over #valid_peers hash map entries. | ||
992 | * | ||
993 | * @param cls closure - unused | ||
994 | * @param peer current peer id | ||
995 | * @param value value in the hash map - unused | ||
996 | * @return #GNUNET_YES if we should continue to | ||
997 | * iterate, | ||
998 | * #GNUNET_NO if not. | ||
999 | */ | ||
1000 | static int | ||
1001 | valid_peer_iterator (void *cls, | ||
1002 | const struct GNUNET_PeerIdentity *peer, | ||
1003 | void *value) | ||
1004 | { | ||
1005 | struct PeersIteratorCls *it_cls = cls; | ||
1006 | |||
1007 | return it_cls->iterator (it_cls->cls, | ||
1008 | peer); | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | /** | ||
1013 | * @brief Get all currently known, valid peer ids. | ||
1014 | * | ||
1015 | * @param it function to call on each peer id | ||
1016 | * @param it_cls extra argument to @a it | ||
1017 | * @return the number of key value pairs processed, | ||
1018 | * #GNUNET_SYSERR if it aborted iteration | ||
1019 | */ | ||
1020 | int | ||
1021 | Peers_get_valid_peers (PeersIterator iterator, | ||
1022 | void *it_cls) | ||
1023 | { | ||
1024 | struct PeersIteratorCls *cls; | ||
1025 | int ret; | ||
1026 | |||
1027 | cls = GNUNET_new (struct PeersIteratorCls); | ||
1028 | cls->iterator = iterator; | ||
1029 | cls->cls = it_cls; | ||
1030 | ret = GNUNET_CONTAINER_multipeermap_iterate (valid_peers, | ||
1031 | valid_peer_iterator, | ||
1032 | cls); | ||
1033 | GNUNET_free (cls); | ||
1034 | return ret; | ||
1035 | } | ||
1036 | |||
1037 | |||
1038 | /** | ||
1039 | * @brief Add peer to known peers. | ||
1040 | * | ||
1041 | * This function is called on new peer_ids from 'external' sources | ||
1042 | * (client seed, cadet get_peers(), ...) | ||
1043 | * | ||
1044 | * @param peer the new #GNUNET_PeerIdentity | ||
1045 | * | ||
1046 | * @return #GNUNET_YES if peer was inserted | ||
1047 | * #GNUNET_NO otherwise (if peer was already known or | ||
1048 | * peer was #own_identity) | ||
1049 | */ | ||
1050 | int | ||
1051 | Peers_insert_peer (const struct GNUNET_PeerIdentity *peer) | ||
1052 | { | ||
1053 | if ( (GNUNET_YES == Peers_check_peer_known (peer)) || | ||
1054 | (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, own_identity)) ) | ||
1055 | { | ||
1056 | return GNUNET_NO; /* We already know this peer - nothing to do */ | ||
1057 | } | ||
1058 | (void) create_peer_ctx (peer); | ||
1059 | return GNUNET_YES; | ||
1060 | } | ||
1061 | |||
1062 | |||
1063 | /** | ||
1064 | * @brief Try connecting to a peer to see whether it is online | ||
1065 | * | ||
1066 | * If not known yet, insert into known peers | ||
1067 | * | ||
1068 | * @param peer the peer whose liveliness is to be checked | ||
1069 | * @return #GNUNET_YES if peer had to be inserted | ||
1070 | * #GNUNET_NO otherwise (if peer was already known or | ||
1071 | * peer was #own_identity) | ||
1072 | */ | ||
1073 | int | ||
1074 | Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer) | ||
1075 | { | ||
1076 | struct PeerContext *peer_ctx; | ||
1077 | int ret; | ||
1078 | |||
1079 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, own_identity)) | ||
1080 | { | ||
1081 | return GNUNET_NO; | ||
1082 | } | ||
1083 | ret = Peers_insert_peer (peer); | ||
1084 | peer_ctx = get_peer_ctx (peer); | ||
1085 | if (GNUNET_NO == Peers_check_peer_flag (peer, Peers_ONLINE)) | ||
1086 | { | ||
1087 | check_peer_live (peer_ctx); | ||
1088 | } | ||
1089 | return ret; | ||
1090 | } | ||
1091 | |||
1092 | |||
1093 | /** | ||
1094 | * @brief Check if peer is removable. | ||
1095 | * | ||
1096 | * Check if | ||
1097 | * - a recv channel exists | ||
1098 | * - there are pending messages | ||
1099 | * - there is no pending pull reply | ||
1100 | * | ||
1101 | * @param peer the peer in question | ||
1102 | * @return #GNUNET_YES if peer is removable | ||
1103 | * #GNUNET_NO if peer is NOT removable | ||
1104 | * #GNUNET_SYSERR if peer is not known | ||
1105 | */ | ||
1106 | int | ||
1107 | Peers_check_removable (const struct GNUNET_PeerIdentity *peer) | ||
1108 | { | ||
1109 | struct PeerContext *peer_ctx; | ||
1110 | |||
1111 | if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) | ||
1112 | { | ||
1113 | return GNUNET_SYSERR; | ||
1114 | } | ||
1115 | |||
1116 | peer_ctx = get_peer_ctx (peer); | ||
1117 | if ( (NULL != peer_ctx->recv_channel) || | ||
1118 | (NULL != peer_ctx->pending_messages_head) || | ||
1119 | (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) ) | ||
1120 | { | ||
1121 | return GNUNET_NO; | ||
1122 | } | ||
1123 | return GNUNET_YES; | ||
1124 | } | ||
1125 | |||
1126 | |||
1127 | /** | ||
1128 | * @brief Remove peer | ||
1129 | * | ||
1130 | * @param peer the peer to clean | ||
1131 | * @return #GNUNET_YES if peer was removed | ||
1132 | * #GNUNET_NO otherwise | ||
1133 | */ | ||
1134 | int | ||
1135 | Peers_remove_peer (const struct GNUNET_PeerIdentity *peer) | ||
1136 | { | ||
1137 | struct PeerContext *peer_ctx; | ||
1138 | |||
1139 | if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) | ||
1140 | { | ||
1141 | return GNUNET_NO; | ||
1142 | } | ||
1143 | |||
1144 | peer_ctx = get_peer_ctx (peer); | ||
1145 | set_peer_flag (peer_ctx, Peers_TO_DESTROY); | ||
1146 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1147 | "Going to remove peer %s\n", | ||
1148 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
1149 | Peers_unset_peer_flag (peer, Peers_ONLINE); | ||
1150 | |||
1151 | GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0); | ||
1152 | while (NULL != peer_ctx->pending_messages_head) | ||
1153 | { | ||
1154 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1155 | "Removing unsent %s\n", | ||
1156 | peer_ctx->pending_messages_head->type); | ||
1157 | remove_pending_message (peer_ctx->pending_messages_head); | ||
1158 | } | ||
1159 | /* If we are still waiting for notification whether this peer is live | ||
1160 | * cancel the according task */ | ||
1161 | if (NULL != peer_ctx->liveliness_check_pending) | ||
1162 | { | ||
1163 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1164 | "Removing pending liveliness check for peer %s\n", | ||
1165 | GNUNET_i2s (&peer_ctx->peer_id)); | ||
1166 | // TODO wait until cadet sets mq->cancel_impl | ||
1167 | //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev); | ||
1168 | GNUNET_free (peer_ctx->liveliness_check_pending); | ||
1169 | peer_ctx->liveliness_check_pending = NULL; | ||
1170 | } | ||
1171 | if (NULL != peer_ctx->send_channel) | ||
1172 | { | ||
1173 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1174 | "Destroying send channel\n"); | ||
1175 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | ||
1176 | peer_ctx->send_channel = NULL; | ||
1177 | } | ||
1178 | if (NULL != peer_ctx->recv_channel) | ||
1179 | { | ||
1180 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1181 | "Destroying recv channel\n"); | ||
1182 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); | ||
1183 | peer_ctx->recv_channel = NULL; | ||
1184 | } | ||
1185 | if (NULL != peer_ctx->mq) | ||
1186 | { | ||
1187 | GNUNET_MQ_destroy (peer_ctx->mq); | ||
1188 | peer_ctx->mq = NULL; | ||
1189 | } | ||
1190 | |||
1191 | GNUNET_free (peer_ctx->send_channel_flags); | ||
1192 | GNUNET_free (peer_ctx->recv_channel_flags); | ||
1193 | |||
1194 | if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, &peer_ctx->peer_id)) | ||
1195 | { | ||
1196 | LOG (GNUNET_ERROR_TYPE_WARNING, "removing peer from peer_map failed\n"); | ||
1197 | } | ||
1198 | GNUNET_free (peer_ctx); | ||
1199 | return GNUNET_YES; | ||
1200 | } | ||
1201 | |||
1202 | |||
1203 | /** | ||
1204 | * @brief set flags on a given peer. | ||
1205 | * | ||
1206 | * @param peer the peer to set flags on | ||
1207 | * @param flags the flags | ||
1208 | */ | ||
1209 | void | ||
1210 | Peers_set_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags) | ||
1211 | { | ||
1212 | struct PeerContext *peer_ctx; | ||
1213 | |||
1214 | peer_ctx = get_peer_ctx (peer); | ||
1215 | set_peer_flag (peer_ctx, flags); | ||
1216 | } | ||
1217 | |||
1218 | |||
1219 | /** | ||
1220 | * @brief unset flags on a given peer. | ||
1221 | * | ||
1222 | * @param peer the peer to unset flags on | ||
1223 | * @param flags the flags | ||
1224 | */ | ||
1225 | void | ||
1226 | Peers_unset_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags) | ||
1227 | { | ||
1228 | struct PeerContext *peer_ctx; | ||
1229 | |||
1230 | peer_ctx = get_peer_ctx (peer); | ||
1231 | unset_peer_flag (peer_ctx, flags); | ||
1232 | } | ||
1233 | |||
1234 | |||
1235 | /** | ||
1236 | * @brief Check whether flags on a peer are set. | ||
1237 | * | ||
1238 | * @param peer the peer to check the flag of | ||
1239 | * @param flags the flags to check | ||
1240 | * | ||
1241 | * @return #GNUNET_SYSERR if peer is not known | ||
1242 | * #GNUNET_YES if all given flags are set | ||
1243 | * #GNUNET_NO otherwise | ||
1244 | */ | ||
1245 | int | ||
1246 | Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags) | ||
1247 | { | ||
1248 | struct PeerContext *peer_ctx; | ||
1249 | |||
1250 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1251 | { | ||
1252 | return GNUNET_SYSERR; | ||
1253 | } | ||
1254 | peer_ctx = get_peer_ctx (peer); | ||
1255 | return check_peer_flag_set (peer_ctx, flags); | ||
1256 | } | ||
1257 | |||
1258 | |||
1259 | /** | ||
1260 | * @brief set flags on a given channel. | ||
1261 | * | ||
1262 | * @param channel the channel to set flags on | ||
1263 | * @param flags the flags | ||
1264 | */ | ||
1265 | void | ||
1266 | Peers_set_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags) | ||
1267 | { | ||
1268 | set_channel_flag (channel_flags, flags); | ||
1269 | } | ||
1270 | |||
1271 | |||
1272 | /** | ||
1273 | * @brief unset flags on a given channel. | ||
1274 | * | ||
1275 | * @param channel the channel to unset flags on | ||
1276 | * @param flags the flags | ||
1277 | */ | ||
1278 | void | ||
1279 | Peers_unset_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags) | ||
1280 | { | ||
1281 | unset_channel_flag (channel_flags, flags); | ||
1282 | } | ||
1283 | |||
1284 | |||
1285 | /** | ||
1286 | * @brief Check whether flags on a channel are set. | ||
1287 | * | ||
1288 | * @param channel the channel to check the flag of | ||
1289 | * @param flags the flags to check | ||
1290 | * | ||
1291 | * @return #GNUNET_YES if all given flags are set | ||
1292 | * #GNUNET_NO otherwise | ||
1293 | */ | ||
1294 | int | ||
1295 | Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags) | ||
1296 | { | ||
1297 | return check_channel_flag_set (channel_flags, flags); | ||
1298 | } | ||
1299 | |||
1300 | /** | ||
1301 | * @brief Get the flags for the channel in @a role for @a peer. | ||
1302 | * | ||
1303 | * @param peer Peer to get the channel flags for. | ||
1304 | * @param role Role of channel to get flags for | ||
1305 | * | ||
1306 | * @return The flags. | ||
1307 | */ | ||
1308 | uint32_t * | ||
1309 | Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer, | ||
1310 | enum Peers_ChannelRole role) | ||
1311 | { | ||
1312 | const struct PeerContext *peer_ctx; | ||
1313 | |||
1314 | peer_ctx = get_peer_ctx (peer); | ||
1315 | if (Peers_CHANNEL_ROLE_SENDING == role) | ||
1316 | { | ||
1317 | return peer_ctx->send_channel_flags; | ||
1318 | } | ||
1319 | else if (Peers_CHANNEL_ROLE_RECEIVING == role) | ||
1320 | { | ||
1321 | return peer_ctx->recv_channel_flags; | ||
1322 | } | ||
1323 | else | ||
1324 | { | ||
1325 | GNUNET_assert (0); | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | /** | ||
1330 | * @brief Check whether we have information about the given peer. | ||
1331 | * | ||
1332 | * FIXME probably deprecated. Make this the new _online. | ||
1333 | * | ||
1334 | * @param peer peer in question | ||
1335 | * | ||
1336 | * @return #GNUNET_YES if peer is known | ||
1337 | * #GNUNET_NO if peer is not knwon | ||
1338 | */ | ||
1339 | int | ||
1340 | Peers_check_peer_known (const struct GNUNET_PeerIdentity *peer) | ||
1341 | { | ||
1342 | return GNUNET_CONTAINER_multipeermap_contains (peer_map, peer); | ||
1343 | } | ||
1344 | |||
1345 | |||
1346 | /** | ||
1347 | * @brief Check whether @a peer is actually a peer. | ||
1348 | * | ||
1349 | * A valid peer is a peer that we know exists eg. we were connected to once. | ||
1350 | * | ||
1351 | * @param peer peer in question | ||
1352 | * | ||
1353 | * @return #GNUNET_YES if peer is valid | ||
1354 | * #GNUNET_NO if peer is not valid | ||
1355 | */ | ||
1356 | int | ||
1357 | Peers_check_peer_valid (const struct GNUNET_PeerIdentity *peer) | ||
1358 | { | ||
1359 | return GNUNET_CONTAINER_multipeermap_contains (valid_peers, peer); | ||
1360 | } | ||
1361 | |||
1362 | |||
1363 | /** | ||
1364 | * @brief Indicate that we want to send to the other peer | ||
1365 | * | ||
1366 | * This establishes a sending channel | ||
1367 | * | ||
1368 | * @param peer the peer to establish channel to | ||
1369 | */ | ||
1370 | void | ||
1371 | Peers_indicate_sending_intention (const struct GNUNET_PeerIdentity *peer) | ||
1372 | { | ||
1373 | GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); | ||
1374 | (void) get_channel (peer); | ||
1375 | } | ||
1376 | |||
1377 | |||
1378 | /** | ||
1379 | * @brief Check whether other peer has the intention to send/opened channel | ||
1380 | * towars us | ||
1381 | * | ||
1382 | * @param peer the peer in question | ||
1383 | * | ||
1384 | * @return #GNUNET_YES if peer has the intention to send | ||
1385 | * #GNUNET_NO otherwise | ||
1386 | */ | ||
1387 | int | ||
1388 | Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer) | ||
1389 | { | ||
1390 | const struct PeerContext *peer_ctx; | ||
1391 | |||
1392 | peer_ctx = get_peer_ctx (peer); | ||
1393 | if (NULL != peer_ctx->recv_channel) | ||
1394 | { | ||
1395 | return GNUNET_YES; | ||
1396 | } | ||
1397 | return GNUNET_NO; | ||
1398 | } | ||
1399 | |||
1400 | |||
1401 | /** | ||
1402 | * Handle the channel a peer opens to us. | ||
1403 | * | ||
1404 | * @param cls The closure | ||
1405 | * @param channel The channel the peer wants to establish | ||
1406 | * @param initiator The peer's peer ID | ||
1407 | * | ||
1408 | * @return initial channel context for the channel | ||
1409 | * (can be NULL -- that's not an error) | ||
1410 | */ | ||
1411 | void * | ||
1412 | Peers_handle_inbound_channel (void *cls, | ||
1413 | struct GNUNET_CADET_Channel *channel, | ||
1414 | const struct GNUNET_PeerIdentity *initiator) | ||
1415 | { | ||
1416 | struct PeerContext *peer_ctx; | ||
1417 | |||
1418 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1419 | "New channel was established to us (Peer %s).\n", | ||
1420 | GNUNET_i2s (initiator)); | ||
1421 | GNUNET_assert (NULL != channel); /* according to cadet API */ | ||
1422 | /* Make sure we 'know' about this peer */ | ||
1423 | peer_ctx = create_or_get_peer_ctx (initiator); | ||
1424 | set_peer_live (peer_ctx); | ||
1425 | /* We only accept one incoming channel per peer */ | ||
1426 | if (GNUNET_YES == Peers_check_peer_send_intention (initiator)) | ||
1427 | { | ||
1428 | set_channel_flag (peer_ctx->recv_channel_flags, | ||
1429 | Peers_CHANNEL_ESTABLISHED_TWICE); | ||
1430 | GNUNET_CADET_channel_destroy (channel); | ||
1431 | /* return the channel context */ | ||
1432 | return &peer_ctx->peer_id; | ||
1433 | } | ||
1434 | peer_ctx->recv_channel = channel; | ||
1435 | return &peer_ctx->peer_id; | ||
1436 | } | ||
1437 | |||
1438 | |||
1439 | /** | ||
1440 | * @brief Check whether a sending channel towards the given peer exists | ||
1441 | * | ||
1442 | * @param peer the peer to check for | ||
1443 | * | ||
1444 | * @return #GNUNET_YES if a sending channel towards that peer exists | ||
1445 | * #GNUNET_NO otherwise | ||
1446 | */ | ||
1447 | int | ||
1448 | Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer) | ||
1449 | { | ||
1450 | struct PeerContext *peer_ctx; | ||
1451 | |||
1452 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1453 | { /* If no such peer exists, there is no channel */ | ||
1454 | return GNUNET_NO; | ||
1455 | } | ||
1456 | peer_ctx = get_peer_ctx (peer); | ||
1457 | if (NULL == peer_ctx->send_channel) | ||
1458 | { | ||
1459 | return GNUNET_NO; | ||
1460 | } | ||
1461 | return GNUNET_YES; | ||
1462 | } | ||
1463 | |||
1464 | |||
1465 | /** | ||
1466 | * @brief check whether the given channel is the sending channel of the given | ||
1467 | * peer | ||
1468 | * | ||
1469 | * @param peer the peer in question | ||
1470 | * @param channel the channel to check for | ||
1471 | * @param role either #Peers_CHANNEL_ROLE_SENDING, or | ||
1472 | * #Peers_CHANNEL_ROLE_RECEIVING | ||
1473 | * | ||
1474 | * @return #GNUNET_YES if the given chennel is the sending channel of the peer | ||
1475 | * #GNUNET_NO otherwise | ||
1476 | */ | ||
1477 | int | ||
1478 | Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer, | ||
1479 | const struct GNUNET_CADET_Channel *channel, | ||
1480 | enum Peers_ChannelRole role) | ||
1481 | { | ||
1482 | const struct PeerContext *peer_ctx; | ||
1483 | |||
1484 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1485 | { | ||
1486 | return GNUNET_NO; | ||
1487 | } | ||
1488 | peer_ctx = get_peer_ctx (peer); | ||
1489 | if ( (Peers_CHANNEL_ROLE_SENDING == role) && | ||
1490 | (channel == peer_ctx->send_channel) ) | ||
1491 | { | ||
1492 | return GNUNET_YES; | ||
1493 | } | ||
1494 | if ( (Peers_CHANNEL_ROLE_RECEIVING == role) && | ||
1495 | (channel == peer_ctx->recv_channel) ) | ||
1496 | { | ||
1497 | return GNUNET_YES; | ||
1498 | } | ||
1499 | return GNUNET_NO; | ||
1500 | } | ||
1501 | |||
1502 | |||
1503 | /** | ||
1504 | * @brief Destroy the send channel of a peer e.g. stop indicating a sending | ||
1505 | * intention to another peer | ||
1506 | * | ||
1507 | * If there is also no channel to receive messages from that peer, remove it | ||
1508 | * from the peermap. | ||
1509 | * TODO really? | ||
1510 | * | ||
1511 | * @peer the peer identity of the peer whose sending channel to destroy | ||
1512 | * @return #GNUNET_YES if channel was destroyed | ||
1513 | * #GNUNET_NO otherwise | ||
1514 | */ | ||
1515 | int | ||
1516 | Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer) | ||
1517 | { | ||
1518 | struct PeerContext *peer_ctx; | ||
1519 | |||
1520 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1521 | { | ||
1522 | return GNUNET_NO; | ||
1523 | } | ||
1524 | peer_ctx = get_peer_ctx (peer); | ||
1525 | if (NULL != peer_ctx->send_channel) | ||
1526 | { | ||
1527 | set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_CLEAN); | ||
1528 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | ||
1529 | peer_ctx->send_channel = NULL; | ||
1530 | (void) Peers_check_connected (peer); | ||
1531 | return GNUNET_YES; | ||
1532 | } | ||
1533 | return GNUNET_NO; | ||
1534 | } | ||
1535 | |||
1536 | /** | ||
1537 | * This is called when a channel is destroyed. | ||
1538 | * | ||
1539 | * @param cls The closure | ||
1540 | * @param channel The channel being closed | ||
1541 | * @param channel_ctx The context associated with this channel | ||
1542 | */ | ||
1543 | void | ||
1544 | Peers_cleanup_destroyed_channel (void *cls, | ||
1545 | const struct GNUNET_CADET_Channel *channel) | ||
1546 | { | ||
1547 | struct GNUNET_PeerIdentity *peer = cls; | ||
1548 | struct PeerContext *peer_ctx; | ||
1549 | |||
1550 | if (GNUNET_NO == Peers_check_peer_known (peer)) | ||
1551 | {/* We don't want to implicitly create a context that we're about to kill */ | ||
1552 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1553 | "channel (%s) without associated context was destroyed\n", | ||
1554 | GNUNET_i2s (peer)); | ||
1555 | return; | ||
1556 | } | ||
1557 | peer_ctx = get_peer_ctx (peer); | ||
1558 | |||
1559 | /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY | ||
1560 | * flag will be set. In this case simply make sure that the channels are | ||
1561 | * cleaned. */ | ||
1562 | /* FIXME This distinction seems to be redundant */ | ||
1563 | if (Peers_check_peer_flag (peer, Peers_TO_DESTROY)) | ||
1564 | {/* We initiatad the destruction of this particular peer */ | ||
1565 | if (channel == peer_ctx->send_channel) | ||
1566 | peer_ctx->send_channel = NULL; | ||
1567 | else if (channel == peer_ctx->recv_channel) | ||
1568 | peer_ctx->recv_channel = NULL; | ||
1569 | |||
1570 | if (NULL != peer_ctx->send_channel) | ||
1571 | { | ||
1572 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | ||
1573 | peer_ctx->send_channel = NULL; | ||
1574 | } | ||
1575 | if (NULL != peer_ctx->recv_channel) | ||
1576 | { | ||
1577 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); | ||
1578 | peer_ctx->recv_channel = NULL; | ||
1579 | } | ||
1580 | /* Set the #Peers_ONLINE flag accordingly */ | ||
1581 | (void) Peers_check_connected (peer); | ||
1582 | return; | ||
1583 | } | ||
1584 | |||
1585 | else | ||
1586 | { /* We did not initiate the destruction of this peer */ | ||
1587 | if (channel == peer_ctx->send_channel) | ||
1588 | { /* Something (but us) killd the channel - clean up peer */ | ||
1589 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1590 | "send channel (%s) was destroyed - cleaning up\n", | ||
1591 | GNUNET_i2s (peer)); | ||
1592 | peer_ctx->send_channel = NULL; | ||
1593 | } | ||
1594 | else if (channel == peer_ctx->recv_channel) | ||
1595 | { /* Other peer doesn't want to send us messages anymore */ | ||
1596 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1597 | "Peer %s destroyed recv channel - cleaning up channel\n", | ||
1598 | GNUNET_i2s (peer)); | ||
1599 | peer_ctx->recv_channel = NULL; | ||
1600 | } | ||
1601 | else | ||
1602 | { | ||
1603 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1604 | "unknown channel (%s) was destroyed\n", | ||
1605 | GNUNET_i2s (peer)); | ||
1606 | } | ||
1607 | } | ||
1608 | (void) Peers_check_connected (peer); | ||
1609 | } | ||
1610 | |||
1611 | /** | ||
1612 | * @brief Send a message to another peer. | ||
1613 | * | ||
1614 | * Keeps track about pending messages so they can be properly removed when the | ||
1615 | * peer is destroyed. | ||
1616 | * | ||
1617 | * @param peer receeiver of the message | ||
1618 | * @param ev envelope of the message | ||
1619 | * @param type type of the message | ||
1620 | */ | ||
1621 | void | ||
1622 | Peers_send_message (const struct GNUNET_PeerIdentity *peer, | ||
1623 | struct GNUNET_MQ_Envelope *ev, | ||
1624 | const char *type) | ||
1625 | { | ||
1626 | struct PendingMessage *pending_msg; | ||
1627 | struct GNUNET_MQ_Handle *mq; | ||
1628 | |||
1629 | pending_msg = insert_pending_message (peer, ev, type); | ||
1630 | mq = get_mq (peer); | ||
1631 | GNUNET_MQ_notify_sent (ev, | ||
1632 | mq_notify_sent_cb, | ||
1633 | pending_msg); | ||
1634 | GNUNET_MQ_send (mq, ev); | ||
1635 | } | ||
1636 | |||
1637 | /** | ||
1638 | * @brief Schedule a operation on given peer | ||
1639 | * | ||
1640 | * Avoids scheduling an operation twice. | ||
1641 | * | ||
1642 | * @param peer the peer we want to schedule the operation for once it gets live | ||
1643 | * | ||
1644 | * @return #GNUNET_YES if the operation was scheduled | ||
1645 | * #GNUNET_NO otherwise | ||
1646 | */ | ||
1647 | int | ||
1648 | Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer, | ||
1649 | const PeerOp peer_op) | ||
1650 | { | ||
1651 | struct PeerPendingOp pending_op; | ||
1652 | struct PeerContext *peer_ctx; | ||
1653 | |||
1654 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, own_identity)) | ||
1655 | { | ||
1656 | return GNUNET_NO; | ||
1657 | } | ||
1658 | GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); | ||
1659 | |||
1660 | //TODO if LIVE/ONLINE execute immediately | ||
1661 | |||
1662 | if (GNUNET_NO == check_operation_scheduled (peer, peer_op)) | ||
1663 | { | ||
1664 | peer_ctx = get_peer_ctx (peer); | ||
1665 | pending_op.op = peer_op; | ||
1666 | pending_op.op_cls = NULL; | ||
1667 | GNUNET_array_append (peer_ctx->pending_ops, | ||
1668 | peer_ctx->num_pending_ops, | ||
1669 | pending_op); | ||
1670 | return GNUNET_YES; | ||
1671 | } | ||
1672 | return GNUNET_NO; | ||
1673 | } | ||
1674 | |||
1675 | /** | ||
1676 | * @brief Get the recv_channel of @a peer. | ||
1677 | * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming | ||
1678 | * messages. | ||
1679 | * | ||
1680 | * @param peer The peer to get the recv_channel from. | ||
1681 | * | ||
1682 | * @return The recv_channel. | ||
1683 | */ | ||
1684 | struct GNUNET_CADET_Channel * | ||
1685 | Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer) | ||
1686 | { | ||
1687 | struct PeerContext *peer_ctx; | ||
1688 | |||
1689 | GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); | ||
1690 | peer_ctx = get_peer_ctx (peer); | ||
1691 | return peer_ctx->recv_channel; | ||
1692 | } | ||
1693 | |||
1694 | /* end of gnunet-service-rps_peers.c */ | ||
diff --git a/src/rps/gnunet-service-rps_peers.h b/src/rps/gnunet-service-rps_peers.h deleted file mode 100644 index 15970a7ce..000000000 --- a/src/rps/gnunet-service-rps_peers.h +++ /dev/null | |||
@@ -1,437 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file rps/gnunet-service-rps_peers.h | ||
23 | * @brief utilities for managing (information about) peers | ||
24 | * @author Julius Bünger | ||
25 | */ | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include <inttypes.h> | ||
28 | #include "gnunet_cadet_service.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Different flags indicating the status of another peer. | ||
33 | */ | ||
34 | enum Peers_PeerFlags | ||
35 | { | ||
36 | /** | ||
37 | * If we are waiting for a reply from that peer (sent a pull request). | ||
38 | */ | ||
39 | Peers_PULL_REPLY_PENDING = 0x01, | ||
40 | |||
41 | /* IN_OTHER_GOSSIP_LIST = 0x02, unneeded? */ | ||
42 | /* IN_OWN_SAMPLER_LIST = 0x04, unneeded? */ | ||
43 | /* IN_OWN_GOSSIP_LIST = 0x08, unneeded? */ | ||
44 | |||
45 | /** | ||
46 | * We set this bit when we know the peer is online. | ||
47 | */ | ||
48 | Peers_ONLINE = 0x20, | ||
49 | |||
50 | /** | ||
51 | * We set this bit when we are going to destroy the channel to this peer. | ||
52 | * When cleanup_channel is called, we know that we wanted to destroy it. | ||
53 | * Otherwise the channel to the other peer was destroyed. | ||
54 | */ | ||
55 | Peers_TO_DESTROY = 0x40, | ||
56 | }; | ||
57 | |||
58 | /** | ||
59 | * Keep track of the status of a channel. | ||
60 | * | ||
61 | * This is needed in order to know what to do with a channel when it's | ||
62 | * destroyed. | ||
63 | */ | ||
64 | enum Peers_ChannelFlags | ||
65 | { | ||
66 | /** | ||
67 | * We destroyed the channel because the other peer established a second one. | ||
68 | */ | ||
69 | Peers_CHANNEL_ESTABLISHED_TWICE = 0x1, | ||
70 | |||
71 | /** | ||
72 | * The channel was removed because it was not needed any more. This should be | ||
73 | * the sending channel. | ||
74 | */ | ||
75 | Peers_CHANNEL_CLEAN = 0x2, | ||
76 | }; | ||
77 | |||
78 | /** | ||
79 | * @brief The role of a channel. Sending or receiving. | ||
80 | */ | ||
81 | enum Peers_ChannelRole | ||
82 | { | ||
83 | /** | ||
84 | * Channel is used for sending | ||
85 | */ | ||
86 | Peers_CHANNEL_ROLE_SENDING = 0x01, | ||
87 | |||
88 | /** | ||
89 | * Channel is used for receiving | ||
90 | */ | ||
91 | Peers_CHANNEL_ROLE_RECEIVING = 0x02, | ||
92 | }; | ||
93 | |||
94 | /** | ||
95 | * @brief Functions of this type can be used to be stored at a peer for later execution. | ||
96 | * | ||
97 | * @param cls closure | ||
98 | * @param peer peer to execute function on | ||
99 | */ | ||
100 | typedef void (* PeerOp) (void *cls, const struct GNUNET_PeerIdentity *peer); | ||
101 | |||
102 | /** | ||
103 | * @brief Iterator over valid peers. | ||
104 | * | ||
105 | * @param cls closure | ||
106 | * @param peer current public peer id | ||
107 | * @return #GNUNET_YES if we should continue to | ||
108 | * iterate, | ||
109 | * #GNUNET_NO if not. | ||
110 | */ | ||
111 | typedef int | ||
112 | (*PeersIterator) (void *cls, | ||
113 | const struct GNUNET_PeerIdentity *peer); | ||
114 | |||
115 | /** | ||
116 | * @brief Initialise storage of peers | ||
117 | * | ||
118 | * @param fn_valid_peers filename of the file used to store valid peer ids | ||
119 | * @param cadet_h cadet handle | ||
120 | * @param disconnect_handler Disconnect handler | ||
121 | * @param c_handlers cadet handlers | ||
122 | * @param own_id own peer identity | ||
123 | */ | ||
124 | void | ||
125 | Peers_initialise (char* fn_valid_peers, | ||
126 | struct GNUNET_CADET_Handle *cadet_h, | ||
127 | GNUNET_CADET_DisconnectEventHandler disconnect_handler, | ||
128 | const struct GNUNET_MQ_MessageHandler *c_handlers, | ||
129 | const struct GNUNET_PeerIdentity *own_id); | ||
130 | |||
131 | /** | ||
132 | * @brief Delete storage of peers that was created with #Peers_initialise () | ||
133 | */ | ||
134 | void | ||
135 | Peers_terminate (); | ||
136 | |||
137 | |||
138 | /** | ||
139 | * @brief Get all currently known, valid peer ids. | ||
140 | * | ||
141 | * @param it function to call on each peer id | ||
142 | * @param it_cls extra argument to @a it | ||
143 | * @return the number of key value pairs processed, | ||
144 | * #GNUNET_SYSERR if it aborted iteration | ||
145 | */ | ||
146 | int | ||
147 | Peers_get_valid_peers (PeersIterator iterator, | ||
148 | void *it_cls); | ||
149 | |||
150 | /** | ||
151 | * @brief Add peer to known peers. | ||
152 | * | ||
153 | * This function is called on new peer_ids from 'external' sources | ||
154 | * (client seed, cadet get_peers(), ...) | ||
155 | * | ||
156 | * @param peer the new #GNUNET_PeerIdentity | ||
157 | * | ||
158 | * @return #GNUNET_YES if peer was inserted | ||
159 | * #GNUNET_NO otherwise (if peer was already known or | ||
160 | * peer was #own_identity) | ||
161 | */ | ||
162 | int | ||
163 | Peers_insert_peer (const struct GNUNET_PeerIdentity *peer); | ||
164 | |||
165 | /** | ||
166 | * @brief Try connecting to a peer to see whether it is online | ||
167 | * | ||
168 | * If not known yet, insert into known peers | ||
169 | * | ||
170 | * @param peer the peer whose liveliness is to be checked | ||
171 | * @return #GNUNET_YES if peer had to be inserted | ||
172 | * #GNUNET_NO otherwise (if peer was already known or | ||
173 | * peer was #own_identity) | ||
174 | */ | ||
175 | int | ||
176 | Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer); | ||
177 | |||
178 | /** | ||
179 | * @brief Check if peer is removable. | ||
180 | * | ||
181 | * Check if | ||
182 | * - a recv channel exists | ||
183 | * - there are pending messages | ||
184 | * - there is no pending pull reply | ||
185 | * | ||
186 | * @param peer the peer in question | ||
187 | * @return #GNUNET_YES if peer is removable | ||
188 | * #GNUNET_NO if peer is NOT removable | ||
189 | * #GNUNET_SYSERR if peer is not known | ||
190 | */ | ||
191 | int | ||
192 | Peers_check_removable (const struct GNUNET_PeerIdentity *peer); | ||
193 | |||
194 | /** | ||
195 | * @brief Remove peer | ||
196 | * | ||
197 | * @param peer the peer to clean | ||
198 | * @return #GNUNET_YES if peer was removed | ||
199 | * #GNUNET_NO otherwise | ||
200 | */ | ||
201 | int | ||
202 | Peers_remove_peer (const struct GNUNET_PeerIdentity *peer); | ||
203 | |||
204 | /** | ||
205 | * @brief set flags on a given peer. | ||
206 | * | ||
207 | * @param peer the peer to set flags on | ||
208 | * @param flags the flags | ||
209 | */ | ||
210 | void | ||
211 | Peers_set_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags); | ||
212 | |||
213 | /** | ||
214 | * @brief unset flags on a given peer. | ||
215 | * | ||
216 | * @param peer the peer to unset flags on | ||
217 | * @param flags the flags | ||
218 | */ | ||
219 | void | ||
220 | Peers_unset_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags); | ||
221 | |||
222 | /** | ||
223 | * @brief Check whether flags on a peer are set. | ||
224 | * | ||
225 | * @param peer the peer to check the flag of | ||
226 | * @param flags the flags to check | ||
227 | * | ||
228 | * @return #GNUNET_YES if all given flags are set | ||
229 | * ##GNUNET_NO otherwise | ||
230 | */ | ||
231 | int | ||
232 | Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags); | ||
233 | |||
234 | |||
235 | /** | ||
236 | * @brief set flags on a given channel. | ||
237 | * | ||
238 | * @param channel the channel to set flags on | ||
239 | * @param flags the flags | ||
240 | */ | ||
241 | void | ||
242 | Peers_set_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags); | ||
243 | |||
244 | /** | ||
245 | * @brief unset flags on a given channel. | ||
246 | * | ||
247 | * @param channel the channel to unset flags on | ||
248 | * @param flags the flags | ||
249 | */ | ||
250 | void | ||
251 | Peers_unset_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags); | ||
252 | |||
253 | /** | ||
254 | * @brief Check whether flags on a channel are set. | ||
255 | * | ||
256 | * @param channel the channel to check the flag of | ||
257 | * @param flags the flags to check | ||
258 | * | ||
259 | * @return #GNUNET_YES if all given flags are set | ||
260 | * #GNUNET_NO otherwise | ||
261 | */ | ||
262 | int | ||
263 | Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags); | ||
264 | |||
265 | /** | ||
266 | * @brief Get the flags for the channel in @a role for @a peer. | ||
267 | * | ||
268 | * @param peer Peer to get the channel flags for. | ||
269 | * @param role Role of channel to get flags for | ||
270 | * | ||
271 | * @return The flags. | ||
272 | */ | ||
273 | uint32_t * | ||
274 | Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer, | ||
275 | enum Peers_ChannelRole role); | ||
276 | |||
277 | /** | ||
278 | * @brief Check whether we have information about the given peer. | ||
279 | * | ||
280 | * FIXME probably deprecated. Make this the new _online. | ||
281 | * | ||
282 | * @param peer peer in question | ||
283 | * | ||
284 | * @return #GNUNET_YES if peer is known | ||
285 | * #GNUNET_NO if peer is not knwon | ||
286 | */ | ||
287 | int | ||
288 | Peers_check_peer_known (const struct GNUNET_PeerIdentity *peer); | ||
289 | |||
290 | /** | ||
291 | * @brief Check whether @a peer is actually a peer. | ||
292 | * | ||
293 | * A valid peer is a peer that we know exists eg. we were connected to once. | ||
294 | * | ||
295 | * @param peer peer in question | ||
296 | * | ||
297 | * @return #GNUNET_YES if peer is valid | ||
298 | * #GNUNET_NO if peer is not valid | ||
299 | */ | ||
300 | int | ||
301 | Peers_check_peer_valid (const struct GNUNET_PeerIdentity *peer); | ||
302 | |||
303 | /** | ||
304 | * @brief Indicate that we want to send to the other peer | ||
305 | * | ||
306 | * This establishes a sending channel | ||
307 | * | ||
308 | * @param peer the peer to establish channel to | ||
309 | */ | ||
310 | void | ||
311 | Peers_indicate_sending_intention (const struct GNUNET_PeerIdentity *peer); | ||
312 | |||
313 | /** | ||
314 | * @brief Check whether other peer has the intention to send/opened channel | ||
315 | * towars us | ||
316 | * | ||
317 | * @param peer the peer in question | ||
318 | * | ||
319 | * @return #GNUNET_YES if peer has the intention to send | ||
320 | * #GNUNET_NO otherwise | ||
321 | */ | ||
322 | int | ||
323 | Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer); | ||
324 | |||
325 | /** | ||
326 | * Handle the channel a peer opens to us. | ||
327 | * | ||
328 | * @param cls The closure | ||
329 | * @param channel The channel the peer wants to establish | ||
330 | * @param initiator The peer's peer ID | ||
331 | * | ||
332 | * @return initial channel context for the channel | ||
333 | * (can be NULL -- that's not an error) | ||
334 | */ | ||
335 | void * | ||
336 | Peers_handle_inbound_channel (void *cls, | ||
337 | struct GNUNET_CADET_Channel *channel, | ||
338 | const struct GNUNET_PeerIdentity *initiator); | ||
339 | |||
340 | /** | ||
341 | * @brief Check whether a sending channel towards the given peer exists | ||
342 | * | ||
343 | * @param peer the peer to check for | ||
344 | * | ||
345 | * @return #GNUNET_YES if a sending channel towards that peer exists | ||
346 | * #GNUNET_NO otherwise | ||
347 | */ | ||
348 | int | ||
349 | Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer); | ||
350 | |||
351 | /** | ||
352 | * @brief check whether the given channel is the sending channel of the given | ||
353 | * peer | ||
354 | * | ||
355 | * @param peer the peer in question | ||
356 | * @param channel the channel to check for | ||
357 | * @param role either #Peers_CHANNEL_ROLE_SENDING, or | ||
358 | * #Peers_CHANNEL_ROLE_RECEIVING | ||
359 | * | ||
360 | * @return #GNUNET_YES if the given chennel is the sending channel of the peer | ||
361 | * #GNUNET_NO otherwise | ||
362 | */ | ||
363 | int | ||
364 | Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer, | ||
365 | const struct GNUNET_CADET_Channel *channel, | ||
366 | enum Peers_ChannelRole role); | ||
367 | |||
368 | /** | ||
369 | * @brief Destroy the send channel of a peer e.g. stop indicating a sending | ||
370 | * intention to another peer | ||
371 | * | ||
372 | * If there is also no channel to receive messages from that peer, remove it | ||
373 | * from the peermap. | ||
374 | * | ||
375 | * @peer the peer identity of the peer whose sending channel to destroy | ||
376 | * @return #GNUNET_YES if channel was destroyed | ||
377 | * #GNUNET_NO otherwise | ||
378 | */ | ||
379 | int | ||
380 | Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer); | ||
381 | |||
382 | /** | ||
383 | * This is called when a channel is destroyed. | ||
384 | * | ||
385 | * Removes peer completely from our knowledge if the send_channel was destroyed | ||
386 | * Otherwise simply delete the recv_channel | ||
387 | * | ||
388 | * @param cls The closure | ||
389 | * @param channel The channel being closed | ||
390 | * @param channel_ctx The context associated with this channel | ||
391 | */ | ||
392 | void | ||
393 | Peers_cleanup_destroyed_channel (void *cls, | ||
394 | const struct GNUNET_CADET_Channel *channel); | ||
395 | |||
396 | /** | ||
397 | * @brief Send a message to another peer. | ||
398 | * | ||
399 | * Keeps track about pending messages so they can be properly removed when the | ||
400 | * peer is destroyed. | ||
401 | * | ||
402 | * @param peer receeiver of the message | ||
403 | * @param ev envelope of the message | ||
404 | * @param type type of the message | ||
405 | */ | ||
406 | void | ||
407 | Peers_send_message (const struct GNUNET_PeerIdentity *peer, | ||
408 | struct GNUNET_MQ_Envelope *ev, | ||
409 | const char *type); | ||
410 | |||
411 | /** | ||
412 | * @brief Schedule a operation on given peer | ||
413 | * | ||
414 | * Avoids scheduling an operation twice. | ||
415 | * | ||
416 | * @param peer the peer we want to schedule the operation for once it gets live | ||
417 | * | ||
418 | * @return #GNUNET_YES if the operation was scheduled | ||
419 | * #GNUNET_NO otherwise | ||
420 | */ | ||
421 | int | ||
422 | Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer, | ||
423 | const PeerOp peer_op); | ||
424 | |||
425 | /** | ||
426 | * @brief Get the recv_channel of @a peer. | ||
427 | * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming | ||
428 | * messages. | ||
429 | * | ||
430 | * @param peer The peer to get the recv_channel from. | ||
431 | * | ||
432 | * @return The recv_channel. | ||
433 | */ | ||
434 | struct GNUNET_CADET_Channel * | ||
435 | Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer); | ||
436 | |||
437 | /* end of gnunet-service-rps_peers.h */ | ||
diff --git a/src/rps/rps.h b/src/rps/rps.h index 3037e2190..f5cc2e8d1 100644 --- a/src/rps/rps.h +++ b/src/rps/rps.h | |||
@@ -175,4 +175,100 @@ struct GNUNET_RPS_CS_ActMaliciousMessage | |||
175 | }; | 175 | }; |
176 | #endif /* ENABLE_MALICIOUS */ | 176 | #endif /* ENABLE_MALICIOUS */ |
177 | 177 | ||
178 | |||
179 | /*********************************************************************** | ||
180 | * Defines from old gnunet-service-rps_peers.h | ||
181 | ***********************************************************************/ | ||
182 | |||
183 | /** | ||
184 | * Different flags indicating the status of another peer. | ||
185 | */ | ||
186 | enum Peers_PeerFlags | ||
187 | { | ||
188 | /** | ||
189 | * If we are waiting for a reply from that peer (sent a pull request). | ||
190 | */ | ||
191 | Peers_PULL_REPLY_PENDING = 0x01, | ||
192 | |||
193 | /* IN_OTHER_GOSSIP_LIST = 0x02, unneeded? */ | ||
194 | /* IN_OWN_SAMPLER_LIST = 0x04, unneeded? */ | ||
195 | /* IN_OWN_GOSSIP_LIST = 0x08, unneeded? */ | ||
196 | |||
197 | /** | ||
198 | * We set this bit when we know the peer is online. | ||
199 | */ | ||
200 | Peers_ONLINE = 0x20, | ||
201 | |||
202 | /** | ||
203 | * We set this bit when we are going to destroy the channel to this peer. | ||
204 | * When cleanup_channel is called, we know that we wanted to destroy it. | ||
205 | * Otherwise the channel to the other peer was destroyed. | ||
206 | */ | ||
207 | Peers_TO_DESTROY = 0x40, | ||
208 | }; | ||
209 | |||
210 | /** | ||
211 | * Keep track of the status of a channel. | ||
212 | * | ||
213 | * This is needed in order to know what to do with a channel when it's | ||
214 | * destroyed. | ||
215 | */ | ||
216 | enum Peers_ChannelFlags | ||
217 | { | ||
218 | /** | ||
219 | * We destroyed the channel because the other peer established a second one. | ||
220 | */ | ||
221 | Peers_CHANNEL_ESTABLISHED_TWICE = 0x1, | ||
222 | |||
223 | /** | ||
224 | * The channel was removed because it was not needed any more. This should be | ||
225 | * the sending channel. | ||
226 | */ | ||
227 | Peers_CHANNEL_CLEAN = 0x2, | ||
228 | |||
229 | /** | ||
230 | * We destroyed the channel because the other peer established a second one. | ||
231 | */ | ||
232 | Peers_CHANNEL_DESTROING = 0x4, | ||
233 | }; | ||
234 | |||
235 | |||
236 | /** | ||
237 | * @brief The role of a channel. Sending or receiving. | ||
238 | */ | ||
239 | enum Peers_ChannelRole | ||
240 | { | ||
241 | /** | ||
242 | * Channel is used for sending | ||
243 | */ | ||
244 | Peers_CHANNEL_ROLE_SENDING = 0x01, | ||
245 | |||
246 | /** | ||
247 | * Channel is used for receiving | ||
248 | */ | ||
249 | Peers_CHANNEL_ROLE_RECEIVING = 0x02, | ||
250 | }; | ||
251 | |||
252 | /** | ||
253 | * @brief Functions of this type can be used to be stored at a peer for later execution. | ||
254 | * | ||
255 | * @param cls closure | ||
256 | * @param peer peer to execute function on | ||
257 | */ | ||
258 | typedef void (* PeerOp) (void *cls, const struct GNUNET_PeerIdentity *peer); | ||
259 | |||
260 | /** | ||
261 | * @brief Iterator over valid peers. | ||
262 | * | ||
263 | * @param cls closure | ||
264 | * @param peer current public peer id | ||
265 | * @return #GNUNET_YES if we should continue to | ||
266 | * iterate, | ||
267 | * #GNUNET_NO if not. | ||
268 | */ | ||
269 | typedef int | ||
270 | (*PeersIterator) (void *cls, | ||
271 | const struct GNUNET_PeerIdentity *peer); | ||
272 | |||
273 | |||
178 | GNUNET_NETWORK_STRUCT_END | 274 | GNUNET_NETWORK_STRUCT_END |
diff --git a/src/rps/test_rps.c b/src/rps/test_rps.c index acd3a165d..0114a19fe 100644 --- a/src/rps/test_rps.c +++ b/src/rps/test_rps.c | |||
@@ -18,7 +18,7 @@ | |||
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | /** | 20 | /** |
21 | * @file rps/test_rps_multipeer.c | 21 | * @file rps/test_rps.c |
22 | * @brief Testcase for the random peer sampling service. Starts | 22 | * @brief Testcase for the random peer sampling service. Starts |
23 | * a peergroup with a given number of peers, then waits to | 23 | * a peergroup with a given number of peers, then waits to |
24 | * receive size pushes/pulls from each peer. Expects to wait | 24 | * receive size pushes/pulls from each peer. Expects to wait |
@@ -344,6 +344,11 @@ struct SingleTestRun | |||
344 | * Number of Requests to make. | 344 | * Number of Requests to make. |
345 | */ | 345 | */ |
346 | uint32_t num_requests; | 346 | uint32_t num_requests; |
347 | |||
348 | /** | ||
349 | * Run with churn | ||
350 | */ | ||
351 | int have_churn; | ||
347 | } cur_test_run; | 352 | } cur_test_run; |
348 | 353 | ||
349 | /** | 354 | /** |
@@ -1023,6 +1028,33 @@ req_cancel_cb (struct RPSPeer *rps_peer) | |||
1023 | } | 1028 | } |
1024 | 1029 | ||
1025 | /*********************************** | 1030 | /*********************************** |
1031 | * CHURN | ||
1032 | ***********************************/ | ||
1033 | |||
1034 | static void | ||
1035 | churn (void *cls); | ||
1036 | |||
1037 | static void | ||
1038 | churn_test_cb (struct RPSPeer *rps_peer) | ||
1039 | { | ||
1040 | /* Start churn */ | ||
1041 | if (GNUNET_YES == cur_test_run.have_churn && NULL == churn_task) | ||
1042 | { | ||
1043 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1044 | "Starting churn task\n"); | ||
1045 | churn_task = GNUNET_SCHEDULER_add_delayed ( | ||
1046 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), | ||
1047 | churn, | ||
1048 | NULL); | ||
1049 | } else { | ||
1050 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1051 | "Not starting churn task\n"); | ||
1052 | } | ||
1053 | |||
1054 | schedule_missing_requests (rps_peer); | ||
1055 | } | ||
1056 | |||
1057 | /*********************************** | ||
1026 | * PROFILER | 1058 | * PROFILER |
1027 | ***********************************/ | 1059 | ***********************************/ |
1028 | 1060 | ||
@@ -1148,6 +1180,9 @@ churn (void *cls) | |||
1148 | double portion_go_online; | 1180 | double portion_go_online; |
1149 | double portion_go_offline; | 1181 | double portion_go_offline; |
1150 | 1182 | ||
1183 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1184 | "Churn function executing\n"); | ||
1185 | |||
1151 | /* Compute the probability for an online peer to go offline | 1186 | /* Compute the probability for an online peer to go offline |
1152 | * this round */ | 1187 | * this round */ |
1153 | portion_online = num_peers_online * 1.0 / num_peers; | 1188 | portion_online = num_peers_online * 1.0 / num_peers; |
@@ -1256,12 +1291,17 @@ static void | |||
1256 | profiler_cb (struct RPSPeer *rps_peer) | 1291 | profiler_cb (struct RPSPeer *rps_peer) |
1257 | { | 1292 | { |
1258 | /* Start churn */ | 1293 | /* Start churn */ |
1259 | if (NULL == churn_task) | 1294 | if (GNUNET_YES == cur_test_run.have_churn && NULL == churn_task) |
1260 | { | 1295 | { |
1296 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1297 | "Starting churn task\n"); | ||
1261 | churn_task = GNUNET_SCHEDULER_add_delayed ( | 1298 | churn_task = GNUNET_SCHEDULER_add_delayed ( |
1262 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), | 1299 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), |
1263 | churn, | 1300 | churn, |
1264 | NULL); | 1301 | NULL); |
1302 | } else { | ||
1303 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1304 | "Not starting churn task\n"); | ||
1265 | } | 1305 | } |
1266 | 1306 | ||
1267 | /* Only request peer ids at one peer. | 1307 | /* Only request peer ids at one peer. |
@@ -1353,6 +1393,24 @@ run (void *cls, | |||
1353 | struct OpListEntry *entry; | 1393 | struct OpListEntry *entry; |
1354 | uint32_t num_mal_peers; | 1394 | uint32_t num_mal_peers; |
1355 | 1395 | ||
1396 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n"); | ||
1397 | |||
1398 | /* Check whether we timed out */ | ||
1399 | if (n_peers != num_peers || | ||
1400 | NULL == peers || | ||
1401 | 0 == links_succeeded) | ||
1402 | { | ||
1403 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Going down due to args (eg. timeout)\n"); | ||
1404 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tn_peers: %u\n", n_peers); | ||
1405 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tnum_peers: %" PRIu32 "\n", num_peers); | ||
1406 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tpeers: %p\n", peers); | ||
1407 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tlinks_succeeded: %u\n", links_succeeded); | ||
1408 | GNUNET_SCHEDULER_shutdown (); | ||
1409 | return; | ||
1410 | } | ||
1411 | |||
1412 | |||
1413 | /* Initialize peers */ | ||
1356 | testbed_peers = peers; | 1414 | testbed_peers = peers; |
1357 | num_peers_online = 0; | 1415 | num_peers_online = 0; |
1358 | for (i = 0; i < num_peers; i++) | 1416 | for (i = 0; i < num_peers; i++) |
@@ -1412,6 +1470,7 @@ main (int argc, char *argv[]) | |||
1412 | cur_test_run.pre_test = NULL; | 1470 | cur_test_run.pre_test = NULL; |
1413 | cur_test_run.reply_handle = default_reply_handle; | 1471 | cur_test_run.reply_handle = default_reply_handle; |
1414 | cur_test_run.eval_cb = default_eval_cb; | 1472 | cur_test_run.eval_cb = default_eval_cb; |
1473 | cur_test_run.have_churn = GNUNET_YES; | ||
1415 | churn_task = NULL; | 1474 | churn_task = NULL; |
1416 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30); | 1475 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30); |
1417 | 1476 | ||
@@ -1446,6 +1505,7 @@ main (int argc, char *argv[]) | |||
1446 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test single request\n"); | 1505 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test single request\n"); |
1447 | cur_test_run.name = "test-rps-single-req"; | 1506 | cur_test_run.name = "test-rps-single-req"; |
1448 | cur_test_run.main_test = single_req_cb; | 1507 | cur_test_run.main_test = single_req_cb; |
1508 | cur_test_run.have_churn = GNUNET_NO; | ||
1449 | } | 1509 | } |
1450 | 1510 | ||
1451 | else if (strstr (argv[0], "_delayed_reqs") != NULL) | 1511 | else if (strstr (argv[0], "_delayed_reqs") != NULL) |
@@ -1453,6 +1513,7 @@ main (int argc, char *argv[]) | |||
1453 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test delayed requests\n"); | 1513 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test delayed requests\n"); |
1454 | cur_test_run.name = "test-rps-delayed-reqs"; | 1514 | cur_test_run.name = "test-rps-delayed-reqs"; |
1455 | cur_test_run.main_test = delay_req_cb; | 1515 | cur_test_run.main_test = delay_req_cb; |
1516 | cur_test_run.have_churn = GNUNET_NO; | ||
1456 | } | 1517 | } |
1457 | 1518 | ||
1458 | else if (strstr (argv[0], "_seed_big") != NULL) | 1519 | else if (strstr (argv[0], "_seed_big") != NULL) |
@@ -1462,6 +1523,7 @@ main (int argc, char *argv[]) | |||
1462 | cur_test_run.name = "test-rps-seed-big"; | 1523 | cur_test_run.name = "test-rps-seed-big"; |
1463 | cur_test_run.main_test = seed_big_cb; | 1524 | cur_test_run.main_test = seed_big_cb; |
1464 | cur_test_run.eval_cb = no_eval; | 1525 | cur_test_run.eval_cb = no_eval; |
1526 | cur_test_run.have_churn = GNUNET_NO; | ||
1465 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); | 1527 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); |
1466 | } | 1528 | } |
1467 | 1529 | ||
@@ -1470,6 +1532,7 @@ main (int argc, char *argv[]) | |||
1470 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding and requesting on a single peer\n"); | 1532 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding and requesting on a single peer\n"); |
1471 | cur_test_run.name = "test-rps-single-peer-seed"; | 1533 | cur_test_run.name = "test-rps-single-peer-seed"; |
1472 | cur_test_run.main_test = single_peer_seed_cb; | 1534 | cur_test_run.main_test = single_peer_seed_cb; |
1535 | cur_test_run.have_churn = GNUNET_NO; | ||
1473 | } | 1536 | } |
1474 | 1537 | ||
1475 | else if (strstr (argv[0], "_seed_request") != NULL) | 1538 | else if (strstr (argv[0], "_seed_request") != NULL) |
@@ -1477,6 +1540,7 @@ main (int argc, char *argv[]) | |||
1477 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding and requesting on multiple peers\n"); | 1540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding and requesting on multiple peers\n"); |
1478 | cur_test_run.name = "test-rps-seed-request"; | 1541 | cur_test_run.name = "test-rps-seed-request"; |
1479 | cur_test_run.main_test = seed_req_cb; | 1542 | cur_test_run.main_test = seed_req_cb; |
1543 | cur_test_run.have_churn = GNUNET_NO; | ||
1480 | } | 1544 | } |
1481 | 1545 | ||
1482 | else if (strstr (argv[0], "_seed") != NULL) | 1546 | else if (strstr (argv[0], "_seed") != NULL) |
@@ -1485,6 +1549,7 @@ main (int argc, char *argv[]) | |||
1485 | cur_test_run.name = "test-rps-seed"; | 1549 | cur_test_run.name = "test-rps-seed"; |
1486 | cur_test_run.main_test = seed_cb; | 1550 | cur_test_run.main_test = seed_cb; |
1487 | cur_test_run.eval_cb = no_eval; | 1551 | cur_test_run.eval_cb = no_eval; |
1552 | cur_test_run.have_churn = GNUNET_NO; | ||
1488 | } | 1553 | } |
1489 | 1554 | ||
1490 | else if (strstr (argv[0], "_req_cancel") != NULL) | 1555 | else if (strstr (argv[0], "_req_cancel") != NULL) |
@@ -1494,6 +1559,20 @@ main (int argc, char *argv[]) | |||
1494 | num_peers = 1; | 1559 | num_peers = 1; |
1495 | cur_test_run.main_test = req_cancel_cb; | 1560 | cur_test_run.main_test = req_cancel_cb; |
1496 | cur_test_run.eval_cb = no_eval; | 1561 | cur_test_run.eval_cb = no_eval; |
1562 | cur_test_run.have_churn = GNUNET_NO; | ||
1563 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); | ||
1564 | } | ||
1565 | |||
1566 | else if (strstr (argv[0], "_churn") != NULL) | ||
1567 | { | ||
1568 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test churn\n"); | ||
1569 | cur_test_run.name = "test-rps-churn"; | ||
1570 | num_peers = 5; | ||
1571 | cur_test_run.init_peer = default_init_peer; | ||
1572 | cur_test_run.main_test = churn_test_cb; | ||
1573 | cur_test_run.reply_handle = default_reply_handle; | ||
1574 | cur_test_run.eval_cb = default_eval_cb; | ||
1575 | cur_test_run.have_churn = GNUNET_YES; | ||
1497 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); | 1576 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); |
1498 | } | 1577 | } |
1499 | 1578 | ||
@@ -1510,6 +1589,7 @@ main (int argc, char *argv[]) | |||
1510 | cur_test_run.eval_cb = profiler_eval; | 1589 | cur_test_run.eval_cb = profiler_eval; |
1511 | cur_test_run.request_interval = 2; | 1590 | cur_test_run.request_interval = 2; |
1512 | cur_test_run.num_requests = 5; | 1591 | cur_test_run.num_requests = 5; |
1592 | cur_test_run.have_churn = GNUNET_YES; | ||
1513 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90); | 1593 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90); |
1514 | 1594 | ||
1515 | /* 'Clean' directory */ | 1595 | /* 'Clean' directory */ |
@@ -1542,4 +1622,4 @@ main (int argc, char *argv[]) | |||
1542 | return ret_value; | 1622 | return ret_value; |
1543 | } | 1623 | } |
1544 | 1624 | ||
1545 | /* end of test_rps_multipeer.c */ | 1625 | /* end of test_rps.c */ |
diff --git a/src/rps/test_rps.conf b/src/rps/test_rps.conf index 7da91ccf0..fce07c945 100644 --- a/src/rps/test_rps.conf +++ b/src/rps/test_rps.conf | |||
@@ -24,16 +24,16 @@ INITSIZE = 4 | |||
24 | [testbed] | 24 | [testbed] |
25 | HOSTNAME = localhost | 25 | HOSTNAME = localhost |
26 | 26 | ||
27 | OPERATION_TIMEOUT = 60 s | 27 | # OPERATION_TIMEOUT = 60 s |
28 | 28 | ||
29 | MAX_PARALLEL_TOPOLOGY_CONFIG_OPERATIONS = 1 | 29 | # MAX_PARALLEL_TOPOLOGY_CONFIG_OPERATIONS = 100 |
30 | #OVERLAY_TOPOLOGY = CLIQUE | 30 | OVERLAY_TOPOLOGY = CLIQUE |
31 | OVERLAY_TOPOLOGY = SMALL_WORLD | 31 | #OVERLAY_TOPOLOGY = SMALL_WORLD |
32 | #SCALE_FREE_TOPOLOGY_CAP = | 32 | #SCALE_FREE_TOPOLOGY_CAP = |
33 | 33 | ||
34 | OVERLAY_RANDOM_LINKS = 25 | 34 | # OVERLAY_RANDOM_LINKS = 25 |
35 | 35 | ||
36 | SETUP_TIMEOUT = 2 m | 36 | # SETUP_TIMEOUT = 2 m |
37 | 37 | ||
38 | [nse] | 38 | [nse] |
39 | WORKBITS = 0 | 39 | WORKBITS = 0 |
@@ -46,7 +46,27 @@ USE_LOCALADDR = YES | |||
46 | RETURN_LOCAL_ADDRESSES = YES | 46 | RETURN_LOCAL_ADDRESSES = YES |
47 | 47 | ||
48 | [transport] | 48 | [transport] |
49 | PLUGINS = unix | 49 | PLUGINS = udp |
50 | |||
51 | [ats] | ||
52 | # Network specific inbound/outbound quotas | ||
53 | UNSPECIFIED_QUOTA_IN = unlimited | ||
54 | UNSPECIFIED_QUOTA_OUT = unlimited | ||
55 | # LOOPBACK | ||
56 | LOOPBACK_QUOTA_IN = unlimited | ||
57 | LOOPBACK_QUOTA_OUT = unlimited | ||
58 | # LAN | ||
59 | LAN_QUOTA_IN = unlimited | ||
60 | LAN_QUOTA_OUT = unlimited | ||
61 | #WAN | ||
62 | WAN_QUOTA_OUT = unlimited | ||
63 | WAN_QUOTA_IN = unlimited | ||
64 | # WLAN | ||
65 | WLAN_QUOTA_IN = unlimited | ||
66 | WLAN_QUOTA_OUT = unlimited | ||
67 | # BLUETOOTH | ||
68 | BLUETOOTH_QUOTA_IN = unlimited | ||
69 | BLUETOOTH_QUOTA_OUT = unlimited | ||
50 | 70 | ||
51 | [dht] | 71 | [dht] |
52 | DISABLE_TRY_CONNECT = YES | 72 | DISABLE_TRY_CONNECT = YES |
@@ -69,6 +89,10 @@ NO_IO = YES | |||
69 | FORCESTART = NO | 89 | FORCESTART = NO |
70 | AUTOSTART = NO | 90 | AUTOSTART = NO |
71 | 91 | ||
92 | [zonemaster] | ||
93 | FORCESTART = NO | ||
94 | AUTOSTART = NO | ||
95 | |||
72 | [namecache] | 96 | [namecache] |
73 | FORCESTART = NO | 97 | FORCESTART = NO |
74 | AUTOSTART = NO | 98 | AUTOSTART = NO |
diff --git a/src/rps/test_service_rps_peers.c b/src/rps/test_service_rps_peers.c deleted file mode 100644 index 9cd677fef..000000000 --- a/src/rps/test_service_rps_peers.c +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file rps/test_service_rps_peers.c | ||
22 | * @brief testcase for gnunet-service-rps_peers.c | ||
23 | */ | ||
24 | #include <platform.h> | ||
25 | #include "gnunet-service-rps_peers.h" | ||
26 | |||
27 | #define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); Peers_terminate (); return 1; } | ||
28 | #define CHECK(c) { if (! (c)) ABORT(); } | ||
29 | |||
30 | #define FN_VALID_PEERS "DISABLE" | ||
31 | |||
32 | /** | ||
33 | * @brief Dummy implementation of #PeerOp (Operation on peer) | ||
34 | * | ||
35 | * @param cls closure | ||
36 | * @param peer peer | ||
37 | */ | ||
38 | void peer_op (void *cls, const struct GNUNET_PeerIdentity *peer) | ||
39 | { | ||
40 | GNUNET_assert (NULL != peer); | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * @brief Function that is called on a peer for later execution | ||
45 | * | ||
46 | * @param cls closure | ||
47 | * @param peer peer to execute function upon | ||
48 | */ | ||
49 | void | ||
50 | peer_op (void *cls, const struct GNUNET_PeerIdentity *peer); | ||
51 | |||
52 | static int | ||
53 | check () | ||
54 | { | ||
55 | struct GNUNET_PeerIdentity k1; | ||
56 | struct GNUNET_PeerIdentity own_id; | ||
57 | |||
58 | memset (&k1, 0, sizeof (k1)); | ||
59 | memset (&own_id, 1, sizeof (own_id)); | ||
60 | |||
61 | /* Do nothing */ | ||
62 | Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id); | ||
63 | Peers_terminate (); | ||
64 | |||
65 | |||
66 | /* Create peer */ | ||
67 | Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id); | ||
68 | CHECK (GNUNET_YES == Peers_insert_peer (&k1)); | ||
69 | Peers_terminate (); | ||
70 | |||
71 | |||
72 | /* Create peer */ | ||
73 | Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id); | ||
74 | CHECK (GNUNET_YES == Peers_insert_peer (&k1)); | ||
75 | CHECK (GNUNET_YES == Peers_remove_peer (&k1)); | ||
76 | Peers_terminate (); | ||
77 | |||
78 | |||
79 | /* Insertion and Removal */ | ||
80 | Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id); | ||
81 | CHECK (GNUNET_NO == Peers_check_peer_known (&k1)); | ||
82 | |||
83 | CHECK (GNUNET_YES == Peers_insert_peer (&k1)); | ||
84 | CHECK (GNUNET_NO == Peers_insert_peer (&k1)); | ||
85 | CHECK (GNUNET_YES == Peers_check_peer_known (&k1)); | ||
86 | |||
87 | CHECK (GNUNET_YES == Peers_remove_peer (&k1)); | ||
88 | CHECK (GNUNET_NO == Peers_remove_peer (&k1)); | ||
89 | CHECK (GNUNET_NO == Peers_check_peer_known (&k1)); | ||
90 | |||
91 | |||
92 | /* Flags */ | ||
93 | Peers_insert_peer (&k1); | ||
94 | |||
95 | CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_PULL_REPLY_PENDING)); | ||
96 | CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_ONLINE)); | ||
97 | CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_TO_DESTROY)); | ||
98 | |||
99 | CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_ONLINE)); | ||
100 | |||
101 | Peers_set_peer_flag (&k1, Peers_ONLINE); | ||
102 | CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, Peers_ONLINE)); | ||
103 | CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_TO_DESTROY)); | ||
104 | CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, Peers_ONLINE)); | ||
105 | CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_TO_DESTROY)); | ||
106 | |||
107 | /* Check send intention */ | ||
108 | CHECK (GNUNET_NO == Peers_check_peer_send_intention (&k1)); | ||
109 | |||
110 | /* Check existence of sending channel */ | ||
111 | CHECK (GNUNET_NO == Peers_check_sending_channel_exists (&k1)); | ||
112 | |||
113 | /* Check role of channels */ | ||
114 | CHECK (GNUNET_YES == Peers_check_channel_role (&k1, | ||
115 | NULL, | ||
116 | Peers_CHANNEL_ROLE_SENDING)); | ||
117 | CHECK (GNUNET_YES == Peers_check_channel_role (&k1, | ||
118 | NULL, | ||
119 | Peers_CHANNEL_ROLE_RECEIVING)); | ||
120 | |||
121 | CHECK (GNUNET_YES == Peers_schedule_operation (&k1, peer_op)); | ||
122 | |||
123 | Peers_terminate (); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | |||
128 | int | ||
129 | main (int argc, char *argv[]) | ||
130 | { | ||
131 | GNUNET_log_setup ("test_service_rps_peers", | ||
132 | "WARNING", | ||
133 | NULL); | ||
134 | return check (); | ||
135 | } | ||
136 | |||
137 | /* end of test_service_rps_peers.c */ | ||
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c index c0b33f8ef..57f275c81 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c | |||
@@ -260,8 +260,6 @@ destroy_service_session (struct AliceServiceSession *s) | |||
260 | } | 260 | } |
261 | if (NULL != s->intersection_listen) | 261 | if (NULL != s->intersection_listen) |
262 | { | 262 | { |
263 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
264 | "Set intersection, listen still up!\n"); | ||
265 | GNUNET_SET_listen_cancel (s->intersection_listen); | 263 | GNUNET_SET_listen_cancel (s->intersection_listen); |
266 | s->intersection_listen = NULL; | 264 | s->intersection_listen = NULL; |
267 | } | 265 | } |
@@ -274,8 +272,6 @@ destroy_service_session (struct AliceServiceSession *s) | |||
274 | } | 272 | } |
275 | if (NULL != s->intersection_set) | 273 | if (NULL != s->intersection_set) |
276 | { | 274 | { |
277 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
278 | "Set intersection, set still there!\n"); | ||
279 | GNUNET_SET_destroy (s->intersection_set); | 275 | GNUNET_SET_destroy (s->intersection_set); |
280 | s->intersection_set = NULL; | 276 | s->intersection_set = NULL; |
281 | } | 277 | } |
@@ -809,10 +805,6 @@ cb_intersection_request_alice (void *cls, | |||
809 | prepare_client_end_notification (s); | 805 | prepare_client_end_notification (s); |
810 | return; | 806 | return; |
811 | } | 807 | } |
812 | GNUNET_SET_destroy (s->intersection_set); | ||
813 | s->intersection_set = NULL; | ||
814 | GNUNET_SET_listen_cancel (s->intersection_listen); | ||
815 | s->intersection_listen = NULL; | ||
816 | } | 808 | } |
817 | 809 | ||
818 | 810 | ||
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_alice.c b/src/scalarproduct/gnunet-service-scalarproduct_alice.c index a55d03900..fcb1ce032 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct_alice.c +++ b/src/scalarproduct/gnunet-service-scalarproduct_alice.c | |||
@@ -243,8 +243,6 @@ free_element_cb (void *cls, | |||
243 | static void | 243 | static void |
244 | destroy_service_session (struct AliceServiceSession *s) | 244 | destroy_service_session (struct AliceServiceSession *s) |
245 | { | 245 | { |
246 | unsigned int i; | ||
247 | |||
248 | if (GNUNET_YES == s->in_destroy) | 246 | if (GNUNET_YES == s->in_destroy) |
249 | return; | 247 | return; |
250 | s->in_destroy = GNUNET_YES; | 248 | s->in_destroy = GNUNET_YES; |
@@ -285,7 +283,7 @@ destroy_service_session (struct AliceServiceSession *s) | |||
285 | } | 283 | } |
286 | if (NULL != s->sorted_elements) | 284 | if (NULL != s->sorted_elements) |
287 | { | 285 | { |
288 | for (i=0;i<s->used_element_count;i++) | 286 | for (unsigned int i=0;i<s->used_element_count;i++) |
289 | gcry_mpi_release (s->sorted_elements[i].value); | 287 | gcry_mpi_release (s->sorted_elements[i].value); |
290 | GNUNET_free (s->sorted_elements); | 288 | GNUNET_free (s->sorted_elements); |
291 | s->sorted_elements = NULL; | 289 | s->sorted_elements = NULL; |
@@ -1043,10 +1041,6 @@ cb_intersection_request_alice (void *cls, | |||
1043 | prepare_client_end_notification (s); | 1041 | prepare_client_end_notification (s); |
1044 | return; | 1042 | return; |
1045 | } | 1043 | } |
1046 | GNUNET_SET_destroy (s->intersection_set); | ||
1047 | s->intersection_set = NULL; | ||
1048 | GNUNET_SET_listen_cancel (s->intersection_listen); | ||
1049 | s->intersection_listen = NULL; | ||
1050 | } | 1044 | } |
1051 | 1045 | ||
1052 | 1046 | ||
diff --git a/src/secretsharing/Makefile.am b/src/secretsharing/Makefile.am index 5ab8739af..c808e8200 100644 --- a/src/secretsharing/Makefile.am +++ b/src/secretsharing/Makefile.am | |||
@@ -47,7 +47,7 @@ libgnunetsecretsharing_la_SOURCES = \ | |||
47 | secretsharing_api.c \ | 47 | secretsharing_api.c \ |
48 | secretsharing_common.c \ | 48 | secretsharing_common.c \ |
49 | secretsharing.h | 49 | secretsharing.h |
50 | libgnunetsecretsharing_la_LIBADD = \ | 50 | libgnunetsecretsharing_la_LIBADD = \ |
51 | $(top_builddir)/src/util/libgnunetutil.la \ | 51 | $(top_builddir)/src/util/libgnunetutil.la \ |
52 | $(LIBGCRYPT_LIBS) \ | 52 | $(LIBGCRYPT_LIBS) \ |
53 | $(LTLIBINTL) | 53 | $(LTLIBINTL) |
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index f98d43a7d..42d06b275 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -155,6 +155,17 @@ static struct Listener *listener_head; | |||
155 | static struct Listener *listener_tail; | 155 | static struct Listener *listener_tail; |
156 | 156 | ||
157 | /** | 157 | /** |
158 | * Number of active clients. | ||
159 | */ | ||
160 | static unsigned int num_clients; | ||
161 | |||
162 | /** | ||
163 | * Are we in shutdown? if #GNUNET_YES and the number of clients | ||
164 | * drops to zero, disconnect from CADET. | ||
165 | */ | ||
166 | static int in_shutdown; | ||
167 | |||
168 | /** | ||
158 | * Counter for allocating unique IDs for clients, used to identify | 169 | * Counter for allocating unique IDs for clients, used to identify |
159 | * incoming operation requests from remote peers, that the client can | 170 | * incoming operation requests from remote peers, that the client can |
160 | * choose to accept or refuse. 0 must not be used (reserved for | 171 | * choose to accept or refuse. 0 must not be used (reserved for |
@@ -485,6 +496,7 @@ client_connect_cb (void *cls, | |||
485 | { | 496 | { |
486 | struct ClientState *cs; | 497 | struct ClientState *cs; |
487 | 498 | ||
499 | num_clients++; | ||
488 | cs = GNUNET_new (struct ClientState); | 500 | cs = GNUNET_new (struct ClientState); |
489 | cs->client = c; | 501 | cs->client = c; |
490 | cs->mq = mq; | 502 | cs->mq = mq; |
@@ -616,13 +628,29 @@ client_disconnect_cb (void *cls, | |||
616 | GNUNET_CADET_close_port (listener->open_port); | 628 | GNUNET_CADET_close_port (listener->open_port); |
617 | listener->open_port = NULL; | 629 | listener->open_port = NULL; |
618 | while (NULL != (op = listener->op_head)) | 630 | while (NULL != (op = listener->op_head)) |
631 | { | ||
632 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
633 | "Destroying incoming operation `%u' from peer `%s'\n", | ||
634 | (unsigned int) op->client_request_id, | ||
635 | GNUNET_i2s (&op->peer)); | ||
619 | incoming_destroy (op); | 636 | incoming_destroy (op); |
637 | } | ||
620 | GNUNET_CONTAINER_DLL_remove (listener_head, | 638 | GNUNET_CONTAINER_DLL_remove (listener_head, |
621 | listener_tail, | 639 | listener_tail, |
622 | listener); | 640 | listener); |
623 | GNUNET_free (listener); | 641 | GNUNET_free (listener); |
624 | } | 642 | } |
625 | GNUNET_free (cs); | 643 | GNUNET_free (cs); |
644 | num_clients--; | ||
645 | if ( (GNUNET_YES == in_shutdown) && | ||
646 | (0 == num_clients) ) | ||
647 | { | ||
648 | if (NULL != cadet) | ||
649 | { | ||
650 | GNUNET_CADET_disconnect (cadet); | ||
651 | cadet = NULL; | ||
652 | } | ||
653 | } | ||
626 | } | 654 | } |
627 | 655 | ||
628 | 656 | ||
@@ -1299,6 +1327,7 @@ handle_client_listen (void *cls, | |||
1299 | } | 1327 | } |
1300 | listener = GNUNET_new (struct Listener); | 1328 | listener = GNUNET_new (struct Listener); |
1301 | listener->cs = cs; | 1329 | listener->cs = cs; |
1330 | cs->listener = listener; | ||
1302 | listener->app_id = msg->app_id; | 1331 | listener->app_id = msg->app_id; |
1303 | listener->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation); | 1332 | listener->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation); |
1304 | GNUNET_CONTAINER_DLL_insert (listener_head, | 1333 | GNUNET_CONTAINER_DLL_insert (listener_head, |
@@ -1917,10 +1946,14 @@ static void | |||
1917 | shutdown_task (void *cls) | 1946 | shutdown_task (void *cls) |
1918 | { | 1947 | { |
1919 | /* Delay actual shutdown to allow service to disconnect clients */ | 1948 | /* Delay actual shutdown to allow service to disconnect clients */ |
1920 | if (NULL != cadet) | 1949 | in_shutdown = GNUNET_YES; |
1950 | if (0 == num_clients) | ||
1921 | { | 1951 | { |
1922 | GNUNET_CADET_disconnect (cadet); | 1952 | if (NULL != cadet) |
1923 | cadet = NULL; | 1953 | { |
1954 | GNUNET_CADET_disconnect (cadet); | ||
1955 | cadet = NULL; | ||
1956 | } | ||
1924 | } | 1957 | } |
1925 | GNUNET_STATISTICS_destroy (_GSS_statistics, | 1958 | GNUNET_STATISTICS_destroy (_GSS_statistics, |
1926 | GNUNET_YES); | 1959 | GNUNET_YES); |
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c index b2983545f..9586dcf27 100644 --- a/src/set/gnunet-service-set_union.c +++ b/src/set/gnunet-service-set_union.c | |||
@@ -364,7 +364,7 @@ fail_union_operation (struct Operation *op) | |||
364 | struct GNUNET_MQ_Envelope *ev; | 364 | struct GNUNET_MQ_Envelope *ev; |
365 | struct GNUNET_SET_ResultMessage *msg; | 365 | struct GNUNET_SET_ResultMessage *msg; |
366 | 366 | ||
367 | LOG (GNUNET_ERROR_TYPE_ERROR, | 367 | LOG (GNUNET_ERROR_TYPE_WARNING, |
368 | "union operation failed\n"); | 368 | "union operation failed\n"); |
369 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT); | 369 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT); |
370 | msg->result_status = htons (GNUNET_SET_STATUS_FAILURE); | 370 | msg->result_status = htons (GNUNET_SET_STATUS_FAILURE); |
@@ -739,11 +739,10 @@ get_order_from_difference (unsigned int diff) | |||
739 | unsigned int ibf_order; | 739 | unsigned int ibf_order; |
740 | 740 | ||
741 | ibf_order = 2; | 741 | ibf_order = 2; |
742 | while ( (1<<ibf_order) < (IBF_ALPHA * diff) || | 742 | while ( ( (1<<ibf_order) < (IBF_ALPHA * diff) || |
743 | ((1<<ibf_order) < SE_IBF_HASH_NUM) ) | 743 | ((1<<ibf_order) < SE_IBF_HASH_NUM) ) && |
744 | (ibf_order < MAX_IBF_ORDER) ) | ||
744 | ibf_order++; | 745 | ibf_order++; |
745 | if (ibf_order > MAX_IBF_ORDER) | ||
746 | ibf_order = MAX_IBF_ORDER; | ||
747 | // add one for correction | 746 | // add one for correction |
748 | return ibf_order + 1; | 747 | return ibf_order + 1; |
749 | } | 748 | } |
@@ -1405,7 +1404,7 @@ send_client_done (void *cls) | |||
1405 | } | 1404 | } |
1406 | 1405 | ||
1407 | if (PHASE_DONE != op->state->phase) { | 1406 | if (PHASE_DONE != op->state->phase) { |
1408 | LOG (GNUNET_ERROR_TYPE_ERROR, | 1407 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1409 | "union operation failed\n"); | 1408 | "union operation failed\n"); |
1410 | ev = GNUNET_MQ_msg (rm, GNUNET_MESSAGE_TYPE_SET_RESULT); | 1409 | ev = GNUNET_MQ_msg (rm, GNUNET_MESSAGE_TYPE_SET_RESULT); |
1411 | rm->result_status = htons (GNUNET_SET_STATUS_FAILURE); | 1410 | rm->result_status = htons (GNUNET_SET_STATUS_FAILURE); |
diff --git a/src/set/gnunet-service-set_union_strata_estimator.c b/src/set/gnunet-service-set_union_strata_estimator.c index e3d6bfaec..0bd22c92e 100644 --- a/src/set/gnunet-service-set_union_strata_estimator.c +++ b/src/set/gnunet-service-set_union_strata_estimator.c | |||
@@ -228,21 +228,19 @@ unsigned int | |||
228 | strata_estimator_difference (const struct StrataEstimator *se1, | 228 | strata_estimator_difference (const struct StrataEstimator *se1, |
229 | const struct StrataEstimator *se2) | 229 | const struct StrataEstimator *se2) |
230 | { | 230 | { |
231 | int i; | ||
232 | unsigned int count; | 231 | unsigned int count; |
233 | 232 | ||
234 | GNUNET_assert (se1->strata_count == se2->strata_count); | 233 | GNUNET_assert (se1->strata_count == se2->strata_count); |
235 | count = 0; | 234 | count = 0; |
236 | for (i = se1->strata_count - 1; i >= 0; i--) | 235 | for (int i = se1->strata_count - 1; i >= 0; i--) |
237 | { | 236 | { |
238 | struct InvertibleBloomFilter *diff; | 237 | struct InvertibleBloomFilter *diff; |
239 | /* number of keys decoded from the ibf */ | 238 | /* number of keys decoded from the ibf */ |
240 | int ibf_count; | ||
241 | 239 | ||
242 | /* FIXME: implement this without always allocating new IBFs */ | 240 | /* FIXME: implement this without always allocating new IBFs */ |
243 | diff = ibf_dup (se1->strata[i]); | 241 | diff = ibf_dup (se1->strata[i]); |
244 | ibf_subtract (diff, se2->strata[i]); | 242 | ibf_subtract (diff, se2->strata[i]); |
245 | for (ibf_count = 0; GNUNET_YES; ibf_count++) | 243 | for (int ibf_count = 0; GNUNET_YES; ibf_count++) |
246 | { | 244 | { |
247 | int more; | 245 | int more; |
248 | 246 | ||
diff --git a/src/set/test_set_intersection_result_full.c b/src/set/test_set_intersection_result_full.c index a36aae4d5..16de983cf 100644 --- a/src/set/test_set_intersection_result_full.c +++ b/src/set/test_set_intersection_result_full.c | |||
@@ -131,8 +131,6 @@ listen_cb (void *cls, | |||
131 | "starting intersection by accepting and committing\n"); | 131 | "starting intersection by accepting and committing\n"); |
132 | GNUNET_assert (NULL != context_msg); | 132 | GNUNET_assert (NULL != context_msg); |
133 | GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY); | 133 | GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY); |
134 | GNUNET_SET_listen_cancel (listen_handle); | ||
135 | listen_handle = NULL; | ||
136 | oh2 = GNUNET_SET_accept (request, | 134 | oh2 = GNUNET_SET_accept (request, |
137 | GNUNET_SET_RESULT_FULL, | 135 | GNUNET_SET_RESULT_FULL, |
138 | (struct GNUNET_SET_Option[]) { 0 }, | 136 | (struct GNUNET_SET_Option[]) { 0 }, |
diff --git a/src/set/test_set_union_result_symmetric.c b/src/set/test_set_union_result_symmetric.c index f81c7b8f7..3008e5aac 100644 --- a/src/set/test_set_union_result_symmetric.c +++ b/src/set/test_set_union_result_symmetric.c | |||
@@ -182,8 +182,6 @@ listen_cb (void *cls, | |||
182 | GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY); | 182 | GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY); |
183 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 183 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
184 | "listen cb called\n"); | 184 | "listen cb called\n"); |
185 | GNUNET_SET_listen_cancel (listen_handle); | ||
186 | listen_handle = NULL; | ||
187 | oh2 = GNUNET_SET_accept (request, | 185 | oh2 = GNUNET_SET_accept (request, |
188 | GNUNET_SET_RESULT_SYMMETRIC, | 186 | GNUNET_SET_RESULT_SYMMETRIC, |
189 | (struct GNUNET_SET_Option[]) { 0 }, | 187 | (struct GNUNET_SET_Option[]) { 0 }, |
diff --git a/src/social/gnunet-social.c b/src/social/gnunet-social.c index 0de8809ff..12c5bf2e1 100644 --- a/src/social/gnunet-social.c +++ b/src/social/gnunet-social.c | |||
@@ -281,7 +281,7 @@ exit_fail () | |||
281 | * This also indicates the end of the connection to the service. | 281 | * This also indicates the end of the connection to the service. |
282 | */ | 282 | */ |
283 | static void | 283 | static void |
284 | host_left () | 284 | host_left (void *cls) |
285 | { | 285 | { |
286 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 286 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
287 | "The host has left the place.\n"); | 287 | "The host has left the place.\n"); |
diff --git a/src/social/social_api.c b/src/social/social_api.c index 96ddfe912..89843831b 100644 --- a/src/social/social_api.c +++ b/src/social/social_api.c | |||
@@ -2773,6 +2773,8 @@ GNUNET_SOCIAL_app_disconnect (struct GNUNET_SOCIAL_App *app, | |||
2773 | GNUNET_ContinuationCallback disconnect_cb, | 2773 | GNUNET_ContinuationCallback disconnect_cb, |
2774 | void *disconnect_cls) | 2774 | void *disconnect_cls) |
2775 | { | 2775 | { |
2776 | if (NULL == app) return; | ||
2777 | |||
2776 | app->disconnect_cb = disconnect_cb; | 2778 | app->disconnect_cb = disconnect_cb; |
2777 | app->disconnect_cls = disconnect_cls; | 2779 | app->disconnect_cls = disconnect_cls; |
2778 | 2780 | ||
diff --git a/src/sq/sq_result_helper.c b/src/sq/sq_result_helper.c index 9579863b2..f2986a053 100644 --- a/src/sq/sq_result_helper.c +++ b/src/sq/sq_result_helper.c | |||
@@ -620,7 +620,7 @@ extract_uint16 (void *cls, | |||
620 | void *dst) | 620 | void *dst) |
621 | { | 621 | { |
622 | uint64_t v; | 622 | uint64_t v; |
623 | uint32_t *u = dst; | 623 | uint16_t *u = dst; |
624 | 624 | ||
625 | GNUNET_assert (sizeof (uint16_t) == *dst_size); | 625 | GNUNET_assert (sizeof (uint16_t) == *dst_size); |
626 | if (SQLITE_INTEGER != | 626 | if (SQLITE_INTEGER != |
diff --git a/src/statistics/Makefile.am b/src/statistics/Makefile.am index b2e256960..16a1ea2d0 100644 --- a/src/statistics/Makefile.am +++ b/src/statistics/Makefile.am | |||
@@ -90,7 +90,8 @@ endif | |||
90 | 90 | ||
91 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' | 91 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' |
92 | 92 | ||
93 | %.py: %.py.in Makefile | 93 | SUFFIXES = .py.in .py |
94 | .py.in.py: | ||
94 | $(do_subst) < $(srcdir)/$< > $@ | 95 | $(do_subst) < $(srcdir)/$< > $@ |
95 | chmod +x $@ | 96 | chmod +x $@ |
96 | 97 | ||
diff --git a/src/testbed/gnunet-daemon-testbed-underlay.c b/src/testbed/gnunet-daemon-testbed-underlay.c index 0b6c44710..3605e0384 100644 --- a/src/testbed/gnunet-daemon-testbed-underlay.c +++ b/src/testbed/gnunet-daemon-testbed-underlay.c | |||
@@ -165,7 +165,8 @@ check_access (void *cls, const struct GNUNET_PeerIdentity * pid) | |||
165 | 165 | ||
166 | 166 | ||
167 | static int | 167 | static int |
168 | get_identity (unsigned int offset, struct GNUNET_PeerIdentity *id) | 168 | get_identity (unsigned int offset, |
169 | struct GNUNET_PeerIdentity *id) | ||
169 | { | 170 | { |
170 | struct GNUNET_CRYPTO_EddsaPrivateKey private_key; | 171 | struct GNUNET_CRYPTO_EddsaPrivateKey private_key; |
171 | 172 | ||
@@ -174,7 +175,8 @@ get_identity (unsigned int offset, struct GNUNET_PeerIdentity *id) | |||
174 | GNUNET_memcpy (&private_key, | 175 | GNUNET_memcpy (&private_key, |
175 | hostkeys_data + (offset * GNUNET_TESTING_HOSTKEYFILESIZE), | 176 | hostkeys_data + (offset * GNUNET_TESTING_HOSTKEYFILESIZE), |
176 | GNUNET_TESTING_HOSTKEYFILESIZE); | 177 | GNUNET_TESTING_HOSTKEYFILESIZE); |
177 | GNUNET_CRYPTO_eddsa_key_get_public (&private_key, &id->public_key); | 178 | GNUNET_CRYPTO_eddsa_key_get_public (&private_key, |
179 | &id->public_key); | ||
178 | return GNUNET_OK; | 180 | return GNUNET_OK; |
179 | } | 181 | } |
180 | 182 | ||
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c index 09849797c..11c45a0f5 100644 --- a/src/testbed/gnunet-service-testbed_oc.c +++ b/src/testbed/gnunet-service-testbed_oc.c | |||
@@ -261,7 +261,7 @@ struct OverlayConnectContext | |||
261 | enum OverlayConnectContextType type; | 261 | enum OverlayConnectContextType type; |
262 | 262 | ||
263 | /** | 263 | /** |
264 | * The id of the second peer which is has to connect to the first peer | 264 | * The id of the second peer which has to connect to the first peer |
265 | */ | 265 | */ |
266 | uint32_t other_peer_id; | 266 | uint32_t other_peer_id; |
267 | }; | 267 | }; |
@@ -930,10 +930,10 @@ send_hello (void *cls) | |||
930 | other_peer_str); | 930 | other_peer_str); |
931 | GNUNET_free (other_peer_str); | 931 | GNUNET_free (other_peer_str); |
932 | lp2c->ohh = | 932 | lp2c->ohh = |
933 | GNUNET_TRANSPORT_offer_hello (lp2c->tcc.cfg, | 933 | GNUNET_TRANSPORT_offer_hello (lp2c->tcc.cfg, |
934 | occ->hello, | 934 | occ->hello, |
935 | &occ_hello_sent_cb, | 935 | &occ_hello_sent_cb, |
936 | occ); | 936 | occ); |
937 | if (NULL == lp2c->ohh) | 937 | if (NULL == lp2c->ohh) |
938 | { | 938 | { |
939 | GNUNET_break (0); | 939 | GNUNET_break (0); |
@@ -1001,6 +1001,11 @@ p2_transport_connect (struct OverlayConnectContext *occ) | |||
1001 | { | 1001 | { |
1002 | struct Peer *peer2; | 1002 | struct Peer *peer2; |
1003 | 1003 | ||
1004 | /* HUH? Why to *obtain* HELLO? Seems we use this to *SEND* the | ||
1005 | HELLO! */ | ||
1006 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1007 | "Connecting to transport of peer %s to obtain HELLO\n", | ||
1008 | GNUNET_i2s (&occ->other_peer_identity)); | ||
1004 | GNUNET_assert (NULL == occ->emsg); | 1009 | GNUNET_assert (NULL == occ->emsg); |
1005 | GNUNET_assert (NULL != occ->hello); | 1010 | GNUNET_assert (NULL != occ->hello); |
1006 | GNUNET_assert (NULL == occ->ghh); | 1011 | GNUNET_assert (NULL == occ->ghh); |
diff --git a/src/testbed/gnunet-testbed-profiler.c b/src/testbed/gnunet-testbed-profiler.c index 9829bbf0d..0fa6d8172 100644 --- a/src/testbed/gnunet-testbed-profiler.c +++ b/src/testbed/gnunet-testbed-profiler.c | |||
@@ -175,9 +175,7 @@ controller_event_cb (void *cls, | |||
175 | { | 175 | { |
176 | printf ("\nAborting due to very high failure rate\n"); | 176 | printf ("\nAborting due to very high failure rate\n"); |
177 | print_overlay_links_summary (); | 177 | print_overlay_links_summary (); |
178 | if (NULL != abort_task) | 178 | GNUNET_SCHEDULER_shutdown (); |
179 | GNUNET_SCHEDULER_cancel (abort_task); | ||
180 | abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL); | ||
181 | return; | 179 | return; |
182 | } | 180 | } |
183 | } | 181 | } |
@@ -260,11 +258,12 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
260 | event_mask = 0; | 258 | event_mask = 0; |
261 | event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); | 259 | event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); |
262 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | 260 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); |
263 | GNUNET_TESTBED_run (hosts_file, cfg, num_peers, event_mask, controller_event_cb, | 261 | GNUNET_TESTBED_run (hosts_file, cfg, num_peers, event_mask, |
264 | NULL, &test_run, NULL); | 262 | &controller_event_cb, NULL, |
263 | &test_run, NULL); | ||
265 | abort_task = | 264 | abort_task = |
266 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_abort, | 265 | GNUNET_SCHEDULER_add_shutdown (&do_abort, |
267 | NULL); | 266 | NULL); |
268 | } | 267 | } |
269 | 268 | ||
270 | 269 | ||
@@ -310,6 +309,8 @@ main (int argc, char *const *argv) | |||
310 | const char *binaryHelp = "gnunet-testbed-profiler [OPTIONS]"; | 309 | const char *binaryHelp = "gnunet-testbed-profiler [OPTIONS]"; |
311 | int ret; | 310 | int ret; |
312 | 311 | ||
312 | unsetenv ("XDG_DATA_HOME"); | ||
313 | unsetenv ("XDG_CONFIG_HOME"); | ||
313 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 314 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) |
314 | return 2; | 315 | return 2; |
315 | result = GNUNET_SYSERR; | 316 | result = GNUNET_SYSERR; |
diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c index 7bc36d1b4..7d0ccd269 100644 --- a/src/testbed/testbed_api_topology.c +++ b/src/testbed/testbed_api_topology.c | |||
@@ -1051,7 +1051,7 @@ gen_topo_from_file (struct TopologyContext *tc, | |||
1051 | state = PEER_INDEX; | 1051 | state = PEER_INDEX; |
1052 | while (offset < fs) | 1052 | while (offset < fs) |
1053 | { | 1053 | { |
1054 | if (0 != isspace (data[offset])) | 1054 | if (0 != isspace ((unsigned char) data[offset])) |
1055 | { | 1055 | { |
1056 | offset++; | 1056 | offset++; |
1057 | continue; | 1057 | continue; |
diff --git a/src/topology/friends.c b/src/topology/friends.c index a960fad17..65f2700bb 100644 --- a/src/topology/friends.c +++ b/src/topology/friends.c | |||
@@ -95,7 +95,7 @@ GNUNET_FRIENDS_parse (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
95 | pos = 0; | 95 | pos = 0; |
96 | while (pos < fsize) | 96 | while (pos < fsize) |
97 | { | 97 | { |
98 | while ((pos < fsize) && (! isspace ((int) data[pos]))) | 98 | while ((pos < fsize) && (! isspace ((unsigned char) data[pos]))) |
99 | pos++; | 99 | pos++; |
100 | if (GNUNET_OK != | 100 | if (GNUNET_OK != |
101 | GNUNET_CRYPTO_eddsa_public_key_from_string (&data[start], | 101 | GNUNET_CRYPTO_eddsa_public_key_from_string (&data[start], |
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index ec4d82164..124260c41 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -541,6 +541,13 @@ client_disconnect_cb (void *cls, | |||
541 | GNUNET_CONTAINER_multipeermap_iterate (active_stccs, | 541 | GNUNET_CONTAINER_multipeermap_iterate (active_stccs, |
542 | &mark_match_down, | 542 | &mark_match_down, |
543 | tc); | 543 | tc); |
544 | for (struct AddressToStringContext *cur = a2s_head; | ||
545 | NULL != cur; | ||
546 | cur = cur->next) | ||
547 | { | ||
548 | if (cur->tc == tc) | ||
549 | cur->tc = NULL; | ||
550 | } | ||
544 | GNUNET_CONTAINER_DLL_remove (clients_head, | 551 | GNUNET_CONTAINER_DLL_remove (clients_head, |
545 | clients_tail, | 552 | clients_tail, |
546 | tc); | 553 | tc); |
@@ -681,6 +688,8 @@ handle_client_hello (void *cls, | |||
681 | { | 688 | { |
682 | struct TransportClient *tc = cls; | 689 | struct TransportClient *tc = cls; |
683 | 690 | ||
691 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
692 | "Received HELLO message\n"); | ||
684 | GST_validation_handle_hello (message); | 693 | GST_validation_handle_hello (message); |
685 | GNUNET_SERVICE_client_continue (tc->client); | 694 | GNUNET_SERVICE_client_continue (tc->client); |
686 | } | 695 | } |
@@ -864,6 +873,8 @@ transmit_address_to_client (void *cls, | |||
864 | 873 | ||
865 | GNUNET_assert ( (GNUNET_OK == res) || | 874 | GNUNET_assert ( (GNUNET_OK == res) || |
866 | (GNUNET_SYSERR == res) ); | 875 | (GNUNET_SYSERR == res) ); |
876 | if (NULL == actx->tc) | ||
877 | return; | ||
867 | if (NULL == buf) | 878 | if (NULL == buf) |
868 | { | 879 | { |
869 | env = GNUNET_MQ_msg (atsm, | 880 | env = GNUNET_MQ_msg (atsm, |
@@ -878,6 +889,7 @@ transmit_address_to_client (void *cls, | |||
878 | GNUNET_CONTAINER_DLL_remove (a2s_head, | 889 | GNUNET_CONTAINER_DLL_remove (a2s_head, |
879 | a2s_tail, | 890 | a2s_tail, |
880 | actx); | 891 | actx); |
892 | GNUNET_free (actx); | ||
881 | return; | 893 | return; |
882 | } | 894 | } |
883 | if (GNUNET_SYSERR == res) | 895 | if (GNUNET_SYSERR == res) |
@@ -2792,7 +2804,7 @@ run (void *cls, | |||
2792 | GNUNET_assert (NULL != GST_my_private_key); | 2804 | GNUNET_assert (NULL != GST_my_private_key); |
2793 | 2805 | ||
2794 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 2806 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
2795 | "My identity is `%4s'\n", | 2807 | "My identity is `%s'\n", |
2796 | GNUNET_i2s_full (&GST_my_identity)); | 2808 | GNUNET_i2s_full (&GST_my_identity)); |
2797 | 2809 | ||
2798 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | 2810 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c index a20c998b3..01e115bfc 100644 --- a/src/transport/gnunet-service-transport_ats.c +++ b/src/transport/gnunet-service-transport_ats.c | |||
@@ -337,15 +337,10 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address, | |||
337 | return; /* our own, ignore! */ | 337 | return; /* our own, ignore! */ |
338 | ai = find_ai (address, | 338 | ai = find_ai (address, |
339 | session); | 339 | session); |
340 | if (NULL == ai) | 340 | if (NULL == ai || NULL == ai->ar) |
341 | { | 341 | { |
342 | GNUNET_assert (0); | 342 | /* The address is already gone/blocked, this can happen during a blacklist |
343 | return; | 343 | * callback. */ |
344 | } | ||
345 | if (NULL == ai->ar) | ||
346 | { | ||
347 | /* already blocked, how did it get used!? */ | ||
348 | GNUNET_break (0); | ||
349 | return; | 344 | return; |
350 | } | 345 | } |
351 | ai->back_off = GNUNET_TIME_STD_BACKOFF (ai->back_off); | 346 | ai->back_off = GNUNET_TIME_STD_BACKOFF (ai->back_off); |
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 19f5fd081..ac72a667c 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -2433,7 +2433,10 @@ switch_address_bl_check_cont (void *cls, | |||
2433 | goto cleanup; | 2433 | goto cleanup; |
2434 | 2434 | ||
2435 | papi = GST_plugins_find (address->transport_name); | 2435 | papi = GST_plugins_find (address->transport_name); |
2436 | GNUNET_assert (NULL != papi); | 2436 | if (NULL == papi) { |
2437 | /* This can happen during shutdown. */ | ||
2438 | goto cleanup; | ||
2439 | } | ||
2437 | 2440 | ||
2438 | if (GNUNET_NO == result) | 2441 | if (GNUNET_NO == result) |
2439 | { | 2442 | { |
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index 4a6d427be..cd5aeb5e2 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c | |||
@@ -784,15 +784,24 @@ revalidate_address (void *cls) | |||
784 | GNUNET_STATISTICS_update (GST_stats, | 784 | GNUNET_STATISTICS_update (GST_stats, |
785 | gettext_noop ("# address revalidations started"), 1, | 785 | gettext_noop ("# address revalidations started"), 1, |
786 | GNUNET_NO); | 786 | GNUNET_NO); |
787 | if (NULL != ve->bc) | ||
788 | { | ||
789 | GST_blacklist_test_cancel (ve->bc); | ||
790 | ve->bc = NULL; | ||
791 | } | ||
787 | bc = GST_blacklist_test_allowed (&ve->address->peer, | 792 | bc = GST_blacklist_test_allowed (&ve->address->peer, |
788 | ve->address->transport_name, | 793 | ve->address->transport_name, |
789 | &transmit_ping_if_allowed, | 794 | &transmit_ping_if_allowed, |
790 | ve, | 795 | ve, |
791 | NULL, | 796 | NULL, |
792 | NULL); | 797 | NULL); |
793 | if (NULL != bc) | 798 | if (NULL != bc) |
794 | ve->bc = bc; /* only set 'bc' if 'transmit_ping_if_allowed' was not already | 799 | { |
795 | * called... */ | 800 | /* If transmit_ping_if_allowed was already called it may have freed ve, |
801 | * so only set ve->bc if it has not been called. | ||
802 | */ | ||
803 | ve->bc = bc; | ||
804 | } | ||
796 | } | 805 | } |
797 | 806 | ||
798 | 807 | ||
@@ -1338,6 +1347,9 @@ GST_validation_handle_address (const struct GNUNET_HELLO_Address *address) | |||
1338 | if (NULL == papi) | 1347 | if (NULL == papi) |
1339 | { | 1348 | { |
1340 | /* This plugin is currently unvailable ... ignore */ | 1349 | /* This plugin is currently unvailable ... ignore */ |
1350 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1351 | "No plugin available for %s\n", | ||
1352 | address->transport_name); | ||
1341 | return; | 1353 | return; |
1342 | } | 1354 | } |
1343 | ve = find_validation_entry (address); | 1355 | ve = find_validation_entry (address); |
@@ -1349,6 +1361,13 @@ GST_validation_handle_address (const struct GNUNET_HELLO_Address *address) | |||
1349 | GNUNET_i2s (&ve->address->peer)); | 1361 | GNUNET_i2s (&ve->address->peer)); |
1350 | ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); | 1362 | ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); |
1351 | } | 1363 | } |
1364 | else | ||
1365 | { | ||
1366 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1367 | "Validation already running for address `%s' of %s\n", | ||
1368 | GST_plugins_a2s (ve->address), | ||
1369 | GNUNET_i2s (&ve->address->peer)); | ||
1370 | } | ||
1352 | } | 1371 | } |
1353 | 1372 | ||
1354 | 1373 | ||
@@ -1648,6 +1667,9 @@ GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) | |||
1648 | sizeof (struct GNUNET_PeerIdentity))) | 1667 | sizeof (struct GNUNET_PeerIdentity))) |
1649 | { | 1668 | { |
1650 | /* got our own HELLO, how boring */ | 1669 | /* got our own HELLO, how boring */ |
1670 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1671 | "Validation received our own HELLO (%s), ignoring\n", | ||
1672 | GNUNET_i2s (&pid)); | ||
1651 | return GNUNET_OK; | 1673 | return GNUNET_OK; |
1652 | } | 1674 | } |
1653 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1675 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
diff --git a/src/transport/test_transport_testing_restart.c b/src/transport/test_transport_testing_restart.c index 595177e03..06275055d 100644 --- a/src/transport/test_transport_testing_restart.c +++ b/src/transport/test_transport_testing_restart.c | |||
@@ -71,7 +71,8 @@ restart_cb (void *cls) | |||
71 | p->no, | 71 | p->no, |
72 | GNUNET_i2s (&p->id)); | 72 | GNUNET_i2s (&p->id)); |
73 | ret = 0; | 73 | ret = 0; |
74 | end (); | 74 | GNUNET_SCHEDULER_add_now (&end, |
75 | NULL); | ||
75 | } | 76 | } |
76 | 77 | ||
77 | 78 | ||
diff --git a/src/transport/test_transport_testing_startstop.c b/src/transport/test_transport_testing_startstop.c index 6ac0250cc..931e922c4 100644 --- a/src/transport/test_transport_testing_startstop.c +++ b/src/transport/test_transport_testing_startstop.c | |||
@@ -71,7 +71,8 @@ start_cb (void *cls) | |||
71 | p->no, | 71 | p->no, |
72 | GNUNET_i2s (&p->id)); | 72 | GNUNET_i2s (&p->id)); |
73 | ret = 0; | 73 | ret = 0; |
74 | end (); | 74 | GNUNET_SCHEDULER_add_now (&end, |
75 | NULL); | ||
75 | } | 76 | } |
76 | 77 | ||
77 | 78 | ||
diff --git a/src/transport/transport-testing.c b/src/transport/transport-testing.c index 2aa6cdbb0..68cda3bd7 100644 --- a/src/transport/transport-testing.c +++ b/src/transport/transport-testing.c | |||
@@ -384,7 +384,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_Handle *tth | |||
384 | { | 384 | { |
385 | char *emsg = NULL; | 385 | char *emsg = NULL; |
386 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p; | 386 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p; |
387 | struct GNUNET_PeerIdentity *dummy; | 387 | struct GNUNET_PeerIdentity dummy; |
388 | unsigned int i; | 388 | unsigned int i; |
389 | 389 | ||
390 | if (GNUNET_NO == GNUNET_DISK_file_test (cfgname)) | 390 | if (GNUNET_NO == GNUNET_DISK_file_test (cfgname)) |
@@ -678,6 +678,11 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_PeerContext | |||
678 | GNUNET_CONFIGURATION_destroy (p->cfg); | 678 | GNUNET_CONFIGURATION_destroy (p->cfg); |
679 | p->cfg = NULL; | 679 | p->cfg = NULL; |
680 | } | 680 | } |
681 | if (NULL != p->handlers) | ||
682 | { | ||
683 | GNUNET_free (p->handlers); | ||
684 | p->handlers = NULL; | ||
685 | } | ||
681 | GNUNET_CONTAINER_DLL_remove (tth->p_head, | 686 | GNUNET_CONTAINER_DLL_remove (tth->p_head, |
682 | tth->p_tail, | 687 | tth->p_tail, |
683 | p); | 688 | p); |
diff --git a/src/util/.gitignore b/src/util/.gitignore index 3576a2134..d32a66833 100644 --- a/src/util/.gitignore +++ b/src/util/.gitignore | |||
@@ -67,3 +67,4 @@ test_socks.nc | |||
67 | perf_crypto_asymmetric | 67 | perf_crypto_asymmetric |
68 | perf_crypto_hash | 68 | perf_crypto_hash |
69 | perf_crypto_symmetric | 69 | perf_crypto_symmetric |
70 | perf_crypto_rsa | ||
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index eaa49a991..7845932ee 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c | |||
@@ -354,6 +354,37 @@ GNUNET_CRYPTO_eddsa_public_key_to_string (const struct GNUNET_CRYPTO_EddsaPublic | |||
354 | 354 | ||
355 | 355 | ||
356 | /** | 356 | /** |
357 | * Convert a private key to a string. | ||
358 | * | ||
359 | * @param priv key to convert | ||
360 | * @return string representing @a pub | ||
361 | */ | ||
362 | char * | ||
363 | GNUNET_CRYPTO_eddsa_private_key_to_string (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | ||
364 | { | ||
365 | char *privkeybuf; | ||
366 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8; | ||
367 | char *end; | ||
368 | |||
369 | if (keylen % 5 > 0) | ||
370 | keylen += 5 - keylen % 5; | ||
371 | keylen /= 5; | ||
372 | privkeybuf = GNUNET_malloc (keylen + 1); | ||
373 | end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv, | ||
374 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey), | ||
375 | privkeybuf, | ||
376 | keylen); | ||
377 | if (NULL == end) | ||
378 | { | ||
379 | GNUNET_free (privkeybuf); | ||
380 | return NULL; | ||
381 | } | ||
382 | *end = '\0'; | ||
383 | return privkeybuf; | ||
384 | } | ||
385 | |||
386 | |||
387 | /** | ||
357 | * Convert a string representing a public key to a public key. | 388 | * Convert a string representing a public key to a public key. |
358 | * | 389 | * |
359 | * @param enc encoded public key | 390 | * @param enc encoded public key |
@@ -374,9 +405,10 @@ GNUNET_CRYPTO_ecdsa_public_key_from_string (const char *enc, | |||
374 | if (enclen != keylen) | 405 | if (enclen != keylen) |
375 | return GNUNET_SYSERR; | 406 | return GNUNET_SYSERR; |
376 | 407 | ||
377 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen, | 408 | if (GNUNET_OK != |
378 | pub, | 409 | GNUNET_STRINGS_string_to_data (enc, enclen, |
379 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | 410 | pub, |
411 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
380 | return GNUNET_SYSERR; | 412 | return GNUNET_SYSERR; |
381 | return GNUNET_OK; | 413 | return GNUNET_OK; |
382 | } | 414 | } |
@@ -403,9 +435,10 @@ GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc, | |||
403 | if (enclen != keylen) | 435 | if (enclen != keylen) |
404 | return GNUNET_SYSERR; | 436 | return GNUNET_SYSERR; |
405 | 437 | ||
406 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen, | 438 | if (GNUNET_OK != |
407 | pub, | 439 | GNUNET_STRINGS_string_to_data (enc, enclen, |
408 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))) | 440 | pub, |
441 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))) | ||
409 | return GNUNET_SYSERR; | 442 | return GNUNET_SYSERR; |
410 | return GNUNET_OK; | 443 | return GNUNET_OK; |
411 | } | 444 | } |
diff --git a/src/util/crypto_paillier.c b/src/util/crypto_paillier.c index 3ed025a2a..530a2957f 100644 --- a/src/util/crypto_paillier.c +++ b/src/util/crypto_paillier.c | |||
@@ -370,9 +370,11 @@ GNUNET_CRYPTO_paillier_decrypt (const struct GNUNET_CRYPTO_PaillierPrivateKey *p | |||
370 | /* mod = cmum1 / n (mod n) */ | 370 | /* mod = cmum1 / n (mod n) */ |
371 | GNUNET_assert (0 != (mod = gcry_mpi_new (0))); | 371 | GNUNET_assert (0 != (mod = gcry_mpi_new (0))); |
372 | gcry_mpi_div (mod, NULL, cmum1, n, 0); | 372 | gcry_mpi_div (mod, NULL, cmum1, n, 0); |
373 | gcry_mpi_release (cmum1); | ||
373 | 374 | ||
374 | /* m = mod * mu mod n */ | 375 | /* m = mod * mu mod n */ |
375 | gcry_mpi_mulm (m, mod, mu, n); | 376 | gcry_mpi_mulm (m, mod, mu, n); |
377 | gcry_mpi_release (mod); | ||
376 | gcry_mpi_release (mu); | 378 | gcry_mpi_release (mu); |
377 | gcry_mpi_release (n); | 379 | gcry_mpi_release (n); |
378 | } | 380 | } |
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index 7a108c21b..a985d8e59 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c | |||
@@ -1046,7 +1046,7 @@ GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key) | |||
1046 | * @return unblinded signature on success, NULL if RSA key is bad or malicious. | 1046 | * @return unblinded signature on success, NULL if RSA key is bad or malicious. |
1047 | */ | 1047 | */ |
1048 | struct GNUNET_CRYPTO_RsaSignature * | 1048 | struct GNUNET_CRYPTO_RsaSignature * |
1049 | GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig, | 1049 | GNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig, |
1050 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, | 1050 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, |
1051 | struct GNUNET_CRYPTO_RsaPublicKey *pkey) | 1051 | struct GNUNET_CRYPTO_RsaPublicKey *pkey) |
1052 | { | 1052 | { |
diff --git a/src/util/gnunet-ecc.c b/src/util/gnunet-ecc.c index 42ecc2101..66a4bd3e9 100644 --- a/src/util/gnunet-ecc.c +++ b/src/util/gnunet-ecc.c | |||
@@ -49,6 +49,11 @@ static unsigned int list_keys_count; | |||
49 | static int print_public_key; | 49 | static int print_public_key; |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * Flag for printing private key. | ||
53 | */ | ||
54 | static int print_private_key; | ||
55 | |||
56 | /** | ||
52 | * Flag for printing public key in hex. | 57 | * Flag for printing public key in hex. |
53 | */ | 58 | */ |
54 | static int print_public_key_hex; | 59 | static int print_public_key_hex; |
@@ -377,7 +382,7 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
377 | create_keys (args[0], args[1]); | 382 | create_keys (args[0], args[1]); |
378 | return; | 383 | return; |
379 | } | 384 | } |
380 | if (print_public_key || print_public_key_hex) | 385 | if (print_public_key || print_public_key_hex || print_private_key) |
381 | { | 386 | { |
382 | char *str; | 387 | char *str; |
383 | struct GNUNET_DISK_FileHandle *keyfile; | 388 | struct GNUNET_DISK_FileHandle *keyfile; |
@@ -388,19 +393,26 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
388 | GNUNET_DISK_PERM_NONE); | 393 | GNUNET_DISK_PERM_NONE); |
389 | if (NULL == keyfile) | 394 | if (NULL == keyfile) |
390 | return; | 395 | return; |
391 | while (sizeof (pk) == GNUNET_DISK_file_read (keyfile, &pk, sizeof (pk))) | 396 | while (sizeof (pk) == |
397 | GNUNET_DISK_file_read (keyfile, &pk, sizeof (pk))) | ||
392 | { | 398 | { |
393 | GNUNET_CRYPTO_eddsa_key_get_public (&pk, &pub); | 399 | GNUNET_CRYPTO_eddsa_key_get_public (&pk, &pub); |
394 | if (print_public_key_hex) | 400 | if (print_public_key_hex) |
395 | { | 401 | { |
396 | print_hex ("HEX:", &pub, sizeof (pub)); | 402 | print_hex ("HEX:", &pub, sizeof (pub)); |
397 | } | 403 | } |
398 | else | 404 | else if (print_public_key) |
399 | { | 405 | { |
400 | str = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub); | 406 | str = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub); |
401 | FPRINTF (stdout, "%s\n", str); | 407 | FPRINTF (stdout, "%s\n", str); |
402 | GNUNET_free (str); | 408 | GNUNET_free (str); |
403 | } | 409 | } |
410 | else if (print_private_key) | ||
411 | { | ||
412 | str = GNUNET_CRYPTO_eddsa_private_key_to_string (&pk); | ||
413 | FPRINTF (stdout, "%s\n", str); | ||
414 | GNUNET_free (str); | ||
415 | } | ||
404 | } | 416 | } |
405 | GNUNET_DISK_file_close (keyfile); | 417 | GNUNET_DISK_file_close (keyfile); |
406 | } | 418 | } |
@@ -438,6 +450,10 @@ main (int argc, | |||
438 | "print-public-key", | 450 | "print-public-key", |
439 | gettext_noop ("print the public key in ASCII format"), | 451 | gettext_noop ("print the public key in ASCII format"), |
440 | &print_public_key), | 452 | &print_public_key), |
453 | GNUNET_GETOPT_option_flag ('P', | ||
454 | "print-private-key", | ||
455 | gettext_noop ("print the private key in ASCII format"), | ||
456 | &print_private_key), | ||
441 | GNUNET_GETOPT_option_flag ('x', | 457 | GNUNET_GETOPT_option_flag ('x', |
442 | "print-hex", | 458 | "print-hex", |
443 | gettext_noop ("print the public key in HEX format"), | 459 | gettext_noop ("print the public key in HEX format"), |
diff --git a/src/util/network.c b/src/util/network.c index 66a468e45..942288613 100644 --- a/src/util/network.c +++ b/src/util/network.c | |||
@@ -1793,10 +1793,18 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1793 | _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"), | 1793 | _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"), |
1794 | "select"); | 1794 | "select"); |
1795 | } | 1795 | } |
1796 | tv.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us; | 1796 | if (timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us > (unsigned long long) LONG_MAX) |
1797 | tv.tv_usec = | 1797 | { |
1798 | (timeout.rel_value_us - | 1798 | tv.tv_sec = LONG_MAX; |
1799 | (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us)); | 1799 | tv.tv_usec = 999999L; |
1800 | } | ||
1801 | else | ||
1802 | { | ||
1803 | tv.tv_sec = (long) (timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us); | ||
1804 | tv.tv_usec = | ||
1805 | (timeout.rel_value_us - | ||
1806 | (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us)); | ||
1807 | } | ||
1800 | return select (nfds, | 1808 | return select (nfds, |
1801 | (NULL != rfds) ? &rfds->sds : NULL, | 1809 | (NULL != rfds) ? &rfds->sds : NULL, |
1802 | (NULL != wfds) ? &wfds->sds : NULL, | 1810 | (NULL != wfds) ? &wfds->sds : NULL, |
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index 33a340729..11b8134d6 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c | |||
@@ -469,6 +469,7 @@ handle_response (void *cls, | |||
469 | uint16_t size; | 469 | uint16_t size; |
470 | char *nret; | 470 | char *nret; |
471 | 471 | ||
472 | GNUNET_assert (NULL != rh); | ||
472 | size = ntohs (msg->size); | 473 | size = ntohs (msg->size); |
473 | if (size == sizeof (struct GNUNET_MessageHeader)) | 474 | if (size == sizeof (struct GNUNET_MessageHeader)) |
474 | { | 475 | { |
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index b07c51811..4615ecee9 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -785,6 +785,14 @@ void | |||
785 | GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, | 785 | GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, |
786 | void *task_cls) | 786 | void *task_cls) |
787 | { | 787 | { |
788 | GNUNET_SCHEDULER_run_with_optional_signals(GNUNET_YES, task, task_cls); | ||
789 | } | ||
790 | |||
791 | void | ||
792 | GNUNET_SCHEDULER_run_with_optional_signals (int install_signals, | ||
793 | GNUNET_SCHEDULER_TaskCallback task, | ||
794 | void *task_cls) | ||
795 | { | ||
788 | struct GNUNET_NETWORK_FDSet *rs; | 796 | struct GNUNET_NETWORK_FDSet *rs; |
789 | struct GNUNET_NETWORK_FDSet *ws; | 797 | struct GNUNET_NETWORK_FDSet *ws; |
790 | struct GNUNET_TIME_Relative timeout; | 798 | struct GNUNET_TIME_Relative timeout; |
@@ -818,24 +826,29 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, | |||
818 | GNUNET_DISK_PIPE_END_READ); | 826 | GNUNET_DISK_PIPE_END_READ); |
819 | GNUNET_assert (NULL != pr); | 827 | GNUNET_assert (NULL != pr); |
820 | my_pid = getpid (); | 828 | my_pid = getpid (); |
821 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 829 | |
822 | "Registering signal handlers\n"); | 830 | if (GNUNET_YES == install_signals) |
823 | shc_int = GNUNET_SIGNAL_handler_install (SIGINT, | 831 | { |
832 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
833 | "Registering signal handlers\n"); | ||
834 | shc_int = GNUNET_SIGNAL_handler_install (SIGINT, | ||
835 | &sighandler_shutdown); | ||
836 | shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, | ||
824 | &sighandler_shutdown); | 837 | &sighandler_shutdown); |
825 | shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, | ||
826 | &sighandler_shutdown); | ||
827 | #if (SIGTERM != GNUNET_TERM_SIG) | 838 | #if (SIGTERM != GNUNET_TERM_SIG) |
828 | shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG, | 839 | shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG, |
829 | &sighandler_shutdown); | 840 | &sighandler_shutdown); |
830 | #endif | 841 | #endif |
831 | #ifndef MINGW | 842 | #ifndef MINGW |
832 | shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE, | 843 | shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE, |
833 | &sighandler_pipe); | 844 | &sighandler_pipe); |
834 | shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, | 845 | shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, |
835 | &sighandler_shutdown); | 846 | &sighandler_shutdown); |
836 | shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, | 847 | shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, |
837 | &sighandler_shutdown); | 848 | &sighandler_shutdown); |
838 | #endif | 849 | #endif |
850 | } | ||
851 | |||
839 | current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; | 852 | current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; |
840 | current_lifeness = GNUNET_YES; | 853 | current_lifeness = GNUNET_YES; |
841 | GNUNET_SCHEDULER_add_with_reason_and_priority (task, | 854 | GNUNET_SCHEDULER_add_with_reason_and_priority (task, |
@@ -951,16 +964,21 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, | |||
951 | busy_wait_warning = 0; | 964 | busy_wait_warning = 0; |
952 | } | 965 | } |
953 | } | 966 | } |
954 | GNUNET_SIGNAL_handler_uninstall (shc_int); | 967 | |
955 | GNUNET_SIGNAL_handler_uninstall (shc_term); | 968 | if (GNUNET_YES == install_signals) |
969 | { | ||
970 | GNUNET_SIGNAL_handler_uninstall (shc_int); | ||
971 | GNUNET_SIGNAL_handler_uninstall (shc_term); | ||
956 | #if (SIGTERM != GNUNET_TERM_SIG) | 972 | #if (SIGTERM != GNUNET_TERM_SIG) |
957 | GNUNET_SIGNAL_handler_uninstall (shc_gterm); | 973 | GNUNET_SIGNAL_handler_uninstall (shc_gterm); |
958 | #endif | 974 | #endif |
959 | #ifndef MINGW | 975 | #ifndef MINGW |
960 | GNUNET_SIGNAL_handler_uninstall (shc_pipe); | 976 | GNUNET_SIGNAL_handler_uninstall (shc_pipe); |
961 | GNUNET_SIGNAL_handler_uninstall (shc_quit); | 977 | GNUNET_SIGNAL_handler_uninstall (shc_quit); |
962 | GNUNET_SIGNAL_handler_uninstall (shc_hup); | 978 | GNUNET_SIGNAL_handler_uninstall (shc_hup); |
963 | #endif | 979 | #endif |
980 | } | ||
981 | |||
964 | GNUNET_DISK_pipe_close (shutdown_pipe_handle); | 982 | GNUNET_DISK_pipe_close (shutdown_pipe_handle); |
965 | shutdown_pipe_handle = NULL; | 983 | shutdown_pipe_handle = NULL; |
966 | GNUNET_NETWORK_fdset_destroy (rs); | 984 | GNUNET_NETWORK_fdset_destroy (rs); |
diff --git a/src/util/test_crypto_paillier.c b/src/util/test_crypto_paillier.c index 9950978c1..1e7e0b301 100644 --- a/src/util/test_crypto_paillier.c +++ b/src/util/test_crypto_paillier.c | |||
@@ -37,6 +37,7 @@ test_crypto () | |||
37 | struct GNUNET_CRYPTO_PaillierCiphertext ciphertext; | 37 | struct GNUNET_CRYPTO_PaillierCiphertext ciphertext; |
38 | struct GNUNET_CRYPTO_PaillierPublicKey public_key; | 38 | struct GNUNET_CRYPTO_PaillierPublicKey public_key; |
39 | struct GNUNET_CRYPTO_PaillierPrivateKey private_key; | 39 | struct GNUNET_CRYPTO_PaillierPrivateKey private_key; |
40 | int ret = 0; | ||
40 | 41 | ||
41 | GNUNET_CRYPTO_paillier_create (&public_key, | 42 | GNUNET_CRYPTO_paillier_create (&public_key, |
42 | &private_key); | 43 | &private_key); |
@@ -54,7 +55,6 @@ test_crypto () | |||
54 | &public_key, | 55 | &public_key, |
55 | &ciphertext, | 56 | &ciphertext, |
56 | plaintext_result); | 57 | plaintext_result); |
57 | |||
58 | if (0 != gcry_mpi_cmp (plaintext, | 58 | if (0 != gcry_mpi_cmp (plaintext, |
59 | plaintext_result)) | 59 | plaintext_result)) |
60 | { | 60 | { |
@@ -65,9 +65,11 @@ test_crypto () | |||
65 | plaintext); | 65 | plaintext); |
66 | gcry_log_debugmpi ("\n", | 66 | gcry_log_debugmpi ("\n", |
67 | plaintext_result); | 67 | plaintext_result); |
68 | return 1; | 68 | ret = 1; |
69 | } | 69 | } |
70 | return 0; | 70 | gcry_mpi_release (plaintext); |
71 | gcry_mpi_release (plaintext_result); | ||
72 | return ret; | ||
71 | } | 73 | } |
72 | 74 | ||
73 | 75 | ||
@@ -84,6 +86,7 @@ test_hom_simple (unsigned int a, | |||
84 | struct GNUNET_CRYPTO_PaillierCiphertext c_result; | 86 | struct GNUNET_CRYPTO_PaillierCiphertext c_result; |
85 | struct GNUNET_CRYPTO_PaillierPublicKey public_key; | 87 | struct GNUNET_CRYPTO_PaillierPublicKey public_key; |
86 | struct GNUNET_CRYPTO_PaillierPrivateKey private_key; | 88 | struct GNUNET_CRYPTO_PaillierPrivateKey private_key; |
89 | int ret = 0; | ||
87 | 90 | ||
88 | GNUNET_CRYPTO_paillier_create (&public_key, | 91 | GNUNET_CRYPTO_paillier_create (&public_key, |
89 | &private_key); | 92 | &private_key); |
@@ -119,9 +122,13 @@ test_hom_simple (unsigned int a, | |||
119 | "GNUNET_CRYPTO_paillier failed simple math!\n"); | 122 | "GNUNET_CRYPTO_paillier failed simple math!\n"); |
120 | gcry_log_debugmpi ("got ", hom_result); | 123 | gcry_log_debugmpi ("got ", hom_result); |
121 | gcry_log_debugmpi ("wanted ", result); | 124 | gcry_log_debugmpi ("wanted ", result); |
122 | return 1; | 125 | ret = 1; |
123 | } | 126 | } |
124 | return 0; | 127 | gcry_mpi_release (m1); |
128 | gcry_mpi_release (m2); | ||
129 | gcry_mpi_release (result); | ||
130 | gcry_mpi_release (hom_result); | ||
131 | return ret; | ||
125 | } | 132 | } |
126 | 133 | ||
127 | 134 | ||
@@ -168,7 +175,8 @@ test_hom () | |||
168 | fprintf (stderr, | 175 | fprintf (stderr, |
169 | "GNUNET_CRYPTO_paillier_encrypt 1 failed, should return 1 allowed operation, got %d!\n", | 176 | "GNUNET_CRYPTO_paillier_encrypt 1 failed, should return 1 allowed operation, got %d!\n", |
170 | ret); | 177 | ret); |
171 | return 1; | 178 | ret = 1; |
179 | goto out; | ||
172 | } | 180 | } |
173 | if (2 != (ret = GNUNET_CRYPTO_paillier_encrypt (&public_key, | 181 | if (2 != (ret = GNUNET_CRYPTO_paillier_encrypt (&public_key, |
174 | m2, | 182 | m2, |
@@ -178,7 +186,8 @@ test_hom () | |||
178 | fprintf (stderr, | 186 | fprintf (stderr, |
179 | "GNUNET_CRYPTO_paillier_encrypt 2 failed, should return 2 allowed operation, got %d!\n", | 187 | "GNUNET_CRYPTO_paillier_encrypt 2 failed, should return 2 allowed operation, got %d!\n", |
180 | ret); | 188 | ret); |
181 | return 1; | 189 | ret = 1; |
190 | goto out; | ||
182 | } | 191 | } |
183 | 192 | ||
184 | if (0 != (ret = GNUNET_CRYPTO_paillier_hom_add (&public_key, | 193 | if (0 != (ret = GNUNET_CRYPTO_paillier_hom_add (&public_key, |
@@ -189,7 +198,8 @@ test_hom () | |||
189 | fprintf (stderr, | 198 | fprintf (stderr, |
190 | "GNUNET_CRYPTO_paillier_hom_add failed, expected 0 remaining operations, got %d!\n", | 199 | "GNUNET_CRYPTO_paillier_hom_add failed, expected 0 remaining operations, got %d!\n", |
191 | ret); | 200 | ret); |
192 | return 1; | 201 | ret = 1; |
202 | goto out; | ||
193 | } | 203 | } |
194 | 204 | ||
195 | GNUNET_CRYPTO_paillier_decrypt (&private_key, | 205 | GNUNET_CRYPTO_paillier_decrypt (&private_key, |
@@ -203,9 +213,14 @@ test_hom () | |||
203 | "GNUNET_CRYPTO_paillier miscalculated with large numbers!\n"); | 213 | "GNUNET_CRYPTO_paillier miscalculated with large numbers!\n"); |
204 | gcry_log_debugmpi ("got", hom_result); | 214 | gcry_log_debugmpi ("got", hom_result); |
205 | gcry_log_debugmpi ("wanted", result); | 215 | gcry_log_debugmpi ("wanted", result); |
206 | return 1; | 216 | ret = 1; |
207 | } | 217 | } |
208 | return 0; | 218 | out: |
219 | gcry_mpi_release (m1); | ||
220 | gcry_mpi_release (m2); | ||
221 | gcry_mpi_release (result); | ||
222 | gcry_mpi_release (hom_result); | ||
223 | return ret; | ||
209 | } | 224 | } |
210 | 225 | ||
211 | 226 | ||
diff --git a/src/util/test_mq.c b/src/util/test_mq.c index 442c110db..9e8fc844e 100644 --- a/src/util/test_mq.c +++ b/src/util/test_mq.c | |||
@@ -51,6 +51,7 @@ test1 () | |||
51 | GNUNET_assert (NULL != mm); | 51 | GNUNET_assert (NULL != mm); |
52 | GNUNET_assert (42 == ntohs (mm->header.type)); | 52 | GNUNET_assert (42 == ntohs (mm->header.type)); |
53 | GNUNET_assert (sizeof (struct MyMessage) == ntohs (mm->header.size)); | 53 | GNUNET_assert (sizeof (struct MyMessage) == ntohs (mm->header.size)); |
54 | GNUNET_MQ_discard (mqm); | ||
54 | } | 55 | } |
55 | 56 | ||
56 | 57 | ||