static int test_quickFindFirst_Iteration (const size_t k, const size_t n, int * buf, int range) { size_t i; int highest_low; int lowest_high; /* populate buf with random ints */ for (i=0; i<n; ++i) buf[i] = tr_rand_int_weak (range); /* find the best k */ tr_quickfindFirstK (buf, n, sizeof(int), compareInts, k); /* confirm that the smallest K ints are in the first slots K slots in buf */ highest_low = INT_MIN; for (i=0; i<k; ++i) if (highest_low < buf[i]) highest_low = buf[i]; lowest_high = INT_MAX; for (i=k; i<n; ++i) if (lowest_high > buf[i]) lowest_high = buf[i]; check (highest_low <= lowest_high); return 0; }
static void nap (int roughly_sec) { const int roughly_msec = roughly_sec * 1000; const int msec = roughly_msec/2 + tr_rand_int_weak (roughly_msec); tr_wait_msec (msec); }
static int test_single_directory_random_payload_impl (const tr_tracker_info * trackers, const size_t trackerCount, const size_t maxFileCount, const size_t maxFileSize, const char * comment, const bool isPrivate) { size_t i; void ** payloads; size_t * payloadSizes; size_t payloadCount; /* build random payloads */ payloadCount = 1 + tr_rand_int_weak (maxFileCount); payloads = tr_new0 (void*, payloadCount); payloadSizes = tr_new0 (size_t, payloadCount); for (i=0; i<payloadCount; i++) { const size_t n = 1 + tr_rand_int_weak (maxFileSize); payloads[i] = tr_new (char, n); tr_rand_buffer (payloads[i], n); payloadSizes[i] = n; } /* run the test */ test_single_directory_impl (trackers, trackerCount, (const void**) payloads, payloadSizes, payloadCount, comment, isPrivate); /* cleanup */ for (i=0; i<payloadCount; i++) tr_free (payloads[i]); tr_free (payloads); tr_free (payloadSizes); return 0; }
static int test_bitfield_count_range (void) { int i; int n; int begin; int end; int count1; int count2; const int bitCount = 100 + tr_rand_int_weak (1000); tr_bitfield bf; /* generate a random bitfield */ tr_bitfieldConstruct (&bf, bitCount); for (i=0, n=tr_rand_int_weak (bitCount); i<n; ++i) tr_bitfieldAdd (&bf, tr_rand_int_weak (bitCount)); begin = tr_rand_int_weak (bitCount); do end = tr_rand_int_weak (bitCount); while (end == begin); /* ensure end <= begin */ if (end < begin) { const int tmp = begin; begin = end; end = tmp; } /* test the bitfield */ count1 = 0; for (i=begin; i<end; ++i) if (tr_bitfieldHas (&bf, i)) ++count1; count2 = tr_bitfieldCountRange (&bf, begin, end); check (count1 == count2); /* cleanup */ tr_bitfieldDestruct (&bf); return 0; }
static void phaseOne (tr_ptrArray * peerArray, tr_direction dir) { int n; int peerCount = tr_ptrArraySize (peerArray); struct tr_peerIo ** peers = (struct tr_peerIo**) tr_ptrArrayBase (peerArray); /* First phase of IO. Tries to distribute bandwidth fairly to keep faster * peers from starving the others. Loop through the peers, giving each a * small chunk of bandwidth. Keep looping until we run out of bandwidth * and/or peers that can use it */ n = peerCount; dbgmsg ("%d peers to go round-robin for %s", n, (dir==TR_UP?"upload":"download")); while (n > 0) { const int i = tr_rand_int_weak (n); /* pick a peer at random */ /* value of 3000 bytes chosen so that when using uTP we'll send a full-size * frame right away and leave enough buffered data for the next frame to go * out in a timely manner. */ const size_t increment = 3000; const int bytesUsed = tr_peerIoFlush (peers[i], dir, increment); dbgmsg ("peer #%d of %d used %d bytes in this pass", i, n, bytesUsed); if (bytesUsed != (int)increment) { /* peer is done writing for now; move it to the end of the list */ tr_peerIo * pio = peers[i]; peers[i] = peers[n-1]; peers[n-1] = pio; --n; } } }
int tr_dhtInit (tr_session *ss) { tr_variant benc; int rc; bool have_id = false; char * dat_file; uint8_t * nodes = NULL, * nodes6 = NULL; const uint8_t * raw; size_t len, len6; struct bootstrap_closure * cl; if (session) /* already initialized */ return -1; tr_logAddNamedDbg ("DHT", "Initializing DHT"); if (tr_env_key_exists ("TR_DHT_VERBOSE")) dht_debug = stderr; dat_file = tr_buildPath (ss->configDir, "dht.dat", NULL); rc = tr_variantFromFile (&benc, TR_VARIANT_FMT_BENC, dat_file, NULL) ? 0 : -1; tr_free (dat_file); if (rc == 0) { have_id = tr_variantDictFindRaw (&benc, TR_KEY_id, &raw, &len); if (have_id && len==20) memcpy (myid, raw, len); if (ss->udp_socket != TR_BAD_SOCKET && tr_variantDictFindRaw (&benc, TR_KEY_nodes, &raw, &len) && ! (len%6)) { nodes = tr_memdup (raw, len); } if (ss->udp6_socket != TR_BAD_SOCKET && tr_variantDictFindRaw (&benc, TR_KEY_nodes6, &raw, &len6) && ! (len6%18)) { nodes6 = tr_memdup (raw, len6); } tr_variantFree (&benc); } if (nodes == NULL) len = 0; if (nodes6 == NULL) len6 = 0; if (have_id) tr_logAddNamedInfo ("DHT", "Reusing old id"); else { /* Note that DHT ids need to be distributed uniformly, * so it should be something truly random. */ tr_logAddNamedInfo ("DHT", "Generating new id"); tr_rand_buffer (myid, 20); } rc = dht_init (ss->udp_socket, ss->udp6_socket, myid, NULL); if (rc < 0) goto fail; session = ss; cl = tr_new (struct bootstrap_closure, 1); cl->session = session; cl->nodes = nodes; cl->nodes6 = nodes6; cl->len = len; cl->len6 = len6; tr_threadNew (dht_bootstrap, cl); dht_timer = evtimer_new (session->event_base, timer_callback, session); tr_timerAdd (dht_timer, 0, tr_rand_int_weak (1000000)); tr_logAddNamedDbg ("DHT", "DHT initialized"); return 1; fail: tr_logAddNamedDbg ("DHT", "DHT initialization failed (errno = %d)", errno); session = NULL; return -1; }