+
+/**
+ * Callback function to process statistic values.
+ *
+ * @param cls closure
+ * @param subsystem name of subsystem that created the statistic
+ * @param name the name of the datum
+ * @param value the current value
+ * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
+ * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
+ */
+static int
+print_stat (void *cls,
+ const char *subsystem,
+ const char *name,
+ uint64_t value,
+ int is_persistent)
+{
+ if (cls==&p1)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Peer1 %50s = %12llu\n",
+ name,
+ (unsigned long long) value);
+ if (cls==&p2)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Peer2 %50s = %12llu\n",
+ name,
+ (unsigned long long) value);
+ return GNUNET_OK;
+}
+
+static void
+measurement_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ unsigned long long int delta;
+ unsigned long long int throughput_out;
+ unsigned long long int throughput_in;
+ unsigned long long int max_quota_in;
+ unsigned long long int max_quota_out;
+ unsigned long long int quota_delta;
+
+ measure_task = GNUNET_SCHEDULER_NO_TASK;
+ fprintf(stdout,"\n");
+ running = GNUNET_NO;
+
+ delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value;
+
+ throughput_out = total_bytes_sent * 1000 / 1024 / delta;
+ throughput_in = total_bytes_recv * 1000 / 1024 / delta;
+
+ if (current_quota_p1_in < current_quota_p2_in)
+ max_quota_in = current_quota_p1_in;
+ else
+ max_quota_in = current_quota_p2_in;
+ if (current_quota_p1_out < current_quota_p2_out)
+ max_quota_out = current_quota_p1_out;
+ else
+ max_quota_out = current_quota_p2_out;
+
+ if (max_quota_out < max_quota_in)
+ quota_delta = max_quota_in / 10;
+ else
+ quota_delta = max_quota_out / 10;
+
+ if ((throughput_out > (max_quota_out+quota_delta)/1024) || (throughput_in > (max_quota_in+quota_delta)/1024))
+ ok = 1;
+ else
+ ok = 0;
+
+ GNUNET_STATISTICS_get (p1.stats,
+ "core",
+ "# discarded CORE_SEND requests",
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ &print_stat, &p1);
+
+ GNUNET_STATISTICS_get (p1.stats,
+ "core",
+ "# discarded CORE_SEND request bytes",
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ &print_stat, &p1);
+ GNUNET_STATISTICS_get (p1.stats,
+ "core",
+ "# discarded lower priority CORE_SEND requests",
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ &print_stat, NULL);
+ GNUNET_STATISTICS_get (p1.stats,
+ "core",
+ "# discarded lower priority CORE_SEND request bytes",
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ &print_stat, &p1);
+ GNUNET_STATISTICS_get (p2.stats,
+ "core",
+ "# discarded CORE_SEND requests",
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ &print_stat, &p2);
+
+ GNUNET_STATISTICS_get (p2.stats,
+ "core",
+ "# discarded CORE_SEND request bytes",
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ &print_stat, &p2);
+ GNUNET_STATISTICS_get (p2.stats,
+ "core",
+ "# discarded lower priority CORE_SEND requests",
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ &print_stat, &p2);
+ GNUNET_STATISTICS_get (p2.stats,
+ "core",
+ "# discarded lower priority CORE_SEND request bytes",
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ &print_stat, &p2);
+
+ enum GNUNET_ErrorType kind = GNUNET_ERROR_TYPE_DEBUG;
+ if (ok==1)
+ {
+ kind = GNUNET_ERROR_TYPE_ERROR;
+ }
+ switch (test)
+ {
+ case SYMMETRIC:
+ GNUNET_log (kind,"Core quota compliance test with symmetric quotas: %s\n", (ok==0)?"PASSED":"FAILED");
+ break;
+ case ASYMMETRIC_SEND_LIMITED:
+ GNUNET_log (kind,"Core quota compliance test with limited sender quota: %s\n", (ok==0)?"PASSED":"FAILED");
+ break;
+ case ASYMMETRIC_RECV_LIMITED:
+ GNUNET_log (kind,"Core quota compliance test with limited receiver quota: %s\n", (ok==0)?"PASSED":"FAILED");
+ break;
+ };
+ GNUNET_log (kind,"Peer 1 send rate: %llu kB/s (%llu Bytes in %u sec.)\n",throughput_out,total_bytes_sent, delta/1000);
+ GNUNET_log (kind,"Peer 1 send quota: %llu kB/s\n",current_quota_p1_out / 1024);
+ GNUNET_log (kind,"Peer 2 receive rate: %llu kB/s (%llu Bytes in %u sec.)\n",throughput_in,total_bytes_recv, delta/1000);
+ GNUNET_log (kind,"Peer 2 receive quota: %llu kB/s\n",current_quota_p2_in / 1024);
+/*
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Max. inbound quota allowed: %llu kB/s\n",max_quota_in /1024);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Max. outbound quota allowed: %llu kB/s\n",max_quota_out/1024);
+*/
+ GNUNET_SCHEDULER_cancel (err_task);
+ GNUNET_SCHEDULER_add_now (&terminate_task, NULL);
+
+}
+
+static size_t
+transmit_ready (void *cls, size_t size, void *buf)
+{
+ char *cbuf = buf;
+ struct TestMessage hdr;
+ unsigned int ret;
+
+ GNUNET_assert (size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE);
+ if (buf == NULL)
+ {
+ if ( (p1.ch != NULL) &&
+ (p1.connect_status == 1) )
+ GNUNET_break (NULL !=
+ GNUNET_CORE_notify_transmit_ready (p1.ch,
+ 0,
+ FAST_TIMEOUT,
+ &p2.id,
+ MESSAGESIZE,
+ &transmit_ready, &p1));
+ return 0;
+ }
+ GNUNET_assert (tr_n < TOTAL_MSGS);
+ ret = 0;
+ GNUNET_assert (size >= MESSAGESIZE);
+ GNUNET_assert (buf != NULL);
+ cbuf = buf;
+ do
+ {
+#if DEBUG_TRANSMISSION
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending message %u of size %u at offset %u\n",
+ tr_n,
+ MESSAGESIZE,
+ ret);
+#endif
+ hdr.header.size = htons (MESSAGESIZE);
+ hdr.header.type = htons (MTYPE);
+ hdr.num = htonl (tr_n);
+ memcpy (&cbuf[ret], &hdr, sizeof (struct TestMessage));
+ ret += sizeof (struct TestMessage);
+ memset (&cbuf[ret], tr_n, MESSAGESIZE - sizeof (struct TestMessage));
+ ret += MESSAGESIZE - sizeof (struct TestMessage);
+ tr_n++;
+ if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16))
+ break; /* sometimes pack buffer full, sometimes not */
+ }
+ while (size - ret >= MESSAGESIZE);
+ GNUNET_SCHEDULER_cancel (err_task);
+ err_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+ &terminate_task_error,
+ NULL);
+
+ total_bytes_sent += ret;
+ return ret;
+}
+
+
+
+static void
+connect_notify (void *cls,