static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id) { Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id); if (!friend_con) { return 0; } Node_format nodes[MAX_SHARED_RELAYS]; uint8_t data[1024]; const int n = copy_connected_tcp_relays(fr_c->net_crypto, nodes, MAX_SHARED_RELAYS); for (int i = 0; i < n; ++i) { /* Associated the relays being sent with this connection. On receiving the peer will do the same which will establish the connection. */ friend_add_tcp_relay(fr_c, friendcon_id, nodes[i].ip_port, nodes[i].public_key); } int length = pack_nodes(data + 1, sizeof(data) - 1, nodes, n); if (length <= 0) { return 0; } data[0] = PACKET_ID_SHARE_RELAYS; ++length; if (write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, data, length, 0) != -1) { friend_con->share_relays_lastsent = mono_time_get(fr_c->mono_time); return 1; } return 0; }
static int handle_packet(void *object, int number, const uint8_t *data, uint16_t length, void *userdata) { if (length == 0) { return -1; } Friend_Connections *const fr_c = (Friend_Connections *)object; Friend_Conn *friend_con = get_conn(fr_c, number); if (!friend_con) { return -1; } if (data[0] == PACKET_ID_FRIEND_REQUESTS) { if (fr_c->fr_request_callback) { fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length, userdata); } return 0; } if (data[0] == PACKET_ID_ALIVE) { friend_con->ping_lastrecv = mono_time_get(fr_c->mono_time); return 0; } if (data[0] == PACKET_ID_SHARE_RELAYS) { Node_format nodes[MAX_SHARED_RELAYS]; const int n = unpack_nodes(nodes, MAX_SHARED_RELAYS, nullptr, data + 1, length - 1, 1); if (n == -1) { return -1; } for (int j = 0; j < n; ++j) { friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key); } return 0; } for (unsigned i = 0; i < MAX_FRIEND_CONNECTION_CALLBACKS; ++i) { if (friend_con->callbacks[i].data_callback) { friend_con->callbacks[i].data_callback( friend_con->callbacks[i].callback_object, friend_con->callbacks[i].callback_id, data, length, userdata); } friend_con = get_conn(fr_c, number); if (!friend_con) { return -1; } } return 0; }
static int handle_packet(void *object, int number, uint8_t *data, uint16_t length, void *userdata) { if (length == 0) return -1; Friend_Connections *fr_c = object; Friend_Conn *friend_con = get_conn(fr_c, number); if (!friend_con) return -1; if (data[0] == PACKET_ID_FRIEND_REQUESTS) { if (fr_c->fr_request_callback) fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length); return 0; } else if (data[0] == PACKET_ID_ALIVE) { friend_con->ping_lastrecv = unix_time(); return 0; } else if (data[0] == PACKET_ID_SHARE_RELAYS) { Node_format nodes[MAX_SHARED_RELAYS]; int n; if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data + 1, length - 1, 1)) == -1) return -1; int j; for (j = 0; j < n; j++) { friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key); } return 0; } unsigned int i; for (i = 0; i < MAX_FRIEND_CONNECTION_CALLBACKS; ++i) { if (friend_con->callbacks[i].data_callback) friend_con->callbacks[i].data_callback( friend_con->callbacks[i].data_callback_object, friend_con->callbacks[i].data_callback_id, data, length, userdata); friend_con = get_conn(fr_c, number); if (!friend_con) return -1; } return 0; }
/* callback for recv TCP relay nodes. */ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key) { Friend_Connections *fr_c = object; Friend_Conn *friend_con = get_conn(fr_c, number); if (!friend_con) return -1; if (friend_con->crypt_connection_id != -1) { return friend_add_tcp_relay(fr_c, number, ip_port, public_key); } else { return add_tcp_relay(fr_c->net_crypto, ip_port, public_key); } }
/* Callback for DHT ip_port changes. */ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port) { Friend_Connections *fr_c = object; Friend_Conn *friend_con = get_conn(fr_c, number); if (!friend_con) return; if (friend_con->crypt_connection_id == -1) { friend_new_connection(fr_c, number); } set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, 1); friend_con->dht_ip_port = ip_port; friend_con->dht_ip_port_lastrecv = unix_time(); if (friend_con->hosting_tcp_relay) { friend_add_tcp_relay(fr_c, number, ip_port, friend_con->dht_temp_pk); friend_con->hosting_tcp_relay = 0; } }