aboutsummaryrefslogtreecommitdiff
path: root/src/transport/test_plugin_transport.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-08-23 10:01:18 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-08-23 10:01:18 +0000
commite162dd11c8f8119ec227da1bcc6f01fa1d2be32f (patch)
tree26b7259787a952917cb3e96a67c5495f09937bcc /src/transport/test_plugin_transport.c
parent71e539f5385364cddf51cb56a0859aa68dfc2375 (diff)
downloadgnunet-e162dd11c8f8119ec227da1bcc6f01fa1d2be32f.tar.gz
gnunet-e162dd11c8f8119ec227da1bcc6f01fa1d2be32f.zip
Diffstat (limited to 'src/transport/test_plugin_transport.c')
-rw-r--r--src/transport/test_plugin_transport.c397
1 files changed, 310 insertions, 87 deletions
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c
index 2cce50622..dbd6c6c63 100644
--- a/src/transport/test_plugin_transport.c
+++ b/src/transport/test_plugin_transport.c
@@ -30,15 +30,17 @@
30#include "gnunet_util_lib.h" 30#include "gnunet_util_lib.h"
31#include "gnunet_hello_lib.h" 31#include "gnunet_hello_lib.h"
32#include "gnunet_peerinfo_service.h" 32#include "gnunet_peerinfo_service.h"
33#include "gnunet_statistics_service.h"
33#include "gnunet_protocols.h" 34#include "gnunet_protocols.h"
34#include "gnunet_signatures.h" 35#include "gnunet_signatures.h"
35#include "gnunet_transport_plugin.h" 36#include "gnunet_transport_plugin.h"
37
36#include "transport.h" 38#include "transport.h"
37 39
38/** 40/**
39 * How long until we give up on transmitting the message? 41 * How long until we give up on transmitting the message?
40 */ 42 */
41#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) 43#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
42 44
43/** 45/**
44 * Our public key. 46 * Our public key.
@@ -61,6 +63,11 @@ static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
61const struct GNUNET_CONFIGURATION_Handle *cfg; 63const struct GNUNET_CONFIGURATION_Handle *cfg;
62 64
63/** 65/**
66 * Our configuration.
67 */
68struct GNUNET_STATISTICS_Handle *stats;
69
70/**
64 * Number of neighbours we'd like to have. 71 * Number of neighbours we'd like to have.
65 */ 72 */
66static uint32_t max_connect_per_transport; 73static uint32_t max_connect_per_transport;
@@ -76,24 +83,230 @@ struct GNUNET_TRANSPORT_PluginEnvironment env;
76struct GNUNET_TRANSPORT_PluginFunctions *api; 83struct GNUNET_TRANSPORT_PluginFunctions *api;
77 84
78/** 85/**
79 * Did the test pass or fail? 86 * Timeout task
80 */ 87 */
81static int ok; 88static GNUNET_SCHEDULER_TaskIdentifier timeout_task;
89
90/**
91 * Library name
92 */
93static char *libname;
94
95struct AddressWrapper *head;
96struct AddressWrapper *tail;
82 97
83/** 98/**
99 * Did the test pass or fail?
84 */ 100 */
101static int ok;
102
103
104struct AddressWrapper
105{
106 struct AddressWrapper *next;
107
108 struct AddressWrapper *prev;
109
110 void *addr;
111
112 size_t addrlen;
113};
114
85static void 115static void
86env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, 116end ()
87 const struct GNUNET_MessageHeader *message, uint32_t distance, 117{
88 const char *sender_address, size_t sender_address_len) 118 if (NULL != head)
119 {
120
121 }
122
123 if (GNUNET_SCHEDULER_NO_TASK != timeout_task)
124 {
125 GNUNET_SCHEDULER_cancel (timeout_task);
126 timeout_task = GNUNET_SCHEDULER_NO_TASK;
127 }
128
129 if (NULL != api)
130 {
131 GNUNET_PLUGIN_unload (libname, api);
132 }
133 GNUNET_free (libname);
134 libname = NULL;
135 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
136 stats = NULL;
137
138 ok = 0;
139}
140
141static void
142
143end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
144{
145 struct AddressWrapper *w;
146 int c = 0;
147
148 timeout_task = GNUNET_SCHEDULER_NO_TASK;
149 if (NULL != libname)
150 {
151 if (NULL != api)
152 GNUNET_PLUGIN_unload (libname, api);
153 GNUNET_free (libname);
154 libname = NULL;
155 }
156
157 w = head;
158 while (NULL != head)
159 {
160 GNUNET_CONTAINER_DLL_remove (head, tail, w);
161 c ++;
162 GNUNET_free (w->addr);
163 GNUNET_free (w);
164 }
165 if (c > 0)
166 {
167 GNUNET_break (0);
168 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
169 _("Plugin did not remove %u addresses \n"), c);
170 }
171
172 if (NULL != stats)
173 {
174 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
175 stats = NULL;
176 }
177
178 ok = 1;
179}
180
181
182static void
183end_badly_now ()
184{
185 if (GNUNET_SCHEDULER_NO_TASK != timeout_task)
186 {
187 GNUNET_SCHEDULER_cancel (timeout_task);
188 timeout_task = GNUNET_SCHEDULER_NO_TASK;
189 }
190 timeout_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
191}
192
193
194static struct GNUNET_TIME_Relative
195env_receive (void *cls,
196 const struct GNUNET_PeerIdentity *peer,
197 const struct GNUNET_MessageHeader *message,
198 const struct GNUNET_ATS_Information *ats,
199 uint32_t ats_count,
200 struct Session * session,
201 const char *sender_address,
202 uint16_t sender_address_len)
89{ 203{
90 /* do nothing */ 204 /* do nothing */
205 GNUNET_break (0);
206 return GNUNET_TIME_relative_get_zero_();
91} 207}
92 208
93void 209
94env_notify_address (void *cls, const char *name, const void *addr, size_t addrlen, 210static void
95 struct GNUNET_TIME_Relative expires) 211env_notify_address (void *cls,
212 int add_remove,
213 const void *addr,
214 size_t addrlen)
96{ 215{
216 struct AddressWrapper *w;
217 char *a2s;
218 void *s2a;
219 size_t s2a_len;
220
221 if (GNUNET_YES == add_remove)
222 {
223 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
224 _("Adding address of length %u\n"), addrlen);
225
226 w = GNUNET_malloc (sizeof (struct AddressWrapper));
227 w->addr = GNUNET_malloc (addrlen);
228 w->addrlen = addrlen;
229 memcpy (w->addr, addr, addrlen);
230 GNUNET_CONTAINER_DLL_insert(head, tail, w);
231
232 a2s = strdup (api->address_to_string (api, w->addr, w->addrlen));
233 if (NULL == a2s)
234 {
235 GNUNET_break (0);
236 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
237 _("Plugin cannot convert address to string!\n"));
238 end_badly_now();
239 return;
240 }
241
242 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
243 _("Plugin added address `%s'\n"), a2s);
244
245 if (GNUNET_OK != api->string_to_address (api, a2s, strlen (a2s)+1, &s2a, &s2a_len))
246 {
247 GNUNET_break (0);
248 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
249 _("Plugin cannot convert string to address!\n"));
250 end_badly_now();
251 return;
252 }
253
254 if (s2a_len != w->addrlen)
255 {
256 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
257 _("Plugin creates different address length when converting address->string->address: %u != %u\n"), w->addrlen, s2a_len);
258 }
259 else
260 {
261 if (0 != memcmp (s2a, w->addr, s2a_len))
262 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
263 _("Plugin creates different address length when connecting back and forth!\n"));
264 }
265
266 if (GNUNET_OK != api->check_address (api->cls, w->addr, w->addrlen))
267 {
268 GNUNET_break (0);
269 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
270 _("Plugin refuses added address!\n"));
271 end_badly_now();
272 return;
273 }
274 }
275 else if (GNUNET_NO == add_remove)
276 {
277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
278 _("Removing address of length %u\n"), addrlen);
279
280 w = head;
281 while (NULL != w)
282 {
283 if ((addrlen == w->addrlen) && (0 == memcmp (w->addr, addr, addrlen)))
284 {
285 break;
286 }
287 w = w->next;
288 }
289
290 if (w == NULL)
291 {
292 GNUNET_break (0);
293 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
294 _("Plugin removes address never added!\n"));
295 end_badly_now();
296 return;
297 }
298
299 GNUNET_CONTAINER_DLL_remove (head, tail, w);
300 GNUNET_free (w->addr);
301 GNUNET_free (w);
302 }
303 else
304 {
305 GNUNET_break (0);
306 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
307 _("Invalid operation\n"));
308 end_badly_now ();
309 }
97} 310}
98 311
99struct GNUNET_ATS_Information 312struct GNUNET_ATS_Information
@@ -122,69 +335,6 @@ void env_session_end (void *cls,
122 335
123} 336}
124 337
125
126/**
127 * Function called when the service shuts
128 * down. Unloads our plugins.
129 *
130 * @param cls closure
131 * @param cfg configuration to use
132 */
133static void
134unload_plugins (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
135{
136 GNUNET_assert (NULL ==
137 GNUNET_PLUGIN_unload ("libgnunet_plugin_transport_tcp", api));
138 if (my_private_key != NULL)
139 GNUNET_CRYPTO_rsa_key_free (my_private_key);
140
141}
142
143
144static void
145unload_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
146{
147 struct GNUNET_CONFIGURATION_Handle *cfg = cls;
148
149 unload_plugins (NULL, cfg);
150}
151
152
153/**
154 * Simple example test that invokes
155 * the "validate" function of the plugin
156 * and tries to see if the plugin would
157 * succeed to validate its own address.
158 * (This test is not well-written since
159 * we hand-compile the address which
160 * kind-of works for TCP but would not
161 * work for other plugins; we should ask
162 * the plugin about its address instead...).
163 */
164/* FIXME: this is TCP/UDP-specific and won't work
165 for HTTP/SMTP/DV; we should instead use an
166 address that we get from the plugin itself
167 (if it is willing/able to give us one...) */
168static void
169test_validation ()
170{
171 struct sockaddr_in soaddr;
172
173 memset (&soaddr, 0, sizeof (soaddr));
174#if HAVE_SOCKADDR_IN_SIN_LEN
175 soaddr.sin_len = sizeof (soaddr);
176#endif
177 soaddr.sin_family = AF_INET;
178 soaddr.sin_port = htons (2368 /* FIXME: get from config! */ );
179 soaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
180 GNUNET_assert (GNUNET_OK ==
181 api->check_address (api->cls, &soaddr, sizeof (soaddr)));
182 ok = 0;
183 GNUNET_SCHEDULER_add_continuation (&unload_task, (void *) cfg,
184 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
185}
186
187
188static void 338static void
189setup_plugin_environment () 339setup_plugin_environment ()
190{ 340{
@@ -192,7 +342,7 @@ setup_plugin_environment ()
192 env.cls = &env; 342 env.cls = &env;
193 env.my_identity = &my_identity; 343 env.my_identity = &my_identity;
194 env.max_connections = max_connect_per_transport; 344 env.max_connections = max_connect_per_transport;
195 env.stats = NULL; 345 env.stats = stats;
196 346
197 env.receive = &env_receive; 347 env.receive = &env_receive;
198 env.notify_address = &env_notify_address; 348 env.notify_address = &env_notify_address;
@@ -212,10 +362,13 @@ static void
212run (void *cls, char *const *args, const char *cfgfile, 362run (void *cls, char *const *args, const char *cfgfile,
213 const struct GNUNET_CONFIGURATION_Handle *c) 363 const struct GNUNET_CONFIGURATION_Handle *c)
214{ 364{
215#if 0 365 char *const *argv = cls;
216 unsigned long long tneigh; 366 unsigned long long tneigh;
217 char *keyfile; 367 char *keyfile;
218 char *libname; 368 char *plugin;
369 char *sep;
370
371 timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, end_badly, NULL);
219 372
220 cfg = c; 373 cfg = c;
221 /* parse configuration */ 374 /* parse configuration */
@@ -229,9 +382,19 @@ run (void *cls, char *const *args, const char *cfgfile,
229 { 382 {
230 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 383 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
231 _("Transport service is lacking key configuration settings. Exiting.\n")); 384 _("Transport service is lacking key configuration settings. Exiting.\n"));
232 GNUNET_SCHEDULER_shutdown (); 385
233 return; 386 return;
234 } 387 }
388
389 stats = GNUNET_STATISTICS_create ("transport", cfg);
390 if (NULL == stats)
391 {
392 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
393 _("Could not create statistics. Exiting.\n"));
394 end_badly_now ();
395 return;
396 }
397
235 max_connect_per_transport = (uint32_t) tneigh; 398 max_connect_per_transport = (uint32_t) tneigh;
236 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); 399 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
237 GNUNET_free (keyfile); 400 GNUNET_free (keyfile);
@@ -239,7 +402,7 @@ run (void *cls, char *const *args, const char *cfgfile,
239 { 402 {
240 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 403 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
241 _("Transport service could not access hostkey. Exiting.\n")); 404 _("Transport service could not access hostkey. Exiting.\n"));
242 GNUNET_SCHEDULER_shutdown (); 405 end_badly_now ();
243 return; 406 return;
244 } 407 }
245 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); 408 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
@@ -248,20 +411,77 @@ run (void *cls, char *const *args, const char *cfgfile,
248 411
249 /* load plugins... */ 412 /* load plugins... */
250 setup_plugin_environment (); 413 setup_plugin_environment ();
251 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading tcp transport plugin\n"));
252 GNUNET_asprintf (&libname, "libgnunet_plugin_transport_tcp");
253 414
415 plugin = strrchr(argv[0],'_');
416 sep = strrchr(argv[0],'.');
417 if (NULL == plugin)
418 {
419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Not a valid test name\n"));
420 end_badly_now ();
421 return;
422 }
423 plugin++;
424 if (NULL != sep)
425 sep[0] = '\0';
426
427 /* Loading plugin */
428 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading transport plugin %s\n"), plugin);
429 GNUNET_asprintf (&libname, "libgnunet_plugin_transport_%s", plugin);
254 api = GNUNET_PLUGIN_load (libname, &env); 430 api = GNUNET_PLUGIN_load (libname, &env);
255 GNUNET_free (libname);
256 if (api == NULL) 431 if (api == NULL)
257 { 432 {
258 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 433 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
259 _("Failed to load transport plugin for tcp\n")); 434 _("Failed to load transport plugin for tcp\n"));
260 /* FIXME: set some error code for main */ 435 end_badly_now ();
261 return; 436 return;
262 } 437 }
263 test_validation (); 438
264#endif 439 /* Check if all functions are implemented */
440 if (NULL == api->address_pretty_printer)
441 {
442 GNUNET_break (0);
443 end_badly_now ();
444 return;
445 }
446 if (NULL == api->address_to_string)
447 {
448 GNUNET_break (0);
449 end_badly_now ();
450 return;
451 }
452 GNUNET_assert (NULL != api->check_address);
453 if (NULL == api->check_address)
454 {
455 GNUNET_break (0);
456 end_badly_now ();
457 return;
458 }
459 GNUNET_assert (NULL != api->disconnect);
460 if (NULL == api->disconnect)
461 {
462 GNUNET_break (0);
463 end_badly_now ();
464 return;
465 }
466 GNUNET_assert (NULL != api->get_session);
467 if (NULL == api->get_session)
468 {
469 GNUNET_break (0);
470 end_badly_now ();
471 return;
472 }
473 if (NULL == api->address_pretty_printer)
474 {
475 GNUNET_break (0);
476 end_badly_now ();
477 return;
478 }
479 if (NULL == api->string_to_address)
480 {
481 GNUNET_break (0);
482 end_badly_now ();
483 return;
484 }
265} 485}
266 486
267 487
@@ -291,10 +511,13 @@ main (int argc, char *const *argv)
291 "WARNING", 511 "WARNING",
292 NULL); 512 NULL);
293 ok = 1; /* set to fail */ 513 ok = 1; /* set to fail */
294 ret = 514 ret = (GNUNET_OK == GNUNET_PROGRAM_run (5,
295 (GNUNET_OK == 515 argv_prog,
296 GNUNET_PROGRAM_run (5, argv_prog, "test-plugin-transport", "testcase", 516 "test-plugin-transport",
297 options, &run, NULL)) ? ok : 1; 517 "testcase",
518 options,
519 &run,
520 (void *) argv)) ? ok : 1;
298 GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-plugin-transport"); 521 GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-plugin-transport");
299 return ret; 522 return ret;
300} 523}