static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, const uint8_t *data, uint32_t len) { if ((uint32_t)peernum >= chat->numpeers) return 1; if (len > sizeof(sendnodes_data) || len < sizeof(uint64_t)) return 1; if ((len - sizeof(uint64_t)) % sizeof(groupchat_nodes) != 0) return 1; if (is_timeout(chat->group[peernum].last_pinged, GROUP_PING_TIMEOUT)) return 1; sendnodes_data contents; memcpy(&contents, data, len); if (contents.pingid != chat->group[peernum].pingid) return 1; uint16_t numnodes = (len - sizeof(contents.pingid)) / sizeof(groupchat_nodes); uint32_t i; IPPTs ippts_send; ippts_send.timestamp = unix_time(); for (i = 0; i < numnodes; ++i) { if (peer_okping(chat, contents.nodes[i].client_id) > 0) { int peern = peer_in_chat(chat, contents.nodes[i].client_id); if (peern == -1) { /*NOTE: This is just for testing and will be removed later.*/ peern = addpeer(chat, contents.nodes[i].client_id); } if (peern == -1) continue; to_host_family(&contents.nodes[i].ip_port.ip); send_getnodes(chat, contents.nodes[i].ip_port, peern); if (chat->assoc) { ippts_send.ip_port = contents.nodes[i].ip_port; Assoc_add_entry(chat->assoc, contents.nodes[i].client_id, &ippts_send, NULL, 0); } } } int ok = add_closepeer(chat, chat->group[peernum].client_id, source); return 0; }
static void ping_close(Group_Chat *chat) { uint32_t i; for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) { int peernum = peer_in_chat(chat, chat->close[i].client_id); if (peernum == -1) continue; if (is_timeout(chat->group[peernum].last_pinged, NODE_PING_INTERVAL)) send_getnodes(chat, chat->close[i].ip_port, peernum); } } }
static int handle_getnodes(Group_Chat *chat, IP_Port source, int peernum, uint8_t *data, uint32_t len) { if (len != sizeof(getnodes_data)) return 1; if ((uint32_t)peernum >= chat->numpeers) return 1; getnodes_data contents; memcpy(&contents, data, sizeof(contents)); send_sendnodes(chat, source, peernum, contents.pingid); if (peer_okping(chat, chat->group[peernum].client_id) > 0) send_getnodes(chat, source, peernum); return 0; }
static void ping_close(Group_Chat *chat) { uint32_t i; for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* previous condition was always true, assuming this is the wanted one: */ if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) { int peernum = peer_in_chat(chat, chat->close[i].client_id); if (peernum == -1) continue; if (is_timeout(chat->group[peernum].last_pinged, NODE_PING_INTERVAL)) send_getnodes(chat, chat->close[i].ip_port, peernum); } } }
static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8_t *data, uint32_t len) { if ((uint32_t)peernum >= chat->numpeers) return 1; if (len > sizeof(sendnodes_data) || len < sizeof(uint64_t)) return 1; if ((len - sizeof(uint64_t)) % sizeof(groupchat_nodes) != 0) return 1; if (is_timeout(chat->group[peernum].last_pinged, PING_TIMEOUT)) return 1; sendnodes_data contents; memcpy(&contents, data, len); if (contents.pingid != chat->group[peernum].pingid) return 1; uint16_t numnodes = (len - sizeof(contents.pingid)) / sizeof(groupchat_nodes); uint32_t i; for (i = 0; i < numnodes; ++i) { if (peer_okping(chat, contents.nodes[i].client_id) > 0) { int peern = peer_in_chat(chat, contents.nodes[i].client_id); if (peern == -1) { /*NOTE: This is just for testing and will be removed later.*/ peern = addpeer(chat, contents.nodes[i].client_id); } if (peern == -1) continue; send_getnodes(chat, contents.nodes[i].ip_port, peern); } } add_closepeer(chat, chat->group[peernum].client_id, source); return 0; }
void chat_bootstrap_nonlazy(Group_Chat *chat, IP_Port ip_port, uint8_t *client_id) { send_getnodes(chat, ip_port, addpeer(chat, client_id)); add_closepeer(chat, client_id, ip_port); }
void chat_bootstrap(Group_Chat *chat, IP_Port ip_port, uint8_t *client_id) { send_getnodes(chat, ip_port, addpeer(chat, client_id)); }