Group chat: Add a nickname message. Remove strange default nickname. (Seriously...)

group_chats.*:
- group_send_nick() to send own name
- setnick() to store a received name

Messenger.c:
- group_send_nick() before group_sendmessage() (in regular intervals, to inform new peers)

nTox.c:
- print_groupmessage(): on error or on a name of length zero the result of tox_group_peername() isn't null-terminated, catch that
This commit is contained in:
Coren[m] 2013-11-12 19:56:32 +01:00
parent ba000a2424
commit 6d31a9be7e
No known key found for this signature in database
GPG Key ID: AFA6943800F5DC6D
4 changed files with 85 additions and 7 deletions

View File

@ -821,8 +821,16 @@ void print_groupmessage(Tox *m, int groupnumber, int peernumber, uint8_t *messag
{ {
char msg[256 + length]; char msg[256 + length];
uint8_t name[TOX_MAX_NAME_LENGTH]; uint8_t name[TOX_MAX_NAME_LENGTH];
tox_group_peername(m, groupnumber, peernumber, name); int len = tox_group_peername(m, groupnumber, peernumber, name);
sprintf(msg, "[g] %u: <%s>: %s", groupnumber, name, message);
if (len <= 0)
name[0] = 0;
if (name[0] != 0)
sprintf(msg, "[g] %u: %u <%s>: %s", groupnumber, peernumber, name, message);
else
sprintf(msg, "[g] %u: %u Unknown: %s", groupnumber, peernumber, message);
new_lines(msg); new_lines(msg);
} }

View File

@ -435,6 +435,9 @@ int setname(Messenger *m, uint8_t *name, uint16_t length)
for (i = 0; i < m->numfriends; ++i) for (i = 0; i < m->numfriends; ++i)
m->friendlist[i].name_sent = 0; m->friendlist[i].name_sent = 0;
for (i = 0; i < m->numchats; i++)
m->chats[i]->last_sent_nick = 0; /* or send the new name right away? */
return 0; return 0;
} }
@ -969,6 +972,17 @@ int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t
if (m->chats[groupnumber] == NULL) if (m->chats[groupnumber] == NULL)
return -1; return -1;
/* send own nick from time to time, to let newly added peers be informed
* first time only: use a shorter timeframe, because we might not be in our own
* peer list yet */
if (is_timeout(m->chats[groupnumber]->last_sent_nick, 180))
if (group_send_nick(m->chats[groupnumber], m->chats[groupnumber]->self_public_key, m->name, m->name_length) > 0) {
if (!m->chats[groupnumber]->last_sent_nick)
m->chats[groupnumber]->last_sent_nick = unix_time() - 150;
else
m->chats[groupnumber]->last_sent_nick = unix_time();
}
if (group_sendmessage(m->chats[groupnumber], message, length) > 0) if (group_sendmessage(m->chats[groupnumber], message, length) > 0)
return 0; return 0;

View File

@ -53,6 +53,11 @@ typedef struct {
} sendnodes_data; } sendnodes_data;
typedef struct {
uint8_t client_id[crypto_box_PUBLICKEYBYTES];
uint8_t nickname[MAX_NICK_BYTES];
} peernick_data;
/* /*
* check if peer with client_id is in peer array. * check if peer with client_id is in peer array.
@ -211,10 +216,12 @@ static int addpeer(Group_Chat *chat, uint8_t *client_id)
memset(&(temp[chat->numpeers]), 0, sizeof(Group_Peer)); memset(&(temp[chat->numpeers]), 0, sizeof(Group_Peer));
chat->group = temp; chat->group = temp;
id_copy(chat->group[chat->numpeers].client_id, client_id); id_copy(chat->group[chat->numpeers].client_id, client_id);
chat->group[chat->numpeers].last_recv = unix_time(); chat->group[chat->numpeers].last_recv = unix_time();
chat->group[chat->numpeers].last_recv_msgping = unix_time(); chat->group[chat->numpeers].last_recv_msgping = unix_time();
++chat->numpeers; ++chat->numpeers;
return (chat->numpeers - 1); return (chat->numpeers - 1);
} }
@ -262,14 +269,34 @@ int group_peername(Group_Chat *chat, int peernum, uint8_t *name)
return -1; return -1;
if (chat->group[peernum].nick_len == 0) { if (chat->group[peernum].nick_len == 0) {
memcpy(name, "NSA Agent", 10); /* Kindly remind the user that someone with no name might be an NSA agent.*/ /* memcpy(name, "NSA agent", 10); */ /* Srsly? */ /* Kindly remind the user that someone with no name might be a moronic NSA agent.*/
return 10; name[0] = 0;
return 0;
} }
memcpy(name, chat->group[peernum].nick, chat->group[peernum].nick_len); memcpy(name, chat->group[peernum].nick, chat->group[peernum].nick_len);
return chat->group[peernum].nick_len; return chat->group[peernum].nick_len;
} }
static void setnick(Group_Chat *chat, uint8_t *contents, uint16_t contents_len)
{
if (contents_len > CLIENT_ID_SIZE + MAX_NICK_BYTES)
return;
peernick_data *data = (peernick_data *)contents;
size_t i;
for (i = 0; i < chat->numpeers; i++)
if (id_equal(chat->group[i].client_id, data->client_id)) {
uint16_t nick_len = contents_len - CLIENT_ID_SIZE;
memcpy(chat->group[i].nick, data->nickname, nick_len);
chat->group[i].nick_len = nick_len;
return;
}
}
/* min time between pings sent to one peer in seconds */ /* min time between pings sent to one peer in seconds */
/* TODO: move this to global section */ /* TODO: move this to global section */
@ -289,7 +316,8 @@ static int send_getnodes(Group_Chat *chat, IP_Port ip_port, int peernum)
chat->group[peernum].last_pinged = unix_time(); chat->group[peernum].last_pinged = unix_time();
chat->group[peernum].pingid = contents.pingid; chat->group[peernum].pingid = contents.pingid;
return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), CRYPTO_PACKET_GROUP_CHAT_GET_NODES); return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents),
CRYPTO_PACKET_GROUP_CHAT_GET_NODES);
} }
static int send_sendnodes(Group_Chat *chat, IP_Port ip_port, int peernum, uint64_t pingid) static int send_sendnodes(Group_Chat *chat, IP_Port ip_port, int peernum, uint64_t pingid)
@ -428,6 +456,13 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
addpeer(chat, contents); addpeer(chat, contents);
break; break;
case GROUP_CHAT_PEER_NICK:
if (contents_len < crypto_box_PUBLICKEYBYTES)
return 1;
setnick(chat, contents, contents_len);
break;
case GROUP_CHAT_CHAT_MESSAGE: /* If message is chat message */ case GROUP_CHAT_CHAT_MESSAGE: /* If message is chat message */
if (chat->group_message != NULL) if (chat->group_message != NULL)
(*chat->group_message)(chat, peernum, contents, contents_len, chat->group_message_userdata); (*chat->group_message)(chat, peernum, contents, contents_len, chat->group_message_userdata);
@ -520,6 +555,18 @@ uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length)
return send_data(chat, message, length, GROUP_CHAT_CHAT_MESSAGE); //TODO: better return values? return send_data(chat, message, length, GROUP_CHAT_CHAT_MESSAGE); //TODO: better return values?
} }
uint32_t group_send_nick(Group_Chat *chat, uint8_t *client_id, uint8_t *nick, uint16_t nick_len)
{
peernick_data peernick;
id_copy(peernick.client_id, client_id);
memcpy(peernick.nickname, nick, nick_len);
/* also set for self */
setnick(chat, (uint8_t *)&peernick, sizeof(peernick.client_id) + nick_len);
return send_data(chat, (uint8_t *)&peernick, sizeof(peernick.client_id) + nick_len, GROUP_CHAT_PEER_NICK);
}
uint32_t group_newpeer(Group_Chat *chat, uint8_t *client_id) uint32_t group_newpeer(Group_Chat *chat, uint8_t *client_id)
{ {
addpeer(chat, client_id); addpeer(chat, client_id);
@ -553,7 +600,6 @@ static void ping_close(Group_Chat *chat)
uint32_t i; uint32_t i;
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
/* previous condition was always true, assuming this is the wanted one: */
if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) { if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
int peernum = peer_in_chat(chat, chat->close[i].client_id); int peernum = peer_in_chat(chat, chat->close[i].client_id);
@ -580,8 +626,9 @@ static void ping_group(Group_Chat *chat)
static void del_dead_peers(Group_Chat *chat) static void del_dead_peers(Group_Chat *chat)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < chat->numpeers; ++i) { for (i = 0; i < chat->numpeers; ++i) {
if (is_timeout(chat->group[i].last_recv_msgping, GROUP_PING_INTERVAL*2)) { if (is_timeout(chat->group[i].last_recv_msgping, GROUP_PING_INTERVAL * 2)) {
delpeer(chat, chat->group[i].client_id); delpeer(chat, chat->group[i].client_id);
} }
} }

View File

@ -63,12 +63,15 @@ typedef struct Group_Chat {
uint32_t message_number; uint32_t message_number;
void (*group_message)(struct Group_Chat *m, int, uint8_t *, uint16_t, void *); void (*group_message)(struct Group_Chat *m, int, uint8_t *, uint16_t, void *);
void *group_message_userdata; void *group_message_userdata;
uint64_t last_sent_ping; uint64_t last_sent_ping;
uint64_t last_sent_nick;
} Group_Chat; } Group_Chat;
#define GROUP_CHAT_PING 0 #define GROUP_CHAT_PING 0
#define GROUP_CHAT_NEW_PEER 16 #define GROUP_CHAT_NEW_PEER 16
#define GROUP_CHAT_PEER_NICK 17
#define GROUP_CHAT_CHAT_MESSAGE 64 #define GROUP_CHAT_CHAT_MESSAGE 64
/* Copy the name of peernum to name. /* Copy the name of peernum to name.
@ -95,6 +98,12 @@ void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat,
*/ */
uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length); uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length);
/*
* Send id/nick combo to the group.
*
* returns the number of peers it has sent it to.
*/
uint32_t group_send_nick(Group_Chat *chat, uint8_t *client_id, uint8_t *nick, uint16_t nick_len);
/* /*
* Tell everyone about a new peer (a person we are inviting for example.) * Tell everyone about a new peer (a person we are inviting for example.)