/** * Calling clear_bridge_list() should remove all bridges from the bridgelist. */ static void test_bridges_clear_bridge_list(void *arg) { const smartlist_t *bridgelist; const smartlist_t *bridgelist_after; const bridge_info_t *bridge; const bridge_info_t *bridge_after; helper_add_bridges_to_bridgelist(arg); bridgelist = bridge_list_get(); tt_ptr_op(bridgelist, OP_NE, NULL); bridge = smartlist_get(bridgelist, 0); tt_ptr_op(bridge, OP_NE, NULL); clear_bridge_list(); bridgelist_after = bridge_list_get(); tt_ptr_op(bridgelist_after, OP_NE, NULL); bridge_after = smartlist_get(bridgelist, 0); // There now shouldn't be a first bridge tt_ptr_op(bridge_after, OP_EQ, NULL); done: return; }
/** Run unit tests for smartlist-of-digests functions. */ static void test_container_smartlist_digests(void) { smartlist_t *sl = smartlist_new(); /* contains_digest */ smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN)); smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN)); smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN)); test_eq(0, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA")); test_assert(smartlist_contains_digest(sl, "AAAAAAAAAAAAAAAAAAAA")); test_assert(smartlist_contains_digest(sl, "\00090AAB2AAAAaasdAAAAA")); test_eq(0, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA")); /* sort digests */ smartlist_sort_digests(sl); test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); test_memeq(smartlist_get(sl, 1), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); test_memeq(smartlist_get(sl, 2), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN); test_eq(3, smartlist_len(sl)); /* uniq_digests */ smartlist_uniq_digests(sl); test_eq(2, smartlist_len(sl)); test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); test_memeq(smartlist_get(sl, 1), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN); done: SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_free(sl); }
static void test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data) { (void)data; rend_cache_store_status_t ret; rend_service_descriptor_t *generated = NULL; smartlist_t *descs = smartlist_new(); time_t t; char *service_id = NULL; rend_encoded_v2_service_descriptor_t *desc_holder_one = NULL; rend_encoded_v2_service_descriptor_t *desc_holder_two = NULL; NS_MOCK(router_get_my_routerinfo); NS_MOCK(hid_serv_responsible_for_desc_id); rend_cache_init(); t = time(NULL); create_descriptor(&generated, &service_id, 3); generated->timestamp = t + RECENT_TIME; rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); desc_holder_one = ((rend_encoded_v2_service_descriptor_t *) smartlist_get(descs, 0)); smartlist_set(descs, 0, NULL); SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, rend_encoded_v2_service_descriptor_free(d)); smartlist_free(descs); descs = smartlist_new(); generated->timestamp = t + RECENT_TIME; generated->protocols = 41; rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); desc_holder_two = ((rend_encoded_v2_service_descriptor_t *) smartlist_get(descs, 0)); smartlist_set(descs, 0, NULL); // Test when we have another descriptor stored, with a different descriptor mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); hid_serv_responsible_for_desc_id_response = 1; rend_cache_store_v2_desc_as_dir(desc_holder_one->desc_str); ret = rend_cache_store_v2_desc_as_dir(desc_holder_two->desc_str); tt_int_op(ret, OP_EQ, RCS_OKAY); done: NS_UNMOCK(router_get_my_routerinfo); NS_UNMOCK(hid_serv_responsible_for_desc_id); rend_cache_free_all(); rend_service_descriptor_free(generated); tor_free(service_id); SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, rend_encoded_v2_service_descriptor_free(d)); smartlist_free(descs); rend_encoded_v2_service_descriptor_free(desc_holder_one); rend_encoded_v2_service_descriptor_free(desc_holder_two); }
/** Free memory occupied by <b>entry_guard_lines</b>. */ static void state_lines_free(smartlist_t *entry_guard_lines) { SMARTLIST_FOREACH_BEGIN(entry_guard_lines, smartlist_t *, state_lines) { char *state_key = smartlist_get(state_lines, 0); char *state_value = smartlist_get(state_lines, 1); tor_free(state_key); tor_free(state_value); smartlist_free(state_lines); } SMARTLIST_FOREACH_END(state_lines);
/** Launch all server listeners that tor wants us to launch. */ static int launch_server_listeners(const managed_proxy_t *proxy) { int ret=-1; int i, n_transports; const char *transport = NULL; const char *bindaddr_temp = NULL; const char *bindaddr = NULL; config_t *cfg = NULL; /* list of transports */ smartlist_t *transports = smartlist_create(); /* a list of "<transport>-<bindaddr>" strings */ smartlist_t *bindaddrs = smartlist_create(); /* split the comma-separated transports/bindaddrs to their smartlists */ smartlist_split_string(transports, proxy->vars.transports, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); smartlist_split_string(bindaddrs, proxy->vars.bindaddrs, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); n_transports = smartlist_len(transports); /* Iterate transports; match them with their bindaddr; create their config_t. */ for (i=0;i<n_transports;i++) { transport = smartlist_get(transports, i); bindaddr_temp = smartlist_get(bindaddrs, i); obfs_assert(strlen(bindaddr_temp) > strlen(transport)+1); bindaddr = bindaddr_temp+strlen(transport)+1; /* +1 for the dash */ cfg = config_create_managed(proxy->is_server, transport, bindaddr, proxy->vars.or_port); if (cfg) /* if a config was created; put it in the config smartlist */ smartlist_add(proxy->configs, cfg); else /* otherwise, spit a method error line */ print_method_error_line(transport, proxy, ST_LAUNCH_FAIL_SETUP); } /* open listeners */ ret = open_listeners_managed(proxy); SMARTLIST_FOREACH(bindaddrs, char *, cp, free(cp)); smartlist_free(bindaddrs); SMARTLIST_FOREACH(transports, char *, cp, free(cp)); smartlist_free(transports); print_method_done_line(proxy); /* print {C,S}METHODS DONE */ return ret; }
static void test_sigsafe_err(void *arg) { const char *fn=get_fname("sigsafe_err_log"); char *content=NULL; log_severity_list_t include_bug; smartlist_t *lines = smartlist_new(); (void)arg; set_log_severity_config(LOG_WARN, LOG_ERR, &include_bug); init_logging(); mark_logs_temp(); add_file_log(&include_bug, fn, 0); tor_log_update_sigsafe_err_fds(); close_temp_logs(); close(STDERR_FILENO); log_err(LD_BUG, "Say, this isn't too cool."); tor_log_err_sigsafe("Minimal.\n", NULL); set_log_time_granularity(100*1000); tor_log_err_sigsafe("Testing any ", "attempt to manually log ", "from a signal.\n", NULL); mark_logs_temp(); close_temp_logs(); close(STDERR_FILENO); content = read_file_to_str(fn, 0, NULL); tt_assert(content != NULL); tor_split_lines(lines, content, (int)strlen(content)); tt_int_op(smartlist_len(lines), >=, 5); if (strstr(smartlist_get(lines, 0), "opening new log file")) smartlist_del_keeporder(lines, 0); tt_assert(strstr(smartlist_get(lines, 0), "Say, this isn't too cool")); /* Next line is blank. */ tt_assert(!strcmpstart(smartlist_get(lines, 1), "==============")); tt_assert(!strcmpstart(smartlist_get(lines, 2), "Minimal.")); /* Next line is blank. */ tt_assert(!strcmpstart(smartlist_get(lines, 3), "==============")); tt_str_op(smartlist_get(lines, 4), ==, "Testing any attempt to manually log from a signal."); done: tor_free(content); smartlist_free(lines); }
static void test_rend_cache_validate_intro_point_failure(void *data) { (void)data; rend_service_descriptor_t *desc = NULL; char *service_id = NULL; rend_intro_point_t *intro = NULL; const char *identity = NULL; rend_cache_failure_t *failure; rend_cache_failure_intro_t *ip; rend_cache_init(); create_descriptor(&desc, &service_id, 3); desc->timestamp = time(NULL) + RECENT_TIME; intro = (rend_intro_point_t *)smartlist_get(desc->intro_nodes, 0); identity = intro->extend_info->identity_digest; failure = rend_cache_failure_entry_new(); ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); digestmap_set(failure->intro_failures, identity, ip); strmap_set_lc(rend_cache_failure, service_id, failure); // Test when we have an intro point in our cache validate_intro_point_failure(desc, service_id); tt_int_op(smartlist_len(desc->intro_nodes), OP_EQ, 2); done: rend_cache_free_all(); rend_service_descriptor_free(desc); tor_free(service_id); }
/** Add an entry to the GeoIP table, mapping all IPs between <b>low</b> and * <b>high</b>, inclusive, to the 2-letter country code <b>country</b>. */ static void geoip_add_entry(uint32_t low, uint32_t high, const char *country) { intptr_t idx; geoip_entry_t *ent; void *idxplus1_; if (high < low) return; idxplus1_ = strmap_get_lc(country_idxplus1_by_lc_code, country); if (!idxplus1_) { geoip_country_t *c = tor_malloc_zero(sizeof(geoip_country_t)); strlcpy(c->countrycode, country, sizeof(c->countrycode)); tor_strlower(c->countrycode); smartlist_add(geoip_countries, c); idx = smartlist_len(geoip_countries) - 1; strmap_set_lc(country_idxplus1_by_lc_code, country, (void*)(idx+1)); } else { idx = ((uintptr_t)idxplus1_)-1; } { geoip_country_t *c = smartlist_get(geoip_countries, idx); tor_assert(!strcasecmp(c->countrycode, country)); } ent = tor_malloc_zero(sizeof(geoip_entry_t)); ent->ip_low = low; ent->ip_high = high; ent->country = idx; smartlist_add(geoip_entries, ent); }
/** Return the config line for transport <b>transport</b> in the current state. * Return NULL if there is no config line for <b>transport</b>. */ static config_line_t * get_transport_in_state_by_name(const char *transport) { or_state_t *or_state = get_or_state(); config_line_t *line; config_line_t *ret = NULL; smartlist_t *items = NULL; for (line = or_state->TransportProxies ; line ; line = line->next) { tor_assert(!strcmp(line->key, "TransportProxy")); items = smartlist_new(); smartlist_split_string(items, line->value, NULL, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); if (smartlist_len(items) != 2) /* broken state */ goto done; if (!strcmp(smartlist_get(items, 0), transport)) { ret = line; goto done; } SMARTLIST_FOREACH(items, char*, s, tor_free(s)); smartlist_free(items); items = NULL; } done: if (items) { SMARTLIST_FOREACH(items, char*, s, tor_free(s)); smartlist_free(items); } return ret; }
static void NS(test_main)(void *arg) { smartlist_t *out = smartlist_new(); routerset_t *set = routerset_new(); int out_len; node_t *ent; (void)arg; NS_MOCK(node_get_by_nickname); NS(mock_nickname) = tor_strdup("foo"); smartlist_add(set->list, NS(mock_nickname)); routerset_get_all_nodes(out, set, NULL, 0); out_len = smartlist_len(out); ent = (node_t *)smartlist_get(out, 0); smartlist_free(out); routerset_free(set); tt_int_op(out_len, ==, 1); tt_ptr_op(ent, ==, &NS(mock_node)); tt_int_op(CALLED(node_get_by_nickname), ==, 1); done: ; }
/** * Calling get_configured_bridge_by_orports_digest() with two * configured bridge orports and an invalid digest should return the * bridge of the first addrport in the list. */ static void test_bridges_get_configured_bridge_by_orports_digest(void *arg) { smartlist_t *orports = NULL; const smartlist_t *bridgelist; const bridge_info_t *bridge1; const bridge_info_t *bridge2; const bridge_info_t *ret; tor_addr_port_t *addrport1; tor_addr_port_t *addrport2; const char *digest; helper_add_bridges_to_bridgelist(arg); bridgelist = bridge_list_get(); tt_ptr_op(bridgelist, OP_NE, NULL); // This should be the bridge at 6.6.6.6:6666 with fingerprint // 0000000000000000000000000000000000000000 bridge1 = smartlist_get(bridgelist, 0); tt_ptr_op(bridge1, OP_NE, NULL); // This should be the bridge at 6.6.6.7:6667 with fingerprint // A10C4F666D27364036B562823E5830BC448E046A bridge2 = smartlist_get(bridgelist, 1); tt_ptr_op(bridge2, OP_NE, NULL); addrport1 = (tor_addr_port_t*)bridge_get_addr_port(bridge1); tt_int_op(addrport1->port, OP_EQ, 6666); addrport2 = (tor_addr_port_t*)bridge_get_addr_port(bridge2); tt_int_op(addrport2->port, OP_EQ, 6667); orports = smartlist_new(); smartlist_add(orports, addrport1); smartlist_add(orports, addrport2); digest = "zzzzzzzzzzzzzzzz"; ret = get_configured_bridge_by_orports_digest(digest, orports); tt_ptr_op(ret, OP_NE, NULL); tt_assert(tor_addr_port_eq(addrport1, bridge_get_addr_port(ret))); done: smartlist_free(orports); mark_bridge_list(); sweep_bridge_list(); }
/* replacement for torflow in Tor. for now just grab the bandwidth we configured * in the XML and use that as the measured bandwidth value. since our configured * bandwidth doesnt change over time, this could just be run once (by setting the * time far in the future so the file is not seen as outdated). but we need to * run it after all routers are loaded, so its best to re-run periodically. * * eventually we will want an option to run something similar to the actual * torflow scripts that download files over Tor and computes bandwidth values. * in that case it needs to run more often to keep monitoring the actual state * of the network. * * torflow writes a few things to the v3bwfile. all Tor currently uses is: * * 0123456789 * node_id=$0123456789ABCDEF0123456789ABCDEF01234567 bw=12345 * ... * * where 0123456789 is the time, 0123456789ABCDEF0123456789ABCDEF01234567 is * the relay's fingerprint, and 12345 is the measured bandwidth in ?. */ void scalliontor_init_v3bw(ScallionTor* stor) { /* open the bw file, clearing it if it exists */ FILE *v3bw = fopen(stor->v3bw_name, "w"); if(v3bw == NULL) { stor->shadowlibFuncs->log(SHADOW_LOG_LEVEL_MESSAGE, __FUNCTION__, "v3bandwidth file not updated: can not open file '%s'\n", stor->v3bw_name); return; } time_t maxtime = -1; /* print time part on first line */ if(fprintf(v3bw, "%lu\n", maxtime) < 0) { /* uhhhh... */ stor->shadowlibFuncs->log(SHADOW_LOG_LEVEL_MESSAGE, __FUNCTION__, "v3bandwidth file not updated: can write time '%u' to file '%s'\n", maxtime, stor->v3bw_name); return; } routerlist_t *rlist = router_get_routerlist(); routerinfo_t *rinfo; /* print an entry for each router */ for (int i=0; i < smartlist_len(rlist->routers); i++) { rinfo = smartlist_get(rlist->routers, i); /* get the fingerprint from its digest */ char node_id[HEX_DIGEST_LEN+1]; base16_encode(node_id, HEX_DIGEST_LEN+1, rinfo->cache_info.identity_digest, DIGEST_LEN); /* the network address */ in_addr_t netaddr = htonl(rinfo->addr); /* ask shadow for this node's configured bandwidth */ guint bwdown = 0, bwup = 0; stor->shadowlibFuncs->getBandwidth(netaddr, &bwdown, &bwup); /* XXX careful here! shadow bandwidth may be different than the consensus * right now i believe this v3bw file is not used to compute the consensus * "w Bandwidth" line, and * intercept_rep_hist_bandwidth_assess and * intercept_router_get_advertised_bandwidth_capped * takes care of things. so leave it for now. */ guint bw = MIN(bwup, bwdown); if(fprintf(v3bw, "node_id=$%s bw=%u\n", node_id, bw) < 0) { /* uhhhh... */ stor->shadowlibFuncs->log(SHADOW_LOG_LEVEL_MESSAGE, __FUNCTION__, "v3bandwidth file not updated: can write line 'node_id=$%s bw=%u\n' to file '%s'\n", node_id, bw, stor->v3bw_name); return; } } fclose(v3bw); /* reschedule */ stor->shadowlibFuncs->createCallback((ShadowPluginCallbackFunc)scalliontor_init_v3bw, (gpointer)stor, VTORFLOW_SCHED_PERIOD); }
/** Assuming the members of <b>sl</b> are in order, return a pointer to the * member that matches <b>key</b>. Ordering and matching are defined by a * <b>compare</b> function that returns 0 on a match; less than 0 if key is * less than member, and greater than 0 if key is greater then member. */ void * smartlist_bsearch(smartlist_t *sl, const void *key, int (*compare)(const void *key, const void **member)) { int found, idx; idx = smartlist_bsearch_idx(sl, key, compare, &found); return found ? smartlist_get(sl, idx) : NULL; }
static int ewma_cmp_cmux(circuitmux_t *cmux_1, circuitmux_policy_data_t *pol_data_1, circuitmux_t *cmux_2, circuitmux_policy_data_t *pol_data_2) { ewma_policy_data_t *p1 = NULL, *p2 = NULL; cell_ewma_t *ce1 = NULL, *ce2 = NULL; tor_assert(cmux_1); tor_assert(pol_data_1); tor_assert(cmux_2); tor_assert(pol_data_2); p1 = TO_EWMA_POL_DATA(pol_data_1); p2 = TO_EWMA_POL_DATA(pol_data_2); if (p1 != p2) { /* Get the head cell_ewma_t from each queue */ if (smartlist_len(p1->active_circuit_pqueue) > 0) { ce1 = smartlist_get(p1->active_circuit_pqueue, 0); } if (smartlist_len(p2->active_circuit_pqueue) > 0) { ce2 = smartlist_get(p2->active_circuit_pqueue, 0); } /* Got both of them? */ if (ce1 != NULL && ce2 != NULL) { /* Pick whichever one has the better best circuit */ return compare_cell_ewma_counts(ce1, ce2); } else { if (ce1 != NULL ) { /* We only have a circuit on cmux_1, so prefer it */ return -1; } else if (ce2 != NULL) { /* We only have a circuit on cmux_2, so prefer it */ return 1; } else { /* No circuits at all; no preference */ return 0; } } } else { /* We got identical params */ return 0; } }
/** Return the two-letter country code associated with the number <b>num</b>, * or "??" for an unknown value. */ const char * geoip_get_country_name(country_t num) { if (geoip_countries && num >= 0 && num < smartlist_len(geoip_countries)) { geoip_country_t *c = smartlist_get(geoip_countries, num); return c->countrycode; } else return "??"; }
static void test_container_smartlist_ints_eq(void *arg) { smartlist_t *sl1 = NULL, *sl2 = NULL; int x; (void)arg; tt_assert(smartlist_ints_eq(NULL, NULL)); sl1 = smartlist_new(); tt_assert(!smartlist_ints_eq(sl1, NULL)); tt_assert(!smartlist_ints_eq(NULL, sl1)); sl2 = smartlist_new(); tt_assert(smartlist_ints_eq(sl1, sl2)); x = 5; smartlist_add(sl1, tor_memdup(&x, sizeof(int))); smartlist_add(sl2, tor_memdup(&x, sizeof(int))); x = 90; smartlist_add(sl1, tor_memdup(&x, sizeof(int))); smartlist_add(sl2, tor_memdup(&x, sizeof(int))); tt_assert(smartlist_ints_eq(sl1, sl2)); x = -50; smartlist_add(sl1, tor_memdup(&x, sizeof(int))); tt_assert(! smartlist_ints_eq(sl1, sl2)); tt_assert(! smartlist_ints_eq(sl2, sl1)); smartlist_add(sl2, tor_memdup(&x, sizeof(int))); tt_assert(smartlist_ints_eq(sl1, sl2)); *(int*)smartlist_get(sl1, 1) = 101010; tt_assert(! smartlist_ints_eq(sl2, sl1)); *(int*)smartlist_get(sl2, 1) = 101010; tt_assert(smartlist_ints_eq(sl1, sl2)); done: if (sl1) SMARTLIST_FOREACH(sl1, int *, ip, tor_free(ip)); if (sl2) SMARTLIST_FOREACH(sl2, int *, ip, tor_free(ip)); smartlist_free(sl1); smartlist_free(sl2); }
/** Append some EntryGuard lines to the Tor state at <b>state</b>. <b>entry_guard_lines</b> is a smartlist containing 2-tuple smartlists that carry the key and values of the statefile. As an example: entry_guard_lines = (("EntryGuard", "name 67E72FF33D7D41BF11C569646A0A7B4B188340DF DirCache"), ("EntryGuardDownSince", "2014-06-07 16:02:46 2014-06-07 16:02:46")) */ static void state_insert_entry_guard_helper(or_state_t *state, smartlist_t *entry_guard_lines) { config_line_t **next, *line; next = &state->EntryGuards; *next = NULL; /* Loop over all the state lines in the smartlist */ SMARTLIST_FOREACH_BEGIN(entry_guard_lines, const smartlist_t *,state_lines) { /* Get key and value for each line */ const char *state_key = smartlist_get(state_lines, 0); const char *state_value = smartlist_get(state_lines, 1); *next = line = tor_malloc_zero(sizeof(config_line_t)); line->key = tor_strdup(state_key); tor_asprintf(&line->value, "%s", state_value); next = &(line->next); } SMARTLIST_FOREACH_END(state_lines); }
/** Parse the '-p' argument of tor-fw-helper. Its format is * [<external port>]:<internal port>, and <external port> is optional. * Return NULL if <b>arg</b> was c0rrupted. */ static port_to_forward_t * parse_port(const char *arg) { smartlist_t *sl = smartlist_new(); port_to_forward_t *port_to_forward = NULL; char *port_str = NULL; int ok; int port; smartlist_split_string(sl, arg, ":", 0, 0); if (smartlist_len(sl) != 2) goto err; port_to_forward = tor_malloc(sizeof(port_to_forward_t)); if (!port_to_forward) goto err; port_str = smartlist_get(sl, 0); /* macroify ? */ port = (int)tor_parse_long(port_str, 10, 1, 65535, &ok, NULL); if (!ok && strlen(port_str)) /* ":1555" is valid */ goto err; port_to_forward->external_port = port; port_str = smartlist_get(sl, 1); port = (int)tor_parse_long(port_str, 10, 1, 65535, &ok, NULL); if (!ok) goto err; port_to_forward->internal_port = port; goto done; err: tor_free(port_to_forward); done: SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_free(sl); return port_to_forward; }
/** Run unit tests for basic dynamic-sized array functionality. */ static void test_container_smartlist_basic(void *arg) { smartlist_t *sl; char *v0 = tor_strdup("v0"); char *v1 = tor_strdup("v1"); char *v2 = tor_strdup("v2"); char *v3 = tor_strdup("v3"); char *v4 = tor_strdup("v4"); char *v22 = tor_strdup("v22"); char *v99 = tor_strdup("v99"); char *v555 = tor_strdup("v555"); /* XXXX test sort_digests, uniq_strings, uniq_digests */ /* Test smartlist add, del_keeporder, insert, get. */ (void)arg; sl = smartlist_new(); smartlist_add(sl, v1); smartlist_add(sl, v2); smartlist_add(sl, v3); smartlist_add(sl, v4); smartlist_del_keeporder(sl, 1); smartlist_insert(sl, 1, v22); smartlist_insert(sl, 0, v0); smartlist_insert(sl, 5, v555); tt_ptr_op(v0,OP_EQ, smartlist_get(sl,0)); tt_ptr_op(v1,OP_EQ, smartlist_get(sl,1)); tt_ptr_op(v22,OP_EQ, smartlist_get(sl,2)); tt_ptr_op(v3,OP_EQ, smartlist_get(sl,3)); tt_ptr_op(v4,OP_EQ, smartlist_get(sl,4)); tt_ptr_op(v555,OP_EQ, smartlist_get(sl,5)); /* Try deleting in the middle. */ smartlist_del(sl, 1); tt_ptr_op(v555,OP_EQ, smartlist_get(sl, 1)); /* Try deleting at the end. */ smartlist_del(sl, 4); tt_int_op(4,OP_EQ, smartlist_len(sl)); /* test isin. */ tt_assert(smartlist_contains(sl, v3)); tt_assert(!smartlist_contains(sl, v99)); done: smartlist_free(sl); tor_free(v0); tor_free(v1); tor_free(v2); tor_free(v3); tor_free(v4); tor_free(v22); tor_free(v99); tor_free(v555); }
/** * Given a <b>cache</b>, return some entry for which <b>key</b>=<b>value</b>. * Return NULL if no such entry exists. * * Does not adjust reference counts. */ consensus_cache_entry_t * consensus_cache_find_first(consensus_cache_t *cache, const char *key, const char *value) { smartlist_t *tmp = smartlist_new(); consensus_cache_find_all(tmp, cache, key, value); consensus_cache_entry_t *ent = NULL; if (smartlist_len(tmp)) ent = smartlist_get(tmp, 0); smartlist_free(tmp); return ent; }
/** Return true iff the two lists contain the same strings in the same * order, or if they are both NULL. */ int smartlist_strings_eq(const smartlist_t *sl1, const smartlist_t *sl2) { if (sl1 == NULL) return sl2 == NULL; if (sl2 == NULL) return 0; if (smartlist_len(sl1) != smartlist_len(sl2)) return 0; SMARTLIST_FOREACH(sl1, const char *, cp1, { const char *cp2 = smartlist_get(sl2, cp1_sl_idx); if (strcmp(cp1, cp2)) return 0; });
/** Note that we've seen a client connect from the IP <b>addr</b> * at time <b>now</b>. Ignored by all but bridges and directories if * configured accordingly. */ void geoip_note_client_seen(geoip_client_action_t action, const tor_addr_t *addr, time_t now) { const or_options_t *options = get_options(); clientmap_entry_t lookup, *ent; if (action == GEOIP_CLIENT_CONNECT) { /* Only remember statistics as entry guard or as bridge. */ if (!options->EntryStatistics && (!(options->BridgeRelay && options->BridgeRecordUsageByCountry))) return; } else { if (options->BridgeRelay || options->BridgeAuthoritativeDir || !options->DirReqStatistics) return; } tor_addr_copy(&lookup.addr, addr); lookup.action = (int)action; ent = HT_FIND(clientmap, &client_history, &lookup); if (! ent) { ent = tor_malloc_zero(sizeof(clientmap_entry_t)); tor_addr_copy(&ent->addr, addr); ent->action = (int)action; HT_INSERT(clientmap, &client_history, ent); } if (now / 60 <= (int)MAX_LAST_SEEN_IN_MINUTES && now >= 0) ent->last_seen_in_minutes = (unsigned)(now/60); else ent->last_seen_in_minutes = 0; if (action == GEOIP_CLIENT_NETWORKSTATUS || action == GEOIP_CLIENT_NETWORKSTATUS_V2) { int country_idx = geoip_get_country_by_addr(addr); if (country_idx < 0) country_idx = 0; /** unresolved requests are stored at index 0. */ if (country_idx >= 0 && country_idx < smartlist_len(geoip_countries)) { geoip_country_t *country = smartlist_get(geoip_countries, country_idx); if (action == GEOIP_CLIENT_NETWORKSTATUS) ++country->n_v3_ns_requests; else ++country->n_v2_ns_requests; } /* Periodically determine share of requests that we should see */ if (last_time_determined_shares + REQUEST_SHARE_INTERVAL < now) geoip_determine_shares(now); } }
static void test_container_smartlist_pos(void *arg) { (void) arg; smartlist_t *sl = smartlist_new(); smartlist_add(sl, tor_strdup("This")); smartlist_add(sl, tor_strdup("is")); smartlist_add(sl, tor_strdup("a")); smartlist_add(sl, tor_strdup("test")); smartlist_add(sl, tor_strdup("for")); smartlist_add(sl, tor_strdup("a")); smartlist_add(sl, tor_strdup("function")); /* Test string_pos */ tt_int_op(smartlist_string_pos(NULL, "Fred"), ==, -1); tt_int_op(smartlist_string_pos(sl, "Fred"), ==, -1); tt_int_op(smartlist_string_pos(sl, "This"), ==, 0); tt_int_op(smartlist_string_pos(sl, "a"), ==, 2); tt_int_op(smartlist_string_pos(sl, "function"), ==, 6); /* Test pos */ tt_int_op(smartlist_pos(NULL, "Fred"), ==, -1); tt_int_op(smartlist_pos(sl, "Fred"), ==, -1); tt_int_op(smartlist_pos(sl, "This"), ==, -1); tt_int_op(smartlist_pos(sl, "a"), ==, -1); tt_int_op(smartlist_pos(sl, "function"), ==, -1); tt_int_op(smartlist_pos(sl, smartlist_get(sl,0)), ==, 0); tt_int_op(smartlist_pos(sl, smartlist_get(sl,2)), ==, 2); tt_int_op(smartlist_pos(sl, smartlist_get(sl,5)), ==, 5); tt_int_op(smartlist_pos(sl, smartlist_get(sl,6)), ==, 6); done: SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_free(sl); }
/** Add an entry to a GeoIP table, mapping all IP addresses between <b>low</b> * and <b>high</b>, inclusive, to the 2-letter country code <b>country</b>. */ static void geoip_add_entry(const tor_addr_t *low, const tor_addr_t *high, const char *country) { intptr_t idx; void *idxplus1_; if (tor_addr_family(low) != tor_addr_family(high)) return; if (tor_addr_compare(high, low, CMP_EXACT) < 0) return; idxplus1_ = strmap_get_lc(country_idxplus1_by_lc_code, country); if (!idxplus1_) { geoip_country_t *c = tor_malloc_zero(sizeof(geoip_country_t)); strlcpy(c->countrycode, country, sizeof(c->countrycode)); tor_strlower(c->countrycode); smartlist_add(geoip_countries, c); idx = smartlist_len(geoip_countries) - 1; strmap_set_lc(country_idxplus1_by_lc_code, country, (void*)(idx+1)); } else { idx = ((uintptr_t)idxplus1_)-1; } { geoip_country_t *c = smartlist_get(geoip_countries, idx); tor_assert(!strcasecmp(c->countrycode, country)); } if (tor_addr_family(low) == AF_INET) { geoip_ipv4_entry_t *ent = tor_malloc_zero(sizeof(geoip_ipv4_entry_t)); ent->ip_low = tor_addr_to_ipv4h(low); ent->ip_high = tor_addr_to_ipv4h(high); ent->country = idx; smartlist_add(geoip_ipv4_entries, ent); } else if (tor_addr_family(low) == AF_INET6) { geoip_ipv6_entry_t *ent = tor_malloc_zero(sizeof(geoip_ipv6_entry_t)); ent->ip_low = *tor_addr_to_in6(low); ent->ip_high = *tor_addr_to_in6(high); ent->country = idx; smartlist_add(geoip_ipv6_entries, ent); } }
/** Test choose_random_entry() with only one of our routers being a guard node. */ static void test_choose_random_entry_one_possible_guard(void *arg) { const node_t *chosen_entry = NULL; node_t *the_guard = NULL; smartlist_t *our_nodelist = NULL; (void) arg; /* Set one of the nodes to be a guard. */ our_nodelist = nodelist_get_list(); the_guard = smartlist_get(our_nodelist, 4); /* chosen by fair dice roll */ the_guard->is_possible_guard = 1; /* Pick an entry. Make sure we pick the node we marked as guard. */ chosen_entry = choose_random_entry(NULL); tt_ptr_op(chosen_entry, OP_EQ, the_guard); done: ; }
static circuit_t * ewma_pick_active_circuit(circuitmux_t *cmux, circuitmux_policy_data_t *pol_data) { ewma_policy_data_t *pol = NULL; circuit_t *circ = NULL; cell_ewma_t *cell_ewma = NULL; tor_assert(cmux); tor_assert(pol_data); pol = TO_EWMA_POL_DATA(pol_data); if (smartlist_len(pol->active_circuit_pqueue) > 0) { /* Get the head of the queue */ cell_ewma = smartlist_get(pol->active_circuit_pqueue, 0); circ = cell_ewma_to_circuit(cell_ewma); } return circ; }
/* Return true iff the given cell digest matches the first digest in the * circuit sendme list. */ static bool v1_digest_matches(const circuit_t *circ, const uint8_t *cell_digest) { bool ret = false; uint8_t *circ_digest = NULL; tor_assert(circ); tor_assert(cell_digest); /* We shouldn't have received a SENDME if we have no digests. Log at * protocol warning because it can be tricked by sending many SENDMEs * without prior data cell. */ if (circ->sendme_last_digests == NULL || smartlist_len(circ->sendme_last_digests) == 0) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "We received a SENDME but we have no cell digests to match. " "Closing circuit."); goto no_match; } /* Pop the first element that was added (FIFO) and compare it. */ circ_digest = smartlist_get(circ->sendme_last_digests, 0); smartlist_del_keeporder(circ->sendme_last_digests, 0); /* Compare the digest with the one in the SENDME. This cell is invalid * without a perfect match. */ if (tor_memneq(circ_digest, cell_digest, TRUNNEL_SENDME_V1_DIGEST_LEN)) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "SENDME v1 cell digest do not match."); goto no_match; } /* Digests matches! */ ret = true; no_match: /* This digest was popped from the circuit list. Regardless of what happens, * we have no more use for it. */ tor_free(circ_digest); return ret; }
/** Return true if <b>line</b> is a valid state TransportProxy line. * Return false otherwise. */ static int state_transport_line_is_valid(const char *line) { smartlist_t *items = NULL; char *addrport=NULL; tor_addr_t addr; uint16_t port = 0; int r; items = smartlist_new(); smartlist_split_string(items, line, NULL, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); if (smartlist_len(items) != 2) { log_warn(LD_CONFIG, "state: Not enough arguments in TransportProxy line."); goto err; } addrport = smartlist_get(items, 1); if (tor_addr_port_lookup(addrport, &addr, &port) < 0) { log_warn(LD_CONFIG, "state: Could not parse addrport."); goto err; } if (!port) { log_warn(LD_CONFIG, "state: Transport line did not contain port."); goto err; } r = 1; goto done; err: r = 0; done: SMARTLIST_FOREACH(items, char*, s, tor_free(s)); smartlist_free(items); return r; }
/** * Calling bridge_get_addrport() should give me the address and port * of the bridge. In this case, we sort the smartlist of bridges on * fingerprints and choose the first one. */ static void test_bridges_bridge_get_addrport(void *arg) { smartlist_t *bridgelist; const bridge_info_t *bridge; const tor_addr_port_t *addrport; helper_add_bridges_to_bridgelist(arg); bridgelist = (smartlist_t*)bridge_list_get(); tt_ptr_op(bridgelist, OP_NE, NULL); // This should be the bridge at 6.6.6.6:6666 with fingerprint // 0000000000000000000000000000000000000000 bridge = smartlist_get(bridgelist, 0); tt_ptr_op(bridge, OP_NE, NULL); addrport = bridge_get_addr_port(bridge); tt_int_op(addrport->port, OP_EQ, 6666); done: mark_bridge_list(); sweep_bridge_list(); }
/** Run unit tests for basic dynamic-sized array functionality. */ static void test_container_smartlist_basic(void) { smartlist_t *sl; /* XXXX test sort_digests, uniq_strings, uniq_digests */ /* Test smartlist add, del_keeporder, insert, get. */ sl = smartlist_new(); smartlist_add(sl, (void*)1); smartlist_add(sl, (void*)2); smartlist_add(sl, (void*)3); smartlist_add(sl, (void*)4); smartlist_del_keeporder(sl, 1); smartlist_insert(sl, 1, (void*)22); smartlist_insert(sl, 0, (void*)0); smartlist_insert(sl, 5, (void*)555); test_eq_ptr((void*)0, smartlist_get(sl,0)); test_eq_ptr((void*)1, smartlist_get(sl,1)); test_eq_ptr((void*)22, smartlist_get(sl,2)); test_eq_ptr((void*)3, smartlist_get(sl,3)); test_eq_ptr((void*)4, smartlist_get(sl,4)); test_eq_ptr((void*)555, smartlist_get(sl,5)); /* Try deleting in the middle. */ smartlist_del(sl, 1); test_eq_ptr((void*)555, smartlist_get(sl, 1)); /* Try deleting at the end. */ smartlist_del(sl, 4); test_eq(4, smartlist_len(sl)); /* test isin. */ test_assert(smartlist_contains(sl, (void*)3)); test_assert(!smartlist_contains(sl, (void*)99)); done: smartlist_free(sl); }