/** * Add or remove an address from this peer's HELLO message. * * @param addremove GNUNET_YES to add, GNUNET_NO to remove * @param address address to add or remove */ void GST_hello_modify_addresses (int addremove, const struct GNUNET_HELLO_Address *address) { struct OwnAddressList *al; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, (addremove == GNUNET_YES) ? "Adding `%s' to the set of our addresses\n" : "Removing `%s' from the set of our addresses\n", GST_plugins_a2s (address)); GNUNET_assert (address != NULL); if (GNUNET_NO == addremove) { for (al = oal_head; al != NULL; al = al->next) if (0 == GNUNET_HELLO_address_cmp (address, al->address)) { GNUNET_CONTAINER_DLL_remove (oal_head, oal_tail, al); GNUNET_HELLO_address_free (al->address); GNUNET_free (al); refresh_hello (); return; } /* address to be removed not found!? */ GNUNET_break (0); return; } al = GNUNET_malloc (sizeof (struct OwnAddressList)); GNUNET_CONTAINER_DLL_insert (oal_head, oal_tail, al); al->address = GNUNET_HELLO_address_copy (address); refresh_hello (); }
/** * Get the ID for the given session object. * * @param sh our handle * @param session session object * @param address the address we are looking for * @return the session id or NOT_FOUND for error */ static uint32_t find_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct GNUNET_ATS_Session *session, const struct GNUNET_HELLO_Address *address) { uint32_t i; if (NULL == address) { GNUNET_break (0); return NOT_FOUND; } for (i = 1; i < sh->session_array_size; i++) if ( (NULL != sh->session_array[i]) && (GNUNET_NO == sh->session_array[i]->in_destroy) && ( (session == sh->session_array[i]->session) || (NULL == sh->session_array[i]->session) ) && (0 == memcmp (&address->peer, &sh->session_array[i]->address->peer, sizeof (struct GNUNET_PeerIdentity))) && (0 == GNUNET_HELLO_address_cmp (address, sh->session_array[i]->address)) ) return i; return NOT_FOUND; }
/** * Iterate over validation entries until a matching one is found. * * @param cls the 'struct ValidationEntryMatchContext' * @param key peer identity (unused) * @param value a 'struct ValidationEntry' to match * @return GNUNET_YES if the entry does not match, * GNUNET_NO if the entry does match */ static int validation_entry_match (void *cls, const GNUNET_HashCode * key, void *value) { struct ValidationEntryMatchContext *vemc = cls; struct ValidationEntry *ve = value; if (0 == GNUNET_HELLO_address_cmp (ve->address, vemc->address)) { vemc->ve = ve; return GNUNET_NO; } return GNUNET_YES; }
static int get_match_exp (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct ExpireContext *ec = cls; if (0 == GNUNET_HELLO_address_cmp (address, ec->address)) { ec->found = GNUNET_YES; ec->expiration = expiration; return GNUNET_SYSERR; /* done here */ } return GNUNET_OK; }
/** * Add or remove an address from this peer's HELLO message. * * @param addremove #GNUNET_YES to add, #GNUNET_NO to remove * @param address address to add or remove */ void GST_hello_modify_addresses (int addremove, const struct GNUNET_HELLO_Address *address) { struct OwnAddressList *al; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, (GNUNET_YES == addremove) ? "Adding `%s' to the set of our addresses\n" : "Removing `%s' from the set of our addresses\n", GST_plugins_a2s (address)); GNUNET_assert (NULL != address); for (al = oal_head; al != NULL; al = al->next) if (0 == GNUNET_HELLO_address_cmp (address, al->address)) break; if (GNUNET_NO == addremove) { if (NULL == al) { /* address to be removed not found!? */ GNUNET_break (0); return; } al->rc--; if (0 != al->rc) return; /* RC not yet zero */ GNUNET_CONTAINER_DLL_remove (oal_head, oal_tail, al); GNUNET_HELLO_address_free (al->address); GNUNET_free (al); refresh_hello (); return; } if (NULL != al) { /* address added twice or more */ al->rc++; return; } al = GNUNET_new (struct OwnAddressList); al->rc = 1; GNUNET_CONTAINER_DLL_insert (oal_head, oal_tail, al); al->address = GNUNET_HELLO_address_copy (address); refresh_hello (); }
/** * Find matching address information. * * @param cls a `struct MatchAddressContext` * @param key unused * @param value a `struct AddressInformationData` * @return #GNUNET_OK if not found */ static int match_address (void *cls, const struct GNUNET_PeerIdentity *key, void *value) { struct MatchAddressContext *mac = cls; struct AddressInformationData *aid = value; if (0 == GNUNET_HELLO_address_cmp (mac->addr, aid->address)) { mac->ret = aid; return GNUNET_NO; } return GNUNET_OK; }
static int find_other_matching (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct EqualsContext *ec = cls; if (expiration.abs_value < ec->expiration_limit.abs_value) return GNUNET_YES; if (0 == GNUNET_HELLO_address_cmp (address, ec->address)) { ec->found = GNUNET_YES; if (expiration.abs_value < ec->expiration.abs_value) ec->result = GNUNET_TIME_absolute_min (expiration, ec->result); return GNUNET_SYSERR; } return GNUNET_YES; }
/** * Find matching address info. Both the address and the session * must match; note that expired addresses are still found (as * the session kind-of keeps those alive). * * @param cls the `struct FindClosure` * @param key which peer is this about * @param value the `struct AddressInfo` * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value */ static int find_ai_cb (void *cls, const struct GNUNET_PeerIdentity *key, void *value) { struct FindClosure *fc = cls; struct AddressInfo *ai = value; if ( (0 == GNUNET_HELLO_address_cmp (fc->address, ai->address) ) && (fc->session == ai->session) ) { fc->ret = ai; return GNUNET_NO; } return GNUNET_YES; }
/** * Test if a particular address is one of ours. * * @param address address to test * @param sig location where to cache PONG signatures for this address [set] * @param sig_expiration how long until the current 'sig' expires? * (ZERO if sig was never created) [set] * @return GNUNET_YES if this is one of our addresses, * GNUNET_NO if not */ int GST_hello_test_address (const struct GNUNET_HELLO_Address *address, struct GNUNET_CRYPTO_EccSignature **sig, struct GNUNET_TIME_Absolute **sig_expiration) { struct OwnAddressList *al; for (al = oal_head; al != NULL; al = al->next) if (0 == GNUNET_HELLO_address_cmp (address, al->address)) { *sig = &al->pong_signature; *sig_expiration = &al->pong_sig_expires; return GNUNET_YES; } *sig = NULL; *sig_expiration = NULL; return GNUNET_NO; }
/** * Find matching address info, ignoring sessions and expired * addresses. * * @param cls the `struct FindClosure` * @param key which peer is this about * @param value the `struct AddressInfo` * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value */ static int find_ai_no_session_cb (void *cls, const struct GNUNET_PeerIdentity *key, void *value) { struct FindClosure *fc = cls; struct AddressInfo *ai = value; if (ai->expired) return GNUNET_YES; /* expired do not count here */ if (0 == GNUNET_HELLO_address_cmp (fc->address, ai->address)) { fc->ret = ai; return GNUNET_NO; } return GNUNET_YES; }
/** * Main interpreter loop. Runs the steps of the test. * * @param cls NULL * @param tc unused */ static void interpreter (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Command *cmd; interpreter_task = NULL; while (1) { cmd = &test_commands[off]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "#%u: %d %s\n", off, (int) cmd->code, (NULL != cmd->label) ? cmd->label : ""); switch (cmd->code) { case CMD_END_PASS: ret = 0; GNUNET_SCHEDULER_shutdown (); return; case CMD_ADD_ADDRESS: { struct GNUNET_HELLO_Address *addr; struct GNUNET_ATS_Session *session; addr = make_address (cmd->details.add_address.pid, cmd->details.add_address.addr_num, cmd->details.add_address.addr_flags); session = make_session (cmd->details.add_address.session); if (cmd->details.add_address.expect_fail) GNUNET_log_skip (1, GNUNET_NO); cmd->details.add_address.ar = GNUNET_ATS_address_add (sched_ats, addr, session, &cmd->details.add_address.properties); GNUNET_free (addr); if (cmd->details.add_address.expect_fail) { GNUNET_log_skip (0, GNUNET_YES); } else if (NULL == cmd->details.add_address.ar) { GNUNET_break (0); GNUNET_SCHEDULER_shutdown (); return; } off++; break; } case CMD_DEL_ADDRESS: { struct Command *add; add = find_command (CMD_ADD_ADDRESS, cmd->details.del_address.add_label); GNUNET_assert (NULL != add->details.add_address.ar); GNUNET_ATS_address_destroy (add->details.add_address.ar); add->details.add_address.ar = NULL; off++; break; } case CMD_AWAIT_ADDRESS_SUGGESTION: { struct GNUNET_PeerIdentity pid; struct GNUNET_HELLO_Address *addr; struct Command *add; struct AddressSuggestData *asd; int done; make_peer (cmd->details.await_address_suggestion.pid, &pid); asd = find_address_suggestion (&pid); if (NULL == asd) return; if (GNUNET_NO == asd->active) return; /* last suggestion was to disconnect, wait longer */ done = GNUNET_YES; if (NULL != cmd->details.await_address_suggestion.add_label) { done = GNUNET_NO; add = find_command (CMD_ADD_ADDRESS, cmd->details.await_address_suggestion.add_label); addr = make_address (add->details.add_address.pid, add->details.add_address.addr_num, add->details.add_address.addr_flags); if ( (asd->session == make_session (add->details.add_address.session)) && (0 == GNUNET_HELLO_address_cmp (addr, asd->address)) ) done = GNUNET_YES; GNUNET_free (addr); } if (GNUNET_NO == done) return; off++; break; } case CMD_AWAIT_DISCONNECT_SUGGESTION: { struct GNUNET_PeerIdentity pid; struct AddressSuggestData *asd; make_peer (cmd->details.await_disconnect_suggestion.pid, &pid); asd = find_address_suggestion (&pid); if (NULL == asd) return; /* odd, no suggestion at all yet!? */ if (GNUNET_YES == asd->active) return; /* last suggestion was to activate, wait longer */ /* last suggestion was to deactivate, condition satisfied! */ off++; break; } case CMD_REQUEST_CONNECTION_START: { struct GNUNET_PeerIdentity pid; make_peer (cmd->details.request_connection_start.pid, &pid); cmd->details.request_connection_start.csh = GNUNET_ATS_connectivity_suggest (con_ats, &pid, 1); off++; break; } case CMD_REQUEST_CONNECTION_STOP: { struct Command *start; start = find_command (CMD_REQUEST_CONNECTION_START, cmd->details.request_connection_stop.connect_label); GNUNET_ATS_connectivity_suggest_cancel (start->details.request_connection_start.csh); start->details.request_connection_start.csh = NULL; off++; break; } case CMD_AWAIT_ADDRESS_INFORMATION: { struct AddressInformationData *aid; struct Command *add; struct Command *update; struct GNUNET_HELLO_Address *addr; const struct GNUNET_ATS_Properties *cmp; add = find_command (CMD_ADD_ADDRESS, cmd->details.await_address_information.add_label); update = find_command (CMD_UPDATE_ADDRESS, cmd->details.await_address_information.update_label); addr = make_address (add->details.add_address.pid, add->details.add_address.addr_num, add->details.add_address.addr_flags); aid = find_address_information (addr); GNUNET_free (addr); if (NULL == update) cmp = &add->details.add_address.properties; else cmp = &update->details.update_address.properties; if ( (NULL != aid) && (cmp->delay.rel_value_us == aid->properties.delay.rel_value_us) && (cmp->utilization_out == aid->properties.utilization_out) && (cmp->utilization_in == aid->properties.utilization_in) && (cmp->distance == aid->properties.distance) && (cmp->scope == aid->properties.scope) ) { off++; break; } return; } case CMD_UPDATE_ADDRESS: { struct Command *add; add = find_command (CMD_ADD_ADDRESS, cmd->details.update_address.add_label); GNUNET_assert (NULL != add->details.add_address.ar); GNUNET_ATS_address_update (add->details.add_address.ar, &cmd->details.update_address.properties); off++; break; } case CMD_ADD_SESSION: { struct Command *add; struct GNUNET_ATS_Session *session; add = find_command (CMD_ADD_ADDRESS, cmd->details.add_session.add_label); session = make_session (cmd->details.add_session.session); GNUNET_assert (NULL != add->details.add_address.ar); GNUNET_ATS_address_add_session (add->details.add_address.ar, session); off++; break; } case CMD_DEL_SESSION: { struct Command *add_address; struct Command *add_session; struct GNUNET_ATS_Session *session; add_session = find_command (CMD_ADD_SESSION, cmd->details.del_session.add_session_label); add_address = find_command (CMD_ADD_ADDRESS, add_session->details.add_session.add_label); GNUNET_assert (NULL != add_address->details.add_address.ar); session = make_session (add_session->details.add_session.session); GNUNET_ATS_address_del_session (add_address->details.add_address.ar, session); off++; break; } case CMD_CHANGE_PREFERENCE: { struct GNUNET_PeerIdentity pid; make_peer (cmd->details.change_preference.pid, &pid); GNUNET_ATS_performance_change_preference (perf_ats, &pid, GNUNET_ATS_PREFERENCE_END); off++; break; } case CMD_PROVIDE_FEEDBACK: { struct GNUNET_PeerIdentity pid; make_peer (cmd->details.provide_feedback.pid, &pid); GNUNET_ATS_performance_give_feedback (perf_ats, &pid, cmd->details.provide_feedback.scope, GNUNET_ATS_PREFERENCE_END); off++; break; } case CMD_LIST_ADDRESSES: { struct GNUNET_PeerIdentity pid; make_peer (cmd->details.list_addresses.pid, &pid); cmd->details.list_addresses.alh = GNUNET_ATS_performance_list_addresses (perf_ats, &pid, cmd->details.list_addresses.all, &info_cb, cmd); return; } case CMD_RESERVE_BANDWIDTH: { struct GNUNET_PeerIdentity pid; make_peer (cmd->details.reserve_bandwidth.pid, &pid); cmd->details.reserve_bandwidth.rc = GNUNET_ATS_reserve_bandwidth (perf_ats, &pid, cmd->details.reserve_bandwidth.amount, &reservation_cb, cmd); return; } case CMD_SLEEP: off++; interpreter_task = GNUNET_SCHEDULER_add_delayed (cmd->details.sleep.delay, &interpreter, NULL); return; } /* end switch */ } /* end while(1) */ }