d7f549b2d56ced38536cd0558dd6df96ce1d29a8
[oweals/gnunet.git] / src / transport / test_quota_compliance.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20 /**
21  * @file transport/test_quota_compliance.c
22  * @brief base test case for transport implementations
23  *
24  * This test case tests quota compliance both on core and transport level
25  */
26 #include "platform.h"
27 #include "gnunet_common.h"
28 #include "gnunet_hello_lib.h"
29 #include "gnunet_getopt_lib.h"
30 #include "gnunet_os_lib.h"
31 #include "gnunet_program_lib.h"
32 #include "gnunet_scheduler_lib.h"
33 #include "gnunet_server_lib.h"
34 #include "gnunet_transport_service.h"
35 #include "transport.h"
36
37 #define VERBOSE GNUNET_YES
38
39 #define VERBOSE_ARM GNUNET_NO
40
41 #define START_ARM GNUNET_YES
42 #define DEBUG_MEASUREMENT GNUNET_NO
43 #define DEBUG_CONNECTIONS GNUNET_NO
44
45 #define MEASUREMENT_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
46 #define MEASUREMENT_MSG_SIZE 10000
47 #define MEASUREMENT_MSG_SIZE_BIG 32768
48 #define MEASUREMENT_MAX_QUOTA 1024 * 1024 * 1024
49 #define MEASUREMENT_MIN_QUOTA 1024 * 10
50 #define SEND_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 35)
51 /**
52  * Testcase timeout
53  */
54 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 200)
55
56
57
58 #define MTYPE 11111
59
60 struct PeerContext
61 {
62   struct GNUNET_CONFIGURATION_Handle *cfg;
63   struct GNUNET_TRANSPORT_Handle *th;
64   struct GNUNET_PeerIdentity id;
65 #if START_ARM
66   pid_t arm_pid;
67 #endif
68 };
69
70 /**
71  * Handle for a transmission-ready request.
72  */
73 struct GNUNET_TRANSPORT_TransmitHandle
74 {
75
76   /**
77    * Neighbour for this handle, NULL for control-traffic.
78    */
79   struct NeighbourList *neighbour;
80
81   /**
82    * Function to call when notify_size bytes are available
83    * for transmission.
84    */
85   GNUNET_CONNECTION_TransmitReadyNotify notify;
86
87   /**
88    * Closure for notify.
89    */
90   void *notify_cls;
91
92   /**
93    * transmit_ready task Id.  The task is used to introduce the
94    * artificial delay that may be required to maintain the bandwidth
95    * limits.  Later, this will be the ID of the "transmit_timeout"
96    * task which is used to signal a timeout if the transmission could
97    * not be done in a timely fashion.
98    */
99   GNUNET_SCHEDULER_TaskIdentifier notify_delay_task;
100
101   /**
102    * Timeout for this request.
103    */
104   struct GNUNET_TIME_Absolute timeout;
105
106   /**
107    * How many bytes is our notify callback waiting for?
108    */
109   size_t notify_size;
110
111   /**
112    * How important is this message?
113    */
114   unsigned int priority;
115
116 };
117
118 static struct PeerContext p1;
119
120 static struct PeerContext p2;
121
122 static struct GNUNET_SCHEDULER_Handle *sched;
123
124 static int ok;
125
126 static int connected;
127 static int measurement_running;
128 static int send_running;
129 static int recv_running;
130
131 static unsigned long long total_bytes;
132 static unsigned long long current_quota_p1;
133 static unsigned long long current_quota_p2;
134
135 static int is_tcp;
136 static int is_tcp_nat;
137 static int is_http;
138 static int is_https;
139 static int is_udp;
140 static int is_asymmetric_send_constant;
141 static int is_asymmetric_recv_constant;
142
143 static struct GNUNET_TIME_Absolute start_time;
144
145 static GNUNET_SCHEDULER_TaskIdentifier die_task;
146 static GNUNET_SCHEDULER_TaskIdentifier measurement_task;
147 static GNUNET_SCHEDULER_TaskIdentifier measurement_counter_task;
148
149 struct GNUNET_TRANSPORT_TransmitHandle * transmit_handle;
150
151 #define OKPP do { ok++; } while (0)
152
153
154
155 static void
156 end_send ()
157 {
158
159 }
160
161 static void
162 end ()
163 {
164   GNUNET_SCHEDULER_cancel (sched, die_task);
165   die_task = GNUNET_SCHEDULER_NO_TASK;
166
167   if (measurement_task != GNUNET_SCHEDULER_NO_TASK)
168   {
169             GNUNET_SCHEDULER_cancel (sched, measurement_task);
170             measurement_task = GNUNET_SCHEDULER_NO_TASK;
171   }
172   if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
173   {
174             GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
175             measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
176   }
177   GNUNET_SCHEDULER_shutdown (sched);
178 #if DEBUG_CONNECTIONS
179   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transports!\n");
180 #endif
181   GNUNET_TRANSPORT_disconnect (p1.th);
182   GNUNET_TRANSPORT_disconnect (p2.th);
183 #if DEBUG_CONNECTIONS
184   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
185               "Transports disconnected, returning success!\n");
186 #endif
187   GNUNET_SCHEDULER_shutdown (sched);
188 }
189
190
191
192 static void
193 stop_arm (struct PeerContext *p)
194 {
195 #if START_ARM
196   if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
197     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
198   GNUNET_OS_process_wait (p->arm_pid);
199 #endif
200   GNUNET_CONFIGURATION_destroy (p->cfg);
201 }
202
203
204 static void
205 end_badly (void *cls,
206            const struct GNUNET_SCHEDULER_TaskContext *tc)
207 {
208   if (measurement_task != GNUNET_SCHEDULER_NO_TASK)
209   {
210             GNUNET_SCHEDULER_cancel (sched, measurement_task);
211             measurement_task = GNUNET_SCHEDULER_NO_TASK;
212   }
213   if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
214   {
215             GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
216             measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
217   }
218   GNUNET_break (0);
219   if (p1.th != NULL)
220           GNUNET_TRANSPORT_disconnect (p1.th);
221   if (p2.th != NULL)
222           GNUNET_TRANSPORT_disconnect (p2.th);
223   ok = 1;
224 }
225
226 struct TestMessage
227 {
228   struct GNUNET_MessageHeader header;
229   uint32_t num;
230 };
231
232 static unsigned int
233 get_size (unsigned int iter)
234 {
235   return MEASUREMENT_MSG_SIZE + sizeof (struct TestMessage);
236 }
237
238 static void
239 notify_receive_new (void *cls,
240                 const struct GNUNET_PeerIdentity *peer,
241                 const struct GNUNET_MessageHeader *message,
242                 struct GNUNET_TIME_Relative latency,
243                 uint32_t distance)
244 {
245   static int n;
246   unsigned int s;
247   const struct TestMessage *hdr;
248
249   hdr = (const struct TestMessage*) message;
250   s = get_size (n);
251   if (measurement_running == GNUNET_NO)
252           return;
253   if (MTYPE != ntohs (message->type))
254     return;
255 #if DEBUG_MEASUREMENT
256   if (ntohl(hdr->num) % 5000 == 0)
257     {
258       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
259                   "Got message %u of size %u\n",
260                   ntohl (hdr->num),
261                   ntohs (message->size));
262     }
263 #endif
264   n++;
265 }
266
267 static size_t
268 notify_ready_new (void *cls, size_t size, void *buf)
269 {
270   static int n;
271   char *cbuf = buf;
272   struct TestMessage hdr;
273   unsigned int s;
274   unsigned int ret;
275
276   transmit_handle = NULL;
277
278   if (measurement_task == GNUNET_SCHEDULER_NO_TASK)
279           return 0;
280
281   if (buf == NULL)
282     {
283       ok = 42;
284       return 0;
285     }
286
287   if (measurement_running != GNUNET_YES)
288   {
289           send_running = GNUNET_NO;
290           end_send();
291           return 0;
292   }
293
294   send_running = GNUNET_YES;
295   ret = 0;
296   s = get_size (n);
297   GNUNET_assert (size >= s);
298   GNUNET_assert (buf != NULL);
299   cbuf = buf;
300   do
301     {
302       hdr.header.size = htons (s);
303       hdr.header.type = htons (MTYPE);
304       hdr.num = htonl (n);
305       memcpy (&cbuf[ret], &hdr, sizeof (struct TestMessage));
306       ret += sizeof (struct TestMessage);
307       memset (&cbuf[ret], n, s - sizeof (struct TestMessage));
308       ret += s - sizeof (struct TestMessage);
309 #if DEBUG_MEASUREMENT
310       if (n % 5000 == 0)
311        {
312           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
313                       "Sending message %u\n",n);
314        }
315 #endif
316       n++;
317       s = get_size (n);
318       if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16))
319         break; /* sometimes pack buffer full, sometimes not */
320     }
321   while (size - ret >= s);
322   transmit_handle = GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
323                                             &p1.id,
324                                             s, 0, SEND_TIMEOUT,
325                                             &notify_ready_new,
326                                             NULL);
327   total_bytes += s;
328   return ret;
329 }
330
331 static void measure (unsigned long long quota_p1, unsigned long long quota_p2 );
332
333 static void measurement_counter
334  (void *cls,
335            const struct GNUNET_SCHEDULER_TaskContext *tc)
336 {
337   measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
338
339   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
340         return;
341
342 #if VERBOSE
343   fprintf(stderr,".");
344 #endif
345   measurement_counter_task = GNUNET_SCHEDULER_add_delayed (sched,
346                                                            GNUNET_TIME_UNIT_SECONDS,
347                                                            &measurement_counter,
348                                                            NULL);
349 }
350
351 static void
352 measurement_end (void *cls,
353            const struct GNUNET_SCHEDULER_TaskContext *tc)
354 {
355   int quota_allowed = 0;
356   measurement_task  = GNUNET_SCHEDULER_NO_TASK;
357   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
358         return;
359
360   measurement_running = GNUNET_NO;
361   struct GNUNET_TIME_Relative duration = GNUNET_TIME_absolute_get_difference(start_time, GNUNET_TIME_absolute_get());
362
363
364   if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
365   {
366     GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
367     measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
368   }
369 #if VERBOSE
370   fprintf(stderr,"\n");
371 #endif
372   /*
373   if (transmit_handle != NULL)
374   {
375           GNUNET_TRANSPORT_notify_transmit_ready_cancel(transmit_handle);
376           transmit_handle = NULL;
377   }
378   */
379
380   if (current_quota_p1 < current_quota_p2)
381           quota_allowed = current_quota_p1;
382   else
383           quota_allowed = current_quota_p2;
384
385   if ((total_bytes/(duration.rel_value / 1000)) > (quota_allowed + (quota_allowed / 10)))
386   {
387           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
388                           "\nQuota compliance failed: \n"\
389                           "Quota allowed: %10llu kB/s\n"\
390                           "Throughput   : %10llu kB/s\n", (quota_allowed / (1024)) , (total_bytes/(duration.rel_value / 1000)/1024));
391           ok = 1;
392 /*        end();
393           return;*/
394   }
395   else
396   {
397
398           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
399                           "\nQuota compliance ok: \n"\
400                           "Quota allowed: %10llu kB/s\n"\
401                           "Throughput   : %10llu kB/s\n", (quota_allowed / (1024)) , (total_bytes/(duration.rel_value / 1000)/1024));
402           ok = 0;
403   }
404
405   if (quota_allowed < MEASUREMENT_MIN_QUOTA)
406   {
407           end();
408           return;
409   }
410   else
411   {
412    if (is_asymmetric_send_constant == GNUNET_YES)
413            measure (current_quota_p1 / 10, MEASUREMENT_MAX_QUOTA);
414    else if (is_asymmetric_recv_constant == GNUNET_YES)
415            measure (MEASUREMENT_MAX_QUOTA, current_quota_p2 / 10);
416    else
417            measure (current_quota_p1 / 10, current_quota_p2 / 10);
418   }
419 }
420
421 static void measure (unsigned long long quota_p1, unsigned long long quota_p2 )
422 {
423           current_quota_p1 = quota_p1;
424           current_quota_p2 = quota_p2;
425 #if VERBOSE
426   if ((is_asymmetric_send_constant == GNUNET_YES) || (is_asymmetric_recv_constant == GNUNET_YES))
427           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
428               "Starting transport level measurement for %u seconds, receiving peer quota %llu kB/s, sending peer quota %llu kB/s\n", MEASUREMENT_INTERVALL.rel_value / 1000 , current_quota_p1 / 1024, current_quota_p2 / 1024);
429   else
430           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
431               "Starting transport level measurement for %u seconds, symmetric quota %llu kB/s\n", MEASUREMENT_INTERVALL.rel_value / 1000 , current_quota_p2 / 1024);
432
433 #endif
434                 GNUNET_TRANSPORT_set_quota (p1.th,
435                           &p2.id,
436                           GNUNET_BANDWIDTH_value_init (current_quota_p1 ),
437                           GNUNET_BANDWIDTH_value_init (current_quota_p1 ),
438                           GNUNET_TIME_UNIT_FOREVER_REL,
439                           NULL, NULL);
440                 GNUNET_TRANSPORT_set_quota (p2.th,
441                           &p1.id,
442                           GNUNET_BANDWIDTH_value_init (current_quota_p2),
443                           GNUNET_BANDWIDTH_value_init (current_quota_p2),
444                           GNUNET_TIME_UNIT_FOREVER_REL,
445                           NULL, NULL);
446
447                 GNUNET_SCHEDULER_cancel (sched, die_task);
448                 die_task = GNUNET_SCHEDULER_add_delayed (sched,
449                                                    TIMEOUT,
450                                                    &end_badly,
451                                                    NULL);
452                 if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
453                   GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
454                 measurement_counter_task = GNUNET_SCHEDULER_add_delayed (sched,
455                                                                    GNUNET_TIME_UNIT_SECONDS,
456                                                                    &measurement_counter,
457                                                                    NULL);
458                 measurement_task = GNUNET_SCHEDULER_add_delayed (sched,
459                                                    MEASUREMENT_INTERVALL,
460                                                    &measurement_end,
461                                                    NULL);
462                 total_bytes = 0;
463                 measurement_running = GNUNET_YES;
464                 start_time = GNUNET_TIME_absolute_get ();
465
466                 if (transmit_handle != NULL)
467                           GNUNET_TRANSPORT_notify_transmit_ready_cancel(transmit_handle);
468                 transmit_handle = GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
469                                                                                           &p1.id,
470                                                                                           get_size (0), 0, SEND_TIMEOUT,
471                                                                                           &notify_ready_new,
472                                                                                           NULL);
473 }
474
475 static void
476 notify_connect (void *cls,
477                 const struct GNUNET_PeerIdentity *peer,
478                 struct GNUNET_TIME_Relative latency,
479                 uint32_t distance)
480 {
481   if (cls == &p1)
482     {
483 #if DEBUG_CONNECTIONS
484   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
485               "Peer 1 `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls);
486 #endif
487           connected++;
488     }
489   else
490     {
491 #if DEBUG_CONNECTIONS
492   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
493               "Peer 2 `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls);
494 #endif
495       connected++;
496     }
497   if (connected == 2)
498     {
499           measure(MEASUREMENT_MAX_QUOTA,MEASUREMENT_MAX_QUOTA);
500     }
501 }
502
503
504 static void
505 notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
506 {
507 #if DEBUG_CONNECTIONS
508   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
509               "Peer `%4s' disconnected (%p)!\n",
510               GNUNET_i2s (peer), cls);
511 #endif
512 }
513
514
515 static void
516 setup_peer (struct PeerContext *p, const char *cfgname)
517 {
518   p->cfg = GNUNET_CONFIGURATION_create ();
519 #if START_ARM
520   p->arm_pid = GNUNET_OS_start_process (NULL, NULL,
521                                         "gnunet-service-arm",
522                                         "gnunet-service-arm",
523 #if VERBOSE_ARM
524                                         "-L", "DEBUG",
525 #endif
526                                         "-c", cfgname, NULL);
527 #endif
528
529   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
530   p->th = GNUNET_TRANSPORT_connect (sched, p->cfg, NULL,
531                                     p,
532                                     &notify_receive_new,
533                                     &notify_connect,
534                                     &notify_disconnect);
535   GNUNET_assert (p->th != NULL);
536 }
537
538
539 static void
540 exchange_hello_last (void *cls,
541                      const struct GNUNET_MessageHeader *message)
542 {
543   struct PeerContext *me = cls;
544
545   GNUNET_TRANSPORT_get_hello_cancel (p2.th, &exchange_hello_last, me);
546
547   GNUNET_assert (ok >= 3);
548   OKPP;
549   GNUNET_assert (message != NULL);
550   GNUNET_assert (GNUNET_OK ==
551                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
552                                       message, &me->id));
553   /* both HELLOs exchanged, get ready to test transmission! */
554 }
555
556
557 static void
558 exchange_hello (void *cls,
559                 const struct GNUNET_MessageHeader *message)
560 {
561   struct PeerContext *me = cls;
562
563   GNUNET_TRANSPORT_get_hello_cancel (p1.th, &exchange_hello, me);
564   GNUNET_assert (ok >= 2);
565   OKPP;
566   GNUNET_assert (message != NULL);
567   GNUNET_assert (GNUNET_OK ==
568                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
569                                       message, &me->id));
570   GNUNET_TRANSPORT_offer_hello (p2.th, message);
571   GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2);
572 }
573
574 static void
575 run (void *cls,
576      struct GNUNET_SCHEDULER_Handle *s,
577      char *const *args,
578      const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
579 {
580   GNUNET_assert (ok == 1);
581   OKPP;
582   sched = s;
583
584   die_task = GNUNET_SCHEDULER_add_delayed (sched,
585                                            TIMEOUT,
586                                            &end_badly,
587                                            NULL);
588   measurement_running = GNUNET_NO;
589   send_running = GNUNET_NO;
590   recv_running = GNUNET_NO;
591
592   if (is_tcp)
593     {
594           if (is_asymmetric_recv_constant == GNUNET_YES)
595                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for TCP transport plugin\n");
596           else if (is_asymmetric_send_constant == GNUNET_YES)
597                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for TCP transport plugin\n");
598           else
599                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for TCP transport plugin\n");
600       setup_peer (&p1, "test_quota_compliance_tcp_peer1.conf");
601       setup_peer (&p2, "test_quota_compliance_tcp_peer2.conf");
602     }
603   else if (is_http)
604     {
605           if (is_asymmetric_recv_constant == GNUNET_YES)
606                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for HTTP transport plugin\n");
607           else if (is_asymmetric_send_constant == GNUNET_YES)
608                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for HTTP transport plugin\n");
609           else
610                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for HTTP transport plugin\n");
611       setup_peer (&p1, "test_quota_compliance_http_peer1.conf");
612       setup_peer (&p2, "test_quota_compliance_http_peer2.conf");
613     }
614   else if (is_https)
615     {
616           if (is_asymmetric_recv_constant == GNUNET_YES)
617                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for HTTPS transport plugin\n");
618           else if (is_asymmetric_send_constant == GNUNET_YES)
619                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for HTTPS transport plugin\n");
620           else
621                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for HTTPS transport plugin\n");
622       setup_peer (&p1, "test_quota_compliance_https_peer1.conf");
623       setup_peer (&p2, "test_quota_compliance_https_peer2.conf");
624     }
625   else if (is_udp)
626     {
627           if (is_asymmetric_recv_constant == GNUNET_YES)
628                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for UDP transport plugin\n");
629           else if (is_asymmetric_send_constant == GNUNET_YES)
630                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for UDP transport plugin\n");
631           else
632                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for UDP transport plugin\n");
633       setup_peer (&p1, "test_quota_compliance_udp_peer1.conf");
634       setup_peer (&p2, "test_quota_compliance_udp_peer2.conf");
635     }
636   else if (is_tcp_nat)
637     {
638           if (is_asymmetric_recv_constant == GNUNET_YES)
639                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for TCP NAT transport plugin\n");
640           else if (is_asymmetric_send_constant == GNUNET_YES)
641                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for TCP NAT transport plugin\n");
642           else
643                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for TCP NAT transport plugin\n");
644       setup_peer (&p1, "test_quota_compliance_tcp_peer1.conf");
645       setup_peer (&p2, "test_quota_compliance_tcp_peer2.conf");
646     }
647   else
648     GNUNET_assert (0);
649
650   GNUNET_assert(p1.th != NULL);
651   GNUNET_assert(p2.th != NULL);
652   GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1);
653 }
654
655 int
656 main (int argc, char *argv[])
657 {
658   int ret = 0;
659 #ifdef MINGW
660   return GNUNET_SYSERR;
661 #endif
662   if (strstr(argv[0], "tcp_nat") != NULL)
663     {
664       is_tcp_nat = GNUNET_YES;
665     }
666   else if (strstr(argv[0], "tcp") != NULL)
667     {
668       is_tcp = GNUNET_YES;
669     }
670   else if (strstr(argv[0], "https") != NULL)
671     {
672       is_https = GNUNET_YES;
673     }
674   else if (strstr(argv[0], "http") != NULL)
675     {
676       is_http = GNUNET_YES;
677     }
678   else if (strstr(argv[0], "udp") != NULL)
679     {
680       is_udp = GNUNET_YES;
681     }
682
683   if (strstr(argv[0], "asymmetric_recv") != NULL)
684   {
685       is_asymmetric_recv_constant = GNUNET_YES;
686   }
687   else
688           is_asymmetric_recv_constant = GNUNET_NO;
689   if (strstr(argv[0], "asymmetric_send") != NULL)
690   {
691       is_asymmetric_send_constant = GNUNET_YES;
692   }
693   else
694           is_asymmetric_send_constant = GNUNET_NO;
695
696   char * logger;
697   if (is_tcp == GNUNET_YES)
698   {
699           if (is_asymmetric_recv_constant == GNUNET_YES)
700                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","tcp","asymmetric_recv_constant");
701           else if (is_asymmetric_send_constant == GNUNET_YES)
702                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","tcp","asymmetric_send_constant");
703           else
704                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","tcp","symmetric");
705   }
706   if (is_udp == GNUNET_YES)
707   {
708           if (is_asymmetric_recv_constant == GNUNET_YES)
709                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","udp","asymmetric_recv_constant");
710           else if (is_asymmetric_send_constant == GNUNET_YES)
711                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","udp","asymmetric_send_constant");
712           else
713                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","udp","symmetric");
714   }
715   if (is_http == GNUNET_YES)
716   {
717           if (is_asymmetric_recv_constant == GNUNET_YES)
718                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","http","asymmetric_recv_constant");
719           else if (is_asymmetric_send_constant == GNUNET_YES)
720                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","http","asymmetric_send_constant");
721           else
722                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","http","symmetric");
723   }
724   if (is_https == GNUNET_YES)
725   {
726           if (is_asymmetric_recv_constant == GNUNET_YES)
727                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","https","asymmetric_recv_constant");
728           else if (is_asymmetric_send_constant == GNUNET_YES)
729                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","https","asymmetric_send_constant");
730           else
731                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","https","symmetric");
732   }
733
734   GNUNET_log_setup ("test-quota-compliance",
735 #if VERBOSE
736                     "DEBUG",
737 #else
738                     "WARNING",
739 #endif
740                     NULL);
741   char *const argv1[] = { "test-quota-compliance",
742     "-c",
743     "test_quota_compliance_data.conf",
744 #if VERBOSE
745     "-L", "DEBUG",
746 #endif
747     NULL
748   };
749   struct GNUNET_GETOPT_CommandLineOption options[] = {
750     GNUNET_GETOPT_OPTION_END
751   };
752   ok = 1;
753   GNUNET_PROGRAM_run ((sizeof (argv1) / sizeof (char *)) - 1,
754                       argv1, logger , "nohelp",
755                       options, &run, &ok);
756   ret = ok;
757   stop_arm (&p1);
758   stop_arm (&p2);
759   GNUNET_free(logger);
760   GNUNET_DISK_directory_remove ("/tmp/test_quota_compliance_peer1");
761   GNUNET_DISK_directory_remove ("/tmp/test_quota_compliance_peer2");
762   return ret;
763 }
764
765 /* end of test_quota_compliance.c */