diff options
Diffstat (limited to 'toxcore/group_chats.c')
-rw-r--r-- | toxcore/group_chats.c | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 9275d63e..60026eed 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c | |||
@@ -53,6 +53,11 @@ typedef struct { | |||
53 | 53 | ||
54 | } sendnodes_data; | 54 | } sendnodes_data; |
55 | 55 | ||
56 | typedef struct { | ||
57 | uint8_t client_id[crypto_box_PUBLICKEYBYTES]; | ||
58 | uint8_t nickname[MAX_NICK_BYTES]; | ||
59 | } peernick_data; | ||
60 | |||
56 | 61 | ||
57 | /* | 62 | /* |
58 | * check if peer with client_id is in peer array. | 63 | * check if peer with client_id is in peer array. |
@@ -211,10 +216,12 @@ static int addpeer(Group_Chat *chat, uint8_t *client_id) | |||
211 | 216 | ||
212 | memset(&(temp[chat->numpeers]), 0, sizeof(Group_Peer)); | 217 | memset(&(temp[chat->numpeers]), 0, sizeof(Group_Peer)); |
213 | chat->group = temp; | 218 | chat->group = temp; |
219 | |||
214 | id_copy(chat->group[chat->numpeers].client_id, client_id); | 220 | id_copy(chat->group[chat->numpeers].client_id, client_id); |
215 | chat->group[chat->numpeers].last_recv = unix_time(); | 221 | chat->group[chat->numpeers].last_recv = unix_time(); |
216 | chat->group[chat->numpeers].last_recv_msgping = unix_time(); | 222 | chat->group[chat->numpeers].last_recv_msgping = unix_time(); |
217 | ++chat->numpeers; | 223 | ++chat->numpeers; |
224 | |||
218 | return (chat->numpeers - 1); | 225 | return (chat->numpeers - 1); |
219 | } | 226 | } |
220 | 227 | ||
@@ -262,14 +269,34 @@ int group_peername(Group_Chat *chat, int peernum, uint8_t *name) | |||
262 | return -1; | 269 | return -1; |
263 | 270 | ||
264 | if (chat->group[peernum].nick_len == 0) { | 271 | if (chat->group[peernum].nick_len == 0) { |
265 | memcpy(name, "NSA Agent", 10); /* Kindly remind the user that someone with no name might be an NSA agent.*/ | 272 | /* memcpy(name, "NSA agent", 10); */ /* Srsly? */ /* Kindly remind the user that someone with no name might be a moronic NSA agent.*/ |
266 | return 10; | 273 | name[0] = 0; |
274 | return 0; | ||
267 | } | 275 | } |
268 | 276 | ||
269 | memcpy(name, chat->group[peernum].nick, chat->group[peernum].nick_len); | 277 | memcpy(name, chat->group[peernum].nick, chat->group[peernum].nick_len); |
270 | return chat->group[peernum].nick_len; | 278 | return chat->group[peernum].nick_len; |
271 | } | 279 | } |
272 | 280 | ||
281 | static void setnick(Group_Chat *chat, uint8_t *contents, uint16_t contents_len) | ||
282 | { | ||
283 | if (contents_len > CLIENT_ID_SIZE + MAX_NICK_BYTES) | ||
284 | return; | ||
285 | |||
286 | peernick_data *data = (peernick_data *)contents; | ||
287 | |||
288 | size_t i; | ||
289 | |||
290 | for (i = 0; i < chat->numpeers; i++) | ||
291 | if (id_equal(chat->group[i].client_id, data->client_id)) { | ||
292 | uint16_t nick_len = contents_len - CLIENT_ID_SIZE; | ||
293 | |||
294 | memcpy(chat->group[i].nick, data->nickname, nick_len); | ||
295 | chat->group[i].nick_len = nick_len; | ||
296 | |||
297 | return; | ||
298 | } | ||
299 | } | ||
273 | 300 | ||
274 | /* min time between pings sent to one peer in seconds */ | 301 | /* min time between pings sent to one peer in seconds */ |
275 | /* TODO: move this to global section */ | 302 | /* TODO: move this to global section */ |
@@ -289,7 +316,8 @@ static int send_getnodes(Group_Chat *chat, IP_Port ip_port, int peernum) | |||
289 | chat->group[peernum].last_pinged = unix_time(); | 316 | chat->group[peernum].last_pinged = unix_time(); |
290 | chat->group[peernum].pingid = contents.pingid; | 317 | chat->group[peernum].pingid = contents.pingid; |
291 | 318 | ||
292 | return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), CRYPTO_PACKET_GROUP_CHAT_GET_NODES); | 319 | return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), |
320 | CRYPTO_PACKET_GROUP_CHAT_GET_NODES); | ||
293 | } | 321 | } |
294 | 322 | ||
295 | static int send_sendnodes(Group_Chat *chat, IP_Port ip_port, int peernum, uint64_t pingid) | 323 | 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) | |||
428 | addpeer(chat, contents); | 456 | addpeer(chat, contents); |
429 | break; | 457 | break; |
430 | 458 | ||
459 | case GROUP_CHAT_PEER_NICK: | ||
460 | if (contents_len < crypto_box_PUBLICKEYBYTES) | ||
461 | return 1; | ||
462 | |||
463 | setnick(chat, contents, contents_len); | ||
464 | break; | ||
465 | |||
431 | case GROUP_CHAT_CHAT_MESSAGE: /* If message is chat message */ | 466 | case GROUP_CHAT_CHAT_MESSAGE: /* If message is chat message */ |
432 | if (chat->group_message != NULL) | 467 | if (chat->group_message != NULL) |
433 | (*chat->group_message)(chat, peernum, contents, contents_len, chat->group_message_userdata); | 468 | (*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) | |||
520 | return send_data(chat, message, length, GROUP_CHAT_CHAT_MESSAGE); //TODO: better return values? | 555 | return send_data(chat, message, length, GROUP_CHAT_CHAT_MESSAGE); //TODO: better return values? |
521 | } | 556 | } |
522 | 557 | ||
558 | uint32_t group_send_nick(Group_Chat *chat, uint8_t *client_id, uint8_t *nick, uint16_t nick_len) | ||
559 | { | ||
560 | peernick_data peernick; | ||
561 | id_copy(peernick.client_id, client_id); | ||
562 | memcpy(peernick.nickname, nick, nick_len); | ||
563 | |||
564 | /* also set for self */ | ||
565 | setnick(chat, (uint8_t *)&peernick, sizeof(peernick.client_id) + nick_len); | ||
566 | |||
567 | return send_data(chat, (uint8_t *)&peernick, sizeof(peernick.client_id) + nick_len, GROUP_CHAT_PEER_NICK); | ||
568 | } | ||
569 | |||
523 | uint32_t group_newpeer(Group_Chat *chat, uint8_t *client_id) | 570 | uint32_t group_newpeer(Group_Chat *chat, uint8_t *client_id) |
524 | { | 571 | { |
525 | addpeer(chat, client_id); | 572 | addpeer(chat, client_id); |
@@ -553,7 +600,6 @@ static void ping_close(Group_Chat *chat) | |||
553 | uint32_t i; | 600 | uint32_t i; |
554 | 601 | ||
555 | for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { | 602 | for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { |
556 | /* previous condition was always true, assuming this is the wanted one: */ | ||
557 | if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) { | 603 | if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) { |
558 | int peernum = peer_in_chat(chat, chat->close[i].client_id); | 604 | int peernum = peer_in_chat(chat, chat->close[i].client_id); |
559 | 605 | ||
@@ -580,8 +626,9 @@ static void ping_group(Group_Chat *chat) | |||
580 | static void del_dead_peers(Group_Chat *chat) | 626 | static void del_dead_peers(Group_Chat *chat) |
581 | { | 627 | { |
582 | uint32_t i; | 628 | uint32_t i; |
629 | |||
583 | for (i = 0; i < chat->numpeers; ++i) { | 630 | for (i = 0; i < chat->numpeers; ++i) { |
584 | if (is_timeout(chat->group[i].last_recv_msgping, GROUP_PING_INTERVAL*2)) { | 631 | if (is_timeout(chat->group[i].last_recv_msgping, GROUP_PING_INTERVAL * 2)) { |
585 | delpeer(chat, chat->group[i].client_id); | 632 | delpeer(chat, chat->group[i].client_id); |
586 | } | 633 | } |
587 | } | 634 | } |