summaryrefslogtreecommitdiff
path: root/toxav/rtp.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-06-28 22:29:39 -0400
committerirungentoo <irungentoo@gmail.com>2014-06-28 22:29:39 -0400
commitbd6f8a2186d73df531552457840d2260339f14b3 (patch)
tree4489b6d101b878a5f6782253cd801223a7a75806 /toxav/rtp.c
parentf4330658753e2ef01dfb32b0cebfe2b8d3cabfc9 (diff)
parentaeaf997ca57052a1589699c8ddfd9a75ca398180 (diff)
Merge branch 'mannol1-master'
Diffstat (limited to 'toxav/rtp.c')
-rw-r--r--toxav/rtp.c222
1 files changed, 54 insertions, 168 deletions
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 1b18777f..e3c1c148 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -27,7 +27,6 @@
27#include "../toxcore/util.h" 27#include "../toxcore/util.h"
28 28
29#include "rtp.h" 29#include "rtp.h"
30#include <assert.h>
31#include <stdlib.h> 30#include <stdlib.h>
32 31
33 32
@@ -50,7 +49,6 @@
50#define GET_SETTING_MARKER(_h) (( _h->marker_payloadt ) >> 7) 49#define GET_SETTING_MARKER(_h) (( _h->marker_payloadt ) >> 7)
51#define GET_SETTING_PAYLOAD(_h) ((_h->marker_payloadt) & 0x7f) 50#define GET_SETTING_PAYLOAD(_h) ((_h->marker_payloadt) & 0x7f)
52 51
53
54/** 52/**
55 * @brief Checks if message came in late. 53 * @brief Checks if message came in late.
56 * 54 *
@@ -70,46 +68,6 @@ inline__ int check_late_message (RTPSession *session, RTPMessage *msg)
70 return ( msg->header->sequnum < session->rsequnum && msg->header->timestamp < session->timestamp ) ? 0 : -1; 68 return ( msg->header->sequnum < session->rsequnum && msg->header->timestamp < session->timestamp ) ? 0 : -1;
71} 69}
72 70
73
74/**
75 * @brief Increases nonce value by 'target'
76 *
77 * @param nonce The nonce
78 * @param target The target
79 * @return void
80 */
81inline__ void increase_nonce(uint8_t *nonce, uint16_t target)
82{
83 uint16_t _nonce_counter;
84
85 uint8_t _reverse_bytes[2];
86 _reverse_bytes[0] = nonce[crypto_box_NONCEBYTES - 1];
87 _reverse_bytes[1] = nonce[crypto_box_NONCEBYTES - 2];
88
89 bytes_to_U16(&_nonce_counter, _reverse_bytes );
90
91 /* Check overflow */
92 if (_nonce_counter > UINT16_MAX - target ) { /* 2 bytes are not long enough */
93 uint8_t _it = 3;
94
95 while ( _it <= crypto_box_NONCEBYTES ) _it += ++nonce[crypto_box_NONCEBYTES - _it] ?
96 crypto_box_NONCEBYTES : 1;
97
98 _nonce_counter = _nonce_counter - (UINT16_MAX - target ); /* Assign the rest of it */
99 } else { /* Increase nonce */
100
101 _nonce_counter += target;
102 }
103
104 /* Assign the last bytes */
105
106 U16_to_bytes( _reverse_bytes, _nonce_counter);
107 nonce [crypto_box_NONCEBYTES - 1] = _reverse_bytes[0];
108 nonce [crypto_box_NONCEBYTES - 2] = _reverse_bytes[1];
109
110}
111
112
113/** 71/**
114 * @brief Speaks for it self. 72 * @brief Speaks for it self.
115 * 73 *
@@ -146,10 +104,16 @@ RTPHeader *extract_header ( const uint8_t *payload, int length )
146 return NULL; 104 return NULL;
147 } 105 }
148 106
149 const uint8_t *_it = payload;
150
151 RTPHeader *_retu = calloc(1, sizeof (RTPHeader)); 107 RTPHeader *_retu = calloc(1, sizeof (RTPHeader));
152 assert(_retu); 108
109 if ( !_retu ) {
110 LOGGER_WARNING("Alloc failed! Program might misbehave!");
111 return NULL;
112 }
113
114 bytes_to_U16(&_retu->sequnum, payload);
115
116 const uint8_t *_it = payload + 2;
153 117
154 _retu->flags = *_it; 118 _retu->flags = *_it;
155 ++_it; 119 ++_it;
@@ -214,7 +178,11 @@ RTPExtHeader *extract_ext_header ( const uint8_t *payload, uint16_t length )
214 const uint8_t *_it = payload; 178 const uint8_t *_it = payload;
215 179
216 RTPExtHeader *_retu = calloc(1, sizeof (RTPExtHeader)); 180 RTPExtHeader *_retu = calloc(1, sizeof (RTPExtHeader));
217 assert(_retu); 181
182 if ( !_retu ) {
183 LOGGER_WARNING("Alloc failed! Program might misbehave!");
184 return NULL;
185 }
218 186
219 uint16_t _ext_length; 187 uint16_t _ext_length;
220 bytes_to_U16(&_ext_length, _it); 188 bytes_to_U16(&_ext_length, _it);
@@ -231,8 +199,11 @@ RTPExtHeader *extract_ext_header ( const uint8_t *payload, uint16_t length )
231 bytes_to_U16(&_retu->type, _it); 199 bytes_to_U16(&_retu->type, _it);
232 _it += 2; 200 _it += 2;
233 201
234 _retu->table = calloc(_ext_length, sizeof (uint32_t)); 202 if ( !(_retu->table = calloc(_ext_length, sizeof (uint32_t))) ) {
235 assert(_retu->table); 203 LOGGER_WARNING("Alloc failed! Program might misbehave!");
204 free(_retu);
205 return NULL;
206 }
236 207
237 uint16_t _x; 208 uint16_t _x;
238 209
@@ -319,7 +290,11 @@ uint8_t *add_ext_header ( RTPExtHeader *header, uint8_t *payload )
319RTPHeader *build_header ( RTPSession *session ) 290RTPHeader *build_header ( RTPSession *session )
320{ 291{
321 RTPHeader *_retu = calloc ( 1, sizeof (RTPHeader) ); 292 RTPHeader *_retu = calloc ( 1, sizeof (RTPHeader) );
322 assert(_retu); 293
294 if ( !_retu ) {
295 LOGGER_WARNING("Alloc failed! Program might misbehave!");
296 return NULL;
297 }
323 298
324 ADD_FLAG_VERSION ( _retu, session->version ); 299 ADD_FLAG_VERSION ( _retu, session->version );
325 ADD_FLAG_PADDING ( _retu, session->padding ); 300 ADD_FLAG_PADDING ( _retu, session->padding );
@@ -355,7 +330,7 @@ RTPHeader *build_header ( RTPSession *session )
355 * @return RTPMessage* 330 * @return RTPMessage*
356 * @retval NULL Error occurred. 331 * @retval NULL Error occurred.
357 */ 332 */
358RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length ) 333RTPMessage *msg_parse ( const uint8_t *data, int length )
359{ 334{
360 RTPMessage *_retu = calloc(1, sizeof (RTPMessage)); 335 RTPMessage *_retu = calloc(1, sizeof (RTPMessage));
361 336
@@ -367,11 +342,9 @@ RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length )
367 return NULL; 342 return NULL;
368 } 343 }
369 344
370 _retu->header->sequnum = sequnum; 345 uint16_t _from_pos = _retu->header->length;
371 346 _retu->length = length - _from_pos;
372 _retu->length = length - _retu->header->length;
373 347
374 uint16_t _from_pos = _retu->header->length - 2 /* Since sequ num is excluded */ ;
375 348
376 349
377 if ( GET_FLAG_EXTENSION ( _retu->header ) ) { 350 if ( GET_FLAG_EXTENSION ( _retu->header ) ) {
@@ -418,7 +391,7 @@ int rtp_handle_packet ( void *object, uint8_t *data, uint32_t length )
418 RTPSession *_session = object; 391 RTPSession *_session = object;
419 RTPMessage *_msg; 392 RTPMessage *_msg;
420 393
421 if ( !_session || length < 13 + crypto_box_MACBYTES) { /* 12 is the minimum length for rtp + desc. byte */ 394 if ( !_session || length < 13 ) { /* 12 is the minimum length for rtp + desc. byte */
422 LOGGER_WARNING("No session or invalid length of received buffer!"); 395 LOGGER_WARNING("No session or invalid length of received buffer!");
423 return -1; 396 return -1;
424 } 397 }
@@ -428,55 +401,7 @@ int rtp_handle_packet ( void *object, uint8_t *data, uint32_t length )
428 return -1; 401 return -1;
429 } 402 }
430 403
431 uint8_t _plain[MAX_UDP_PACKET_SIZE]; 404 _msg = msg_parse ( data + 1, length - 1 );
432
433 uint16_t _sequnum;
434 bytes_to_U16(&_sequnum, data + 1);
435
436 /* Clculate the right nonce */
437 uint8_t _calculated[crypto_box_NONCEBYTES];
438 memcpy(_calculated, _session->decrypt_nonce, crypto_box_NONCEBYTES);
439 increase_nonce ( _calculated, _sequnum );
440
441 /* Decrypt message */
442 int _decrypted_length = decrypt_data_symmetric(
443 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
444
445 /* This packet is either not encrypted properly or late
446 */
447 if ( -1 == _decrypted_length ) {
448
449 /* If this is the case, then the packet is most likely late.
450 * Try with old nonce cycle.
451 */
452 if ( _session->rsequnum < _sequnum ) {
453 _decrypted_length = decrypt_data_symmetric(
454 (uint8_t *)_session->decrypt_key, _session->nonce_cycle, data + 3, length - 3, _plain );
455
456 if ( _decrypted_length == -1 ) {
457 LOGGER_WARNING("Packet not ecrypted properly!");
458 return -1; /* This packet is not encrypted properly */
459 }
460
461 /* Otherwise, if decryption is ok with new cycle, set new cycle
462 */
463 } else {
464 increase_nonce ( _calculated, MAX_SEQU_NUM );
465 _decrypted_length = decrypt_data_symmetric(
466 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
467
468 if ( _decrypted_length == -1 ) {
469 LOGGER_WARNING("Error decrypting!");
470 return -1; /* This is just an error */
471 }
472
473 /* A new cycle setting. */
474 memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_box_NONCEBYTES);
475 memcpy(_session->decrypt_nonce, _calculated, crypto_box_NONCEBYTES);
476 }
477 }
478
479 _msg = msg_parse ( _sequnum, _plain, _decrypted_length );
480 405
481 if ( !_msg ) { 406 if ( !_msg ) {
482 LOGGER_WARNING("Could not parse message!"); 407 LOGGER_WARNING("Could not parse message!");
@@ -526,22 +451,28 @@ RTPMessage *rtp_new_message ( RTPSession *session, const uint8_t *data, uint32_t
526 451
527 uint8_t *_from_pos; 452 uint8_t *_from_pos;
528 RTPMessage *_retu = calloc(1, sizeof (RTPMessage)); 453 RTPMessage *_retu = calloc(1, sizeof (RTPMessage));
529 assert(_retu); 454
455 if ( !_retu ) {
456 LOGGER_WARNING("Alloc failed! Program might misbehave!");
457 return NULL;
458 }
530 459
531 /* Sets header values and copies the extension header in _retu */ 460 /* Sets header values and copies the extension header in _retu */
532 _retu->header = build_header ( session ); /* It allocates memory and all */ 461 _retu->header = build_header ( session ); /* It allocates memory and all */
533 _retu->ext_header = session->ext_header; 462 _retu->ext_header = session->ext_header;
534 463
535 464
536 uint32_t _total_length = length + _retu->header->length; 465 uint32_t _total_length = length + _retu->header->length + 1;
466
467 _retu->data[0] = session->prefix;
537 468
538 if ( _retu->ext_header ) { 469 if ( _retu->ext_header ) {
539 _total_length += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 ); 470 _total_length += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
540 471
541 _from_pos = add_header ( _retu->header, _retu->data ); 472 _from_pos = add_header ( _retu->header, _retu->data + 1 );
542 _from_pos = add_ext_header ( _retu->ext_header, _from_pos + 1 ); 473 _from_pos = add_ext_header ( _retu->ext_header, _from_pos + 1 );
543 } else { 474 } else {
544 _from_pos = add_header ( _retu->header, _retu->data ); 475 _from_pos = add_header ( _retu->header, _retu->data + 1 );
545 } 476 }
546 477
547 /* 478 /*
@@ -679,25 +610,7 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
679 return -1; 610 return -1;
680 } 611 }
681 612
682 uint8_t _send_data [ MAX_UDP_PACKET_SIZE ]; 613 if ( -1 == send_custom_lossy_packet(messenger, session->dest, msg->data, msg->length) ) {
683
684 _send_data[0] = session->prefix;
685
686 /* Generate the right nonce */
687 uint8_t _calculated[crypto_box_NONCEBYTES];
688 memcpy(_calculated, session->encrypt_nonce, crypto_box_NONCEBYTES);
689 increase_nonce ( _calculated, msg->header->sequnum );
690
691 /* Need to skip 2 bytes that are for sequnum */
692 int encrypted_length = encrypt_data_symmetric( /* TODO: msg->length - 2 (fix this properly)*/
693 (uint8_t *) session->encrypt_key, _calculated, msg->data + 2, msg->length, _send_data + 3 );
694
695
696 _send_data[1] = msg->data[0];
697 _send_data[2] = msg->data[1];
698
699
700 if ( -1 == send_custom_lossy_packet(messenger, session->dest, _send_data, encrypted_length + 3) ) {
701 LOGGER_WARNING("Failed to send full packet! std error: %s", strerror(errno)); 614 LOGGER_WARNING("Failed to send full packet! std error: %s", strerror(errno));
702 rtp_free_msg ( session, msg ); 615 rtp_free_msg ( session, msg );
703 return -1; 616 return -1;
@@ -705,13 +618,7 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
705 618
706 619
707 /* Set sequ number */ 620 /* Set sequ number */
708 if ( session->sequnum >= MAX_SEQU_NUM ) { 621 session->sequnum = session->sequnum >= MAX_SEQU_NUM ? 0 : session->sequnum + 1;
709 session->sequnum = 0;
710 memcpy(session->encrypt_nonce, _calculated, crypto_box_NONCEBYTES);
711 } else {
712 session->sequnum++;
713 }
714
715 rtp_free_msg ( session, msg ); 622 rtp_free_msg ( session, msg );
716 623
717 return 0; 624 return 0;
@@ -752,26 +659,19 @@ void rtp_free_msg ( RTPSession *session, RTPMessage *msg )
752 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType 659 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType
753 * @param messenger Tox* object. 660 * @param messenger Tox* object.
754 * @param friend_num Friend id. 661 * @param friend_num Friend id.
755 * @param encrypt_key Speaks for it self.
756 * @param decrypt_key Speaks for it self.
757 * @param encrypt_nonce Speaks for it self.
758 * @param decrypt_nonce Speaks for it self.
759 * @return RTPSession* Created control session. 662 * @return RTPSession* Created control session.
760 * @retval NULL Error occurred. 663 * @retval NULL Error occurred.
761 */ 664 */
762RTPSession *rtp_init_session ( int payload_type, 665RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int friend_num )
763 Messenger *messenger,
764 int friend_num,
765 const uint8_t *encrypt_key,
766 const uint8_t *decrypt_key,
767 const uint8_t *encrypt_nonce,
768 const uint8_t *decrypt_nonce )
769{ 666{
770 RTPSession *_retu = calloc(1, sizeof(RTPSession)); 667 RTPSession *_retu = calloc(1, sizeof(RTPSession));
771 assert(_retu);
772 668
773 if ( -1 == custom_lossy_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, _retu) || 669 if ( !_retu ) {
774 !encrypt_key || !decrypt_key || !encrypt_nonce || !decrypt_nonce) { 670 LOGGER_WARNING("Alloc failed! Program might misbehave!");
671 return NULL;
672 }
673
674 if ( -1 == custom_lossy_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, _retu)) {
775 LOGGER_ERROR("Error setting custom register handler for rtp session"); 675 LOGGER_ERROR("Error setting custom register handler for rtp session");
776 free(_retu); 676 free(_retu);
777 return NULL; 677 return NULL;
@@ -794,23 +694,12 @@ RTPSession *rtp_init_session ( int payload_type,
794 694
795 _retu->ext_header = NULL; /* When needed allocate */ 695 _retu->ext_header = NULL; /* When needed allocate */
796 696
797 _retu->encrypt_key = encrypt_key;
798 _retu->decrypt_key = decrypt_key;
799
800 /* Need to allocate new memory */
801 _retu->encrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
802 assert(_retu->encrypt_nonce);
803 _retu->decrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
804 assert(_retu->decrypt_nonce);
805 _retu->nonce_cycle = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
806 assert(_retu->nonce_cycle);
807
808 memcpy(_retu->encrypt_nonce, encrypt_nonce, crypto_box_NONCEBYTES);
809 memcpy(_retu->decrypt_nonce, decrypt_nonce, crypto_box_NONCEBYTES);
810 memcpy(_retu->nonce_cycle , decrypt_nonce, crypto_box_NONCEBYTES);
811 697
812 _retu->csrc = calloc(1, sizeof (uint32_t)); 698 if ( !(_retu->csrc = calloc(1, sizeof (uint32_t))) ) {
813 assert(_retu->csrc); 699 LOGGER_WARNING("Alloc failed! Program might misbehave!");
700 free(_retu);
701 return NULL;
702 }
814 703
815 _retu->csrc[0] = _retu->ssrc; /* Set my ssrc to the list receive */ 704 _retu->csrc[0] = _retu->ssrc; /* Set my ssrc to the list receive */
816 705
@@ -853,9 +742,6 @@ int rtp_terminate_session ( RTPSession *session, Messenger *messenger )
853 742
854 free ( session->ext_header ); 743 free ( session->ext_header );
855 free ( session->csrc ); 744 free ( session->csrc );
856 free ( session->decrypt_nonce );
857 free ( session->encrypt_nonce );
858 free ( session->nonce_cycle );
859 745
860 pthread_mutex_unlock(&session->mutex); 746 pthread_mutex_unlock(&session->mutex);
861 747
@@ -865,4 +751,4 @@ int rtp_terminate_session ( RTPSession *session, Messenger *messenger )
865 free ( session ); 751 free ( session );
866 752
867 return 0; 753 return 0;
868} 754} \ No newline at end of file