/** * Client is done with ATS scheduling, release resources. * * @param sh handle to release */ void GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) { struct GNUNET_ATS_AddressRecord *ar; unsigned int i; if (NULL != sh->mq) { GNUNET_MQ_destroy (sh->mq); sh->mq = NULL; } if (NULL != sh->client) { GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; } if (NULL != sh->task) { GNUNET_SCHEDULER_cancel (sh->task); sh->task = NULL; } for (i=0;i<sh->session_array_size;i++) { if (NULL != (ar = sh->session_array[i])) { GNUNET_HELLO_address_free (ar->address); GNUNET_free (ar); sh->session_array[i] = NULL; } } GNUNET_array_grow (sh->session_array, sh->session_array_size, 0); GNUNET_free (sh); }
/** * Release memory used by the given address data. * * @param ai the `struct AddressInfo` */ static void destroy_ai (struct AddressInfo *ai) { GNUNET_assert (NULL == ai->session); if (NULL != ai->unblock_task) { GNUNET_SCHEDULER_cancel (ai->unblock_task); ai->unblock_task = NULL; num_blocked--; } GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (p2a, &ai->address->peer, ai)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Telling ATS to destroy address from peer %s\n", GNUNET_i2s (&ai->address->peer)); if (NULL != ai->ar) { GNUNET_ATS_address_destroy (ai->ar); ai->ar = NULL; } publish_p2a_stat_update (); GNUNET_HELLO_address_free (ai->address); GNUNET_free (ai); }
/** * 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 (); }
/** * Release the session slot from the session table (ATS service is * also done using it). * * @param sh our handle * @param session_id identifies session that is no longer valid */ static void release_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id) { struct GNUNET_ATS_AddressRecord *ar; if (NOT_FOUND == session_id) return; if (session_id >= sh->session_array_size) { GNUNET_break (0); force_reconnect (sh); return; } /* this slot should have been removed from remove_session before */ ar = sh->session_array[session_id]; if (NULL != ar->session) { GNUNET_break (0); force_reconnect (sh); return; } GNUNET_HELLO_address_free (ar->address); GNUNET_free (ar); sh->session_array[session_id] = NULL; }
/** * Iterate over validation entries and free them. * * @param cls (unused) * @param key peer identity (unused) * @param value a 'struct ValidationEntry' to clean up * @return GNUNET_YES (continue to iterate) */ static int cleanup_validation_entry (void *cls, const GNUNET_HashCode * key, void *value) { struct ValidationEntry *ve = value; if (NULL != ve->bc) { GST_blacklist_test_cancel (ve->bc); ve->bc = NULL; } GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (validation_map, &ve->pid.hashPubKey, ve)); GNUNET_HELLO_address_free (ve->address); if (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) { GNUNET_SCHEDULER_cancel (ve->timeout_task); ve->timeout_task = GNUNET_SCHEDULER_NO_TASK; } if (GNUNET_SCHEDULER_NO_TASK != ve->revalidation_task) { GNUNET_SCHEDULER_cancel (ve->revalidation_task); ve->revalidation_task = GNUNET_SCHEDULER_NO_TASK; } GNUNET_free (ve); 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 (); }
/** * Parse broadcast message received. * * @param cls the `struct Plugin` * @param client the `struct MstContext` with sender address * @param message the message we received * @return #GNUNET_OK (always) */ static int broadcast_mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message) { struct Plugin *plugin = cls; struct MstContext *mc = client; struct GNUNET_HELLO_Address *address; const struct GNUNET_MessageHeader *hello; const struct UDP_Beacon_Message *msg; msg = (const struct UDP_Beacon_Message *) message; if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON != ntohs (msg->header.type)) return GNUNET_OK; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received beacon with %u bytes from peer `%s' via address `%s'\n", ntohs (msg->header.size), GNUNET_i2s (&msg->sender), udp_address_to_string (NULL, mc->udp_addr, mc->udp_addr_len)); hello = (struct GNUNET_MessageHeader *) &msg[1]; address = GNUNET_HELLO_address_allocate (&msg->sender, PLUGIN_NAME, mc->udp_addr, mc->udp_addr_len, GNUNET_HELLO_ADDRESS_INFO_NONE); plugin->env->receive (plugin->env->cls, address, NULL, hello); GNUNET_HELLO_address_free (address); GNUNET_STATISTICS_update (plugin->env->stats, _("# Multicast HELLO beacons received via UDP"), 1, GNUNET_NO); return GNUNET_OK; }
/** * Function called with responses from the service. * * @param cls our `struct GNUNET_TRANSPORT_ValidationMonitoringContext *` * @param msg NULL on timeout or error, otherwise presumably a * message with the human-readable address */ static void val_response_processor (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx = cls; struct ValidationIterateResponseMessage *vr_msg; struct GNUNET_HELLO_Address *address; const char *addr; const char *transport_name; size_t size; size_t tlen; size_t alen; if (NULL == msg) { if (val_ctx->one_shot) { /* Disconnect */ val_ctx->cb (val_ctx->cb_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_TIMEOUT); GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx); } else { reconnect_val_ctx (val_ctx); } return; } size = ntohs (msg->size); GNUNET_break (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE); if (size == sizeof (struct GNUNET_MessageHeader)) { /* Done! */ if (val_ctx->one_shot) { val_ctx->cb (val_ctx->cb_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE); GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx); } else { reconnect_val_ctx (val_ctx); } return; } if ((size < sizeof (struct ValidationIterateResponseMessage)) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE)) { GNUNET_break (0); if (val_ctx->one_shot) { val_ctx->cb (val_ctx->cb_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE); GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx); } else { reconnect_val_ctx (val_ctx); } return; } vr_msg = (struct ValidationIterateResponseMessage *) msg; tlen = ntohl (vr_msg->pluginlen); alen = ntohl (vr_msg->addrlen); if (size != sizeof (struct ValidationIterateResponseMessage) + tlen + alen) { GNUNET_break (0); if (val_ctx->one_shot) { val_ctx->cb (val_ctx->cb_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE); GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx); } else { reconnect_val_ctx (val_ctx); } return; } if (0 == tlen) { GNUNET_break (0); /* This must not happen: address without plugin */ return; } addr = (const char *) &vr_msg[1]; transport_name = &addr[alen]; if (transport_name[tlen - 1] != '\0') { /* Corrupt plugin name */ GNUNET_break (0); if (val_ctx->one_shot) { val_ctx->cb (val_ctx->cb_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE); GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx); } else { reconnect_val_ctx (val_ctx); } return; } /* notify client */ address = GNUNET_HELLO_address_allocate (&vr_msg->peer, transport_name, addr, alen, ntohl (vr_msg->local_address_info)); val_ctx->cb (val_ctx->cb_cls, address, GNUNET_TIME_absolute_ntoh (vr_msg->last_validation), GNUNET_TIME_absolute_ntoh (vr_msg->valid_until), GNUNET_TIME_absolute_ntoh (vr_msg->next_validation), ntohl(vr_msg->state)); GNUNET_HELLO_address_free (address); /* expect more replies */ GNUNET_CLIENT_receive (val_ctx->client, &val_response_processor, val_ctx, GNUNET_TIME_absolute_get_remaining (val_ctx->timeout)); }
/** * Function called with responses from the service. * * @param cls our 'struct GNUNET_TRANSPORT_PeerMonitoringContext*' * @param msg NULL on timeout or error, otherwise presumably a * message with the human-readable address */ static void peer_response_processor (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; struct PeerIterateResponseMessage *pir_msg; struct GNUNET_HELLO_Address *address; const char *addr; const char *transport_name; uint16_t size; size_t alen; size_t tlen; if (msg == NULL) { if (pal_ctx->one_shot) { /* Disconnect */ pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); } else { reconnect_peer_ctx (pal_ctx); } return; } size = ntohs (msg->size); GNUNET_break (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE); if (size == sizeof (struct GNUNET_MessageHeader)) { /* Done! */ if (pal_ctx->one_shot) { pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); } else { reconnect_peer_ctx (pal_ctx); } return; } if ((size < sizeof (struct PeerIterateResponseMessage)) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE)) { GNUNET_break (0); if (pal_ctx->one_shot) { pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); } else { reconnect_peer_ctx (pal_ctx); } return; } pir_msg = (struct PeerIterateResponseMessage *) msg; tlen = ntohl (pir_msg->pluginlen); alen = ntohl (pir_msg->addrlen); if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen) { GNUNET_break (0); if (pal_ctx->one_shot) { pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); } else { reconnect_peer_ctx (pal_ctx); } return; } if ( (0 == tlen) && (0 == alen) ) { /* No address available */ pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, NULL, ntohl(pir_msg->state), GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout)); } else { if (0 == tlen) { GNUNET_break (0); /* This must not happen: address without plugin */ return; } addr = (const char *) &pir_msg[1]; transport_name = &addr[alen]; if (transport_name[tlen - 1] != '\0') { /* Corrupt plugin name */ GNUNET_break (0); if (pal_ctx->one_shot) { pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); } else { reconnect_peer_ctx (pal_ctx); } return; } /* notify client */ address = GNUNET_HELLO_address_allocate (&pir_msg->peer, transport_name, addr, alen, ntohl(pir_msg->local_address_info)); pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, address, ntohl(pir_msg->state), GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout)); GNUNET_HELLO_address_free (address); } /* expect more replies */ GNUNET_CLIENT_receive (pal_ctx->client, &peer_response_processor, pal_ctx, GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout)); }