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