static int handle_send_peers(Group_Chats *g_c, int groupnumber, const uint8_t *data, uint16_t length) { if (length == 0) return -1; Group_c *g = get_group_c(g_c, groupnumber); if (!g) return -1; unsigned int i; const uint8_t *d = data; while ((length - (d - data)) >= sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES * 2 + 1) { uint16_t peer_num; memcpy(&peer_num, d, sizeof(peer_num)); peer_num = ntohs(peer_num); d += sizeof(uint16_t); int peer_index = addpeer(g_c, groupnumber, d, d + crypto_box_PUBLICKEYBYTES, peer_num); if (peer_index == -1) return -1; if (g->status == GROUPCHAT_STATUS_VALID && memcmp(d, g_c->m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { g->peer_number = peer_num; g->status = GROUPCHAT_STATUS_CONNECTED; group_name_send(g_c, groupnumber, g_c->m->name, g_c->m->name_length); } d += crypto_box_PUBLICKEYBYTES * 2; uint8_t name_length = *d; d += 1; if (name_length > (length - (d - data)) || name_length > MAX_NAME_LENGTH) return -1; setnick(g_c, groupnumber, peer_index, d, name_length); d += name_length; } return 0; }
void Game:: login (char * nick, char * mode, int num) { setnick (nick); if ( strcmp (mode, "create") == 0) { create (); waitplayers (num); } else if ( strcmp (mode, "join") == 0) { joinroom (num); waitstart (); } else { printf ("Error in check mode. [ %s ].\n", mode ); exit (EXIT_FAILURE); } startinfo (); market (); }
/* Creates a new groupchat and puts it in the chats array. * * return group number on success. * return -1 on failure. */ int add_groupchat(Group_Chats *g_c) { int groupnumber = create_group_chat(g_c); if (groupnumber == -1) return -1; Group_c *g = &g_c->chats[groupnumber]; g->status = GROUPCHAT_STATUS_CONNECTED; g->number_joined = -1; new_symmetric_key(g->identifier); g->peer_number = 0; /* Founder is peer 0. */ memcpy(g->real_pk, g_c->m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES); int peer_index = addpeer(g_c, groupnumber, g->real_pk, g_c->m->dht->self_public_key, 0); if (peer_index == -1) { return -1; } setnick(g_c, groupnumber, peer_index, g_c->m->name, g_c->m->name_length); return groupnumber; }
static void handle_message_packet_group(Group_Chats *g_c, int groupnumber, const uint8_t *data, uint16_t length, int close_index) { if (length < sizeof(uint16_t) + sizeof(uint32_t) + 1) return; Group_c *g = get_group_c(g_c, groupnumber); if (!g) return; uint16_t peer_number; memcpy(&peer_number, data, sizeof(uint16_t)); peer_number = ntohs(peer_number); int index = get_peer_index(g, peer_number); if (index == -1) return; uint32_t message_number; memcpy(&message_number, data + sizeof(uint16_t), sizeof(message_number)); message_number = ntohl(message_number); if (g->group[index].last_message_number == 0) { g->group[index].last_message_number = message_number; } else if (message_number - g->group[index].last_message_number > 64 || message_number == g->group[index].last_message_number) { return; } g->group[index].last_message_number = message_number; uint8_t message_id = data[sizeof(uint16_t) + sizeof(message_number)]; const uint8_t *msg_data = data + sizeof(uint16_t) + sizeof(message_number) + 1; uint16_t msg_data_len = length - (sizeof(uint16_t) + sizeof(message_number) + 1); switch (message_id) { case GROUP_MESSAGE_PING_ID: { if (msg_data_len != 0) return; g->group[index].last_recv = unix_time(); } break; case GROUP_MESSAGE_NEW_PEER_ID: { if (msg_data_len != GROUP_MESSAGE_NEW_PEER_LENGTH) return; uint16_t new_peer_number; memcpy(&new_peer_number, msg_data, sizeof(uint16_t)); new_peer_number = ntohs(new_peer_number); addpeer(g_c, groupnumber, msg_data + sizeof(uint16_t), msg_data + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES, new_peer_number); } break; case GROUP_MESSAGE_KILL_PEER_ID: { if (msg_data_len != GROUP_MESSAGE_KILL_PEER_LENGTH) return; uint16_t kill_peer_number; memcpy(&kill_peer_number, msg_data, sizeof(uint16_t)); kill_peer_number = ntohs(kill_peer_number); if (peer_number == kill_peer_number) { delpeer(g_c, groupnumber, index); } else { //TODO } } break; case GROUP_MESSAGE_NAME_ID: { if (setnick(g_c, groupnumber, index, msg_data, msg_data_len) == -1) return; } break; case PACKET_ID_MESSAGE: { if (msg_data_len == 0) return; uint8_t newmsg[msg_data_len + 1]; memcpy(newmsg, msg_data, msg_data_len); newmsg[msg_data_len] = 0; //TODO if (g_c->message_callback) g_c->message_callback(g_c->m, groupnumber, index, newmsg, msg_data_len, g_c->message_callback_userdata); break; } default: return; } send_message_all_close(g_c, groupnumber, data, length, -1/*TODO close_index*/); }
static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) { if (len < GROUP_DATA_MIN_SIZE) return 1; //TODO: int peernum = peer_in_chat(chat, data); if (peernum == -1) { /*NOTE: This is just for testing and will be removed later.*/ peernum = addpeer(chat, data); } if (peernum == -1) return 1; /* Spam prevention (1 message per peer per second limit.) if (chat->group[peernum].last_recv == temp_time) return 1; */ chat->group[peernum].last_recv = unix_time(); uint32_t message_num; memcpy(&message_num, data + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); message_num = ntohl(message_num); if (chat->group[peernum].last_message_number == 0) { chat->group[peernum].last_message_number = message_num; } else if (message_num - chat->group[peernum].last_message_number > 64 || message_num == chat->group[peernum].last_message_number) return 1; chat->group[peernum].last_message_number = message_num; int handled = 1; uint8_t *contents = data + GROUP_DATA_MIN_SIZE; uint16_t contents_len = len - GROUP_DATA_MIN_SIZE; switch (data[crypto_box_PUBLICKEYBYTES + sizeof(message_num)]) { case GROUP_CHAT_PING: /* If message is ping */ if (contents_len != 0) return 1; chat->group[peernum].last_recv_msgping = unix_time(); break; case GROUP_CHAT_NEW_PEER: /* If message is new peer */ if (contents_len != crypto_box_PUBLICKEYBYTES) return 1; addpeer(chat, contents); send_names_new_peer(chat); break; case GROUP_CHAT_PEER_NICK: if (contents_len > MAX_NICK_BYTES || contents_len == 0) return 1; setnick(chat, peernum, contents, contents_len); break; case GROUP_CHAT_CHAT_MESSAGE: /* If message is chat message */ if (chat->group_message != NULL) (*chat->group_message)(chat, peernum, contents, contents_len, chat->group_message_userdata); break; default: handled = 0; break; } if (handled == 1) { sendto_allpeers(chat, data, len, CRYPTO_PACKET_GROUP_CHAT_BROADCAST); return 0; } return 1; }