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; }
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; return 0; }
static void handle_friend_invite_packet(Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length) { Group_Chats *g_c = m->group_chat_object; if (length <= 1) return; const uint8_t *invite_data = data + 1; uint16_t invite_length = length - 1; switch (data[0]) { case INVITE_ID: { if (length != INVITE_PACKET_SIZE) return; int groupnumber = get_group_num(g_c, data + 1 + sizeof(uint16_t)); if (groupnumber == -1) { if (g_c->invite_callback) g_c->invite_callback(m, friendnumber, invite_data, invite_length, g_c->invite_callback_userdata); return; } break; } case INVITE_RESPONSE_ID: { if (length != INVITE_RESPONSE_PACKET_SIZE) return; uint16_t other_groupnum, groupnum; memcpy(&groupnum, data + 1 + sizeof(uint16_t), sizeof(uint16_t)); groupnum = ntohs(groupnum); Group_c *g = get_group_c(g_c, groupnum); if (!g) return; if (memcmp(data + 1 + sizeof(uint16_t) * 2, g->identifier, GROUP_IDENTIFIER_LENGTH) != 0) return; uint16_t peer_number = rand(); /* TODO: what if two people enter the group at the same time and are given the same peer_number by different nodes? */ unsigned int tries = 0; while (get_peer_index(g, peer_number) != -1) { peer_number = rand(); ++tries; if (tries > 32) return; } memcpy(&other_groupnum, data + 1, sizeof(uint16_t)); other_groupnum = ntohs(other_groupnum); int friendcon_id = getfriendcon_id(m, friendnumber); uint8_t real_pk[crypto_box_PUBLICKEYBYTES], temp_pk[crypto_box_PUBLICKEYBYTES]; get_friendcon_public_keys(real_pk, temp_pk, g_c->fr_c, friendcon_id); addpeer(g_c, groupnum, real_pk, temp_pk, peer_number); int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnum, 0, 1); if (close_index != -1) { g->close[close_index].group_number = other_groupnum; g->close[close_index].type = GROUPCHAT_CLOSE_ONLINE; } group_new_peer_send(g_c, groupnum, peer_number, real_pk, temp_pk); break; } default: return; } }