static be32_t ipv4ll_pick_address(sd_ipv4ll *ll) { be32_t addr; assert(ll); if (ll->address) { do { uint32_t r = random_u32() & 0x0000FFFF; addr = htonl(IPV4LL_NETWORK | r); } while (addr == ll->address || (ntohl(addr) & IPV4LL_NETMASK) != IPV4LL_NETWORK || (ntohl(addr) & 0x0000FF00) == 0x0000 || (ntohl(addr) & 0x0000FF00) == 0xFF00); } else { uint32_t a = 1; int i; for (i = 0; i < ETH_ALEN; i++) a += ll->mac_addr.ether_addr_octet[i]*i; a = (a % 0xFE00) + 0x0100; addr = htonl(IPV4LL_NETWORK | (uint32_t) a); } return addr; }
/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays. * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. * * return number of relays copied to tcp_relays on success. * return 0 on failure. */ uint32_t tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num) { const uint32_t r = random_u32(); uint32_t copied = 0; for (uint32_t i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) { TCP_con *tcp_con = get_tcp_connection(tcp_c, (i + r) % tcp_c->tcp_connections_length); if (!tcp_con) { continue; } if (tcp_con->status == TCP_CONN_CONNECTED) { memcpy(tcp_relays[copied].public_key, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); tcp_relays[copied].ip_port = tcp_con_ip_port(tcp_con->connection); Family *const family = &tcp_relays[copied].ip_port.ip.family; if (net_family_is_ipv4(*family)) { *family = net_family_tcp_ipv4; } else if (net_family_is_ipv6(*family)) { *family = net_family_tcp_ipv6; } ++copied; } } return copied; }
static int client_start(sd_dhcp_client *client) { int r; assert_return(client, -EINVAL); assert_return(client->event, -EINVAL); assert_return(client->index > 0, -EINVAL); assert_return(client->fd < 0, -EBUSY); assert_return(client->xid == 0, -EINVAL); assert_return(client->state == DHCP_STATE_INIT || client->state == DHCP_STATE_INIT_REBOOT, -EBUSY); client->xid = random_u32(); r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid); if (r < 0) { client_stop(client, r); return r; } client->fd = r; if (client->state == DHCP_STATE_INIT) { client->start_time = now(CLOCK_MONOTONIC); client->secs = 0; } return client_initialize_events(client, client_receive_message_raw); }
static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) { assert(client); assert(client->request_sent); assert(lifetime); return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) + + (random_u32() & 0x1fffff); }
int main (void) { sei (); uart0_init (); proto_send0 ('z'); while (42) proto_send1d ('r', random_u32 ()); }
/* Return a random TCP connection number for use in send_tcp_onion_request. * * TODO(irungentoo): This number is just the index of an array that the elements * can change without warning. * * return TCP connection number on success. * return -1 on failure. */ int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c) { const uint32_t r = random_u32(); for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) { uint32_t index = ((i + r) % tcp_c->tcp_connections_length); if (tcp_c->tcp_connections[index].onion && tcp_c->tcp_connections[index].status == TCP_CONN_CONNECTED) { return index; } } return -1; }
void dhcp6_pd_send_client_message (vlib_main_t * vm, u32 sw_if_index, u8 stop, dhcp6_pd_send_client_message_params_t * params) { dhcp6_pd_client_main_t *cm = &dhcp6_pd_client_main; dhcp6_pd_client_state_t *client_state = 0; dhcp6_pd_client_state_t empty_state = { 0, }; ASSERT (~0 != sw_if_index); vec_validate_init_empty (cm->client_state_by_sw_if_index, sw_if_index, empty_state); client_state = &cm->client_state_by_sw_if_index[sw_if_index]; if (!client_state->entry_valid) { client_state->entry_valid = 1; client_state->adj_index = ~0; } stop_sending_client_message (vm, client_state); if (!stop) { client_state->keep_sending_client_message = 1; vec_free (client_state->params.prefixes); client_state->params = *params; client_state->params.prefixes = vec_dup (params->prefixes); client_state->n_left = params->mrc; client_state->start_time = vlib_time_now (vm); client_state->sleep_interval = (1 + random_f64_from_to (-0.1, 0.1)) * params->irt; client_state->due_time = 0; /* send first packet ASAP */ client_state->transaction_id = random_u32 (&cm->seed) & 0x00ffffff; client_state->buffer = create_buffer_for_client_message (vm, sw_if_index, client_state, params->msg_type); if (!client_state->buffer) client_state->keep_sending_client_message = 0; else vlib_process_signal_event (vm, send_dhcp6_pd_client_message_process_node.index, 1, 0); } }
static void ipv4ll_set_next_wakeup(sd_ipv4ll *ll, int sec, int random_sec) { usec_t next_timeout = 0; usec_t time_now = 0; assert(sec >= 0); assert(random_sec >= 0); assert(ll); next_timeout = sec * USEC_PER_SEC; if (random_sec) next_timeout += random_u32() % (random_sec * USEC_PER_SEC); assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) >= 0); ll->next_wakeup = time_now + next_timeout; ll->next_wakeup_valid = 1; }
/** * proto_new - create a new protocol instance * @c: protocol configuration * @size: size of protocol data structure (each protocol instance is represented by * a structure starting with generic part [struct &proto] and continued * with data specific to the protocol) * * When a new configuration has been read in, the core code starts * initializing all the protocol instances configured by calling their * init() hooks with the corresponding instance configuration. The initialization * code of the protocol is expected to create a new instance according to the * configuration by calling this function and then modifying the default settings * to values wanted by the protocol. */ void * proto_new(struct proto_config *c, unsigned size) { struct protocol *pr = c->protocol; struct proto *p = mb_allocz(proto_pool, size); p->cf = c; p->debug = c->debug; p->mrtdump = c->mrtdump; p->name = c->name; p->preference = c->preference; p->disabled = c->disabled; p->proto = pr; p->table = c->table->table; p->hash_key = random_u32(); c->proto = p; return p; }
static void ipv4ll_set_next_wakeup (sd_ipv4ll *ll, int sec, int random_sec) { usec_t next_timeout = 0; usec_t time_now = 0; assert(sec >= 0); assert(random_sec >= 0); assert(ll); next_timeout = sec * USEC_PER_SEC; if (random_sec) next_timeout += random_u32() % (random_sec * USEC_PER_SEC); if (sd_event_get_now_monotonic(ll->event, &time_now) < 0) time_now = now(CLOCK_MONOTONIC); ll->next_wakeup = time_now + next_timeout; ll->next_wakeup_valid = 1; }
static int shuffle_array(void **array, int len) { int n = len; unsigned int k; void *tmp; while(n > 1) { n--; if(random_u32(&k) != 0) return -1; k %= n+1; tmp = array[k]; array[k] = array[n]; array[n] = tmp; } return 0; }
static int ipv4acd_set_next_wakeup(sd_ipv4acd *ll, int sec, int random_sec) { _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL; usec_t next_timeout; usec_t time_now; int r; assert(sec >= 0); assert(random_sec >= 0); assert(ll); next_timeout = sec * USEC_PER_SEC; if (random_sec) next_timeout += random_u32() % (random_sec * USEC_PER_SEC); assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) >= 0); r = sd_event_add_time(ll->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, ll); if (r < 0) return r; r = sd_event_source_set_priority(timer, ll->event_priority); if (r < 0) return r; r = sd_event_source_set_description(timer, "ipv4acd-timer"); if (r < 0) return r; ll->timer = sd_event_source_unref(ll->timer); ll->timer = timer; timer = NULL; return 0; }
int main (int argc, char * argv[]) { word i, j, k, n, check_mask; u32 seed; u32 * h = 0; uword * objects = 0; uword * handles = 0; uword objects_used; uword align, fixed_size; n = 10; seed = (u32) getpid (); check_mask = 0; fixed_size = 0; if (argc > 1) { n = atoi (argv[1]); verbose = 1; } if (argc > 2) { word i = atoi (argv[2]); if (i) seed = i; } if (argc > 3) check_mask = atoi (argv[3]); align = 0; if (argc > 4) align = 1 << atoi (argv[4]); if_verbose ("testing %wd iterations seed %wd\n", n, seed); if (verbose) fformat (stderr, "%U\n", format_clib_mem_usage, /* verbose */ 0); vec_resize (objects, 1000); if (vec_bytes(objects)) /* stupid warning be gone */ memset (objects, ~0, vec_bytes (objects)); vec_resize (handles, vec_len (objects)); objects_used = 0; if (fixed_size) { uword max_len = 1024 * 1024; void * memory = clib_mem_alloc (max_len * sizeof (h[0])); h = heap_create_from_memory (memory, max_len, sizeof (h[0])); } for (i = 0; i < n; i++) { while (1) { j = random_u32 (&seed) % vec_len (objects); if (objects[j] != ~0 || i + objects_used < n) break; } if (objects[j] != ~0) { heap_dealloc (h, handles[j]); objects_used--; objects[j] = ~0; } else { u32 * data; uword size; size = 1 + (random_u32 (&seed) % 100); objects[j] = heap_alloc_aligned (h, size, align, handles[j]); objects_used++; if (align) ASSERT (0 == (objects[j] & (align - 1))); ASSERT (objects[j] < vec_len (h)); ASSERT (size <= heap_len (h, handles[j])); /* Set newly allocated object with test data. */ if (check_mask & 2) { data = h + objects[j]; for (k = 0; k < size; k++) data[k] = objects[j] + k; } } if (check_mask & 1) heap_validate (h); if (check_mask & 4) { /* Duplicate heap at each iteration. */ u32 * h1 = heap_dup (h); heap_free (h); h = h1; } /* Verify that all used objects have correct test data. */ if (check_mask & 2) { for (j = 0; j < vec_len (objects); j++) if (objects[j] != ~0) { u32 * data = h + objects[j]; for (k = 0; k < heap_len (h, handles[j]); k++) ASSERT(data[k] == objects[j] + k); } } } if (verbose) fformat (stderr, "%U\n", format_heap, h, 1); { u32 * h1 = heap_dup (h); if (verbose) fformat (stderr, "%U\n", format_heap, h1, 1); heap_free (h1); } heap_free (h); if (verbose) fformat (stderr, "%U\n", format_heap, h, 1); ASSERT (objects_used == 0); vec_free (objects); vec_free (handles); if (fixed_size) vec_free_h (h, sizeof (heap_header_t)); if (verbose) fformat (stderr, "%U\n", format_clib_mem_usage, /* verbose */ 0); return 0; }
END_TEST START_TEST(test_endtoend) { unsigned char pk1[CRYPTO_PUBLIC_KEY_SIZE]; unsigned char sk1[CRYPTO_SECRET_KEY_SIZE]; unsigned char pk2[CRYPTO_PUBLIC_KEY_SIZE]; unsigned char sk2[CRYPTO_SECRET_KEY_SIZE]; unsigned char k1[CRYPTO_SHARED_KEY_SIZE]; unsigned char k2[CRYPTO_SHARED_KEY_SIZE]; unsigned char n[CRYPTO_NONCE_SIZE]; unsigned char m[500]; unsigned char c1[sizeof(m) + CRYPTO_MAC_SIZE]; unsigned char c2[sizeof(m) + CRYPTO_MAC_SIZE]; unsigned char c3[sizeof(m) + CRYPTO_MAC_SIZE]; unsigned char c4[sizeof(m) + CRYPTO_MAC_SIZE]; unsigned char m1[sizeof(m)]; unsigned char m2[sizeof(m)]; unsigned char m3[sizeof(m)]; unsigned char m4[sizeof(m)]; int mlen; int c1len, c2len, c3len, c4len; int m1len, m2len, m3len, m4len; int testno; // Test 100 random messages and keypairs for (testno = 0; testno < 100; testno++) { //Generate random message (random length from 100 to 500) mlen = (random_u32() % 400) + 100; rand_bytes(m, mlen); rand_bytes(n, CRYPTO_NONCE_SIZE); //Generate keypairs crypto_new_keypair(pk1, sk1); crypto_new_keypair(pk2, sk2); //Precompute shared keys encrypt_precompute(pk2, sk1, k1); encrypt_precompute(pk1, sk2, k2); ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); //Encrypt all four ways c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); ck_assert_msg(c1len == mlen + (int)CRYPTO_MAC_SIZE, "wrong cyphertext length"); ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); //Decrypt all four ways m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); ck_assert_msg(m1len == mlen, "wrong decrypted text length"); ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); } }
int test_random_main (unformat_input_t * input) { uword n_iterations; uword i, repeat_count; uword * bitmap = 0; uword print; u32 seed; u32 *seedp = &seed; /* first, check known sequence from Numerical Recipes in C, 2nd ed. page 284 */ seed = known_random_sequence[0]; for (i = 0; i < ARRAY_LEN(known_random_sequence)-1; i++) { u32 rv; rv = random_u32 (seedp); if (rv != known_random_sequence[i+1]) { fformat(stderr, "known sequence check FAILS at index %d", i+1); break; } } clib_warning ("known sequence check passes"); n_iterations = 1000; seed = 0; print = 1 << 24; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (0 == unformat (input, "iter %d", &n_iterations) && 0 == unformat (input, "print %d", &print) && 0 == unformat (input, "seed %d", &seed)) clib_error ("unknown input `%U'", format_unformat_error, input); } if (! seed) seed = random_default_seed (); if (n_iterations == 0) n_iterations = random_u32_max (); clib_warning ("%d iterations, seed %d\n", n_iterations, seed); repeat_count = 0; for (i = 0; i < n_iterations; i++) { uword r = random_u32 (&seed); uword b, ri, rj; ri = r / BITS (bitmap[0]); rj = (uword) 1 << (r % BITS (bitmap[0])); vec_validate (bitmap, ri); b = bitmap[ri]; if (b & rj) goto repeat; b |= rj; bitmap[ri] = b; if (0 == (i & (print - 1))) fformat (stderr, "0x%08x iterations %d repeats\n", i, repeat_count); continue; repeat: fformat (stderr, "repeat found at iteration %d/%d\n", i, n_iterations); repeat_count++; continue; } return 0; }
/** * Determine unique filename for `file' in `path', with optional trailing * extension `ext'. If no `ext' is wanted, one must supply an empty string. * * @param path A directory path. * @param file The basename for the resulting pathname. * @param ext An optional filename extension to be appended to the basename. * @param name_is_uniq An optional callback to decide whether a created * pathname is uniq. If omitted, the default is file_does_not_exist(). * * @returns the chosen unique complete filename as a pointer which must be * freed via hfree(). */ char * filename_unique(const char *path, const char *name, const char *ext, bool (*name_is_uniq)(const char *pathname)) { char filename_buf[FILENAME_MAXBYTES]; char name_buf[FILENAME_MAXBYTES]; char mid_buf[32]; char ext_buf[32]; const char *mid; char *pathname; size_t name_len, mid_len, ext_len; int i; g_assert(path); g_assert(name); g_assert(ext); g_assert(is_absolute_path(path)); STATIC_ASSERT(sizeof filename_buf > sizeof mid_buf + sizeof ext_buf + GUID_HEX_SIZE); /** * NOTE: The generated filename must not exceed FILENAME_MAXBYTES * because such a file cannot be created. In reality, it depends * on the filesystem as well and the limit might be even smaller. * In any case, we don't want to cut-off arbitrary bytes but * at least preserve the filename extension and the (potential) * UTF-8 encoding. */ /* Because "ext" can be an additional extension like .BAD rather than * one that indicates the filetype, try to preserve the next "extension" * as well, if there's any. */ mid = strrchr(name, '.'); if (NULL == mid || mid == name || strlen(mid) >= sizeof mid_buf) { mid = strchr(name, '\0'); } ext_len = strlen(ext); mid_len = strlen(mid); name_len = strlen(name) - mid_len; ext_len = MIN(ext_len, sizeof ext_buf - 1); mid_len = MIN(mid_len, sizeof mid_buf - 1); name_len = MIN(name_len, sizeof name_buf - 1); if (name_len + mid_len + ext_len >= sizeof filename_buf) { g_assert(name_len >= ext_len); name_len -= ext_len; } /* Truncate strings so that an UTF-8 encoding is preserved */ ext_len = utf8_truncate(ext, ext_buf, ext_len + 1); mid_len = utf8_truncate(mid, mid_buf, mid_len + 1); name_len = utf8_truncate(name, name_buf, name_len + 1); str_bprintf(filename_buf, sizeof filename_buf, "%s%s%s", name_buf, mid_buf, ext_buf); pathname = unique_pathname(path, filename_buf, name_is_uniq); if (pathname) goto finish; if (!is_directory(path)) return NULL; /* * Looks like we need to make the filename more unique. Append .00, then * .01, etc... until .99. */ while (name_len + mid_len + ext_len + 3 >= sizeof filename_buf) { g_assert(name_len > 0); name_len--; } name_len = utf8_truncate(name, name_buf, name_len + 1); for (i = 0; i < 100; i++) { str_bprintf(filename_buf, sizeof filename_buf, "%s.%02u%s%s", name_buf, i, mid_buf, ext_buf); pathname = unique_pathname(path, filename_buf, name_is_uniq); if (pathname) goto finish; } /* * OK, no luck. Try with a few random numbers then. */ while (name_len + mid_len + ext_len + 9 >= sizeof filename_buf) { g_assert(name_len > 0); name_len--; } name_len = utf8_truncate(name, name_buf, name_len + 1); for (i = 0; i < 100; i++) { str_bprintf(filename_buf, sizeof filename_buf, "%s.%x%s%s", name_buf, (unsigned) random_u32(), mid_buf, ext_buf); pathname = unique_pathname(path, filename_buf, name_is_uniq); if (pathname) goto finish; } /* * Bad luck. Allocate a random GUID then. */ while ( name_len + mid_len + ext_len + GUID_HEX_SIZE + 1 >= sizeof filename_buf ) { g_assert(name_len > 0); name_len--; } name_len = utf8_truncate(name, name_buf, name_len + 1); { struct guid guid; guid_random_fill(&guid); str_bprintf(filename_buf, sizeof filename_buf, "%s.%s%s%s", name_buf, guid_hex_str(&guid), mid_buf, ext_buf); } pathname = unique_pathname(path, filename_buf, name_is_uniq); if (pathname) goto finish; /* * This may also be the result of permission problems or inode * exhaustion. */ g_warning("%s(): no luck with random number generator", G_STRFUNC); finish: return pathname; }
END_TEST #define NUM_TCP_RELAYS 3 START_TEST(test_many_clients_tcp_b) { long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; uint32_t index[NUM_TOXES_TCP]; uint32_t i, j; uint32_t to_comp = 974536; for (i = 0; i < NUM_TOXES_TCP; ++i) { struct Tox_Options *opts = tox_options_new(nullptr); if (i < NUM_TCP_RELAYS) { tox_options_set_tcp_port(opts, TCP_RELAY_PORT + i); } else { tox_options_set_udp_enabled(opts, 0); } index[i] = i + 1; toxes[i] = tox_new_log(opts, nullptr, &index[i]); ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); tox_callback_friend_request(toxes[i], accept_friend_request); uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk); ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, TCP_RELAY_PORT + (i % NUM_TCP_RELAYS), dpk, nullptr), "add relay error"); tox_self_get_dht_id(toxes[0], dpk); uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr); ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, first_port, dpk, nullptr), "Bootstrap error"); tox_options_free(opts); } struct { uint16_t tox1; uint16_t tox2; } pairs[NUM_FRIENDS]; uint8_t address[TOX_ADDRESS_SIZE]; for (i = 0; i < NUM_FRIENDS; ++i) { loop_top: pairs[i].tox1 = random_u32() % NUM_TOXES_TCP; pairs[i].tox2 = (pairs[i].tox1 + random_u32() % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP; for (j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { goto loop_top; } } tox_self_get_address(toxes[pairs[i].tox1], address); TOX_ERR_FRIEND_ADD test; uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test); if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) { goto loop_top; } ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test); } uint16_t last_count = 0; while (1) { uint16_t counter = 0; for (i = 0; i < NUM_TOXES_TCP; ++i) { for (j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) { if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) { ++counter; } } } if (counter != last_count) { printf("many_clients_tcp_b got to %u\n", counter); last_count = counter; } if (counter == NUM_FRIENDS * 2) { break; } for (i = 0; i < NUM_TOXES_TCP; ++i) { tox_iterate(toxes[i], &to_comp); } c_sleep(30); } for (i = 0; i < NUM_TOXES_TCP; ++i) { tox_kill(toxes[i]); } printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time); }
static inline u32 dispatch_t216(t216 a217, unit_t a218) { return random_u32(a218); }
int test_mheap_main (unformat_input_t * input) { int i, j, k, n_iterations; void *h, *h_mem; uword *objects = 0; u32 objects_used, really_verbose, n_objects, max_object_size; u32 check_mask, seed, trace, use_vm; u32 print_every = 0; u32 *data; mheap_t *mh; /* Validation flags. */ check_mask = 0; #define CHECK_VALIDITY 1 #define CHECK_DATA 2 #define CHECK_ALIGN 4 #define TEST1 8 n_iterations = 10; seed = 0; max_object_size = 100; n_objects = 1000; trace = 0; really_verbose = 0; use_vm = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (0 == unformat (input, "iter %d", &n_iterations) && 0 == unformat (input, "count %d", &n_objects) && 0 == unformat (input, "size %d", &max_object_size) && 0 == unformat (input, "seed %d", &seed) && 0 == unformat (input, "print %d", &print_every) && 0 == unformat (input, "validdata %|", &check_mask, CHECK_DATA | CHECK_VALIDITY) && 0 == unformat (input, "valid %|", &check_mask, CHECK_VALIDITY) && 0 == unformat (input, "verbose %=", &really_verbose, 1) && 0 == unformat (input, "trace %=", &trace, 1) && 0 == unformat (input, "vm %=", &use_vm, 1) && 0 == unformat (input, "align %|", &check_mask, CHECK_ALIGN) && 0 == unformat (input, "test1 %|", &check_mask, TEST1)) { clib_warning ("unknown input `%U'", format_unformat_error, input); return 1; } } /* Zero seed means use default. */ if (!seed) seed = random_default_seed (); if (check_mask & TEST1) { return test1 (); } if_verbose ("testing %d iterations, %d %saligned objects, max. size %d, seed %d", n_iterations, n_objects, (check_mask & CHECK_ALIGN) ? "randomly " : "un", max_object_size, seed); vec_resize (objects, n_objects); if (vec_bytes (objects) > 0) /* stupid warning be gone */ clib_memset (objects, ~0, vec_bytes (objects)); objects_used = 0; /* Allocate initial heap. */ { uword size = max_pow2 (2 * n_objects * max_object_size * sizeof (data[0])); h_mem = clib_mem_alloc (size); if (!h_mem) return 0; h = mheap_alloc (h_mem, size); } if (trace) mheap_trace (h, trace); mh = mheap_header (h); if (use_vm) mh->flags &= ~MHEAP_FLAG_DISABLE_VM; else mh->flags |= MHEAP_FLAG_DISABLE_VM; if (check_mask & CHECK_VALIDITY) mh->flags |= MHEAP_FLAG_VALIDATE; for (i = 0; i < n_iterations; i++) { while (1) { j = random_u32 (&seed) % vec_len (objects); if (objects[j] != ~0 || i + objects_used < n_iterations) break; } if (objects[j] != ~0) { mheap_put (h, objects[j]); objects_used--; objects[j] = ~0; } else { uword size, align, align_offset; size = (random_u32 (&seed) % max_object_size) * sizeof (data[0]); align = align_offset = 0; if (check_mask & CHECK_ALIGN) { align = 1 << (random_u32 (&seed) % 10); align_offset = round_pow2 (random_u32 (&seed) & (align - 1), sizeof (u32)); } h = mheap_get_aligned (h, size, align, align_offset, &objects[j]); if (align > 0) ASSERT (0 == ((objects[j] + align_offset) & (align - 1))); ASSERT (objects[j] != ~0); objects_used++; /* Set newly allocated object with test data. */ if (check_mask & CHECK_DATA) { uword len; data = (void *) h + objects[j]; len = mheap_len (h, data); ASSERT (size <= mheap_data_bytes (h, objects[j])); data[0] = len; for (k = 1; k < len; k++) data[k] = objects[j] + k; } } /* Verify that all used objects have correct test data. */ if (check_mask & 2) { for (j = 0; j < vec_len (objects); j++) if (objects[j] != ~0) { u32 *data = h + objects[j]; uword len = data[0]; for (k = 1; k < len; k++) ASSERT (data[k] == objects[j] + k); } } if (print_every != 0 && i > 0 && (i % print_every) == 0) fformat (stderr, "iteration %d: %U\n", i, format_mheap, h, really_verbose); } if (verbose) fformat (stderr, "%U\n", format_mheap, h, really_verbose); mheap_free (h); clib_mem_free (h_mem); vec_free (objects); return 0; }
/** * Do an actual search. * * @param table table containing organized entries to search from * @param search_term the query string * @param callback routine to invoke for each match * @param ctx user-supplied data to pass on to callback * @param max_res maximum amount of results to return * @param qhv query hash vector built from query string, for routing * * @return number of hits we produced */ G_GNUC_HOT int st_search( search_table_t *table, const char *search_term, st_search_callback callback, gpointer ctx, int max_res, query_hashvec_t *qhv) { char *search; int key, nres = 0; guint i, len; struct st_bin *best_bin = NULL; int best_bin_size = INT_MAX; word_vec_t *wovec; guint wocnt; cpattern_t **pattern; struct st_entry **vals; guint vcnt; int scanned = 0; /* measure search mask efficiency */ guint32 search_mask; size_t minlen; guint random_offset; /* Randomizer for search returns */ search = UNICODE_CANONIZE(search_term); if (GNET_PROPERTY(query_debug) > 4 && 0 != strcmp(search, search_term)) { char *safe_search = hex_escape(search, FALSE); char *safe_search_term = hex_escape(search_term, FALSE); g_debug("original search term: \"%s\"", safe_search_term); g_debug("canonical search term: \"%s\"", safe_search); if (safe_search != search) HFREE_NULL(safe_search); if (safe_search_term != search_term) HFREE_NULL(safe_search_term); } len = strlen(search); /* * Find smallest bin */ if (len >= 2) { for (i = 0; i < len - 1; i++) { struct st_bin *bin; if (is_ascii_space(search[i]) || is_ascii_space(search[i+1])) continue; key = st_key(table, search + i); if ((bin = table->bins[key]) == NULL) { best_bin = NULL; break; } if (bin->nvals < best_bin_size) { best_bin = bin; best_bin_size = bin->nvals; } } if (GNET_PROPERTY(matching_debug) > 4) g_debug("MATCH st_search(): str=\"%s\", len=%d, best_bin_size=%d", lazy_safe_search(search_term), len, best_bin_size); } /* * If the best_bin is NULL, we did not find a matching bin, and we're * sure we won't be able to find the search string. * * Note that on search strings like "r e m ", we always have a letter * followed by spaces, so we won't search that. * --RAM, 06/10/2001 */ if (best_bin == NULL) { /* * If we have a `qhv', we need to compute the word vector anway, * for query routing... */ if (qhv == NULL) goto finish; } /* * Prepare matching patterns */ wocnt = word_vec_make(search, &wovec); /* * Compute the query hashing information for query routing, if needed. */ if (qhv != NULL) { for (i = 0; i < wocnt; i++) { if (wovec[i].len >= QRP_MIN_WORD_LENGTH) qhvec_add(qhv, wovec[i].word, QUERY_H_WORD); } } if (wocnt == 0 || best_bin == NULL) { if (wocnt > 0) word_vec_free(wovec, wocnt); goto finish; } g_assert(best_bin_size > 0); /* Allocated bin, it must hold something */ pattern = walloc0(wocnt * sizeof *pattern); /* * Prepare matching optimization, an idea from Mike Green. * * At library building time, we computed a mask hash, made from the * lowercased file name, using one bit per different letter, roughly * (see mask_hash() for the exact algorigthm). * * We're now going to compute the same mask on the query, and compare * it bitwise with the mask for each file. If the file does not hold * at least all the chars present in the query, it's no use applying * the pattern matching algorithm, it won't match at all. * * --RAM, 01/10/2001 */ search_mask = mask_hash(search); /* * Prepare second matching optimization: since all words in the query * must match the exact amount of time, we can compute the minimum length * the searched file must have. We add one character after each word * but the last, to account for space between words. * --RAM, 11/07/2002 */ for (minlen = 0, i = 0; i < wocnt; i++) minlen += wovec[i].len + 1; minlen--; g_assert(minlen <= INT_MAX); /* * Search through the smallest bin */ vcnt = best_bin->nvals; vals = best_bin->vals; random_offset = random_u32() % vcnt; nres = 0; for (i = 0; i < vcnt; i++) { const struct st_entry *e; shared_file_t *sf; size_t canonic_len; /* * As we only return a limited count of results, pick a random * offset, so that repeated searches will match different items * instead of always the first - with some probability. */ e = vals[(i + random_offset) % vcnt]; if ((e->mask & search_mask) != search_mask) continue; /* Can't match */ sf = e->sf; canonic_len = shared_file_name_canonic_len(sf); if (canonic_len < minlen) continue; /* Can't match */ scanned++; if (entry_match(e->string, canonic_len, pattern, wovec, wocnt)) { if (GNET_PROPERTY(matching_debug) > 4) { g_debug("MATCH \"%s\" matches %s", search, shared_file_name_nfc(sf)); } if ((*callback)(ctx, sf)) { nres++; if (nres >= max_res) break; } } } if (GNET_PROPERTY(matching_debug) > 3) g_debug("MATCH st_search(): scanned %d entr%s from the %d in bin, " "got %d match%s", scanned, 1 == scanned ? "y" : "ies", best_bin_size, nres, 1 == nres ? "" : "es"); for (i = 0; i < wocnt; i++) if (pattern[i]) /* Lazily compiled by entry_match() */ pattern_free(pattern[i]); wfree(pattern, wocnt * sizeof *pattern); word_vec_free(wovec, wocnt); finish: if (search != search_term) { HFREE_NULL(search); } return nres; }
static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp_client *client = userdata; usec_t next_timeout = 0; uint64_t time_now; uint32_t time_left; int r; assert(s); assert(client); assert(client->event); r = sd_event_now(client->event, CLOCK_MONOTONIC, &time_now); if (r < 0) goto error; switch (client->state) { case DHCP_STATE_RENEWING: time_left = (client->lease->t2 - client->lease->t1) / 2; if (time_left < 60) time_left = 60; next_timeout = time_now + time_left * USEC_PER_SEC; break; case DHCP_STATE_REBINDING: time_left = (client->lease->lifetime - client->lease->t2) / 2; if (time_left < 60) time_left = 60; next_timeout = time_now + time_left * USEC_PER_SEC; break; case DHCP_STATE_REBOOTING: /* start over as we did not receive a timely ack or nak */ r = client_initialize(client); if (r < 0) goto error; r = client_start(client); if (r < 0) goto error; else { log_dhcp_client(client, "REBOOTED"); return 0; } case DHCP_STATE_INIT: case DHCP_STATE_INIT_REBOOT: case DHCP_STATE_SELECTING: case DHCP_STATE_REQUESTING: case DHCP_STATE_BOUND: if (client->attempt < 64) client->attempt *= 2; next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC; break; case DHCP_STATE_STOPPED: r = -EINVAL; goto error; } next_timeout += (random_u32() & 0x1fffff); client->timeout_resend = sd_event_source_unref(client->timeout_resend); r = sd_event_add_time(client->event, &client->timeout_resend, CLOCK_MONOTONIC, next_timeout, 10 * USEC_PER_MSEC, client_timeout_resend, client); if (r < 0) goto error; r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); if (r < 0) goto error; switch (client->state) { case DHCP_STATE_INIT: r = client_send_discover(client); if (r >= 0) { client->state = DHCP_STATE_SELECTING; client->attempt = 1; } else { if (client->attempt >= 64) goto error; } break; case DHCP_STATE_SELECTING: r = client_send_discover(client); if (r < 0 && client->attempt >= 64) goto error; break; case DHCP_STATE_INIT_REBOOT: case DHCP_STATE_REQUESTING: case DHCP_STATE_RENEWING: case DHCP_STATE_REBINDING: r = client_send_request(client); if (r < 0 && client->attempt >= 64) goto error; if (client->state == DHCP_STATE_INIT_REBOOT) client->state = DHCP_STATE_REBOOTING; client->request_sent = time_now; break; case DHCP_STATE_REBOOTING: case DHCP_STATE_BOUND: break; case DHCP_STATE_STOPPED: r = -EINVAL; goto error; } return 0; error: client_stop(client, r); /* Errors were dealt with when stopping the client, don't spill errors into the event loop handler */ return 0; }
static int get_insert_run_id( struct rldb_plugin_cnts *cdata, time_t t, int uid, int nsec) { struct rldb_file_cnts *cs = (struct rldb_file_cnts*) cdata; struct runlog_state *rls = cs->rl_state; int i, j; struct run_entry *runs = 0; ASSERT(rls->run_u <= rls->run_a); if (rls->run_u == rls->run_a) { int new_a = rls->run_a * 2; struct run_entry *new_r = 0; if (!new_a) new_a = 128; XCALLOC(new_r, new_a); for (i = 0; i < new_a; ++i) new_r[i].status = RUN_EMPTY; if (rls->run_u > 0) memcpy(new_r, rls->runs, rls->run_u * sizeof(rls->runs[0])); xfree(rls->runs); rls->runs = new_r; rls->run_a = new_a; } runs = rls->runs; /* * RUN_EMPTY compilicates things! :( */ if (!rls->run_u) return append_to_end(rls, t, nsec); j = rls->run_u - 1; while (j >= 0 && runs[j].status == RUN_EMPTY) j--; if (j < 0) return append_to_end(rls, t, nsec); if (t > runs[j].time) return append_to_end(rls, t, nsec); if (t == runs[j].time) { if (nsec < 0 && runs[j].nsec < NSEC_MAX) { nsec = runs[j].nsec + 1; return append_to_end(rls, t, nsec); } if (nsec > runs[j].nsec) return append_to_end(rls, t, nsec); if (nsec == runs[j].nsec && uid >= runs[j].user_id) return append_to_end(rls, t, nsec); } if (nsec < 0) { for (i = 0; i < rls->run_u; i++) { if (runs[i].status == RUN_EMPTY) continue; if (runs[i].time > t) break; if (runs[i].time < t) continue; // runs[i].time == t while (runs[i].status == RUN_EMPTY || runs[i].time == t) i++; j = i - 1; while (runs[j].status == RUN_EMPTY) j--; if (runs[j].nsec < NSEC_MAX) { nsec = runs[j].nsec + 1; break; } // DUMB :( nsec = random_u32() % (NSEC_MAX + 1); goto try_with_nsec; } ASSERT(i < rls->run_u); } else { try_with_nsec: for (i = 0; i < rls->run_u; i++) { if (runs[i].status == RUN_EMPTY) continue; if (runs[i].time > t) break; if (runs[i].time < t) continue; if (runs[i].nsec > nsec) break; if (runs[i].nsec < nsec) continue; if (runs[i].user_id > uid) break; } } /* So we going to insert a run at position i. * Check, that there is no "transient"-statused runs after this position. * This is very unlikely, because such runs appears when the run * is being compiled or run, and in this case its precise (nanosecond) * timestamp should be less, than the current run. However, if such * sutuation is detected, we fail because we cannot safely change * the run_id's when it is possible to receive compile or run response * packets. */ for (j = i; j < rls->run_u; j++) if (runs[j].status >= RUN_TRANSIENT_FIRST && runs[j].status <= RUN_TRANSIENT_LAST) break; if (j < rls->run_u) { err("append_record: cannot safely insert a run at position %d", i); err("append_record: the run %d is transient!", j); return -1; } memmove(&runs[i + 1], &runs[i], (rls->run_u - i) * sizeof(runs[0])); rls->run_u++; for (j = i + 1; j < rls->run_u; j++) runs[j].run_id = j; if (nsec < 0) nsec = 0; memset(&runs[i], 0, sizeof(runs[0])); runs[i].run_id = i; runs[i].status = RUN_EMPTY; runs[i].time = t; runs[i].nsec = nsec; if (sf_lseek(cs->run_fd, sizeof(rls->head) + i * sizeof(runs[0]), SEEK_SET, "run") == (off_t) -1) return -1; if (do_write(cs->run_fd, &runs[i], (rls->run_u - i) * sizeof(runs[0])) < 0) return -1; return i; }
inline u64 random_u64() { return u64(random_u32()) ^ (u64(random_u32()) << 30); }
inline s32 random_i32() { return s32(random_u32()); }
void proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) { uint8_t ap, bp, as, bs; uint16_t i; int32_t al, bl, rl[4]; uint32_t patl[] = { 0xa66a6aa6, 0x5a5affff, 0xffcdffcd, 0xffffffff }; #define patn (sizeof (patl) / sizeof (patl[0])) #define c(cmd, size) (cmd << 8 | size) switch (c (cmd, size)) { case c ('z', 0): utils_reset (); break; case c ('m', 0): for (ap = 0; ap < patn; ap++) for (bp = 0; bp < patn; bp++) for (as = 0; as < 32; as++) for (bs = 0; bs < 32; bs++) { al = patl[ap] >> as; bl = patl[bp] >> bs; proto_send2d ('a', al, bl); rl[0] = fixed_mul_f824 (al, bl); check_mul (al, bl, rl[0]); rl[1] = fixed_mul_f824 (-al, bl); check_mul (-al, bl, rl[1]); rl[2] = fixed_mul_f824 (al, -bl); check_mul (al, -bl, rl[2]); rl[3] = fixed_mul_f824 (-al, -bl); check_mul (-al, -bl, rl[3]); proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]); } for (i = 0; i < 64000; i++) { al = random_u32 (); bl = random_u32 (); proto_send2d ('a', al, bl); rl[0] = fixed_mul_f824 (al, bl); check_mul (al, bl, rl[0]); rl[1] = fixed_mul_f824 (-al, bl); check_mul (-al, bl, rl[1]); rl[2] = fixed_mul_f824 (al, -bl); check_mul (al, -bl, rl[2]); rl[3] = fixed_mul_f824 (-al, -bl); check_mul (-al, -bl, rl[3]); proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]); } break; case c ('d', 0): for (ap = 0; ap < patn; ap++) for (bp = 0; bp < patn; bp++) for (as = 0; as < 32; as++) for (bs = 0; bs < 31; bs++) { al = patl[ap] >> as; bl = patl[bp] >> bs; proto_send2d ('a', al, bl); rl[0] = fixed_div_f824 (al, bl); check_div (al, bl, rl[0]); rl[1] = fixed_div_f824 (-al, bl); check_div (-al, bl, rl[1]); rl[2] = fixed_div_f824 (al, -bl); check_div (al, -bl, rl[2]); rl[3] = fixed_div_f824 (-al, -bl); check_div (-al, -bl, rl[3]); proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]); } for (i = 0; i < 64000; i++) { al = random_u32 (); bl = random_u32 (); if (bl != 0) { proto_send2d ('a', al, bl); rl[0] = fixed_div_f824 (al, bl); check_div (al, bl, rl[0]); rl[1] = fixed_div_f824 (-al, bl); check_div (-al, bl, rl[1]); rl[2] = fixed_div_f824 (al, -bl); check_div (al, -bl, rl[2]); rl[3] = fixed_div_f824 (-al, -bl); check_div (-al, -bl, rl[3]); proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]); } } break; case c ('c', 0): for (al = 0; al < (1L << 24); al += 257) { proto_send1d ('a', al); rl[0] = fixed_cos_f824 (al); rl[1] = fixed_sin_f824 (al); check_cos (al, rl[0], rl[1]); proto_send2d ('r', rl[0], rl[1]); } for (i = 0; i < 64000; i++) { al = random_u32 () & 0xffffff; proto_send1d ('a', al); rl[0] = fixed_cos_f824 (al); rl[1] = fixed_sin_f824 (al); check_cos (al, rl[0], rl[1]); proto_send2d ('r', rl[0], rl[1]); } break; case c ('s', 0): for (ap = 0; ap < patn; ap++) for (as = 0; as < 32; as++) { al = patl[ap] >> as; proto_send1d ('a', al); rl[0] = fixed_sqrt_uf248 (al); rl[1] = fixed_sqrt_ui32 (al); check_sqrt (al, rl[0], rl[1]); proto_send2d ('r', rl[0], rl[1]); } for (i = 0; i < 64000; i++) { al = random_u32 (); proto_send1d ('a', al); rl[0] = fixed_sqrt_uf248 (al); rl[1] = fixed_sqrt_ui32 (al); check_sqrt (al, rl[0], rl[1]); proto_send2d ('r', rl[0], rl[1]); } break; default: proto_send0 ('?'); return; } /* When no error acknoledge. */ proto_send (cmd, size, args); #undef c }
uint64_t random_u64(struct random_src *rnd) { uint64_t val = random_u32(rnd); val <<= 32; return val | random_u32(rnd); }
int test_elog_main (unformat_input_t * input) { clib_error_t * error = 0; u32 i, n_iter, seed, max_events; elog_main_t _em, * em = &_em; u32 verbose; f64 min_sample_time; char * dump_file, * load_file, * merge_file, ** merge_files; u8 * tag, ** tags; n_iter = 100; max_events = 100000; seed = 1; verbose = 0; dump_file = 0; load_file = 0; merge_files = 0; tags = 0; min_sample_time = 2; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "iter %d", &n_iter)) ; else if (unformat (input, "seed %d", &seed)) ; else if (unformat (input, "dump %s", &dump_file)) ; else if (unformat (input, "load %s", &load_file)) ; else if (unformat (input, "tag %s", &tag)) vec_add1 (tags, tag); else if (unformat (input, "merge %s", &merge_file)) vec_add1 (merge_files, merge_file); else if (unformat (input, "verbose %=", &verbose, 1)) ; else if (unformat (input, "max-events %d", &max_events)) ; else if (unformat (input, "sample-time %f", &min_sample_time)) ; else { error = clib_error_create ("unknown input `%U'\n", format_unformat_error, input); goto done; } } #ifdef CLIB_UNIX if (load_file) { if ((error = elog_read_file (em, load_file))) goto done; } else if (merge_files) { uword i; elog_main_t * ems; vec_clone (ems, merge_files); elog_init (em, max_events); for (i = 0; i < vec_len (ems); i++) { if ((error = elog_read_file (i == 0 ? em : &ems[i], merge_files[i]))) goto done; if (i > 0) { elog_merge (em, tags[0], &ems[i], tags[i]); tags[0] = 0; } } } else #endif /* CLIB_UNIX */ { f64 t[2]; elog_init (em, max_events); elog_enable_disable (em, 1); t[0] = unix_time_now (); for (i = 0; i < n_iter; i++) { u32 j, n, sum; n = 1 + (random_u32 (&seed) % 128); sum = 0; for (j = 0; j < n; j++) sum += random_u32 (&seed); { ELOG_TYPE_XF (e); ELOG (em, e, sum); } { ELOG_TYPE_XF (e); ELOG (em, e, sum + 1); } { struct { u32 string_index; f32 f; } * d; ELOG_TYPE_DECLARE (e) = { .format = "fumble %s %.9f", .format_args = "t4f4", .n_enum_strings = 4, .enum_strings = { "string0", "string1", "string2", "string3", }, }; d = ELOG_DATA (em, e); d->string_index = sum & 3; d->f = (sum & 0xff) / 128.; } { ELOG_TYPE_DECLARE (e) = { .format = "bar %d.%d.%d.%d", .format_args = "i1i1i1i1", }; ELOG_TRACK (my_track); u8 * d = ELOG_TRACK_DATA (em, e, my_track); d[0] = i + 0; d[1] = i + 1; d[2] = i + 2; d[3] = i + 3; } { ELOG_TYPE_DECLARE (e) = { .format = "bar `%s'", .format_args = "s20", }; struct { char s[20]; } * d; u8 * v; d = ELOG_DATA (em, e); v = format (0, "foo %d%c", i, 0); memcpy (d->s, v, clib_min (vec_len (v), sizeof (d->s))); } { ELOG_TYPE_DECLARE (e) = { .format = "bar `%s'", .format_args = "T4", }; struct { u32 offset; } * d; d = ELOG_DATA (em, e); d->offset = elog_string (em, "string table %d", i); } } do { t[1] = unix_time_now (); } while (t[1] - t[0] < min_sample_time); } #ifdef CLIB_UNIX if (dump_file) { if ((error = elog_write_file (em, dump_file))) goto done; } #endif if (verbose) { elog_event_t * e, * es; es = elog_get_events (em); vec_foreach (e, es) { clib_warning ("%18.9f: %12U %U\n", e->time, format_elog_track, em, e, format_elog_event, em, e); } } done: if (error) clib_error_report (error); return 0; } #ifdef CLIB_UNIX int main (int argc, char * argv []) { unformat_input_t i; int r; unformat_init_command_line (&i, argv); r = test_elog_main (&i); unformat_free (&i); return r; }