/* Send the packets to tell our friends what our DHT public key is. * * if onion_dht_both is 0, use only the onion to send the packet. * if it is 1, use only the dht. * if it is something else, use both. * * return the number of packets sent on success * return -1 on failure. */ static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both) { if (friend_num >= onion_c->num_friends) return -1; uint8_t data[FAKEID_DATA_MAX_LENGTH]; data[0] = FAKEID_DATA_ID; uint64_t no_replay = unix_time(); host_to_net((uint8_t *)&no_replay, sizeof(no_replay)); memcpy(data + 1, &no_replay, sizeof(no_replay)); memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); Node_format nodes[MAX_SENT_NODES]; uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES); uint32_t i; for (i = 0; i < num_nodes; ++i) to_net_family(&nodes[i].ip_port.ip); memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes); int num1 = -1, num2 = -1; if (onion_dht_both != 1) num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes); if (onion_dht_both != 0) num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes); if (num1 == -1) return num2; if (num2 == -1) return num1; return num1 + num2; }
/* Send a Friend request packet. * * return -1 if failure. * return 0 if it sent the friend request directly to the friend. * return the number of peers it was routed through if it did not send it directly. */ int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data, uint16_t length) { if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0) { return -1; } const Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id); if (!friend_con) { return -1; } VLA(uint8_t, packet, 1 + sizeof(nospam_num) + length); memcpy(packet + 1, &nospam_num, sizeof(nospam_num)); memcpy(packet + 1 + sizeof(nospam_num), data, length); if (friend_con->status == FRIENDCONN_STATUS_CONNECTED) { packet[0] = PACKET_ID_FRIEND_REQUESTS; return write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, packet, SIZEOF_VLA(packet), 0) != -1; } packet[0] = CRYPTO_PACKET_FRIEND_REQ; const int num = send_onion_data(fr_c->onion_c, friend_con->onion_friendnum, packet, SIZEOF_VLA(packet)); if (num <= 0) { return -1; } return num; }
/* Send the packets to tell our friends * return the number of packets sent on success * return -1 on failure. */ static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num) { if (friend_num >= onion_c->num_friends) return -1; uint8_t data[FAKEID_DATA_MAX_LENGTH]; data[0] = FAKEID_DATA_ID; memcpy(data + 1, onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); Node_format nodes[MAX_SENT_NODES]; uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES); memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes); return send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes); //TODO: somehow make this function send our DHT client id directly to the other if we know theirs but they don't //seem to know ours. }
/* Send the packets to tell our friends what our DHT public key is. * * if onion_dht_both is 0, use only the onion to send the packet. * if it is 1, use only the dht. * if it is something else, use both. * * return the number of packets sent on success * return -1 on failure. */ static int send_fakeid_announce(const Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both) { if (friend_num >= onion_c->num_friends) return -1; uint8_t data[FAKEID_DATA_MAX_LENGTH]; data[0] = FAKEID_DATA_ID; uint64_t no_replay = unix_time(); host_to_net((uint8_t *)&no_replay, sizeof(no_replay)); memcpy(data + 1, &no_replay, sizeof(no_replay)); memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); Node_format nodes[MAX_SENT_NODES]; uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2)); uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays); num_nodes += num_relays; int nodes_len = 0; if (num_nodes != 0) { nodes_len = pack_nodes(data + FAKEID_DATA_MIN_LENGTH, FAKEID_DATA_MAX_LENGTH - FAKEID_DATA_MIN_LENGTH, nodes, num_nodes); if (nodes_len <= 0) return -1; } int num1 = -1, num2 = -1; if (onion_dht_both != 1) num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len); if (onion_dht_both != 0) num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len); if (num1 == -1) return num2; if (num2 == -1) return num1; return num1 + num2; }
/* Try to send a friend request to peer with public_key. * data is the data in the request and length is the length. * * return -1 if failure. * return 0 if it sent the friend request directly to the friend. * return the number of peers it was routed through if it did not send it directly. */ int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) { if (length + sizeof(nospam_num) > MAX_DATA_SIZE) return -1; uint8_t temp[MAX_DATA_SIZE]; temp[0] = CRYPTO_PACKET_FRIEND_REQ; memcpy(temp + 1, &nospam_num, sizeof(nospam_num)); memcpy(temp + 1 + sizeof(nospam_num), data, length); int friend_num = onion_friend_num(onion_c, public_key); if (friend_num == -1) return -1; int num = send_onion_data(onion_c, friend_num, temp, 1 + sizeof(nospam_num) + length); if (num <= 0) return -1; return num; }