static int connect_to_closest(Group_Chats *g_c, int groupnumber) { Group_c *g = get_group_c(g_c, groupnumber); if (!g) return -1; if (!g->changed) return 0; unsigned int i; for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { if (g->close[i].type == GROUPCHAT_CLOSE_NONE) continue; if (!g->close[i].closest) continue; uint8_t real_pk[crypto_box_PUBLICKEYBYTES]; uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES]; get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[i].number); if (!pk_in_closest_peers(g, real_pk)) { g->close[i].type = GROUPCHAT_CLOSE_NONE; kill_friend_connection(g_c->fr_c, g->close[i].number); } } for (i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { if (!g->closest_peers[i].entry) continue; int friendcon_id = getfriend_conn_id_pk(g_c->fr_c, g->closest_peers[i].real_pk); if (friendcon_id == -1) { friendcon_id = new_friend_connection(g_c->fr_c, g->closest_peers[i].real_pk); if (friendcon_id == -1) { continue; } set_dht_temp_pk(g_c->fr_c, friendcon_id, g->closest_peers[i].temp_pk); } add_conn_to_groupchat(g_c, friendcon_id, groupnumber, 1); if (friend_con_connected(g_c->fr_c, friendcon_id) == FRIENDCONN_STATUS_CONNECTED) { send_packet_online(g_c->fr_c, friendcon_id, groupnumber, g->identifier); } } g->changed = 0; return 0; }
/* Free everything related with friend_connections. */ void kill_friend_connections(Friend_Connections *fr_c) { if (!fr_c) return; uint32_t i; for (i = 0; i < fr_c->num_cons; ++i) { kill_friend_connection(fr_c, i); } free(fr_c); }
/* Free everything related with friend_connections. */ void kill_friend_connections(Friend_Connections *fr_c) { if (!fr_c) return; uint32_t i; for (i = 0; i < fr_c->num_cons; ++i) { kill_friend_connection(fr_c, i); } LANdiscovery_kill(fr_c->dht); free(fr_c); }
/* Free everything related with friend_connections. */ void kill_friend_connections(Friend_Connections *fr_c) { if (!fr_c) { return; } for (uint32_t i = 0; i < fr_c->num_cons; ++i) { kill_friend_connection(fr_c, i); } if (fr_c->local_discovery_enabled) { lan_discovery_kill(fr_c->dht); } free(fr_c); }
static int handle_packet_online(Group_Chats *g_c, int friendcon_id, uint8_t *data, uint16_t length) { if (length != ONLINE_PACKET_DATA_SIZE) return -1; int groupnumber = get_group_num(g_c, data + sizeof(uint16_t)); uint16_t other_groupnum; memcpy(&other_groupnum, data, sizeof(uint16_t)); other_groupnum = ntohs(other_groupnum); Group_c *g = get_group_c(g_c, groupnumber); if (!g) return -1; int index = friend_in_close(g, friendcon_id); if (index == -1) return -1; g->close[index].group_number = other_groupnum; g->close[index].type = GROUPCHAT_CLOSE_ONLINE; if (g->number_joined != -1 && g->number_joined != friendcon_id) { int fr_close_index = friend_in_close(g, g->number_joined); uint8_t real_pk[crypto_box_PUBLICKEYBYTES]; uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES]; get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->number_joined); g->number_joined = -1; if (fr_close_index == -1) return -1; if (!g->close[fr_close_index].closest && pk_in_closest_peers(g, real_pk)) { g->close[fr_close_index].closest = 1; } if (!g->close[fr_close_index].closest) { g->close[fr_close_index].type = GROUPCHAT_CLOSE_NONE; send_peer_kill(g_c, g->close[fr_close_index].number, g->close[fr_close_index].group_number); kill_friend_connection(g_c->fr_c, g->close[fr_close_index].number); } } return 0; }
/* Delete a groupchat from the chats array. * * return 0 on success. * return -1 if failure. */ int del_groupchat(Group_Chats *g_c, int groupnumber) { Group_c *g = get_group_c(g_c, groupnumber); if (!g) return -1; unsigned int i; for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { if (g->close[i].type == GROUPCHAT_CLOSE_NONE) continue; g->close[i].type = GROUPCHAT_CLOSE_NONE; kill_friend_connection(g_c->fr_c, g->close[i].number); } free(g->group); return wipe_group_chat(g_c, groupnumber); }
static int remove_close_conn(Group_Chats *g_c, int groupnumber, int friendcon_id) { Group_c *g = get_group_c(g_c, groupnumber); if (!g) return -1; uint32_t i; for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { if (g->close[i].type == GROUPCHAT_CLOSE_NONE) continue; if (g->close[i].number == friendcon_id) { g->close[i].type = GROUPCHAT_CLOSE_NONE; kill_friend_connection(g_c->fr_c, friendcon_id); return 0; } } return -1; }
static void handle_direct_packet(Group_Chats *g_c, int groupnumber, const uint8_t *data, uint16_t length, int close_index) { if (length == 0) return; switch (data[0]) { case PEER_KILL_ID: { Group_c *g = get_group_c(g_c, groupnumber); if (!g) return; if (!g->close[close_index].closest) { g->close[close_index].type = GROUPCHAT_CLOSE_NONE; kill_friend_connection(g_c->fr_c, g->close[close_index].number); } } case PEER_QUERY_ID: { Group_c *g = get_group_c(g_c, groupnumber); if (!g) return; send_peers(g_c, groupnumber, g->close[close_index].number, g->close[close_index].group_number); } break; case PEER_RESPONSE_ID: { handle_send_peers(g_c, groupnumber, data + 1, length - 1); } break; } }