More groupchats code written.

This commit is contained in:
irungentoo 2014-09-25 21:05:17 -04:00
parent ebdfa892b3
commit d5d84818fe
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
6 changed files with 269 additions and 52 deletions

View File

@ -135,8 +135,7 @@ typedef struct {
NAT nat;
} DHT_Friend;
typedef struct
{
typedef struct {
uint8_t client_id[CLIENT_ID_SIZE];
IP_Port ip_port;
}

View File

@ -1014,22 +1014,20 @@ static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_
/* Set the callback for group invites.
*
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number)
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length)
*/
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number)
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t))
{
m->group_invite = function;
m->group_invite_number = number;
}
/* Set the callback for group messages.
*
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number)
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length)
*/
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number)
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t))
{
m->group_message = function;
m->group_message_number = number;
}
/* Send a group invite packet.
@ -2179,7 +2177,7 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
break;
if (m->group_invite)
(*m->group_invite)(m, i, temp, len, m->group_invite_number);
(*m->group_invite)(m, i, data, data_length);
break;
}
@ -2189,7 +2187,8 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
break;
if (m->group_message)
(*m->group_message)(m, i, temp, len, m->group_message_number);
(*m->group_message)(m, i, data, data_length);
break;
}

View File

@ -300,10 +300,8 @@ typedef struct Messenger {
void (*avatar_data_recv)(struct Messenger *m, int32_t, uint8_t, uint8_t *, uint8_t *, uint32_t, void *);
void *group_chat_object; /* Set by new_groupchats()*/
void (*group_invite)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t);
uint32_t group_invite_number;
void (*group_message)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t);
uint32_t group_message_number;
void (*group_invite)(struct Messenger *m, int32_t, const uint8_t *, uint16_t);
void (*group_message)(struct Messenger *m, int32_t, const uint8_t *, uint16_t);
void (*file_sendrequest)(struct Messenger *m, int32_t, uint8_t, uint64_t, const uint8_t *, uint16_t, void *);
void *file_sendrequest_userdata;
@ -735,15 +733,15 @@ void m_callback_avatar_data(Messenger *m, void (*function)(Messenger *m, int32_t
/* Set the callback for group invites.
*
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number)
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length)
*/
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number);
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t));
/* Set the callback for group messages.
*
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number)
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length)
*/
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number);
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t));
/* Send a group invite packet.
*

View File

@ -24,7 +24,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "group.h"
#include "util.h"
@ -248,6 +248,25 @@ static int peer_in_chat(const Group_c *chat, const uint8_t *client_id)
return -1;
}
/*
* check if group with identifier is in group array.
*
* return group number if peer is in list.
* return -1 if group is not in list.
*
* TODO: make this more efficient and maybe use constant time comparisons?
*/
static int get_group_num(const Group_Chats *g_c, const uint8_t *identifier)
{
uint32_t i;
for (i = 0; i < g_c->num_chats; ++i)
if (memcmp(g_c->chats[i].identifier, identifier, GROUP_IDENTIFIER_LENGTH) == 0)
return i;
return -1;
}
/*
* Add a peer to the group chat.
*
@ -287,20 +306,162 @@ static int addpeer(Group_c *chat, const uint8_t *client_id)
* return group number on success.
* return -1 on failure.
*/
int temp_c_add_groupchat(Group_Chats *g_c)
int add_groupchat(Group_Chats *g_c)
{
int groupnumber = create_group_chat(g_c);
Group_c *g = get_group_c(g_c, groupnumber);
if (!g) {
if (!g)
return -1;
}
g->status = GROUPCHAT_STATUS_VALID;
new_symmetric_key(g->identifier);
return groupnumber;
}
#define INVITE_PACKET_SIZE (1 + sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH)
#define INVITE_ID 0
#define INVITE_RESPONSE_PACKET_SIZE (1 + sizeof(uint16_t) * 2 + GROUP_IDENTIFIER_LENGTH)
#define INVITE_RESPONSE_ID 1
/* invite friendnumber to groupnumber
* return 0 on success
* return -1 on failure
*/
int invite_friend(Group_Chats *g_c, int32_t friendnumber, int groupnumber)
{
Group_c *g = get_group_c(g_c, groupnumber);
if (!g)
return -1;
uint8_t invite[INVITE_PACKET_SIZE];
invite[0] = INVITE_ID;
uint16_t groupchat_num = htons((uint16_t)groupnumber);
memcpy(invite + 1, &groupchat_num, sizeof(groupchat_num));
memcpy(invite + 1 + sizeof(groupchat_num), g->identifier, GROUP_IDENTIFIER_LENGTH);
if (send_group_invite_packet(g_c->m, friendnumber, invite, sizeof(invite))) {
return 0;
} else {
wipe_group_chat(g_c, groupnumber);
return -1;
}
}
/* Join a group (you need to have been invited first.)
*
* returns group number on success
* returns -1 on failure.
*/
int join_groupchat(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length)
{
if (length != sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH)
return -1;
int groupnumber = create_group_chat(g_c);
Group_c *g = get_group_c(g_c, groupnumber);
if (!g)
return -1;
uint16_t group_num = htons(groupnumber);
g->status = GROUPCHAT_STATUS_VALID;
uint8_t response[INVITE_RESPONSE_PACKET_SIZE];
response[0] = INVITE_RESPONSE_ID;
memcpy(response + 1, &group_num, sizeof(uint16_t));
memcpy(response + 1 + sizeof(uint16_t), data, sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH);
if (send_group_invite_packet(g_c->m, friendnumber, response, sizeof(response))) {
uint16_t other_groupnum;
memcpy(&other_groupnum, data, sizeof(other_groupnum));
other_groupnum = htons(other_groupnum);
//TODO add_friend_to_groupchat(g_c, friendnumber, groupnumber, other_groupnum);
return groupnumber;
} else {
return -1;
}
}
/* Set the callback for group invites.
*
* Function(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length, void *userdata)
*
* data of length is what needs to be passed to join_groupchat().
*/
void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t,
void *), void *userdata)
{
g_c->invite_callback = function;
g_c->invite_callback_userdata = userdata;
}
/* Set the callback for group messages.
*
* Function(Group_Chats *g_c, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t,
void *), void *userdata)
{
g_c->message_callback = function;
g_c->message_callback_userdata = userdata;
}
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) {
g_c->invite_callback(m, friendnumber, invite_data, invite_length, g_c->invite_callback_userdata);
return;
} else {
//TODO
}
break;
}
case INVITE_RESPONSE_ID: {
if (length != INVITE_RESPONSE_PACKET_SIZE)
return;
int groupnumber = get_group_num(g_c, data + 1 + sizeof(uint16_t));
if (groupnumber == -1) {
return;
} else {
//TODO add_friend_to_groupchat(g_c, friendnumber, groupnumber, other_groupnum);
}
break;
}
default:
return;
}
}
static void handle_friend_message_packet(Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length)
{
}
/* Create new groupchat instance. */
Group_Chats *new_groupchats(Messenger *m)
{
@ -313,6 +474,9 @@ Group_Chats *new_groupchats(Messenger *m)
return NULL;
temp->m = m;
m->group_chat_object = temp;
m_callback_group_invite(m, &handle_friend_invite_packet);
return temp;
}
@ -326,6 +490,57 @@ void do_groupchats(Group_Chats *g_c)
void kill_groupchats(Group_Chats *g_c)
{
//TODO
g_c->m->group_chat_object = 0;
free(g_c);
}
/* Return the number of chats in the instance m.
* You should use this to determine how much memory to allocate
* for copy_chatlist. */
/*
uint32_t count_chatlist(const Messenger *m)
{
uint32_t ret = 0;
uint32_t i;
for (i = 0; i < m->numchats; i++) {
if (m->chats[i]) {
ret++;
}
}
return ret;
}*/
/* Copy a list of valid chat IDs into the array out_list.
* If out_list is NULL, returns 0.
* Otherwise, returns the number of elements copied.
* If the array was too small, the contents
* of out_list will be truncated to list_size. */
/*
uint32_t copy_chatlist(const Messenger *m, int *out_list, uint32_t list_size)
{
if (!out_list)
return 0;
if (m->numchats == 0) {
return 0;
}
uint32_t i;
uint32_t ret = 0;
for (i = 0; i < m->numchats; i++) {
if (ret >= list_size) {
break; *//* Abandon ship *//*
}
if (m->chats[i]) {
out_list[ret] = i;
ret++;
}
}
return ret;
}
*/

View File

@ -36,7 +36,7 @@ enum {
GROUPCON_STATUS_NONE,
GROUPCON_STATUS_VALID
};
/*
typedef struct {
uint8_t client_id[crypto_box_PUBLICKEYBYTES];
uint64_t pingid;
@ -47,15 +47,16 @@ typedef struct {
uint64_t last_recv_msgping;
uint32_t last_message_number;
uint8_t nick[MAX_NICK_BYTES];
uint8_t nick[MAX_NAME_LENGTH];
uint16_t nick_len;
uint8_t deleted;
uint64_t deleted_time;
} Group_Peer;
*/
#define MAX_GROUP_CONNECTIONS 4
#define GROUP_IDENTIFIER_LENGTH crypto_box_KEYBYTES /* So we can use new_symmetric_key(...) to fill it */
typedef struct {
uint8_t status;
@ -67,6 +68,8 @@ typedef struct {
uint8_t type;
uint32_t number;
} close[MAX_GROUP_CONNECTIONS];
uint8_t identifier[GROUP_IDENTIFIER_LENGTH];
} Group_c;
typedef struct {
@ -78,31 +81,38 @@ typedef struct {
Group_c *chats;
uint32_t num_chats;
Group_Connection *cons;
uint32_t num_cons;
void (*invite_callback)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *);
void *invite_callback_userdata;
void (*message_callback)(Messenger *m, int, int, const uint8_t *, uint16_t, void *);
void *message_callback_userdata;
} Group_Chats;
/* Set the callback for group invites.
*
* Function(Group_Chats *g_c, int32_t friendnumber, uint8_t *group_public_key, void *userdata)
* Function(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length, void *userdata)
*
* data of length is what needs to be passed to join_groupchat().
*/
void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, int32_t, const uint8_t *, void *),
void *userdata);
void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t,
void *), void *userdata);
/* Set the callback for group messages.
*
* Function(Group_Chats *g_c, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *),
void *userdata);
void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t,
void *), void *userdata);
/* Set the callback for group actions.
*
* Function(Group_Chats *g_c, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void g_callback_group_action(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *),
void *userdata);
void g_callback_group_action(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t,
void *), void *userdata);
/* Set callback function for peer name list changes.
*
@ -117,56 +127,56 @@ void g_callback_group_namelistchange(Group_Chats *g_c, void (*function)(Messenge
* return group number on success.
* return -1 on failure.
*/
int temp_c_add_groupchat(Group_Chats *g_c);
int add_groupchat(Group_Chats *g_c);
/* Delete a groupchat from the chats array.
*
* return 0 on success.
* return -1 if failure.
*/
int temp_c_del_groupchat(Group_Chats *g_c, int groupnumber);
int del_groupchat(Group_Chats *g_c, int groupnumber);
/* Copy the name of peernumber who is in groupnumber to name.
* name must be at least MAX_NICK_BYTES long.
* name must be at least MAX_NAME_LENGTH long.
*
* return length of name if success
* return -1 if failure
*/
int temp_c_m_group_peername(const Group_Chats *g_c, int groupnumber, int peernumber, uint8_t *name);
int group_peername(const Group_Chats *g_c, int groupnumber, int peernumber, uint8_t *name);
/* invite friendnumber to groupnumber
* return 0 on success
* return -1 on failure
*/
int temp_c_invite_friend(Group_Chats *g_c, int32_t friendnumber, int groupnumber);
int invite_friend(Group_Chats *g_c, int32_t friendnumber, int groupnumber);
/* Join a group (you need to have been invited first.)
*
* returns group number on success
* returns -1 on failure.
*/
int temp_c_join_groupchat(Group_Chats *g_c, int32_t friendnumber, const uint8_t *friend_group_public_key);
int join_groupchat(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length);
/* send a group message
* return 0 on success
* return -1 on failure
*/
int temp_c_group_message_send(const Group_Chats *g_c, int groupnumber, const uint8_t *message, uint32_t length);
int group_message_send(const Group_Chats *g_c, int groupnumber, const uint8_t *message, uint32_t length);
/* send a group action
* return 0 on success
* return -1 on failure
*/
int temp_c_group_action_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint32_t length);
int group_action_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint32_t length);
/* Return the number of peers in the group chat on success.
* return -1 on failure
*/
int temp_c_group_number_peers(const Group_Chats *g_c, int groupnumber);
int group_number_peers(const Group_Chats *g_c, int groupnumber);
/* List all the peers in the group chat.
*
* Copies the names of the peers to the name[length][MAX_NICK_BYTES] array.
* Copies the names of the peers to the name[length][MAX_NAME_LENGTH] array.
*
* Copies the lengths of the names to lengths[length]
*
@ -174,7 +184,7 @@ int temp_c_group_number_peers(const Group_Chats *g_c, int groupnumber);
*
* return -1 on failure.
*/
int temp_c_group_names(const Group_Chats *g_c, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[],
int group_names(const Group_Chats *g_c, int groupnumber, uint8_t names[][MAX_NAME_LENGTH], uint16_t lengths[],
uint16_t length);
/* Create new groupchat instance. */

View File

@ -134,8 +134,7 @@ typedef int sock_t;
#define TCP_INET6 (AF_INET6 + 3)
#define TCP_FAMILY (AF_INET6 + 4)
typedef union
{
typedef union {
uint8_t uint8[4];
uint16_t uint16[2];
uint32_t uint32;
@ -143,8 +142,7 @@ typedef union
}
IP4;
typedef union
{
typedef union {
uint8_t uint8[16];
uint16_t uint16[8];
uint32_t uint32[4];
@ -153,8 +151,7 @@ typedef union
}
IP6;
typedef struct
{
typedef struct {
uint8_t family;
union {
IP4 ip4;
@ -163,8 +160,7 @@ typedef struct
}
IP;
typedef struct
{
typedef struct {
IP ip;
uint16_t port;
}