/** * Copy an address struct. * * @param address address to copy * @return a copy of the address struct */ struct GNUNET_HELLO_Address * GNUNET_HELLO_address_copy (const struct GNUNET_HELLO_Address *address) { return GNUNET_HELLO_address_allocate (&address->peer, address->transport_name, address->address, address->address_length, address->local_info); }
/** * Generate a fake address based on the given parameters. * * @param pid number of the peer * @param num number of the address at peer @a pid * @param addr_flags flags to use for the address * @return the address */ static struct GNUNET_HELLO_Address * make_address (uint32_t pid, uint32_t num, enum GNUNET_HELLO_AddressInfo addr_flags) { struct GNUNET_PeerIdentity pk; uint32_t nbo; nbo = htonl (num); make_peer (pid, &pk); return GNUNET_HELLO_address_allocate (&pk, "test", &nbo, sizeof (nbo), addr_flags); }
/** * 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)); }