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