static void do_announce(Onion_Client *onion_c) { uint32_t i, count = 0; Onion_Node *list_nodes = onion_c->clients_announce_list; for (i = 0; i < MAX_ONION_CLIENTS; ++i) { if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) continue; ++count; uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) { interval = ANNOUNCE_INTERVAL_ANNOUNCED; } if (is_timeout(list_nodes[i].last_pinged, interval)) { if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].client_id, list_nodes[i].ping_id) == 0) { list_nodes[i].last_pinged = unix_time(); } } } if (count < MAX_ONION_CLIENTS / 2) { Node_format nodes_list[MAX_SENT_NODES]; uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list, rand() % 2 ? AF_INET : AF_INET6, rand() % 2, 1); for (i = 0; i < num_nodes; ++i) client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0); } }
static void do_friend(Onion_Client *onion_c, uint16_t friendnum) { if (friendnum >= onion_c->num_friends) return; if (onion_c->friends_list[friendnum].status == 0) return; uint32_t i, count = 0; Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list; if (!onion_c->friends_list[friendnum].is_online) { for (i = 0; i < MAX_ONION_CLIENTS; ++i) { if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) continue; ++count; if (list_nodes[i].last_pinged == 0) { list_nodes[i].last_pinged = unix_time(); continue; } if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) { if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0, ~0) == 0) { list_nodes[i].last_pinged = unix_time(); } } } if (count != MAX_ONION_CLIENTS) { if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) { Node_format nodes_list[MAX_SENT_NODES]; uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[friendnum].real_client_id, nodes_list, (rand() % 2) ? AF_INET : AF_INET6, 1, 0); for (i = 0; i < num_nodes; ++i) client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0); } } /* send packets to friend telling them our fake DHT id. */ if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_onion_sent, ONION_FAKEID_INTERVAL)) if (send_fakeid_announce(onion_c, friendnum, 0) >= 1) onion_c->friends_list[friendnum].last_fakeid_onion_sent = unix_time(); if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_dht_sent, DHT_FAKEID_INTERVAL)) if (send_fakeid_announce(onion_c, friendnum, 1) >= 1) onion_c->friends_list[friendnum].last_fakeid_dht_sent = unix_time(); } }
static void do_announce(Onion_Client *onion_c) { uint32_t i, count = 0; Onion_Node *list_nodes = onion_c->clients_announce_list; for (i = 0; i < MAX_ONION_CLIENTS; ++i) { if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) continue; ++count; /* Don't announce ourselves the first time this is run to new peers */ if (list_nodes[i].last_pinged == 0) { list_nodes[i].last_pinged = 1; continue; } uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; if (list_nodes[i].is_stored) { interval = ANNOUNCE_INTERVAL_ANNOUNCED; } if (is_timeout(list_nodes[i].last_pinged, interval)) { if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].client_id, list_nodes[i].ping_id, list_nodes[i].path_used) == 0) { list_nodes[i].last_pinged = unix_time(); } } } if (count != MAX_ONION_CLIENTS) { if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) { unsigned int num_nodes = (onion_c->path_nodes_index < MAX_PATH_NODES) ? onion_c->path_nodes_index : MAX_PATH_NODES; if (num_nodes != 0) { unsigned int num = rand() % num_nodes; client_send_announce_request(onion_c, 0, onion_c->path_nodes[num].ip_port, onion_c->path_nodes[num].client_id, 0, ~0); } } } }
static void do_announce(Onion_Client *onion_c) { uint32_t i, count = 0; Onion_Node *list_nodes = onion_c->clients_announce_list; for (i = 0; i < MAX_ONION_CLIENTS; ++i) { if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) continue; ++count; /* Don't announce ourselves the first time this is run to new peers */ if (list_nodes[i].last_pinged == 0) { list_nodes[i].last_pinged = 1; continue; } uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; if (list_nodes[i].is_stored) { interval = ANNOUNCE_INTERVAL_ANNOUNCED; } if (is_timeout(list_nodes[i].last_pinged, interval)) { if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].client_id, list_nodes[i].ping_id, list_nodes[i].path_used) == 0) { list_nodes[i].last_pinged = unix_time(); } } } if (count != MAX_ONION_CLIENTS) { if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) { Node_format nodes_list[MAX_SENT_NODES]; uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->c->self_public_key, nodes_list, (rand() % 2) ? AF_INET : AF_INET6, 1, 0); for (i = 0; i < num_nodes; ++i) { client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0); } } } }
static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *nodes, uint16_t num_nodes, IP_Port source) { if (num > onion_c->num_friends) return -1; if (num_nodes == 0) return 0; Onion_Node *list_nodes = NULL; uint8_t *reference_id = NULL; uint32_t *ping_nodes_sent_second = NULL; if (num == 0) { list_nodes = onion_c->clients_announce_list; reference_id = onion_c->dht->c->self_public_key; ping_nodes_sent_second = &onion_c->ping_nodes_sent_second; } else { list_nodes = onion_c->friends_list[num - 1].clients_list; reference_id = onion_c->friends_list[num - 1].real_client_id; ping_nodes_sent_second = &onion_c->friends_list[num - 1].ping_nodes_sent_second; } uint32_t i, j; int lan_ips_accepted = (LAN_ip(source.ip) == 0); for (i = 0; i < num_nodes; ++i) { if (*ping_nodes_sent_second > MAX_PING_NODES_SECOND_PEER) return 0; to_host_family(&nodes[i].ip_port.ip); if (!lan_ips_accepted) if (LAN_ip(nodes[i].ip_port.ip) == 0) continue; if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) { /* check if node is already in list. */ for (j = 0; j < MAX_ONION_CLIENTS; ++j) { if (memcmp(list_nodes[j].client_id, nodes[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) { break; } } if (j == MAX_ONION_CLIENTS) { if (client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL, ~0) == 0) ++*ping_nodes_sent_second; } } } return 0; }
static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_format *nodes, uint16_t num_nodes, IP_Port source) { if (num > onion_c->num_friends) return -1; if (num_nodes == 0) return 0; Onion_Node *list_nodes = NULL; uint8_t *reference_id = NULL; Last_Pinged *last_pinged = NULL; uint8_t *last_pinged_index = NULL; if (num == 0) { list_nodes = onion_c->clients_announce_list; reference_id = onion_c->c->self_public_key; last_pinged = onion_c->last_pinged; last_pinged_index = &onion_c->last_pinged_index; } else { list_nodes = onion_c->friends_list[num - 1].clients_list; reference_id = onion_c->friends_list[num - 1].real_client_id; last_pinged = onion_c->friends_list[num - 1].last_pinged; last_pinged_index = &onion_c->friends_list[num - 1].last_pinged_index; } uint32_t i, j; int lan_ips_accepted = (LAN_ip(source.ip) == 0); for (i = 0; i < num_nodes; ++i) { if (!lan_ips_accepted) if (LAN_ip(nodes[i].ip_port.ip) == 0) continue; if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) { /* check if node is already in list. */ for (j = 0; j < MAX_ONION_CLIENTS; ++j) { if (memcmp(list_nodes[j].client_id, nodes[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) { break; } } if (j == MAX_ONION_CLIENTS && good_to_ping(last_pinged, last_pinged_index, nodes[i].client_id)) { client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL, ~0); } } } return 0; }
static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *nodes, uint16_t num_nodes, IP_Port source) { if (num > onion_c->num_friends) return -1; if (num_nodes == 0) return 0; Onion_Node *list_nodes = NULL; uint8_t *reference_id = NULL; if (num == 0) { list_nodes = onion_c->clients_announce_list; reference_id = onion_c->dht->c->self_public_key; } else { list_nodes = onion_c->friends_list[num - 1].clients_list; reference_id = onion_c->friends_list[num - 1].real_client_id; } uint32_t i; int lan_ips_accepted = (LAN_ip(source.ip) == 0); for (i = 0; i < num_nodes; ++i) { to_host_family(&nodes[i].ip_port.ip); if (!lan_ips_accepted) if (LAN_ip(nodes[i].ip_port.ip) == 0) continue; if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) { client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL); } } return 0; }
static void do_friend(Onion_Client *onion_c, uint16_t friendnum) { if (friendnum >= onion_c->num_friends) return; if (onion_c->friends_list[friendnum].status == 0) return; uint32_t interval = ANNOUNCE_FRIEND; if (onion_c->friends_list[friendnum].run_count < RUN_COUNT_FRIEND_ANNOUNCE_BEGINNING) interval = ANNOUNCE_FRIEND_BEGINNING; uint32_t i, count = 0; Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list; if (!onion_c->friends_list[friendnum].is_online) { ++onion_c->friends_list[friendnum].run_count; for (i = 0; i < MAX_ONION_CLIENTS; ++i) { if (is_timeout(list_nodes[i].timestamp, FRIEND_ONION_NODE_TIMEOUT)) continue; ++count; if (list_nodes[i].last_pinged == 0) { list_nodes[i].last_pinged = unix_time(); continue; } if (is_timeout(list_nodes[i].last_pinged, interval)) { if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0, ~0) == 0) { list_nodes[i].last_pinged = unix_time(); } } } if (count != MAX_ONION_CLIENTS) { unsigned int num_nodes = (onion_c->path_nodes_index < MAX_PATH_NODES) ? onion_c->path_nodes_index : MAX_PATH_NODES; unsigned int n = num_nodes; if (num_nodes > (MAX_ONION_CLIENTS / 2)) n = (MAX_ONION_CLIENTS / 2); if (num_nodes != 0) { unsigned int j; for (j = 0; j < n; ++j) { unsigned int num = rand() % num_nodes; client_send_announce_request(onion_c, friendnum + 1, onion_c->path_nodes[num].ip_port, onion_c->path_nodes[num].client_id, 0, ~0); } } } /* send packets to friend telling them our fake DHT id. */ if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_onion_sent, ONION_FAKEID_INTERVAL)) if (send_fakeid_announce(onion_c, friendnum, 0) >= 1) onion_c->friends_list[friendnum].last_fakeid_onion_sent = unix_time(); if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_dht_sent, DHT_FAKEID_INTERVAL)) if (send_fakeid_announce(onion_c, friendnum, 1) >= 1) onion_c->friends_list[friendnum].last_fakeid_dht_sent = unix_time(); } }