// If 's' was already defined, return true. // Otherwise, define 's' and return false. static bool check_redef(CTX *ctx, char *s) { if (HT_GET(dstr, dempty, ctx->redef, s)) return true; HT_INSERT(dstr, dempty, ctx->redef, s, NULL); return false; }
static char *def_tuple(CTX *ctx, struct ir_struct_type *st, bool add_names) { // NOTE: we use the same C type for empty tuples and compounds; should be ok if (st->members_count == 0) return VOID_MANGLE; char *m = get_mangle(ctx, st); if (m) return m; assert(ctx->writing_types); m = talloc_strdup(ctx, MANGLE_PREFIX "tuple_"); for (int n = 0; n < st->members_count; n++) { struct ir_struct_member *sm = st->members[n]; mangle_append_sub(&m, def_type(ctx, sm->type)); assert(add_names == (sm->name[0])); if (sm->name) m = talloc_asprintf_append_buffer(m, "n%zd_%s_", strlen(sm->name), sm->name); } if (use_anon_mangle_for_tuples) { char *new_mangle = HT_GET_DEF(dstr, dstr, ctx->tuple_abbrev, m, NULL); if (!new_mangle) { new_mangle = gen_anon_mangle(ctx, "tuple"); HT_INSERT(dstr, dstr, ctx->tuple_abbrev, m, new_mangle); } m = new_mangle; } add_mangle(ctx, st, m); if (!check_redef(ctx, m)) write_struct(ctx, st, m); return m; }
void * fp_pair_map_set(fp_pair_map_t *map, const fp_pair_t *key, void *val) { fp_pair_map_entry_t *resolve; fp_pair_map_entry_t search; void *oldval; tor_assert(map); tor_assert(key); tor_assert(val); memcpy(&(search.key), key, sizeof(*key)); resolve = HT_FIND(fp_pair_map_impl, &(map->head), &search); if (resolve) { oldval = resolve->val; resolve->val = val; } else { resolve = tor_malloc_zero(sizeof(fp_pair_map_entry_t)); memcpy(&(resolve->key), key, sizeof(*key)); resolve->val = val; HT_INSERT(fp_pair_map_impl, &(map->head), resolve); oldval = NULL; } return oldval; }
/* this is only for test */ void create_lsa_entry(uint32_t sender_id, uint32_t nbr_id1, uint32_t nbr_id2, int is_valid) { lnk_entr_t *lnk_base; uint32_t size = sizeof(lsa_t) // need minus one for lnk num, to exclude the node itself + 2 * sizeof(lnk_entr_t); lsa_t *llsa; char *p = (char *)malloc(size); llsa = (lsa_t *)p; llsa->next = NULL; llsa->is_valid = is_valid; llsa->ann_size = 1; llsa->ver = 1; llsa->ttl = LSA_MAX_TTL; llsa->snder_id = sender_id; llsa->seq_num = 0; llsa->num_lnk_entr = 2; llsa->num_obj_entr = 0; lnk_base = (lnk_entr_t *)(p + sizeof(lsa_t)); lnk_base->nid = nbr_id1; lnk_base += 1; lnk_base->nid = nbr_id2; /* test */ reset_LSA_timeout(llsa); HT_INSERT(&g_lsa_ht, lsa_t, llsa->snder_id, llsa); return; }
/* Helper function that registers <b>circ</b> with <b>token</b> on the HS circuitmap. This function steals reference of <b>token</b>. */ static void hs_circuitmap_register_impl(circuit_t *circ, hs_token_t *token) { tor_assert(circ); tor_assert(token); tor_assert(the_hs_circuitmap); /* If this circuit already has a token, clear it. */ if (circ->hs_token) { hs_circuitmap_remove_circuit(circ); } /* Kill old circuits with the same token. We want new intro/rend circuits to take precedence over old ones, so that HSes and clients and reestablish killed circuits without changing the HS token. */ { circuit_t *found_circ; found_circ = get_circuit_with_token(token); if (found_circ) { hs_circuitmap_remove_circuit(found_circ); if (!found_circ->marked_for_close) { circuit_mark_for_close(found_circ, END_CIRC_REASON_FINISHED); } } } /* Register circuit and token to circuitmap. */ circ->hs_token = token; HT_INSERT(hs_circuitmap_ht, the_hs_circuitmap, circ); }
int sandbox_getaddrinfo(const char *name, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { int err; struct cached_getaddrinfo_item_t search, *item; if (servname != NULL) { log_warn(LD_BUG, "called with non-NULL servname"); return EAI_NONAME; } if (name == NULL) { log_warn(LD_BUG, "called with NULL name"); return EAI_NONAME; } *res = NULL; memset(&search, 0, sizeof(search)); search.name = (char *) name; search.family = hints ? hints->ai_family : AF_UNSPEC; item = HT_FIND(getaddrinfo_cache, &getaddrinfo_cache, &search); if (! sandbox_is_active()) { /* If the sandbox is not turned on yet, then getaddrinfo and store the result. */ err = getaddrinfo(name, NULL, hints, res); log_info(LD_NET,"(Sandbox) getaddrinfo %s.", err ? "failed" : "succeeded"); if (! item) { item = tor_malloc_zero(sizeof(*item)); item->name = tor_strdup(name); item->family = hints ? hints->ai_family : AF_UNSPEC; HT_INSERT(getaddrinfo_cache, &getaddrinfo_cache, item); } if (item->res) { freeaddrinfo(item->res); item->res = NULL; } item->res = *res; item->err = err; return err; } /* Otherwise, the sanbox is on. If we have an item, yield its cached result. */ if (item) { *res = item->res; return item->err; } /* getting here means something went wrong */ log_err(LD_BUG,"(Sandbox) failed to get address %s!", name); return EAI_NONAME; }
/** 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 int sessions_cache_add(struct xio_session *session, uint32_t session_id) { struct xio_session *s; struct xio_key_int32 key = { session_id }; HT_LOOKUP(&sessions_cache, &key, s, sessions_htbl); if (s != NULL) return -1; HT_INSERT(&sessions_cache, &key, session, sessions_htbl); return 0; }
/*---------------------------------------------------------------------------*/ static int sessions_cache_add(struct xio_session *session, uint32_t session_id) { struct xio_session *s; struct xio_key_int32 key = { .id = session_id, .pad = {0}, }; HT_LOOKUP(&sessions_cache, &key, s, sessions_htbl); if (s) return -1; HT_INSERT(&sessions_cache, &key, session, sessions_htbl); return 0; }
/** Internal: return the node_t whose identity_digest is * <b>identity_digest</b>. If none exists, create a new one, add it to the * nodelist, and return it. * * Requires that the nodelist be initialized. */ static node_t * node_get_or_create(const char *identity_digest) { node_t *node; if ((node = node_get_mutable_by_id(identity_digest))) return node; node = tor_malloc_zero(sizeof(node_t)); memcpy(node->identity, identity_digest, DIGEST_LEN); HT_INSERT(nodelist_map, &the_nodelist->nodes_by_id, node); smartlist_add(the_nodelist->nodes, node); node->nodelist_idx = smartlist_len(the_nodelist->nodes) - 1; node->country = -1; return node; }
void create_pend_lsa_entry(uint32_t nid, uint32_t seqno) { uint32_t size = sizeof(pend_lsa_t); pend_lsa_t *pending_lsa; char *p = (char *)malloc(size); pending_lsa = (pend_lsa_t *)p; pending_lsa->next = NULL; pending_lsa->snder_id = nid; pending_lsa->seq_num = seqno; pending_lsa->type = LSA_TYPE_AD; //ad, ack or seq reset_ACK_timeout(pending_lsa); HT_INSERT(&g_pd_ack_ht, pend_lsa_t, nid, pending_lsa); return; }
void create_nbr_entry(uint32_t nbr_id) { uint32_t size = sizeof(node_info_t); node_info_t *nbr_info; char *p = (char *)malloc(size); nbr_info = (node_info_t *)p; nbr_info->next = NULL; nbr_info->nid = nbr_id; nbr_info->rd_port = 0; nbr_info->local_port = 0; nbr_info->server_port = 0; //nbr_info->ip = "aa"; nbr_info->is_valid = 1; HT_INSERT(&g_nb_nodes_ht, node_info_t, nbr_info->nid, nbr_info); return; }
/** Like strmap_set() above but for digestmaps. */ void * digestmap_set(digestmap_t *map, const char *key, void *val) { #ifndef OPTIMIZED_DIGESTMAP_SET digestmap_entry_t *resolve; #endif digestmap_entry_t search; void *oldval; tor_assert(map); tor_assert(key); tor_assert(val); memcpy(&search.key, key, DIGEST_LEN); #ifndef OPTIMIZED_DIGESTMAP_SET resolve = HT_FIND(digestmap_impl, &map->head, &search); if (resolve) { oldval = resolve->val; resolve->val = val; return oldval; } else { resolve = tor_malloc_zero(sizeof(digestmap_entry_t)); memcpy(resolve->key, key, DIGEST_LEN); resolve->val = val; HT_INSERT(digestmap_impl, &map->head, resolve); return NULL; } #else /* We spend up to 5% of our time in this function, so the code below is * meant to optimize the check/alloc/set cycle by avoiding the two trips to * the hash table that we do in the unoptimized code above. (Each of * HT_INSERT and HT_FIND calls HT_SET_HASH and HT_FIND_P.) */ _HT_FIND_OR_INSERT(digestmap_impl, node, digestmap_entry_hash, &(map->head), digestmap_entry_t, &search, ptr, { /* we found an entry. */ oldval = (*ptr)->val; (*ptr)->val = val; return oldval; },
/** Set the current value for <b>key</b> to <b>val</b>. Returns the previous * value for <b>key</b> if one was set, or NULL if one was not. * * This function makes a copy of <b>key</b> if necessary, but not of * <b>val</b>. */ void * strmap_set(strmap_t *map, const char *key, void *val) { strmap_entry_t *resolve; strmap_entry_t search; void *oldval; tor_assert(map); tor_assert(key); tor_assert(val); search.key = (char*)key; resolve = HT_FIND(strmap_impl, &map->head, &search); if (resolve) { oldval = resolve->val; resolve->val = val; return oldval; } else { resolve = tor_malloc_zero(sizeof(strmap_entry_t)); resolve->key = tor_strdup(key); resolve->val = val; tor_assert(!HT_FIND(strmap_impl, &map->head, resolve)); HT_INSERT(strmap_impl, &map->head, resolve); return NULL; } }
static void add_mangle(CTX *ctx, void *key, char *val) { assert(!HT_GET(dptr, dstr, ctx->type_mangle, key)); HT_INSERT(dptr, dstr, ctx->type_mangle, key, val); }
/** Implementation helper for circuit_set_{p,n}_circid_orconn: A circuit ID * and/or or_connection for circ has just changed from <b>old_conn, old_id</b> * to <b>conn, id</b>. Adjust the conn,circid map as appropriate, removing * the old entry (if any) and adding a new one. If <b>active</b> is true, * remove the circuit from the list of active circuits on old_conn and add it * to the list of active circuits on conn. * XXX "active" isn't an arg anymore */ static void circuit_set_circid_orconn_helper(circuit_t *circ, int direction, circid_t id, or_connection_t *conn) { orconn_circid_circuit_map_t search; orconn_circid_circuit_map_t *found; or_connection_t *old_conn, **conn_ptr; circid_t old_id, *circid_ptr; int was_active, make_active; if (direction == CELL_DIRECTION_OUT) { conn_ptr = &circ->n_conn; circid_ptr = &circ->n_circ_id; was_active = circ->next_active_on_n_conn != NULL; make_active = circ->n_conn_cells.n > 0; } else { or_circuit_t *c = TO_OR_CIRCUIT(circ); conn_ptr = &c->p_conn; circid_ptr = &c->p_circ_id; was_active = c->next_active_on_p_conn != NULL; make_active = c->p_conn_cells.n > 0; } old_conn = *conn_ptr; old_id = *circid_ptr; if (id == old_id && conn == old_conn) return; if (_last_circid_orconn_ent && ((old_id == _last_circid_orconn_ent->circ_id && old_conn == _last_circid_orconn_ent->or_conn) || (id == _last_circid_orconn_ent->circ_id && conn == _last_circid_orconn_ent->or_conn))) { _last_circid_orconn_ent = NULL; } if (old_conn) { /* we may need to remove it from the conn-circid map */ tor_assert(old_conn->_base.magic == OR_CONNECTION_MAGIC); search.circ_id = old_id; search.or_conn = old_conn; found = HT_REMOVE(orconn_circid_map, &orconn_circid_circuit_map, &search); if (found) { tor_free(found); --old_conn->n_circuits; } if (was_active && old_conn != conn) make_circuit_inactive_on_conn(circ,old_conn); } /* Change the values only after we have possibly made the circuit inactive * on the previous conn. */ *conn_ptr = conn; *circid_ptr = id; if (conn == NULL) return; /* now add the new one to the conn-circid map */ search.circ_id = id; search.or_conn = conn; found = HT_FIND(orconn_circid_map, &orconn_circid_circuit_map, &search); if (found) { found->circuit = circ; } else { found = tor_malloc_zero(sizeof(orconn_circid_circuit_map_t)); found->circ_id = id; found->or_conn = conn; found->circuit = circ; HT_INSERT(orconn_circid_map, &orconn_circid_circuit_map, found); } if (make_active && old_conn != conn) make_circuit_active_on_conn(circ,conn); ++conn->n_circuits; }