86357c5409c39a2a62d58cfa81718df70e210aa6
[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 1024
47 #define MEASUREMENT_MSG_SIZE_BIG 32768
48 #define MEASUREMENT_MAX_QUOTA 1024 * 1024 * 1024
49 #define MEASUREMENT_MIN_QUOTA 1024 * 1024
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   static int strike_counter;
356   unsigned long long  quota_allowed = 0;
357   measurement_task  = GNUNET_SCHEDULER_NO_TASK;
358   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
359         return;
360
361   measurement_running = GNUNET_NO;
362   struct GNUNET_TIME_Relative duration = GNUNET_TIME_absolute_get_difference(start_time, GNUNET_TIME_absolute_get());
363
364
365   if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
366   {
367     GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
368     measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
369   }
370 #if VERBOSE
371   fprintf(stderr,"\n");
372 #endif
373   /*
374   if (transmit_handle != NULL)
375   {
376           GNUNET_TRANSPORT_notify_transmit_ready_cancel(transmit_handle);
377           transmit_handle = NULL;
378   }
379   */
380
381   if (current_quota_p1 < current_quota_p2)
382           quota_allowed = current_quota_p1;
383   else
384           quota_allowed = current_quota_p2;
385
386   if ((total_bytes/(duration.rel_value / 1000)) > (quota_allowed + (quota_allowed / 10)))
387   {
388           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
389                           "\nQuota compliance failed: \n"\
390                           "Quota allowed: %10llu kB/s\n"\
391                           "Throughput   : %10llu kB/s\n", (quota_allowed / (1024)), (total_bytes/(duration.rel_value / 1000)/1024));
392           ok = 1;
393           /*end();
394           return;*/
395   }
396   else
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) > (2 *(total_bytes/(duration.rel_value / 1000))))
406   {
407           strike_counter++;
408           if (strike_counter == 2)
409           {
410                   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
411                                   "Maximum transmission rate reached, stopping test\n");
412                   end();
413                   return;
414           }
415   }
416   else
417   {
418           strike_counter = 0;
419   }
420
421   if (quota_allowed == MEASUREMENT_MAX_QUOTA)
422   {
423           end();
424           return;
425   }
426
427   if (is_asymmetric_send_constant == GNUNET_YES)
428   {
429    if ((quota_allowed * 2) < MEASUREMENT_MAX_QUOTA)
430           measure (current_quota_p1 * 2, MEASUREMENT_MAX_QUOTA);
431    else
432            measure (MEASUREMENT_MAX_QUOTA, MEASUREMENT_MAX_QUOTA);
433   }
434   else if (is_asymmetric_recv_constant == GNUNET_YES)
435   {
436    if ((quota_allowed * 2) < MEASUREMENT_MAX_QUOTA)
437           measure (MEASUREMENT_MAX_QUOTA, current_quota_p2 * 2);
438    else
439            measure (MEASUREMENT_MAX_QUOTA, MEASUREMENT_MAX_QUOTA);
440   }
441   else
442   {
443    if ((quota_allowed * 2) < MEASUREMENT_MAX_QUOTA)
444           measure ((current_quota_p1) * 2, (current_quota_p2) * 2);
445    else
446            measure (MEASUREMENT_MAX_QUOTA, MEASUREMENT_MAX_QUOTA);
447   }
448 }
449
450 static void measure (unsigned long long quota_p1, unsigned long long quota_p2 )
451 {
452           current_quota_p1 = quota_p1;
453           current_quota_p2 = quota_p2;
454 #if VERBOSE
455   if ((is_asymmetric_send_constant == GNUNET_YES) || (is_asymmetric_recv_constant == GNUNET_YES))
456           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
457               "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);
458   else
459           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
460               "Starting transport level measurement for %u seconds, symmetric quota %llu kB/s\n", MEASUREMENT_INTERVALL.rel_value / 1000 , current_quota_p2 / 1024);
461
462 #endif
463                 GNUNET_TRANSPORT_set_quota (p1.th,
464                           &p2.id,
465                           GNUNET_BANDWIDTH_value_init (current_quota_p1 ),
466                           GNUNET_BANDWIDTH_value_init (current_quota_p1 ),
467                           GNUNET_TIME_UNIT_FOREVER_REL,
468                           NULL, NULL);
469                 GNUNET_TRANSPORT_set_quota (p2.th,
470                           &p1.id,
471                           GNUNET_BANDWIDTH_value_init (current_quota_p2),
472                           GNUNET_BANDWIDTH_value_init (current_quota_p2),
473                           GNUNET_TIME_UNIT_FOREVER_REL,
474                           NULL, NULL);
475
476                 GNUNET_SCHEDULER_cancel (sched, die_task);
477                 die_task = GNUNET_SCHEDULER_add_delayed (sched,
478                                                    TIMEOUT,
479                                                    &end_badly,
480                                                    NULL);
481                 if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
482                   GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
483                 measurement_counter_task = GNUNET_SCHEDULER_add_delayed (sched,
484                                                                    GNUNET_TIME_UNIT_SECONDS,
485                                                                    &measurement_counter,
486                                                                    NULL);
487                 measurement_task = GNUNET_SCHEDULER_add_delayed (sched,
488                                                    MEASUREMENT_INTERVALL,
489                                                    &measurement_end,
490                                                    NULL);
491                 total_bytes = 0;
492                 measurement_running = GNUNET_YES;
493                 start_time = GNUNET_TIME_absolute_get ();
494
495                 if (transmit_handle != NULL)
496                           GNUNET_TRANSPORT_notify_transmit_ready_cancel(transmit_handle);
497                 transmit_handle = GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
498                                                                                           &p1.id,
499                                                                                           get_size (0), 0, SEND_TIMEOUT,
500                                                                                           &notify_ready_new,
501                                                                                           NULL);
502 }
503
504 static void
505 notify_connect (void *cls,
506                 const struct GNUNET_PeerIdentity *peer,
507                 struct GNUNET_TIME_Relative latency,
508                 uint32_t distance)
509 {
510   if (cls == &p1)
511     {
512 #if DEBUG_CONNECTIONS
513   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
514               "Peer 1 `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls);
515 #endif
516           connected++;
517     }
518   else
519     {
520 #if DEBUG_CONNECTIONS
521   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
522               "Peer 2 `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls);
523 #endif
524       connected++;
525     }
526   if (connected == 2)
527     {
528            if (is_asymmetric_send_constant == GNUNET_YES)
529                    measure (MEASUREMENT_MIN_QUOTA, MEASUREMENT_MAX_QUOTA);
530            else if (is_asymmetric_recv_constant == GNUNET_YES)
531                    measure (MEASUREMENT_MAX_QUOTA, MEASUREMENT_MIN_QUOTA);
532            else
533                    measure (MEASUREMENT_MIN_QUOTA, MEASUREMENT_MIN_QUOTA);
534     }
535 }
536
537
538 static void
539 notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
540 {
541 #if DEBUG_CONNECTIONS
542   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
543               "Peer `%4s' disconnected (%p)!\n",
544               GNUNET_i2s (peer), cls);
545 #endif
546 }
547
548
549 static void
550 setup_peer (struct PeerContext *p, const char *cfgname)
551 {
552   p->cfg = GNUNET_CONFIGURATION_create ();
553 #if START_ARM
554   p->arm_pid = GNUNET_OS_start_process (NULL, NULL,
555                                         "gnunet-service-arm",
556                                         "gnunet-service-arm",
557 #if VERBOSE_ARM
558                                         "-L", "DEBUG",
559 #endif
560                                         "-c", cfgname, NULL);
561 #endif
562
563   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
564   p->th = GNUNET_TRANSPORT_connect (sched, p->cfg, NULL,
565                                     p,
566                                     &notify_receive_new,
567                                     &notify_connect,
568                                     &notify_disconnect);
569   GNUNET_assert (p->th != NULL);
570 }
571
572
573 static void
574 exchange_hello_last (void *cls,
575                      const struct GNUNET_MessageHeader *message)
576 {
577   struct PeerContext *me = cls;
578
579   GNUNET_TRANSPORT_get_hello_cancel (p2.th, &exchange_hello_last, me);
580
581   GNUNET_assert (ok >= 3);
582   OKPP;
583   GNUNET_assert (message != NULL);
584   GNUNET_assert (GNUNET_OK ==
585                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
586                                       message, &me->id));
587   /* both HELLOs exchanged, get ready to test transmission! */
588 }
589
590
591 static void
592 exchange_hello (void *cls,
593                 const struct GNUNET_MessageHeader *message)
594 {
595   struct PeerContext *me = cls;
596
597   GNUNET_TRANSPORT_get_hello_cancel (p1.th, &exchange_hello, me);
598   GNUNET_assert (ok >= 2);
599   OKPP;
600   GNUNET_assert (message != NULL);
601   GNUNET_assert (GNUNET_OK ==
602                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
603                                       message, &me->id));
604   GNUNET_TRANSPORT_offer_hello (p2.th, message);
605   GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2);
606 }
607
608 static void
609 run (void *cls,
610      struct GNUNET_SCHEDULER_Handle *s,
611      char *const *args,
612      const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
613 {
614   GNUNET_assert (ok == 1);
615   OKPP;
616   sched = s;
617
618   die_task = GNUNET_SCHEDULER_add_delayed (sched,
619                                            TIMEOUT,
620                                            &end_badly,
621                                            NULL);
622   measurement_running = GNUNET_NO;
623   send_running = GNUNET_NO;
624   recv_running = GNUNET_NO;
625
626   if (is_tcp)
627     {
628           if (is_asymmetric_recv_constant == GNUNET_YES)
629                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for TCP transport plugin\n");
630           else if (is_asymmetric_send_constant == GNUNET_YES)
631                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for TCP transport plugin\n");
632           else
633                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for TCP transport plugin\n");
634       setup_peer (&p1, "test_quota_compliance_tcp_peer1.conf");
635       setup_peer (&p2, "test_quota_compliance_tcp_peer2.conf");
636     }
637   else if (is_http)
638     {
639           if (is_asymmetric_recv_constant == GNUNET_YES)
640                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for HTTP transport plugin\n");
641           else if (is_asymmetric_send_constant == GNUNET_YES)
642                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for HTTP transport plugin\n");
643           else
644                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for HTTP transport plugin\n");
645       setup_peer (&p1, "test_quota_compliance_http_peer1.conf");
646       setup_peer (&p2, "test_quota_compliance_http_peer2.conf");
647     }
648   else if (is_https)
649     {
650           if (is_asymmetric_recv_constant == GNUNET_YES)
651                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for HTTPS transport plugin\n");
652           else if (is_asymmetric_send_constant == GNUNET_YES)
653                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for HTTPS transport plugin\n");
654           else
655                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for HTTPS transport plugin\n");
656       setup_peer (&p1, "test_quota_compliance_https_peer1.conf");
657       setup_peer (&p2, "test_quota_compliance_https_peer2.conf");
658     }
659   else if (is_udp)
660     {
661           if (is_asymmetric_recv_constant == GNUNET_YES)
662                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for UDP transport plugin\n");
663           else if (is_asymmetric_send_constant == GNUNET_YES)
664                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for UDP transport plugin\n");
665           else
666                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for UDP transport plugin\n");
667       setup_peer (&p1, "test_quota_compliance_udp_peer1.conf");
668       setup_peer (&p2, "test_quota_compliance_udp_peer2.conf");
669     }
670   else if (is_tcp_nat)
671     {
672           if (is_asymmetric_recv_constant == GNUNET_YES)
673                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for TCP NAT transport plugin\n");
674           else if (is_asymmetric_send_constant == GNUNET_YES)
675                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for TCP NAT transport plugin\n");
676           else
677                   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for TCP NAT transport plugin\n");
678       setup_peer (&p1, "test_quota_compliance_tcp_peer1.conf");
679       setup_peer (&p2, "test_quota_compliance_tcp_peer2.conf");
680     }
681   else
682     GNUNET_assert (0);
683
684   GNUNET_assert(p1.th != NULL);
685   GNUNET_assert(p2.th != NULL);
686   GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1);
687 }
688
689 int
690 main (int argc, char *argv[])
691 {
692   int ret = 0;
693 #ifdef MINGW
694   return GNUNET_SYSERR;
695 #endif
696   if (strstr(argv[0], "tcp_nat") != NULL)
697     {
698       is_tcp_nat = GNUNET_YES;
699     }
700   else if (strstr(argv[0], "tcp") != NULL)
701     {
702       is_tcp = GNUNET_YES;
703     }
704   else if (strstr(argv[0], "https") != NULL)
705     {
706       is_https = GNUNET_YES;
707     }
708   else if (strstr(argv[0], "http") != NULL)
709     {
710       is_http = GNUNET_YES;
711     }
712   else if (strstr(argv[0], "udp") != NULL)
713     {
714       is_udp = GNUNET_YES;
715     }
716
717   if (strstr(argv[0], "asymmetric_recv") != NULL)
718   {
719       is_asymmetric_recv_constant = GNUNET_YES;
720   }
721   else
722           is_asymmetric_recv_constant = GNUNET_NO;
723   if (strstr(argv[0], "asymmetric_send") != NULL)
724   {
725       is_asymmetric_send_constant = GNUNET_YES;
726   }
727   else
728           is_asymmetric_send_constant = GNUNET_NO;
729
730   char * logger;
731   if (is_tcp == GNUNET_YES)
732   {
733           if (is_asymmetric_recv_constant == GNUNET_YES)
734                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","tcp","asymmetric_recv_constant");
735           else if (is_asymmetric_send_constant == GNUNET_YES)
736                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","tcp","asymmetric_send_constant");
737           else
738                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","tcp","symmetric");
739   }
740   if (is_udp == GNUNET_YES)
741   {
742           if (is_asymmetric_recv_constant == GNUNET_YES)
743                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","udp","asymmetric_recv_constant");
744           else if (is_asymmetric_send_constant == GNUNET_YES)
745                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","udp","asymmetric_send_constant");
746           else
747                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","udp","symmetric");
748   }
749   if (is_http == GNUNET_YES)
750   {
751           if (is_asymmetric_recv_constant == GNUNET_YES)
752                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","http","asymmetric_recv_constant");
753           else if (is_asymmetric_send_constant == GNUNET_YES)
754                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","http","asymmetric_send_constant");
755           else
756                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","http","symmetric");
757   }
758   if (is_https == GNUNET_YES)
759   {
760           if (is_asymmetric_recv_constant == GNUNET_YES)
761                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","https","asymmetric_recv_constant");
762           else if (is_asymmetric_send_constant == GNUNET_YES)
763                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","https","asymmetric_send_constant");
764           else
765                   GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","https","symmetric");
766   }
767
768   GNUNET_log_setup ("test-quota-compliance",
769 #if VERBOSE
770                     "DEBUG",
771 #else
772                     "WARNING",
773 #endif
774                     NULL);
775   char *const argv1[] = { "test-quota-compliance",
776     "-c",
777     "test_quota_compliance_data.conf",
778 #if VERBOSE
779     "-L", "DEBUG",
780 #endif
781     NULL
782   };
783   struct GNUNET_GETOPT_CommandLineOption options[] = {
784     GNUNET_GETOPT_OPTION_END
785   };
786   ok = 1;
787   GNUNET_PROGRAM_run ((sizeof (argv1) / sizeof (char *)) - 1,
788                       argv1, logger , "nohelp",
789                       options, &run, &ok);
790   ret = ok;
791   stop_arm (&p1);
792   stop_arm (&p2);
793   GNUNET_free(logger);
794   GNUNET_DISK_directory_remove ("/tmp/test_quota_compliance_peer1");
795   GNUNET_DISK_directory_remove ("/tmp/test_quota_compliance_peer2");
796   return ret;
797 }
798
799 /* end of test_quota_compliance.c */