aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arm/Makefile.am3
-rw-r--r--src/arm/gnunet-service-arm.c3
-rw-r--r--src/ats-tool/gnunet-ats.c6
-rw-r--r--src/cadet/cadet_api.c118
-rw-r--r--src/cadet/gnunet-cadet.c1
-rw-r--r--src/cadet/gnunet-service-cadet_core.c33
-rw-r--r--src/cadet/gnunet-service-cadet_paths.c170
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c2
-rw-r--r--src/cadet/test_cadet.c16
-rw-r--r--src/conversation/gnunet-conversation.c2
-rw-r--r--src/core/gnunet-service-core_kx.c2
-rw-r--r--src/core/gnunet-service-core_sessions.c1
-rw-r--r--src/core/test_core_api_reliability.c3
-rw-r--r--src/datastore/datastore_api.c115
-rw-r--r--src/datastore/plugin_datastore_sqlite.c29
-rw-r--r--src/dht/Makefile.am3
-rw-r--r--src/dns/dnsparser.c4
-rw-r--r--src/fs/fs_misc.c8
-rw-r--r--src/fs/fs_publish_ublock.c1
-rw-r--r--src/fs/plugin_block_fs.c17
-rw-r--r--src/gns/gnunet-gns-proxy.c18
-rw-r--r--src/hello/hello.c7
-rw-r--r--src/include/gnunet_crypto_lib.h20
-rw-r--r--src/include/gnunet_getopt_lib.h54
-rw-r--r--src/include/gnunet_json_lib.h10
-rw-r--r--src/include/gnunet_scheduler_lib.h16
-rw-r--r--src/include/gnunet_set_service.h5
-rw-r--r--src/integration-tests/Makefile.am3
-rw-r--r--src/json/json_generator.c13
-rw-r--r--src/multicast/.gitignore2
-rw-r--r--src/peerinfo/gnunet-service-peerinfo.c6
-rw-r--r--src/peerinfo/peerinfo_api.c5
-rw-r--r--src/revocation/gnunet-service-revocation.c2
-rw-r--r--src/rps/.gitignore11
-rw-r--r--src/rps/Makefile.am15
-rw-r--r--src/rps/gnunet-service-rps.c1798
-rw-r--r--src/rps/gnunet-service-rps_peers.c1694
-rw-r--r--src/rps/gnunet-service-rps_peers.h437
-rw-r--r--src/rps/rps.h96
-rw-r--r--src/rps/test_rps.c86
-rw-r--r--src/rps/test_rps.conf38
-rw-r--r--src/rps/test_service_rps_peers.c137
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c8
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct_alice.c8
-rw-r--r--src/secretsharing/Makefile.am2
-rw-r--r--src/set/gnunet-service-set.c39
-rw-r--r--src/set/gnunet-service-set_union.c11
-rw-r--r--src/set/gnunet-service-set_union_strata_estimator.c6
-rw-r--r--src/set/test_set_intersection_result_full.c2
-rw-r--r--src/set/test_set_union_result_symmetric.c2
-rw-r--r--src/social/gnunet-social.c2
-rw-r--r--src/social/social_api.c2
-rw-r--r--src/sq/sq_result_helper.c2
-rw-r--r--src/statistics/Makefile.am3
-rw-r--r--src/testbed/gnunet-daemon-testbed-underlay.c6
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c15
-rw-r--r--src/testbed/gnunet-testbed-profiler.c15
-rw-r--r--src/testbed/testbed_api_topology.c2
-rw-r--r--src/topology/friends.c2
-rw-r--r--src/transport/gnunet-service-transport.c14
-rw-r--r--src/transport/gnunet-service-transport_ats.c11
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c5
-rw-r--r--src/transport/gnunet-service-transport_validation.c34
-rw-r--r--src/transport/test_transport_testing_restart.c3
-rw-r--r--src/transport/test_transport_testing_startstop.c3
-rw-r--r--src/transport/transport-testing.c7
-rw-r--r--src/util/.gitignore1
-rw-r--r--src/util/crypto_ecc.c45
-rw-r--r--src/util/crypto_paillier.c2
-rw-r--r--src/util/crypto_rsa.c2
-rw-r--r--src/util/gnunet-ecc.c22
-rw-r--r--src/util/network.c16
-rw-r--r--src/util/resolver_api.c1
-rw-r--r--src/util/scheduler.c48
-rw-r--r--src/util/test_crypto_paillier.c35
-rw-r--r--src/util/test_mq.c1
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
93do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' 93do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g'
94 94
95%.py: %.py.in Makefile 95SUFFIXES = .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 */
834static int
835check_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 */
832static void 855static void
833handle_get_peers (void *cls, 856handle_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 */
988static int
989check_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 */
954static void 1009static void
955handle_get_tunnels (void *cls, 1010handle_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 */
194static void 198static void
195path_destroy (struct CadetPeerPath *path) 199attach_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
228GCPP_release (struct CadetPeerPath *path) 246GCPP_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 */
661static struct GNUNET_DATASTORE_QueueEntry *
662get_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
185create_indices (sqlite3 * dbh) 185create_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
214do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' -e 's,[@]bindir[@],$(bindir),g' 214do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' -e 's,[@]bindir[@],$(bindir),g'
215 215
216%.py: %.py.in Makefile 216SUFFIXES = .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
789static void
790curl_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 */
1118char *
1119GNUNET_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 */
2021int 2031int
2022GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, 2032GNUNET_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 */
2036struct GNUNET_CRYPTO_RsaSignature * 2047struct GNUNET_CRYPTO_RsaSignature *
2037GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key, 2048GNUNET_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 */
2107struct GNUNET_CRYPTO_RsaSignature * 2119struct GNUNET_CRYPTO_RsaSignature *
2108GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig, 2120GNUNET_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 */
231struct GNUNET_GETOPT_CommandLineOption 231struct GNUNET_GETOPT_CommandLineOption
232GNUNET_GETOPT_option_base32_fixed_size (char shortName, 232GNUNET_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 */
265struct GNUNET_GETOPT_CommandLineOption 265struct GNUNET_GETOPT_CommandLineOption
266GNUNET_GETOPT_option_flag (char shortName, 266GNUNET_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 */
281struct GNUNET_GETOPT_CommandLineOption 281struct GNUNET_GETOPT_CommandLineOption
282GNUNET_GETOPT_option_uint (char shortName, 282GNUNET_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 */
298struct GNUNET_GETOPT_CommandLineOption 298struct GNUNET_GETOPT_CommandLineOption
299GNUNET_GETOPT_option_ulong (char shortName, 299GNUNET_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 */
316struct GNUNET_GETOPT_CommandLineOption 316struct GNUNET_GETOPT_CommandLineOption
317GNUNET_GETOPT_option_relative_time (char shortName, 317GNUNET_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 */
334struct GNUNET_GETOPT_CommandLineOption 334struct GNUNET_GETOPT_CommandLineOption
335GNUNET_GETOPT_option_absolute_time (char shortName, 335GNUNET_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 */
351struct GNUNET_GETOPT_CommandLineOption 351struct GNUNET_GETOPT_CommandLineOption
352GNUNET_GETOPT_option_increment_uint (char shortName, 352GNUNET_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 */
351json_t *
352GNUNET_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
400GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, 400GNUNET_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 */
414void
415GNUNET_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 */
558void 560void
559GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash); 561GNUNET_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
43do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' 43do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g'
44 44
45%.py: %.py.in Makefile 45SUFFIXES = .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 */
81json_t *
82GNUNET_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
3test_multicast 3test_multicast
4test_multicast_multipeer 4test_multicast_multipeer
5test_multicast_2peers 5test_multicast_2peers
6test_multicast_multipeer_line
7test_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 @@
1gnunet-service-rps 1gnunet-service-rps
2gnunet-rps 2gnunet-rps
3gnunet-rps-profiler 3gnunet-rps-profiler
4test_rps_malicious_1
5test_rps_malicious_2
6test_rps_malicious_3
7test_rps_req_cancel
8test_rps_seed_big
9test_rps_seed_request
10test_rps_single_req
11test_service_rps_custommap
12test_service_rps_sampler_elem
13test_service_rps_view
14test_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
49gnunet_service_rps_SOURCES = \ 49gnunet_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
73check_PROGRAMS = \ 72check_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
85endif 84endif
86 85
87ld_rps_test_lib = \ 86ld_rps_test_lib = \
@@ -105,13 +104,6 @@ test_service_rps_view_SOURCES = \
105 test_service_rps_view.c 104 test_service_rps_view.c
106test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la 105test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la
107 106
108test_service_rps_peers_SOURCES = \
109 gnunet-service-rps_peers.h gnunet-service-rps_peers.c \
110 test_service_rps_peers.c
111test_service_rps_peers_LDADD = \
112 $(top_builddir)/src/util/libgnunetutil.la \
113 $(top_builddir)/src/cadet/libgnunetcadet.la
114
115test_service_rps_custommap_SOURCES = \ 107test_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)
145test_rps_seed_big_SOURCES = $(rps_test_src) 137test_rps_seed_big_SOURCES = $(rps_test_src)
146test_rps_seed_big_LDADD = $(ld_rps_test_lib) 138test_rps_seed_big_LDADD = $(ld_rps_test_lib)
147 139
140test_rps_churn_SOURCES = $(rps_test_src)
141test_rps_churn_LDADD = $(ld_rps_test_lib)
142
148gnunet_rps_profiler_SOURCES = $(rps_test_src) 143gnunet_rps_profiler_SOURCES = $(rps_test_src)
149gnunet_rps_profiler_LDADD = $(ld_rps_test_lib) 144gnunet_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;
66static struct GNUNET_PeerIdentity own_identity; 65static 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 */
113struct 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 */
132struct 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 */
164struct 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 */
244struct 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 */
260static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers;
261
262/**
263 * @brief Maximum number of valid peers to keep.
264 * TODO read from config
265 */
266static uint32_t num_valid_peers_max = UINT32_MAX;
267
268/**
269 * @brief Filename of the file that stores the valid peers persistently.
270 */
271static char *filename_valid_peers;
272
273/**
274 * Set of all peers to keep track of them.
275 */
276static struct GNUNET_CONTAINER_MultiPeerMap *peer_map;
277
278/**
279 * Cadet handle.
280 */
281static 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 */
292static struct PeerContext *
293get_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
305int
306Peers_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 */
315static struct PeerContext *
316create_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 */
341static struct PeerContext *
342create_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
351void
352Peers_unset_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags);
353
354void
355Peers_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 */
367int
368Peers_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 */
395struct 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 */
426static int
427get_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 */
449static const struct GNUNET_PeerIdentity *
450get_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 */
478static int
479add_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 */
505static void
506set_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
539static void
540cleanup_destroyed_channel (void *cls,
541 const struct GNUNET_CADET_Channel *channel);
542
543/* Declaration of handlers */
544static void
545handle_peer_check (void *cls,
546 const struct GNUNET_MessageHeader *msg);
547
548static void
549handle_peer_push (void *cls,
550 const struct GNUNET_MessageHeader *msg);
551
552static void
553handle_peer_pull_request (void *cls,
554 const struct GNUNET_MessageHeader *msg);
555
556static int
557check_peer_pull_reply (void *cls,
558 const struct GNUNET_RPS_P2P_PullReplyMessage *msg);
559
560static void
561handle_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 */
573struct GNUNET_CADET_Channel *
574get_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 */
633static struct GNUNET_MQ_Handle *
634get_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 */
655static void
656mq_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 */
676static void
677check_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 */
706static struct PendingMessage *
707insert_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 */
732static void
733remove_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 */
763static int
764check_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
777int
778Peers_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 */
789static int
790peermap_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 */
806static void
807mq_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 */
832static int
833store_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 */
862static void
863store_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 */
923static const struct GNUNET_PeerIdentity *
924s2i_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 */
963static void
964restore_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 */
1033void
1034Peers_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 */
1051void
1052Peers_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 */
1079static int
1080valid_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 */
1099int
1100Peers_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 */
1129int
1130Peers_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
1141int
1142Peers_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 */
1154int
1155Peers_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 */
1187int
1188Peers_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
1207uint32_t *
1208Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
1209 enum Peers_ChannelRole role);
1210
1211int
1212Peers_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 */
1221int
1222Peers_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 */
1297void
1298Peers_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 */
1313void
1314Peers_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 */
1333int
1334Peers_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 */
1353void
1354Peers_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 */
1366void
1367Peers_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 */
1382int
1383Peers_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 */
1396uint32_t *
1397Peers_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 */
1427int
1428Peers_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 */
1444int
1445Peers_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 */
1458void
1459Peers_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 */
1475int
1476Peers_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 */
1499void *
1500Peers_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 */
1535int
1536Peers_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 */
1565int
1566Peers_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 */
1603int
1604Peers_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 */
1631void
1632Peers_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 */
1709void
1710Peers_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 */
1739int
1740Peers_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 */
1776struct GNUNET_CADET_Channel *
1777Peers_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
1360handle_peer_pull_reply (void *cls, 3088handle_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 */
79struct 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 */
98struct 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 */
130struct 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 */
210struct 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 */
226static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers;
227
228/**
229 * @brief Maximum number of valid peers to keep.
230 * TODO read from config
231 */
232static uint32_t num_valid_peers_max = UINT32_MAX;
233
234/**
235 * @brief Filename of the file that stores the valid peers persistently.
236 */
237static char *filename_valid_peers;
238
239/**
240 * Set of all peers to keep track of them.
241 */
242static struct GNUNET_CONTAINER_MultiPeerMap *peer_map;
243
244/**
245 * Own #GNUNET_PeerIdentity.
246 */
247static const struct GNUNET_PeerIdentity *own_identity;
248
249/**
250 * Cadet handle.
251 */
252static struct GNUNET_CADET_Handle *cadet_handle;
253
254/**
255 * @brief Disconnect handler
256 */
257static GNUNET_CADET_DisconnectEventHandler cleanup_destroyed_channel;
258
259/**
260 * @brief cadet handlers
261 */
262static 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 */
273static struct PeerContext *
274get_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 */
294static struct PeerContext *
295create_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 */
320static struct PeerContext *
321create_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 */
341int
342Peers_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 */
369struct 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 */
400static int
401get_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 */
423static const struct GNUNET_PeerIdentity *
424get_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 */
452static int
453add_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 */
479static void
480set_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 */
520struct GNUNET_CADET_Channel *
521get_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 */
559static struct GNUNET_MQ_Handle *
560get_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 */
581static void
582mq_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 */
602static void
603check_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 */
632static struct PendingMessage *
633insert_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 */
657static void
658remove_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 */
683static int
684check_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 */
707static int
708peermap_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 */
724static void
725mq_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 */
749static int
750store_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 */
779static void
780store_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 */
840static const struct GNUNET_PeerIdentity *
841s2i_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 */
880static void
881restore_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 */
951void
952Peers_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 */
972void
973Peers_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 */
1000static int
1001valid_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 */
1020int
1021Peers_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 */
1050int
1051Peers_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 */
1073int
1074Peers_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 */
1106int
1107Peers_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 */
1134int
1135Peers_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 */
1209void
1210Peers_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 */
1225void
1226Peers_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 */
1245int
1246Peers_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 */
1265void
1266Peers_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 */
1278void
1279Peers_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 */
1294int
1295Peers_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 */
1308uint32_t *
1309Peers_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 */
1339int
1340Peers_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 */
1356int
1357Peers_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 */
1370void
1371Peers_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 */
1387int
1388Peers_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 */
1411void *
1412Peers_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 */
1447int
1448Peers_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 */
1477int
1478Peers_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 */
1515int
1516Peers_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 */
1543void
1544Peers_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 */
1621void
1622Peers_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 */
1647int
1648Peers_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 */
1684struct GNUNET_CADET_Channel *
1685Peers_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 */
34enum 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 */
64enum 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 */
81enum 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 */
100typedef 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 */
111typedef 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 */
124void
125Peers_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 */
134void
135Peers_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 */
146int
147Peers_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 */
162int
163Peers_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 */
175int
176Peers_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 */
191int
192Peers_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 */
201int
202Peers_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 */
210void
211Peers_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 */
219void
220Peers_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 */
231int
232Peers_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 */
241void
242Peers_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 */
250void
251Peers_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 */
262int
263Peers_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 */
273uint32_t *
274Peers_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 */
287int
288Peers_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 */
300int
301Peers_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 */
310void
311Peers_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 */
322int
323Peers_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 */
335void *
336Peers_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 */
348int
349Peers_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 */
363int
364Peers_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 */
379int
380Peers_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 */
392void
393Peers_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 */
406void
407Peers_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 */
421int
422Peers_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 */
434struct GNUNET_CADET_Channel *
435Peers_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 */
186enum 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 */
216enum 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 */
239enum 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 */
258typedef 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 */
269typedef int
270(*PeersIterator) (void *cls,
271 const struct GNUNET_PeerIdentity *peer);
272
273
178GNUNET_NETWORK_STRUCT_END 274GNUNET_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
1034static void
1035churn (void *cls);
1036
1037static void
1038churn_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
1256profiler_cb (struct RPSPeer *rps_peer) 1291profiler_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]
25HOSTNAME = localhost 25HOSTNAME = localhost
26 26
27OPERATION_TIMEOUT = 60 s 27# OPERATION_TIMEOUT = 60 s
28 28
29MAX_PARALLEL_TOPOLOGY_CONFIG_OPERATIONS = 1 29# MAX_PARALLEL_TOPOLOGY_CONFIG_OPERATIONS = 100
30#OVERLAY_TOPOLOGY = CLIQUE 30OVERLAY_TOPOLOGY = CLIQUE
31OVERLAY_TOPOLOGY = SMALL_WORLD 31#OVERLAY_TOPOLOGY = SMALL_WORLD
32#SCALE_FREE_TOPOLOGY_CAP = 32#SCALE_FREE_TOPOLOGY_CAP =
33 33
34OVERLAY_RANDOM_LINKS = 25 34# OVERLAY_RANDOM_LINKS = 25
35 35
36SETUP_TIMEOUT = 2 m 36# SETUP_TIMEOUT = 2 m
37 37
38[nse] 38[nse]
39WORKBITS = 0 39WORKBITS = 0
@@ -46,7 +46,27 @@ USE_LOCALADDR = YES
46RETURN_LOCAL_ADDRESSES = YES 46RETURN_LOCAL_ADDRESSES = YES
47 47
48[transport] 48[transport]
49PLUGINS = unix 49PLUGINS = udp
50
51[ats]
52# Network specific inbound/outbound quotas
53UNSPECIFIED_QUOTA_IN = unlimited
54UNSPECIFIED_QUOTA_OUT = unlimited
55# LOOPBACK
56LOOPBACK_QUOTA_IN = unlimited
57LOOPBACK_QUOTA_OUT = unlimited
58# LAN
59LAN_QUOTA_IN = unlimited
60LAN_QUOTA_OUT = unlimited
61#WAN
62WAN_QUOTA_OUT = unlimited
63WAN_QUOTA_IN = unlimited
64# WLAN
65WLAN_QUOTA_IN = unlimited
66WLAN_QUOTA_OUT = unlimited
67# BLUETOOTH
68BLUETOOTH_QUOTA_IN = unlimited
69BLUETOOTH_QUOTA_OUT = unlimited
50 70
51[dht] 71[dht]
52DISABLE_TRY_CONNECT = YES 72DISABLE_TRY_CONNECT = YES
@@ -69,6 +89,10 @@ NO_IO = YES
69FORCESTART = NO 89FORCESTART = NO
70AUTOSTART = NO 90AUTOSTART = NO
71 91
92[zonemaster]
93FORCESTART = NO
94AUTOSTART = NO
95
72[namecache] 96[namecache]
73FORCESTART = NO 97FORCESTART = NO
74AUTOSTART = NO 98AUTOSTART = 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 */
38void 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 */
49void
50peer_op (void *cls, const struct GNUNET_PeerIdentity *peer);
51
52static int
53check ()
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
128int
129main (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,
243static void 243static void
244destroy_service_session (struct AliceServiceSession *s) 244destroy_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
50libgnunetsecretsharing_la_LIBADD = \ 50libgnunetsecretsharing_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;
155static struct Listener *listener_tail; 155static struct Listener *listener_tail;
156 156
157/** 157/**
158 * Number of active clients.
159 */
160static 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 */
166static 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
1917shutdown_task (void *cls) 1946shutdown_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
228strata_estimator_difference (const struct StrataEstimator *se1, 228strata_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 */
283static void 283static void
284host_left () 284host_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
91do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' 91do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g'
92 92
93%.py: %.py.in Makefile 93SUFFIXES = .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
167static int 167static int
168get_identity (unsigned int offset, struct GNUNET_PeerIdentity *id) 168get_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
67perf_crypto_asymmetric 67perf_crypto_asymmetric
68perf_crypto_hash 68perf_crypto_hash
69perf_crypto_symmetric 69perf_crypto_symmetric
70perf_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 */
362char *
363GNUNET_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 */
1048struct GNUNET_CRYPTO_RsaSignature * 1048struct GNUNET_CRYPTO_RsaSignature *
1049GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig, 1049GNUNET_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;
49static int print_public_key; 49static int print_public_key;
50 50
51/** 51/**
52 * Flag for printing private key.
53 */
54static int print_private_key;
55
56/**
52 * Flag for printing public key in hex. 57 * Flag for printing public key in hex.
53 */ 58 */
54static int print_public_key_hex; 59static 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
785GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, 785GNUNET_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
791void
792GNUNET_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; 218out:
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