static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t message_id) { if (len + GROUP_DATA_MIN_SIZE > MAX_DATA_SIZE) /*NOTE: not the real maximum len.*/ return 1; uint8_t packet[MAX_DATA_SIZE]; ++chat->message_number; if (chat->message_number == 0) chat->message_number = 1; uint32_t message_num = htonl(chat->message_number); //TODO id_copy(packet, chat->self_public_key); memcpy(packet + crypto_box_PUBLICKEYBYTES, &message_num, sizeof(message_num)); memcpy(packet + GROUP_DATA_MIN_SIZE, data, len); packet[crypto_box_PUBLICKEYBYTES + sizeof(message_num)] = message_id; return sendto_allpeers(chat, packet, len + GROUP_DATA_MIN_SIZE, 50); }
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; }