diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-06-14 18:30:49 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-06-14 18:30:49 +0000 |
commit | 18308311e0d3f83ca05171b060430428d65ae0dd (patch) | |
tree | f90ca31cc1077732103251c16dbb0ce1c8a7cc37 /src/dv/test_transport_api_dv.c | |
parent | 90a4c9922ef5fe5d15b832598449de8663b110bb (diff) | |
download | gnunet-18308311e0d3f83ca05171b060430428d65ae0dd.tar.gz gnunet-18308311e0d3f83ca05171b060430428d65ae0dd.zip |
dv changes, still working out an issue
Diffstat (limited to 'src/dv/test_transport_api_dv.c')
-rw-r--r-- | src/dv/test_transport_api_dv.c | 1158 |
1 files changed, 692 insertions, 466 deletions
diff --git a/src/dv/test_transport_api_dv.c b/src/dv/test_transport_api_dv.c index 50eeeb60c..33c1b936f 100644 --- a/src/dv/test_transport_api_dv.c +++ b/src/dv/test_transport_api_dv.c | |||
@@ -18,637 +18,859 @@ | |||
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | /** | 20 | /** |
21 | * @file transport/test_transport_api_dv.c | 21 | * @file dv/test_transport_api_dv.c |
22 | * @brief base test case for dv transport (separated from other transport | 22 | * @brief base testcase for testing distance vector transport |
23 | * testcases for two reasons. 1) dv-service relies on core and other | ||
24 | * transport plugins, dv plugin relies on dv-service, so dv-plugin needs | ||
25 | * to live here, and 2) a dv plugin testcase is different from other | ||
26 | * tranport plugin testcases because we need at least three peer to test | ||
27 | * it. | ||
28 | * | ||
29 | * This test case tests DV functionality. Specifically it starts three | ||
30 | * peers connected in a line (1 <-> 2 <-> 3). Then a message is transmitted | ||
31 | * from peer 1 to peer 3. Assuming that DV is working, peer 2 should have | ||
32 | * gossiped about peer 3 to 1, and should then forward a message from one | ||
33 | * to 3. | ||
34 | */ | 23 | */ |
35 | #include "platform.h" | 24 | #include "platform.h" |
36 | #include "gnunet_common.h" | 25 | #include "gnunet_testing_lib.h" |
37 | #include "gnunet_hello_lib.h" | 26 | #include "gnunet_core_service.h" |
38 | #include "gnunet_getopt_lib.h" | ||
39 | #include "gnunet_os_lib.h" | ||
40 | #include "gnunet_program_lib.h" | ||
41 | #include "gnunet_scheduler_lib.h" | ||
42 | #include "gnunet_transport_service.h" | ||
43 | #include "../transport/transport.h" | ||
44 | 27 | ||
45 | #define VERBOSE GNUNET_YES | 28 | #define VERBOSE GNUNET_YES |
46 | 29 | ||
47 | #define VERBOSE_ARM GNUNET_NO | 30 | /** |
48 | 31 | * How long until we fail the whole testcase? | |
49 | #define START_ARM GNUNET_YES | 32 | */ |
33 | #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) | ||
50 | 34 | ||
51 | /** | 35 | /** |
52 | * How long until we give up on transmitting the message? | 36 | * How long until we give up on starting the peers? |
53 | */ | 37 | */ |
54 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 50) | 38 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 500) |
55 | 39 | ||
56 | #define MTYPE 12345 | 40 | #define DEFAULT_NUM_PEERS 4 |
57 | 41 | ||
58 | static int num_wanted = 2; | 42 | #define MAX_OUTSTANDING_CONNECTIONS 100 |
59 | 43 | ||
60 | static int num_received = 0; | 44 | static float fail_percentage = 0.00; |
61 | 45 | ||
62 | struct PeerContext | 46 | static int ok; |
63 | { | ||
64 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
65 | struct GNUNET_TRANSPORT_Handle *th; | ||
66 | struct GNUNET_PeerIdentity id; | ||
67 | const char *cfg_file; | ||
68 | struct GNUNET_HELLO_Message *hello; | ||
69 | #if START_ARM | ||
70 | pid_t arm_pid; | ||
71 | #endif | ||
72 | }; | ||
73 | 47 | ||
74 | static struct PeerContext p1; | 48 | static unsigned long long num_peers; |
75 | 49 | ||
76 | static struct PeerContext p2; | 50 | static unsigned int total_connections; |
77 | 51 | ||
78 | static struct PeerContext p3; | 52 | static unsigned int failed_connections; |
79 | 53 | ||
80 | static struct PeerContext p4; | 54 | static unsigned int total_server_connections; |
55 | |||
56 | static unsigned int total_messages_received; | ||
57 | |||
58 | static unsigned int expected_messages; | ||
59 | |||
60 | static unsigned int expected_connections; | ||
61 | |||
62 | static unsigned long long peers_left; | ||
63 | |||
64 | static struct GNUNET_TESTING_PeerGroup *pg; | ||
81 | 65 | ||
82 | static struct GNUNET_SCHEDULER_Handle *sched; | 66 | static struct GNUNET_SCHEDULER_Handle *sched; |
83 | 67 | ||
84 | static int ok; | 68 | const struct GNUNET_CONFIGURATION_Handle *main_cfg; |
85 | 69 | ||
86 | GNUNET_SCHEDULER_TaskIdentifier die_task; | 70 | GNUNET_SCHEDULER_TaskIdentifier die_task; |
87 | 71 | ||
88 | #if VERBOSE | 72 | static char *dotOutFileName = "topology.dot"; |
89 | #define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) | ||
90 | #else | ||
91 | #define OKPP do { ok++; } while (0) | ||
92 | #endif | ||
93 | 73 | ||
74 | static FILE *dotOutFile; | ||
94 | 75 | ||
95 | static void | 76 | static char *blacklist_transports; |
96 | end () | 77 | |
78 | static int transmit_ready_scheduled; | ||
79 | |||
80 | static int transmit_ready_failed; | ||
81 | |||
82 | static int transmit_ready_called; | ||
83 | |||
84 | static enum GNUNET_TESTING_Topology topology; | ||
85 | |||
86 | static enum GNUNET_TESTING_Topology blacklist_topology = GNUNET_TESTING_TOPOLOGY_NONE; /* Don't do any blacklisting */ | ||
87 | |||
88 | static enum GNUNET_TESTING_Topology connection_topology = GNUNET_TESTING_TOPOLOGY_NONE; /* NONE actually means connect all allowed peers */ | ||
89 | |||
90 | static enum GNUNET_TESTING_TopologyOption connect_topology_option = GNUNET_TESTING_TOPOLOGY_OPTION_ALL; | ||
91 | |||
92 | static double connect_topology_option_modifier = 0.0; | ||
93 | |||
94 | static char *test_directory; | ||
95 | |||
96 | #define MTYPE 12345 | ||
97 | |||
98 | struct GNUNET_TestMessage | ||
97 | { | 99 | { |
98 | /* do work here */ | 100 | /** |
99 | GNUNET_SCHEDULER_cancel (sched, die_task); | 101 | * Header of the message |
102 | */ | ||
103 | struct GNUNET_MessageHeader header; | ||
104 | |||
105 | /** | ||
106 | * Unique identifier for this message. | ||
107 | */ | ||
108 | uint32_t uid; | ||
109 | }; | ||
100 | 110 | ||
101 | if (p1.th != NULL) | 111 | struct PeerContext |
102 | { | 112 | { |
103 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 1!\n"); | 113 | /* This is a linked list */ |
104 | GNUNET_TRANSPORT_disconnect (p1.th); | 114 | struct PeerContext *next; |
105 | p1.th = NULL; | 115 | |
106 | } | 116 | /* Handle to the peer core */ |
117 | struct GNUNET_CORE_Handle *peer_handle; | ||
118 | }; | ||
119 | |||
120 | static struct PeerContext *all_peers; | ||
121 | |||
122 | struct TestMessageContext | ||
123 | { | ||
124 | /* This is a linked list */ | ||
125 | struct TestMessageContext *next; | ||
126 | |||
127 | /* Handle to the sending peer core */ | ||
128 | struct GNUNET_CORE_Handle *peer1handle; | ||
129 | |||
130 | /* Handle to the receiving peer core */ | ||
131 | struct GNUNET_CORE_Handle *peer2handle; | ||
132 | |||
133 | /* Handle to the sending peer daemon */ | ||
134 | struct GNUNET_TESTING_Daemon *peer1; | ||
135 | |||
136 | /* Handle to the receiving peer daemon */ | ||
137 | struct GNUNET_TESTING_Daemon *peer2; | ||
107 | 138 | ||
108 | if (p2.th != NULL) | 139 | /* Identifier for this message, so we don't disconnect other peers! */ |
140 | uint32_t uid; | ||
141 | |||
142 | /* Task for disconnecting cores, allow task to be cancelled on shutdown */ | ||
143 | GNUNET_SCHEDULER_TaskIdentifier disconnect_task; | ||
144 | }; | ||
145 | |||
146 | static struct TestMessageContext *test_messages; | ||
147 | |||
148 | static void | ||
149 | finish_testing () | ||
150 | { | ||
151 | GNUNET_assert (pg != NULL); | ||
152 | struct PeerContext *peer_pos; | ||
153 | struct PeerContext *free_peer_pos; | ||
154 | struct TestMessageContext *pos; | ||
155 | struct TestMessageContext *free_pos; | ||
156 | #if VERBOSE | ||
157 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
158 | "Called finish testing, stopping daemons.\n"); | ||
159 | #endif | ||
160 | peer_pos = all_peers; | ||
161 | while (peer_pos != NULL) | ||
109 | { | 162 | { |
110 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 2!\n"); | 163 | fprintf(stderr, "Disconnecting from peer core\n"); |
111 | GNUNET_TRANSPORT_disconnect (p2.th); | 164 | if (peer_pos->peer_handle != NULL) |
112 | p2.th = NULL; | 165 | GNUNET_CORE_disconnect(peer_pos->peer_handle); |
166 | free_peer_pos = peer_pos; | ||
167 | peer_pos = peer_pos->next; | ||
168 | GNUNET_free(free_peer_pos); | ||
113 | } | 169 | } |
114 | 170 | ||
115 | if (p3.th != NULL) | 171 | int count; |
172 | count = 0; | ||
173 | pos = test_messages; | ||
174 | while (pos != NULL) | ||
116 | { | 175 | { |
117 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 3!\n"); | 176 | if (pos->peer1handle != NULL) |
118 | GNUNET_TRANSPORT_disconnect (p3.th); | 177 | { |
119 | p3.th = NULL; | 178 | GNUNET_CORE_disconnect(pos->peer1handle); |
179 | pos->peer1handle = NULL; | ||
180 | } | ||
181 | if (pos->peer2handle != NULL) | ||
182 | { | ||
183 | GNUNET_CORE_disconnect(pos->peer2handle); | ||
184 | pos->peer2handle = NULL; | ||
185 | } | ||
186 | free_pos = pos; | ||
187 | pos = pos->next; | ||
188 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) | ||
189 | { | ||
190 | GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task); | ||
191 | } | ||
192 | GNUNET_free(free_pos); | ||
120 | } | 193 | } |
194 | #if VERBOSE | ||
195 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
196 | "transmit_ready's scheduled %d, failed %d, transmit_ready's called %d\n", transmit_ready_scheduled, transmit_ready_failed, transmit_ready_called); | ||
197 | #endif | ||
121 | 198 | ||
122 | if (p4.th != NULL) | 199 | #if VERBOSE |
200 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
201 | "Calling daemons_stop\n"); | ||
202 | #endif | ||
203 | GNUNET_TESTING_daemons_stop (pg, TIMEOUT); | ||
204 | #if VERBOSE | ||
205 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
206 | "daemons_stop finished\n"); | ||
207 | #endif | ||
208 | if (dotOutFile != NULL) | ||
123 | { | 209 | { |
124 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 4!\n"); | 210 | fprintf(dotOutFile, "}"); |
125 | GNUNET_TRANSPORT_disconnect (p4.th); | 211 | fclose(dotOutFile); |
126 | p4.th = NULL; | ||
127 | } | 212 | } |
128 | 213 | ||
129 | die_task = GNUNET_SCHEDULER_NO_TASK; | ||
130 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transports disconnected, returning success!\n"); | ||
131 | sleep(2); | ||
132 | ok = 0; | 214 | ok = 0; |
133 | } | 215 | } |
134 | 216 | ||
217 | |||
135 | static void | 218 | static void |
136 | stop_arm (struct PeerContext *p) | 219 | disconnect_cores (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) |
137 | { | 220 | { |
138 | #if START_ARM | 221 | struct TestMessageContext *pos = cls; |
139 | p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm", | 222 | |
140 | "gnunet-arm", | 223 | /* Disconnect from the respective cores */ |
141 | #if VERBOSE | 224 | #if VERBOSE |
142 | "-L", "DEBUG", | 225 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
226 | "Disconnecting from peer 1 `%4s'\n", GNUNET_i2s (&pos->peer1->id)); | ||
143 | #endif | 227 | #endif |
144 | "-c", p->cfg_file, "-e", "-q", NULL); | 228 | if (pos->peer1handle != NULL) |
145 | 229 | GNUNET_CORE_disconnect(pos->peer1handle); | |
146 | GNUNET_OS_process_wait (p->arm_pid); | 230 | #if VERBOSE |
231 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
232 | "Disconnecting from peer 2 `%4s'\n", GNUNET_i2s (&pos->peer2->id)); | ||
147 | #endif | 233 | #endif |
148 | GNUNET_CONFIGURATION_destroy (p->cfg); | 234 | if (pos->peer2handle != NULL) |
235 | GNUNET_CORE_disconnect(pos->peer2handle); | ||
236 | /* Set handles to NULL so test case can be ended properly */ | ||
237 | pos->peer1handle = NULL; | ||
238 | pos->peer2handle = NULL; | ||
239 | pos->disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
240 | /* Decrement total connections so new can be established */ | ||
241 | total_server_connections -= 2; | ||
149 | } | 242 | } |
150 | 243 | ||
151 | |||
152 | static void | 244 | static void |
153 | restart_transport (struct PeerContext *p) | 245 | send_other_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) |
154 | { | 246 | { |
155 | #if START_ARM | 247 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 25), &finish_testing, NULL); |
156 | p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm", | ||
157 | "gnunet-arm", | ||
158 | #if VERBOSE | ||
159 | "-L", "DEBUG", | ||
160 | #endif | ||
161 | "-c", p->cfg_file, "-k", "transport", "-q", NULL); | ||
162 | |||
163 | GNUNET_OS_process_wait (p->arm_pid); | ||
164 | #endif | ||
165 | |||
166 | #if START_ARM | ||
167 | p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm", | ||
168 | "gnunet-arm", | ||
169 | #if VERBOSE | ||
170 | "-L", "DEBUG", | ||
171 | #endif | ||
172 | "-c", p->cfg_file, "-i", "transport", "-q", NULL); | ||
173 | |||
174 | GNUNET_OS_process_wait (p->arm_pid); | ||
175 | #endif | ||
176 | } | 248 | } |
177 | 249 | ||
178 | 250 | static int | |
179 | static void | 251 | process_mtype (void *cls, |
180 | end_badly () | 252 | const struct GNUNET_PeerIdentity *peer, |
253 | const struct GNUNET_MessageHeader *message, | ||
254 | struct GNUNET_TIME_Relative latency, | ||
255 | uint32_t distance) | ||
181 | { | 256 | { |
182 | /* do work here */ | 257 | struct TestMessageContext *pos = cls; |
258 | struct GNUNET_TestMessage *msg = (struct GNUNET_TestMessage *)message; | ||
259 | if (pos->uid != ntohl(msg->uid)) | ||
260 | return GNUNET_OK; | ||
261 | |||
262 | total_messages_received++; | ||
183 | #if VERBOSE | 263 | #if VERBOSE |
184 | fprintf(stderr, "Ending on an unhappy note.\n"); | 264 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
265 | "Received message from `%4s', type %d, distance %u.\n", GNUNET_i2s (peer), ntohs(message->type), distance); | ||
266 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
267 | "Total messages received %d, expected %d.\n", total_messages_received, expected_messages); | ||
185 | #endif | 268 | #endif |
186 | 269 | ||
187 | if (p1.th != NULL) | 270 | if (total_messages_received == expected_messages) |
188 | { | ||
189 | GNUNET_TRANSPORT_disconnect (p1.th); | ||
190 | p1.th = NULL; | ||
191 | } | ||
192 | |||
193 | if (p2.th != NULL) | ||
194 | { | 271 | { |
195 | GNUNET_TRANSPORT_disconnect (p2.th); | 272 | GNUNET_SCHEDULER_cancel (sched, die_task); |
196 | p2.th = NULL; | 273 | GNUNET_SCHEDULER_add_now (sched, &send_other_messages, NULL); |
197 | } | 274 | } |
198 | 275 | else | |
199 | if (p3.th != NULL) | ||
200 | { | 276 | { |
201 | GNUNET_TRANSPORT_disconnect (p3.th); | 277 | pos->disconnect_task = GNUNET_SCHEDULER_add_now(sched, &disconnect_cores, pos); |
202 | p3.th = NULL; | ||
203 | } | 278 | } |
204 | 279 | ||
205 | if (p4.th != NULL) | 280 | return GNUNET_OK; |
206 | { | ||
207 | GNUNET_TRANSPORT_disconnect (p4.th); | ||
208 | p4.th = NULL; | ||
209 | } | ||
210 | sleep(2); | ||
211 | ok = 1; | ||
212 | return; | ||
213 | } | 281 | } |
214 | 282 | ||
215 | static void | 283 | static void |
216 | notify_receive (void *cls, | 284 | end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) |
217 | const struct GNUNET_PeerIdentity *peer, | ||
218 | const struct GNUNET_MessageHeader *message, | ||
219 | struct GNUNET_TIME_Relative latency, | ||
220 | uint32_t distance) | ||
221 | { | 285 | { |
222 | if (ntohs(message->type) != MTYPE) | 286 | char *msg = cls; |
223 | return; | 287 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
224 | 288 | "End badly was called (%s)... stopping daemons.\n", msg); | |
225 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %d from peer (%p) distance %d latency %u!\n", | 289 | struct TestMessageContext *pos; |
226 | ntohs(message->type), cls, distance, latency.value); | 290 | struct TestMessageContext *free_pos; |
291 | |||
292 | pos = test_messages; | ||
293 | while (pos != NULL) | ||
294 | { | ||
295 | if (pos->peer1handle != NULL) | ||
296 | { | ||
297 | GNUNET_CORE_disconnect(pos->peer1handle); | ||
298 | pos->peer1handle = NULL; | ||
299 | } | ||
300 | if (pos->peer2handle != NULL) | ||
301 | { | ||
302 | GNUNET_CORE_disconnect(pos->peer2handle); | ||
303 | pos->peer2handle = NULL; | ||
304 | } | ||
305 | free_pos = pos; | ||
306 | pos = pos->next; | ||
307 | GNUNET_free(free_pos); | ||
308 | } | ||
227 | 309 | ||
228 | GNUNET_assert (MTYPE == ntohs (message->type)); | 310 | if (pg != NULL) |
229 | GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == | 311 | { |
230 | ntohs (message->size)); | 312 | GNUNET_TESTING_daemons_stop (pg, TIMEOUT); |
231 | num_received++; | 313 | ok = 7331; /* Opposite of leet */ |
232 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d of %d messages.\n", num_received, num_wanted); | 314 | } |
315 | else | ||
316 | ok = 401; /* Never got peers started */ | ||
233 | 317 | ||
234 | if (num_wanted == num_received) | 318 | if (dotOutFile != NULL) |
235 | { | 319 | { |
236 | end (); | 320 | fprintf(dotOutFile, "}"); |
321 | fclose(dotOutFile); | ||
237 | } | 322 | } |
238 | } | 323 | } |
239 | 324 | ||
240 | |||
241 | static size_t | 325 | static size_t |
242 | notify_ready (void *cls, size_t size, void *buf) | 326 | transmit_ready (void *cls, size_t size, void *buf) |
243 | { | 327 | { |
244 | struct GNUNET_MessageHeader *hdr; | 328 | struct GNUNET_TestMessage *m; |
245 | 329 | struct TestMessageContext *pos = cls; | |
330 | |||
331 | GNUNET_assert (buf != NULL); | ||
332 | m = (struct GNUNET_TestMessage *) buf; | ||
333 | m->header.type = htons (MTYPE); | ||
334 | m->header.size = htons (sizeof (struct GNUNET_TestMessage)); | ||
335 | m->uid = htonl(pos->uid); | ||
336 | transmit_ready_called++; | ||
337 | #if VERBOSE | ||
246 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 338 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
247 | "Transmitting message to peer (%p) - %u!\n", cls, size); | 339 | "transmit ready for peer %s\ntransmit_ready's scheduled %d, transmit_ready's called %d\n", GNUNET_i2s(&pos->peer1->id), transmit_ready_scheduled, transmit_ready_called); |
248 | GNUNET_assert (size >= 256); | 340 | #endif |
341 | return sizeof (struct GNUNET_TestMessage); | ||
342 | } | ||
249 | 343 | ||
250 | if (buf != NULL) | ||
251 | { | ||
252 | hdr = buf; | ||
253 | hdr->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
254 | hdr->type = htons (MTYPE); | ||
255 | } | ||
256 | 344 | ||
257 | return sizeof (struct GNUNET_MessageHeader); | 345 | static struct GNUNET_CORE_MessageHandler no_handlers[] = { |
258 | } | 346 | {NULL, 0, 0} |
347 | }; | ||
259 | 348 | ||
349 | static struct GNUNET_CORE_MessageHandler handlers[] = { | ||
350 | {&process_mtype, MTYPE, sizeof (struct GNUNET_TestMessage)}, | ||
351 | {NULL, 0, 0} | ||
352 | }; | ||
260 | 353 | ||
261 | static void | 354 | static void |
262 | notify_connect (void *cls, | 355 | init_notify_peer2 (void *cls, |
263 | const struct GNUNET_PeerIdentity *peer, | 356 | struct GNUNET_CORE_Handle *server, |
264 | struct GNUNET_TIME_Relative latency, | 357 | const struct GNUNET_PeerIdentity *my_identity, |
265 | uint32_t distance) | 358 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey) |
266 | { | 359 | { |
267 | int peer_num = 0; | 360 | struct TestMessageContext *pos = cls; |
268 | int connect_num = 0; | ||
269 | struct PeerContext *from_peer = cls; | ||
270 | char *from_peer_str; | ||
271 | |||
272 | if (cls == &p1) | ||
273 | peer_num = 1; | ||
274 | else if (cls == &p2) | ||
275 | peer_num = 2; | ||
276 | else if (cls == &p3) | ||
277 | peer_num = 3; | ||
278 | else if (cls == &p4) | ||
279 | peer_num = 4; | ||
280 | |||
281 | if (memcmp(peer, &p1.id, sizeof(struct GNUNET_PeerIdentity)) == 0) | ||
282 | connect_num = 1; | ||
283 | else if (memcmp(peer, &p2.id, sizeof(struct GNUNET_PeerIdentity)) == 0) | ||
284 | connect_num = 2; | ||
285 | else if (memcmp(peer, &p3.id, sizeof(struct GNUNET_PeerIdentity)) == 0) | ||
286 | connect_num = 3; | ||
287 | else if (memcmp(peer, &p4.id, sizeof(struct GNUNET_PeerIdentity)) == 0) | ||
288 | connect_num = 4; | ||
289 | else | ||
290 | connect_num = -1; | ||
291 | 361 | ||
292 | if ((cls == &p1) && (memcmp(peer, &p3.id, sizeof(struct GNUNET_PeerIdentity)) == 0)) | 362 | #if VERBOSE |
363 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
364 | "Core connection to `%4s' established, scheduling message send\n", | ||
365 | GNUNET_i2s (my_identity)); | ||
366 | #endif | ||
367 | total_server_connections++; | ||
368 | |||
369 | if (NULL == GNUNET_CORE_notify_transmit_ready (pos->peer1handle, | ||
370 | 0, | ||
371 | TIMEOUT, | ||
372 | &pos->peer2->id, | ||
373 | sizeof (struct GNUNET_TestMessage), | ||
374 | &transmit_ready, pos)) | ||
293 | { | 375 | { |
294 | GNUNET_TRANSPORT_notify_transmit_ready (p1.th, | 376 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
295 | &p3.id, | 377 | "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n", |
296 | 256, 0, TIMEOUT, ¬ify_ready, | 378 | GNUNET_i2s (&pos->peer2->id)); |
297 | &p1); | 379 | transmit_ready_failed++; |
298 | } | 380 | } |
299 | 381 | else | |
300 | if ((cls == &p4) && (memcmp(peer, &p1.id, sizeof(struct GNUNET_PeerIdentity)) == 0)) | ||
301 | { | 382 | { |
302 | 383 | transmit_ready_scheduled++; | |
303 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
304 | "Peer 4 notified about connection to peer 1, distance %u!\n", distance); | ||
305 | |||
306 | GNUNET_TRANSPORT_notify_transmit_ready (p4.th, | ||
307 | &p1.id, | ||
308 | 256, 0, TIMEOUT, ¬ify_ready, | ||
309 | &p4); | ||
310 | } | 384 | } |
311 | |||
312 | GNUNET_asprintf(&from_peer_str, "%s", GNUNET_i2s(&from_peer->id)); | ||
313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
314 | "Peer `%d' %4s connected to peer `%d' %4s distance %d!\n", peer_num, from_peer_str, connect_num, GNUNET_i2s(peer), distance); | ||
315 | } | 385 | } |
316 | 386 | ||
317 | 387 | ||
318 | static void | 388 | static void |
319 | notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | 389 | init_notify_peer1 (void *cls, |
390 | struct GNUNET_CORE_Handle *server, | ||
391 | const struct GNUNET_PeerIdentity *my_identity, | ||
392 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey) | ||
320 | { | 393 | { |
394 | struct TestMessageContext *pos = cls; | ||
395 | total_server_connections++; | ||
396 | |||
397 | #if VERBOSE | ||
321 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 398 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
322 | "Peer `%4s' disconnected (%p)!\n", | 399 | "Core connection to `%4s' established, setting up handles\n", |
323 | GNUNET_i2s (peer), cls); | 400 | GNUNET_i2s (my_identity)); |
401 | #endif | ||
402 | |||
403 | /* | ||
404 | * Connect to the receiving peer | ||
405 | */ | ||
406 | pos->peer2handle = GNUNET_CORE_connect (sched, | ||
407 | pos->peer2->cfg, | ||
408 | TIMEOUT, | ||
409 | pos, | ||
410 | &init_notify_peer2, | ||
411 | NULL, | ||
412 | NULL, | ||
413 | NULL, | ||
414 | GNUNET_YES, NULL, GNUNET_YES, handlers); | ||
415 | |||
324 | } | 416 | } |
325 | 417 | ||
326 | 418 | ||
327 | static void | 419 | static void |
328 | setup_peer (struct PeerContext *p, const char *cfgname) | 420 | send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) |
329 | { | 421 | { |
330 | p->cfg = GNUNET_CONFIGURATION_create (); | 422 | struct TestMessageContext *pos = cls; |
331 | p->cfg_file = strdup(cfgname); | 423 | |
332 | #if START_ARM | 424 | if ((tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) || (cls == NULL)) |
333 | p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm", | 425 | return; |
334 | "gnunet-arm", | ||
335 | #if VERBOSE_ARM | ||
336 | "-L", "DEBUG", | ||
337 | #endif | ||
338 | "-c", cfgname, "-s", "-q", NULL); | ||
339 | #endif | ||
340 | GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); | ||
341 | } | ||
342 | 426 | ||
427 | if (die_task == GNUNET_SCHEDULER_NO_TASK) | ||
428 | { | ||
429 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | ||
430 | TEST_TIMEOUT, | ||
431 | &end_badly, "from create topology (timeout)"); | ||
432 | } | ||
343 | 433 | ||
344 | static void blacklist_peer(struct GNUNET_DISK_FileHandle *file, struct PeerContext *peer) | 434 | if (total_server_connections >= MAX_OUTSTANDING_CONNECTIONS) |
345 | { | 435 | { |
346 | struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc; | 436 | GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1), |
347 | char *buf; | 437 | &send_test_messages, pos); |
348 | size_t size; | 438 | return; /* Otherwise we'll double schedule messages here! */ |
349 | 439 | } | |
350 | GNUNET_CRYPTO_hash_to_enc(&peer->id.hashPubKey, &peer_enc); | 440 | |
351 | size = GNUNET_asprintf(&buf, "%s:%s\n", "tcp", (char *)&peer_enc); | 441 | /* |
352 | GNUNET_DISK_file_write(file, buf, size); | 442 | * Connect to the sending peer |
353 | GNUNET_free_non_null(buf); | 443 | */ |
444 | pos->peer1handle = GNUNET_CORE_connect (sched, | ||
445 | pos->peer1->cfg, | ||
446 | TIMEOUT, | ||
447 | pos, | ||
448 | &init_notify_peer1, | ||
449 | NULL, | ||
450 | NULL, | ||
451 | NULL, | ||
452 | GNUNET_NO, NULL, GNUNET_NO, no_handlers); | ||
453 | |||
454 | GNUNET_assert(pos->peer1handle != NULL); | ||
455 | |||
456 | if (total_server_connections < MAX_OUTSTANDING_CONNECTIONS) | ||
457 | { | ||
458 | GNUNET_SCHEDULER_add_now (sched, | ||
459 | &send_test_messages, pos->next); | ||
460 | } | ||
461 | else | ||
462 | { | ||
463 | GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1), | ||
464 | &send_test_messages, pos->next); | ||
465 | } | ||
354 | } | 466 | } |
355 | 467 | ||
356 | static void | ||
357 | setup_blacklists (void *cls, | ||
358 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
359 | { | ||
360 | char *blacklist_filename; | ||
361 | struct GNUNET_DISK_FileHandle *file; | ||
362 | int i; | ||
363 | 468 | ||
364 | for (i = 1; i <= 4; i++) | 469 | void |
470 | topology_callback (void *cls, | ||
471 | const struct GNUNET_PeerIdentity *first, | ||
472 | const struct GNUNET_PeerIdentity *second, | ||
473 | uint32_t distance, | ||
474 | const struct GNUNET_CONFIGURATION_Handle *first_cfg, | ||
475 | const struct GNUNET_CONFIGURATION_Handle *second_cfg, | ||
476 | struct GNUNET_TESTING_Daemon *first_daemon, | ||
477 | struct GNUNET_TESTING_Daemon *second_daemon, | ||
478 | const char *emsg) | ||
479 | { | ||
480 | struct TestMessageContext *temp_context; | ||
481 | if (emsg == NULL) | ||
365 | { | 482 | { |
366 | GNUNET_asprintf(&blacklist_filename, "/tmp/test-gnunetd-transport-peer-%d/blacklist", i); | 483 | total_connections++; |
367 | if (blacklist_filename != NULL) | 484 | #if VERBOSE |
485 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s, distance %u\n", | ||
486 | first_daemon->shortname, | ||
487 | second_daemon->shortname, | ||
488 | distance); | ||
489 | #endif | ||
490 | temp_context = GNUNET_malloc(sizeof(struct TestMessageContext)); | ||
491 | temp_context->peer1 = first_daemon; | ||
492 | temp_context->peer2 = second_daemon; | ||
493 | temp_context->next = test_messages; | ||
494 | temp_context->uid = total_connections; | ||
495 | temp_context->disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
496 | test_messages = temp_context; | ||
497 | |||
498 | expected_messages++; | ||
499 | /*if (dotOutFile != NULL) | ||
368 | { | 500 | { |
369 | file = GNUNET_DISK_file_open(blacklist_filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE | GNUNET_DISK_OPEN_CREATE, | 501 | if (distance == 1) |
370 | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | 502 | fprintf(dotOutFile, "\tn%s -- n%s;\n", first_daemon->shortname, second_daemon->shortname); |
371 | GNUNET_free(blacklist_filename); | 503 | else if (distance == 2) |
372 | 504 | fprintf(dotOutFile, "\tn%s -- n%s [color=blue];\n", first_daemon->shortname, second_daemon->shortname); | |
373 | if (file == NULL) | 505 | else if (distance == 3) |
374 | { | 506 | fprintf(dotOutFile, "\tn%s -- n%s [color=red];\n", first_daemon->shortname, second_daemon->shortname); |
375 | GNUNET_SCHEDULER_cancel(sched, die_task); | ||
376 | GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL); | ||
377 | return; | ||
378 | } | ||
379 | switch (i) | ||
380 | { | ||
381 | case 1: | ||
382 | blacklist_peer(file, &p3); | ||
383 | blacklist_peer(file, &p4); | ||
384 | break; | ||
385 | case 2: | ||
386 | blacklist_peer(file, &p4); | ||
387 | break; | ||
388 | case 3: | ||
389 | blacklist_peer(file, &p1); | ||
390 | break; | ||
391 | case 4: | ||
392 | blacklist_peer(file, &p1); | ||
393 | blacklist_peer(file, &p2); | ||
394 | break; | ||
395 | } | ||
396 | } | 507 | } |
508 | */ | ||
397 | } | 509 | } |
510 | #if VERBOSE | ||
511 | else | ||
512 | { | ||
513 | failed_connections++; | ||
514 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect peer %s to peer %s with error :\n%s\n", | ||
515 | first_daemon->shortname, | ||
516 | second_daemon->shortname, emsg); | ||
517 | } | ||
518 | #endif | ||
398 | 519 | ||
399 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 520 | if (total_connections == expected_connections) |
400 | "Disconnecting transports...\n"); | 521 | { |
522 | #if VERBOSE | ||
523 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
524 | "Created %d total connections, which is our target number! Calling send messages.\n", | ||
525 | total_connections); | ||
526 | #endif | ||
401 | 527 | ||
402 | if (p1.th != NULL) | 528 | GNUNET_SCHEDULER_cancel (sched, die_task); |
529 | die_task = GNUNET_SCHEDULER_NO_TASK; | ||
530 | GNUNET_SCHEDULER_add_now (sched, &send_test_messages, test_messages); | ||
531 | //GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &send_test_messages, test_messages); | ||
532 | } | ||
533 | else if (total_connections + failed_connections == expected_connections) | ||
403 | { | 534 | { |
404 | GNUNET_TRANSPORT_disconnect (p1.th); | 535 | if (failed_connections < (unsigned int)(fail_percentage * total_connections)) |
405 | p1.th = NULL; | 536 | { |
537 | GNUNET_SCHEDULER_cancel (sched, die_task); | ||
538 | die_task = GNUNET_SCHEDULER_NO_TASK; | ||
539 | GNUNET_SCHEDULER_add_now (sched, &send_test_messages, test_messages); | ||
540 | //GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &send_test_messages, test_messages); | ||
541 | } | ||
542 | else | ||
543 | { | ||
544 | GNUNET_SCHEDULER_cancel (sched, die_task); | ||
545 | die_task = GNUNET_SCHEDULER_add_now (sched, | ||
546 | &end_badly, "from topology_callback (too many failed connections)"); | ||
547 | } | ||
406 | } | 548 | } |
407 | 549 | else | |
408 | if (p2.th != NULL) | ||
409 | { | 550 | { |
410 | GNUNET_TRANSPORT_disconnect (p2.th); | 551 | #if VERBOSE |
411 | p2.th = NULL; | 552 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
553 | "Have %d total connections, %d failed connections, Want %d (at least %d)\n", | ||
554 | total_connections, failed_connections, expected_connections, expected_connections - (unsigned int)(fail_percentage * expected_connections)); | ||
555 | #endif | ||
412 | } | 556 | } |
557 | } | ||
413 | 558 | ||
414 | if (p3.th != NULL) | 559 | static void |
560 | connect_topology () | ||
561 | { | ||
562 | expected_connections = -1; | ||
563 | if ((pg != NULL) && (peers_left == 0)) | ||
415 | { | 564 | { |
416 | GNUNET_TRANSPORT_disconnect (p3.th); | 565 | expected_connections = GNUNET_TESTING_connect_topology (pg, connection_topology, connect_topology_option, connect_topology_option_modifier); |
417 | p3.th = NULL; | 566 | #if VERBOSE |
567 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
568 | "Have %d expected connections\n", expected_connections); | ||
569 | #endif | ||
418 | } | 570 | } |
419 | 571 | ||
420 | if (p4.th != NULL) | 572 | GNUNET_SCHEDULER_cancel (sched, die_task); |
573 | if (expected_connections == GNUNET_SYSERR) | ||
421 | { | 574 | { |
422 | GNUNET_TRANSPORT_disconnect (p4.th); | 575 | die_task = GNUNET_SCHEDULER_add_now (sched, |
423 | p4.th = NULL; | 576 | &end_badly, "from connect topology (bad return)"); |
424 | } | 577 | } |
425 | 578 | ||
426 | sleep(1); | 579 | die_task = GNUNET_SCHEDULER_add_delayed (sched, |
427 | 580 | TEST_TIMEOUT, | |
428 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 581 | &end_badly, "from connect topology (timeout)"); |
429 | "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p1.arm_pid, p1.cfg_file); | ||
430 | restart_transport(&p1); | ||
431 | |||
432 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
433 | "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p2.arm_pid, p2.cfg_file); | ||
434 | restart_transport(&p2); | ||
435 | |||
436 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
437 | "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p3.arm_pid, p3.cfg_file); | ||
438 | restart_transport(&p3); | ||
439 | |||
440 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
441 | "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p4.arm_pid, p4.cfg_file); | ||
442 | restart_transport(&p4); | ||
443 | |||
444 | p1.th = GNUNET_TRANSPORT_connect (sched, p1.cfg, | ||
445 | &p1, | ||
446 | ¬ify_receive, | ||
447 | ¬ify_connect, ¬ify_disconnect); | ||
448 | |||
449 | p2.th = GNUNET_TRANSPORT_connect (sched, p2.cfg, | ||
450 | &p2, | ||
451 | ¬ify_receive, | ||
452 | ¬ify_connect, ¬ify_disconnect); | ||
453 | |||
454 | p3.th = GNUNET_TRANSPORT_connect (sched, p3.cfg, | ||
455 | &p3, | ||
456 | ¬ify_receive, | ||
457 | ¬ify_connect, ¬ify_disconnect); | ||
458 | |||
459 | p4.th = GNUNET_TRANSPORT_connect (sched, p4.cfg, | ||
460 | &p4, | ||
461 | ¬ify_receive, | ||
462 | ¬ify_connect, ¬ify_disconnect); | ||
463 | GNUNET_assert(p1.th != NULL); | ||
464 | GNUNET_assert(p2.th != NULL); | ||
465 | GNUNET_assert(p3.th != NULL); | ||
466 | GNUNET_assert(p4.th != NULL); | ||
467 | |||
468 | GNUNET_TRANSPORT_offer_hello (p1.th, GNUNET_HELLO_get_header(p2.hello)); | ||
469 | GNUNET_TRANSPORT_offer_hello (p2.th, GNUNET_HELLO_get_header(p3.hello)); | ||
470 | GNUNET_TRANSPORT_offer_hello (p3.th, GNUNET_HELLO_get_header(p4.hello)); | ||
471 | |||
472 | } | 582 | } |
473 | 583 | ||
474 | |||
475 | static void | 584 | static void |
476 | get_hello_fourth (void *cls, | 585 | create_topology () |
477 | const struct GNUNET_MessageHeader *message) | ||
478 | { | 586 | { |
479 | struct PeerContext *me = cls; | 587 | peers_left = num_peers; /* Reset counter */ |
480 | 588 | if (GNUNET_TESTING_create_topology (pg, topology, blacklist_topology, blacklist_transports) != GNUNET_SYSERR) | |
481 | GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_fourth, me); | 589 | { |
482 | 590 | #if VERBOSE | |
483 | GNUNET_assert (message != NULL); | 591 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
484 | GNUNET_assert (GNUNET_OK == | 592 | "Topology set up, now starting peers!\n"); |
485 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | 593 | #endif |
486 | message, &me->id)); | 594 | GNUNET_TESTING_daemons_continue_startup(pg); |
487 | 595 | } | |
488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 596 | else |
489 | "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 597 | { |
490 | 598 | GNUNET_SCHEDULER_cancel (sched, die_task); | |
491 | me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 599 | die_task = GNUNET_SCHEDULER_add_now (sched, |
492 | memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 600 | &end_badly, "from create topology (bad return)"); |
601 | } | ||
602 | GNUNET_SCHEDULER_cancel (sched, die_task); | ||
603 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | ||
604 | TEST_TIMEOUT, | ||
605 | &end_badly, "from continue startup (timeout)"); | ||
606 | } | ||
493 | 607 | ||
494 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 608 | /** |
495 | "All HELLO's received, setting up blacklists!\n"); | 609 | * Method called whenever a given peer connects. |
610 | * | ||
611 | * @param cls closure | ||
612 | * @param peer peer identity this notification is about | ||
613 | * @param latency reported latency of the connection with 'other' | ||
614 | * @param distance reported distance (DV) to 'other' | ||
615 | */ | ||
616 | static void all_connect_handler (void *cls, | ||
617 | const struct | ||
618 | GNUNET_PeerIdentity * peer, | ||
619 | struct GNUNET_TIME_Relative latency, | ||
620 | uint32_t distance) | ||
621 | { | ||
622 | struct GNUNET_TESTING_Daemon *d = cls; | ||
623 | char *second_shortname = strdup(GNUNET_i2s(peer)); | ||
496 | 624 | ||
497 | GNUNET_SCHEDULER_add_now(sched, &setup_blacklists, NULL); | 625 | #if VERBOSE |
626 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s, distance %u\n", | ||
627 | d->shortname, | ||
628 | second_shortname, | ||
629 | distance); | ||
630 | #endif | ||
631 | /*temp_context = GNUNET_malloc(sizeof(struct TestMessageContext)); | ||
632 | temp_context->peer1 = first_daemon; | ||
633 | temp_context->peer2 = second_daemon; | ||
634 | temp_context->next = test_messages; | ||
635 | temp_context->uid = total_connections; | ||
636 | temp_context->disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
637 | test_messages = temp_context;*/ | ||
638 | |||
639 | if (dotOutFile != NULL) | ||
640 | { | ||
641 | if (distance == 1) | ||
642 | fprintf(dotOutFile, "\tn%s -- n%s;\n", d->shortname, second_shortname); | ||
643 | else if (distance == 2) | ||
644 | fprintf(dotOutFile, "\tn%s -- n%s [color=blue];\n", d->shortname, second_shortname); | ||
645 | else if (distance == 3) | ||
646 | fprintf(dotOutFile, "\tn%s -- n%s [color=red];\n", d->shortname, second_shortname); | ||
647 | } | ||
648 | GNUNET_free(second_shortname); | ||
498 | } | 649 | } |
499 | 650 | ||
500 | |||
501 | static void | 651 | static void |
502 | get_hello_third (void *cls, | 652 | peers_started_callback (void *cls, |
503 | const struct GNUNET_MessageHeader *message) | 653 | const struct GNUNET_PeerIdentity *id, |
654 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
655 | struct GNUNET_TESTING_Daemon *d, const char *emsg) | ||
504 | { | 656 | { |
505 | struct PeerContext *me = cls; | 657 | struct PeerContext *new_peer; |
506 | 658 | if (emsg != NULL) | |
507 | GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_third, me); | 659 | { |
508 | 660 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to start daemon with error: `%s'\n", | |
509 | GNUNET_assert (message != NULL); | 661 | emsg); |
510 | GNUNET_assert (GNUNET_OK == | 662 | return; |
511 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | 663 | } |
512 | message, &me->id)); | 664 | GNUNET_assert (id != NULL); |
665 | #if VERBOSE | ||
666 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n", | ||
667 | (num_peers - peers_left) + 1, num_peers); | ||
668 | #endif | ||
669 | new_peer = GNUNET_malloc(sizeof(struct PeerContext)); | ||
670 | new_peer->peer_handle = GNUNET_CORE_connect(sched, cfg, GNUNET_TIME_UNIT_FOREVER_REL, d, NULL, &all_connect_handler, NULL, NULL, GNUNET_NO, NULL, GNUNET_NO, no_handlers); | ||
671 | new_peer->next = all_peers; | ||
672 | all_peers = new_peer; | ||
673 | peers_left--; | ||
513 | 674 | ||
514 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 675 | if (peers_left == 0) |
515 | "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 676 | { |
677 | #if VERBOSE | ||
678 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
679 | "All %d daemons started, now creating topology!\n", | ||
680 | num_peers); | ||
681 | #endif | ||
682 | GNUNET_SCHEDULER_cancel (sched, die_task); | ||
683 | /* Set up task in case topology creation doesn't finish | ||
684 | * within a reasonable amount of time */ | ||
685 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | ||
686 | GNUNET_TIME_relative_multiply | ||
687 | (GNUNET_TIME_UNIT_MINUTES, 5), | ||
688 | &end_badly, "from peers_started_callback"); | ||
689 | |||
690 | connect_topology (); | ||
691 | ok = 0; | ||
692 | } | ||
693 | } | ||
516 | 694 | ||
517 | me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 695 | /** |
518 | memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 696 | * Callback indicating that the hostkey was created for a peer. |
697 | * | ||
698 | * @param cls NULL | ||
699 | * @param id the peer identity | ||
700 | * @param d the daemon handle (pretty useless at this point, remove?) | ||
701 | * @param emsg non-null on failure | ||
702 | */ | ||
703 | void hostkey_callback (void *cls, | ||
704 | const struct GNUNET_PeerIdentity *id, | ||
705 | struct GNUNET_TESTING_Daemon *d, | ||
706 | const char *emsg) | ||
707 | { | ||
708 | if (emsg != NULL) | ||
709 | { | ||
710 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Hostkey callback received error: %s\n", emsg); | ||
711 | } | ||
519 | 712 | ||
520 | GNUNET_TRANSPORT_get_hello (p4.th, &get_hello_fourth, &p4); | 713 | #if VERBOSE |
714 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
715 | "Hostkey created for peer `%s'\n", | ||
716 | GNUNET_i2s(id)); | ||
717 | #endif | ||
718 | peers_left--; | ||
719 | if (peers_left == 0) | ||
720 | { | ||
721 | #if VERBOSE | ||
722 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
723 | "All %d hostkeys created, now creating topology!\n", | ||
724 | num_peers); | ||
725 | #endif | ||
726 | GNUNET_SCHEDULER_cancel (sched, die_task); | ||
727 | /* Set up task in case topology creation doesn't finish | ||
728 | * within a reasonable amount of time */ | ||
729 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | ||
730 | GNUNET_TIME_relative_multiply | ||
731 | (GNUNET_TIME_UNIT_MINUTES, 5), | ||
732 | &end_badly, "from hostkey_callback"); | ||
733 | GNUNET_SCHEDULER_add_now(sched, &create_topology, NULL); | ||
734 | ok = 0; | ||
735 | } | ||
521 | } | 736 | } |
522 | 737 | ||
523 | |||
524 | static void | 738 | static void |
525 | get_hello_second (void *cls, | 739 | run (void *cls, |
526 | const struct GNUNET_MessageHeader *message) | 740 | struct GNUNET_SCHEDULER_Handle *s, |
741 | char *const *args, | ||
742 | const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
527 | { | 743 | { |
528 | struct PeerContext *me = cls; | 744 | char * topology_str; |
529 | 745 | char * connect_topology_str; | |
530 | GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_second, me); | 746 | char * blacklist_topology_str; |
747 | char * connect_topology_option_str; | ||
748 | char * connect_topology_option_modifier_string; | ||
749 | sched = s; | ||
750 | ok = 1; | ||
531 | 751 | ||
532 | GNUNET_assert (message != NULL); | 752 | dotOutFile = fopen (dotOutFileName, "w"); |
533 | GNUNET_assert (GNUNET_OK == | 753 | if (dotOutFile != NULL) |
534 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | 754 | { |
535 | message, &me->id)); | 755 | fprintf (dotOutFile, "strict graph G {\n"); |
756 | } | ||
536 | 757 | ||
758 | #if VERBOSE | ||
537 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 759 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
538 | "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 760 | "Starting daemons based on config file %s\n", cfgfile); |
761 | #endif | ||
539 | 762 | ||
540 | me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 763 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", "servicehome", &test_directory)) |
541 | memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 764 | { |
765 | ok = 404; | ||
766 | return; | ||
767 | } | ||
542 | 768 | ||
543 | GNUNET_TRANSPORT_get_hello (p3.th, &get_hello_third, &p3); | 769 | if ((GNUNET_YES == |
544 | } | 770 | GNUNET_CONFIGURATION_get_value_string(cfg, "testing", "topology", |
771 | &topology_str)) && (GNUNET_NO == GNUNET_TESTING_topology_get(&topology, topology_str))) | ||
772 | { | ||
773 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
774 | "Invalid topology `%s' given for section %s option %s\n", topology_str, "TESTING", "TOPOLOGY"); | ||
775 | topology = GNUNET_TESTING_TOPOLOGY_CLIQUE; /* Defaults to NONE, so set better default here */ | ||
776 | } | ||
545 | 777 | ||
778 | if ((GNUNET_YES == | ||
779 | GNUNET_CONFIGURATION_get_value_string(cfg, "testing", "connect_topology", | ||
780 | &connect_topology_str)) && (GNUNET_NO == GNUNET_TESTING_topology_get(&connection_topology, connect_topology_str))) | ||
781 | { | ||
782 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
783 | "Invalid connect topology `%s' given for section %s option %s\n", connect_topology_str, "TESTING", "CONNECT_TOPOLOGY"); | ||
784 | } | ||
546 | 785 | ||
547 | static void | 786 | if ((GNUNET_YES == |
548 | get_hello_first (void *cls, | 787 | GNUNET_CONFIGURATION_get_value_string(cfg, "testing", "connect_topology_option", |
549 | const struct GNUNET_MessageHeader *message) | 788 | &connect_topology_option_str)) && (GNUNET_NO == GNUNET_TESTING_topology_option_get(&connect_topology_option, connect_topology_option_str))) |
550 | { | 789 | { |
551 | struct PeerContext *me = cls; | 790 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
791 | "Invalid connect topology option `%s' given for section %s option %s\n", connect_topology_option_str, "TESTING", "CONNECT_TOPOLOGY_OPTION"); | ||
792 | connect_topology_option = GNUNET_TESTING_TOPOLOGY_OPTION_ALL; /* Defaults to NONE, set to ALL */ | ||
793 | } | ||
552 | 794 | ||
553 | GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_first, me); | 795 | if (GNUNET_YES == |
796 | GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "connect_topology_option_modifier", | ||
797 | &connect_topology_option_modifier_string)) | ||
798 | { | ||
799 | if (sscanf(connect_topology_option_modifier_string, "%lf", &connect_topology_option_modifier) != 1) | ||
800 | { | ||
801 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
802 | _("Invalid value `%s' for option `%s' in section `%s': expected float\n"), | ||
803 | connect_topology_option_modifier_string, | ||
804 | "connect_topology_option_modifier", | ||
805 | "TESTING"); | ||
806 | } | ||
807 | GNUNET_free (connect_topology_option_modifier_string); | ||
808 | } | ||
554 | 809 | ||
555 | GNUNET_assert (message != NULL); | 810 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "blacklist_transports", |
556 | GNUNET_assert (GNUNET_OK == | 811 | &blacklist_transports)) |
557 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | 812 | blacklist_transports = NULL; |
558 | message, &me->id)); | ||
559 | 813 | ||
560 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 814 | if ((GNUNET_YES == |
561 | "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 815 | GNUNET_CONFIGURATION_get_value_string(cfg, "testing", "blacklist_topology", |
816 | & blacklist_topology_str)) && (GNUNET_NO == GNUNET_TESTING_topology_get(&blacklist_topology, blacklist_topology_str))) | ||
817 | { | ||
818 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
819 | "Invalid topology `%s' given for section %s option %s\n", topology_str, "TESTING", "BLACKLIST_TOPOLOGY"); | ||
820 | } | ||
562 | 821 | ||
563 | me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 822 | if (GNUNET_SYSERR == |
564 | memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | 823 | GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", |
824 | &num_peers)) | ||
825 | num_peers = DEFAULT_NUM_PEERS; | ||
565 | 826 | ||
566 | GNUNET_TRANSPORT_get_hello (p2.th, &get_hello_second, &p2); | 827 | main_cfg = cfg; |
567 | } | ||
568 | 828 | ||
569 | static void | 829 | peers_left = num_peers; |
570 | run (void *cls, | ||
571 | struct GNUNET_SCHEDULER_Handle *s, | ||
572 | char *const *args, | ||
573 | const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
574 | { | ||
575 | GNUNET_assert (ok == 1); | ||
576 | OKPP; | ||
577 | sched = s; | ||
578 | 830 | ||
831 | /* Set up a task to end testing if peer start fails */ | ||
579 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 832 | die_task = GNUNET_SCHEDULER_add_delayed (sched, |
580 | GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5), &end_badly, NULL); | 833 | GNUNET_TIME_relative_multiply |
581 | 834 | (GNUNET_TIME_UNIT_MINUTES, 5), | |
582 | setup_peer (&p1, "test_transport_api_dv_peer1.conf"); | 835 | &end_badly, "didn't start all daemons in reasonable amount of time!!!"); |
583 | setup_peer (&p2, "test_transport_api_dv_peer2.conf"); | 836 | |
584 | setup_peer (&p3, "test_transport_api_dv_peer3.conf"); | 837 | pg = GNUNET_TESTING_daemons_start (sched, cfg, |
585 | setup_peer (&p4, "test_transport_api_dv_peer4.conf"); | 838 | peers_left, TIMEOUT, &hostkey_callback, NULL, &peers_started_callback, NULL, |
586 | 839 | &topology_callback, NULL, NULL); | |
587 | p1.th = GNUNET_TRANSPORT_connect (sched, p1.cfg, | 840 | |
588 | &p1, | ||
589 | ¬ify_receive, | ||
590 | ¬ify_connect, ¬ify_disconnect); | ||
591 | |||
592 | p2.th = GNUNET_TRANSPORT_connect (sched, p2.cfg, | ||
593 | &p2, | ||
594 | ¬ify_receive, | ||
595 | ¬ify_connect, ¬ify_disconnect); | ||
596 | |||
597 | p3.th = GNUNET_TRANSPORT_connect (sched, p3.cfg, | ||
598 | &p3, | ||
599 | ¬ify_receive, | ||
600 | ¬ify_connect, ¬ify_disconnect); | ||
601 | |||
602 | p4.th = GNUNET_TRANSPORT_connect (sched, p4.cfg, | ||
603 | &p4, | ||
604 | ¬ify_receive, | ||
605 | ¬ify_connect, ¬ify_disconnect); | ||
606 | GNUNET_assert(p1.th != NULL); | ||
607 | GNUNET_assert(p2.th != NULL); | ||
608 | GNUNET_assert(p3.th != NULL); | ||
609 | GNUNET_assert(p4.th != NULL); | ||
610 | |||
611 | GNUNET_TRANSPORT_get_hello (p1.th, &get_hello_first, &p1); | ||
612 | } | 841 | } |
613 | 842 | ||
614 | static int | 843 | static int |
615 | check () | 844 | check () |
616 | { | 845 | { |
617 | 846 | int ret; | |
618 | char *const argv[] = { "test-transport-api", | 847 | char *const argv[] = {"test-transport-dv", |
619 | "-c", | 848 | "-c", |
620 | "test_transport_api_data.conf", | 849 | "test_transport_dv_data.conf", |
621 | #if VERBOSE | 850 | #if VERBOSE |
622 | "-L", "DEBUG", | 851 | "-L", "DEBUG", |
623 | #endif | 852 | #endif |
624 | NULL | 853 | NULL |
625 | }; | 854 | }; |
626 | |||
627 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 855 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
628 | GNUNET_GETOPT_OPTION_END | 856 | GNUNET_GETOPT_OPTION_END |
629 | }; | 857 | }; |
630 | 858 | ret = GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, | |
631 | ok = 1; | 859 | argv, "test-transport-dv", "nohelp", |
632 | GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, | ||
633 | argv, "test-transport-api", "nohelp", | ||
634 | options, &run, &ok); | 860 | options, &run, &ok); |
635 | stop_arm (&p1); | 861 | if (ret != GNUNET_OK) |
636 | stop_arm (&p2); | 862 | { |
637 | stop_arm (&p3); | 863 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "`test-transport-dv': Failed with error code %d\n", ret); |
638 | stop_arm (&p4); | 864 | } |
639 | return ok; | 865 | return ok; |
640 | } | 866 | } |
641 | 867 | ||
642 | |||
643 | int | 868 | int |
644 | main (int argc, char *argv[]) | 869 | main (int argc, char *argv[]) |
645 | { | 870 | { |
646 | int ret; | 871 | int ret; |
647 | #ifdef MINGW | ||
648 | return GNUNET_SYSERR; | ||
649 | #endif | ||
650 | 872 | ||
651 | GNUNET_log_setup ("test-transport-api-dv", | 873 | GNUNET_log_setup ("test-transport-dv", |
652 | #if VERBOSE | 874 | #if VERBOSE |
653 | "DEBUG", | 875 | "DEBUG", |
654 | #else | 876 | #else |
@@ -656,12 +878,16 @@ main (int argc, char *argv[]) | |||
656 | #endif | 878 | #endif |
657 | NULL); | 879 | NULL); |
658 | ret = check (); | 880 | ret = check (); |
659 | GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-1"); | 881 | |
660 | GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-2"); | 882 | /** |
661 | GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-3"); | 883 | * Need to remove base directory, subdirectories taken care |
662 | GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-4"); | 884 | * of by the testing framework. |
885 | */ | ||
886 | if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK) | ||
887 | { | ||
888 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to remove testing directory %s\n", test_directory); | ||
889 | } | ||
663 | return ret; | 890 | return ret; |
664 | } | 891 | } |
665 | 892 | ||
666 | /* end of test_transport_api_dv.c */ | 893 | /* end of test_testing_topology.c */ |
667 | |||