/** * Function called by the transport for each received message. * This function should also be called with "NULL" for the * message to signal that the other peer disconnected. * * @param cls closure, const char* with the name of the plugin we received the message from * @param peer (claimed) identity of the other peer * @param message the message, NULL if we only care about * learning about the delay until we should receive again -- FIXME! * @param ats performance information * @param ats_count number of records in ats * @param session identifier used for this session (NULL for plugins * that do not offer bi-directional communication to the sender * using the same "connection") * @param sender_address binary address of the sender (if we established the * connection or are otherwise sure of it; should be NULL * for inbound TCP/UDP connections since it it not clear * that we could establish ourselves a connection to that * IP address and get the same system) * @param sender_address_len number of bytes in sender_address * @return how long the plugin should wait until receiving more data * (plugins that do not support this, can ignore the return value) */ static struct GNUNET_TIME_Relative plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, const struct GNUNET_ATS_Information *ats, uint32_t ats_count, struct Session *session, const char *sender_address, uint16_t sender_address_len) { const char *plugin_name = cls; struct GNUNET_TIME_Relative ret; struct GNUNET_HELLO_Address address; uint16_t type; address.peer = *peer; address.address = sender_address; address.address_length = sender_address_len; address.transport_name = plugin_name; ret = GNUNET_TIME_UNIT_ZERO; if (NULL == message) goto end; type = ntohs (message->type); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Message with type %u from peer `%s'\n", type, GNUNET_i2s (peer)); GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes total received"), ntohs (message->size), GNUNET_NO); switch (type) { case GNUNET_MESSAGE_TYPE_HELLO: GST_validation_handle_hello (message); return ret; case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Processing `%s' from `%s'\n", "PING", (sender_address != NULL) ? GST_plugins_a2s (&address) : "<inbound>"); GST_validation_handle_ping (peer, message, &address, session); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Processing `%s' from `%s'\n", "PONG", (sender_address != NULL) ? GST_plugins_a2s (&address) : "<inbound>"); GST_validation_handle_pong (peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT: GST_neighbours_handle_connect (message, peer, &address, session, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT_ACK: GST_neighbours_handle_connect_ack (message, peer, &address, session, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK: GST_neighbours_handle_session_ack (message, peer, &address, session, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: GST_neighbours_handle_disconnect_message (peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE: GST_neighbours_keepalive (peer); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE: GST_neighbours_keepalive_response (peer, ats, ats_count); break; default: /* should be payload */ GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes payload received"), ntohs (message->size), GNUNET_NO); ret = process_payload (peer, &address, session, message, ats, ats_count); break; } end: #if 1 /* FIXME: this should not be needed, and not sure it's good to have it, but without * this connections seem to go extra-slow */ GNUNET_ATS_address_update (GST_ats, &address, session, ats, ats_count); #endif GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Allowing receive from peer %s to continue in %llu ms\n", GNUNET_i2s (peer), (unsigned long long) ret.rel_value); return ret; }
/** * Function called by the transport for each received message. * * @param cls closure, const char* with the name of the plugin we received the message from * @param address address and (claimed) identity of the other peer * @param message the message, NULL if we only care about * learning about the delay until we should receive again * @param session identifier used for this session (NULL for plugins * that do not offer bi-directional communication to the sender * using the same "connection") * @return how long the plugin should wait until receiving more data * (plugins that do not support this, can ignore the return value) */ struct GNUNET_TIME_Relative GST_receive_callback (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, const struct GNUNET_MessageHeader *message) { const char *plugin_name = cls; struct GNUNET_TIME_Relative ret; uint16_t type; ret = GNUNET_TIME_UNIT_ZERO; if (NULL == message) goto end; type = ntohs (message->type); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message with type %u from peer `%s'\n", type, GNUNET_i2s (&address->peer)); GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes total received"), ntohs (message->size), GNUNET_NO); GST_neighbours_notify_data_recv (address, message); switch (type) { case GNUNET_MESSAGE_TYPE_HELLO_LEGACY: /* Legacy HELLO message, discard */ return ret; case GNUNET_MESSAGE_TYPE_HELLO: if (GNUNET_OK != GST_validation_handle_hello (message)) { GNUNET_break_op (0); GST_blacklist_abort_matching (address, session); } return ret; case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing PING from `%s'\n", GST_plugins_a2s (address)); if (GNUNET_OK != GST_validation_handle_ping (&address->peer, message, address, session)) { GST_blacklist_abort_matching (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Processing PONG from `%s'\n", GST_plugins_a2s (address)); if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message)) { GNUNET_break_op (0); GST_blacklist_abort_matching (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN: /* Do blacklist check if communication with this peer is allowed */ (void) GST_blacklist_test_allowed (&address->peer, NULL, &connect_bl_check_cont, GNUNET_copy_message (message), address, session); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK: if (GNUNET_OK != GST_neighbours_handle_session_syn_ack (message, address, session)) { GST_blacklist_abort_matching (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK: if (GNUNET_OK != GST_neighbours_handle_session_ack (message, address, session)) { GNUNET_break_op(0); GST_blacklist_abort_matching (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: GST_neighbours_handle_disconnect_message (&address->peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA: GST_neighbours_handle_quota_message (&address->peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE: GST_neighbours_keepalive (&address->peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE: GST_neighbours_keepalive_response (&address->peer, message); break; default: /* should be payload */ GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes payload received"), ntohs (message->size), GNUNET_NO); ret = process_payload (address, session, message); break; } end: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Allowing receive from peer %s to continue in %s\n", GNUNET_i2s (&address->peer), GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES)); return ret; }