From f818c1a197cdd40145868be97c0472e150c563bb Mon Sep 17 00:00:00 2001 From: irungentoo Date: Wed, 21 May 2014 15:28:14 -0400 Subject: Added functions to send and receive lossy encrypted packets over the Tox connection. A/V should now work over TCP. --- toxav/msi.h | 2 +- toxav/rtp.c | 7 +----- toxav/rtp.h | 1 - toxcore/Messenger.c | 46 +++++++++++++--------------------- toxcore/Messenger.h | 9 ++++--- toxcore/net_crypto.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++--- toxcore/net_crypto.h | 36 ++++++++++++++++++++++++--- toxcore/network.h | 6 ----- 8 files changed, 125 insertions(+), 52 deletions(-) diff --git a/toxav/msi.h b/toxav/msi.h index 39a9c792..052126d2 100755 --- a/toxav/msi.h +++ b/toxav/msi.h @@ -40,7 +40,7 @@ typedef void ( *MSICallback ) ( void *arg ); * @brief Call type identifier. Also used as rtp callback prefix. */ typedef enum { - type_audio = 70, + type_audio = 192, type_video } MSICallType; diff --git a/toxav/rtp.c b/toxav/rtp.c index 9462a467..d4aa5476 100755 --- a/toxav/rtp.c +++ b/toxav/rtp.c @@ -491,7 +491,7 @@ RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length ) * @retval -1 Error occurred. * @retval 0 Success. */ -int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t length ) +int rtp_handle_packet ( void *object, uint8_t *data, uint32_t length ) { RTPSession *_session = object; RTPMessage *_msg; @@ -545,11 +545,6 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l if ( !_msg ) return -1; - /* Hopefully this goes well - * NOTE: Is this even used? - */ - memcpy(&_msg->from, &ip_port, sizeof(IP_Port)); - /* Check if message came in late */ if ( check_late_message(_session, _msg) < 0 ) { /* Not late */ _session->rsequnum = _msg->header->sequnum; diff --git a/toxav/rtp.h b/toxav/rtp.h index 58b16ab1..40532391 100755 --- a/toxav/rtp.h +++ b/toxav/rtp.h @@ -75,7 +75,6 @@ typedef struct _RTPMessage { uint8_t data[MAX_RTP_SIZE]; uint32_t length; - IP_Port from; struct _RTPMessage *next; } RTPMessage; diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 1e6e6c06..aefa3a68 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1699,46 +1699,35 @@ int m_msi_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t len return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length); } -static int32_t friendnum_from_ip_port(Messenger *m, IP_Port ip_port) -{ - uint32_t i; - - for (i = 0; i < m->numonline_friends; ++i) { - if (ipport_equal(&m->online_friendlist[i].ip_port, &ip_port)) - return m->online_friendlist[i].friend_num; - } - - return -1; -} - -static int handle_custom_user_packet(void *object, IP_Port source, uint8_t *packet, uint32_t length) +static int handle_custom_user_packet(void *object, int friend_num, uint8_t *packet, uint16_t length) { Messenger *m = object; - int32_t friend_num = friendnum_from_ip_port(m, source); - if (friend_num == -1) + if (friend_not_valid(m, friend_num)) return 1; - if (m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].function) - return m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].function( - m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].object, source, packet, length); + if (m->friendlist[friend_num].packethandlers[packet[0] % PACKET_ID_LOSSY_RANGE_SIZE].function) + return m->friendlist[friend_num].packethandlers[packet[0] % PACKET_ID_LOSSY_RANGE_SIZE].function( + m->friendlist[friend_num].packethandlers[packet[0] % PACKET_ID_LOSSY_RANGE_SIZE].object, packet, length); return 1; } -int custom_user_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, packet_handler_callback cb, - void *object) +int custom_user_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, + int (*packet_handler_callback)(void *object, uint8_t *data, uint32_t len), void *object) { if (friend_not_valid(m, friendnumber)) return -1; - if (byte < NET_PACKET_CUSTOM_RANGE_START || byte >= NET_PACKET_CUSTOM_RANGE_END) + if (byte < PACKET_ID_LOSSY_RANGE_START) + return -1; + + if (byte >= (PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE)) return -1; - m->friendlist[friendnumber].packethandlers[byte % TOTAL_USERPACKETS].function = cb; - m->friendlist[friendnumber].packethandlers[byte % TOTAL_USERPACKETS].object = object; - networking_registerhandler(m->net, byte, handle_custom_user_packet, m); + m->friendlist[friendnumber].packethandlers[byte % PACKET_ID_LOSSY_RANGE_SIZE].function = packet_handler_callback; + m->friendlist[friendnumber].packethandlers[byte % PACKET_ID_LOSSY_RANGE_SIZE].object = object; return 0; } @@ -1750,12 +1739,10 @@ int send_custom_user_packet(Messenger *m, int32_t friendnumber, uint8_t *data, u if (m->friendlist[friendnumber].status != FRIEND_ONLINE) return -1; - IP_Port ip_port = get_friend_ipport(m, friendnumber); - - if (ip_port.port == 0) + if (m->friendlist[friendnumber].crypt_connection_id == -1) return -1; - return sendpacket(m->net, ip_port, data, length); + return send_lossy_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, data, length); } @@ -1794,6 +1781,7 @@ static int handle_new_connections(void *object, New_Connection *n_c) int id = accept_crypto_connection(m->net_crypto, n_c); connection_status_handler(m->net_crypto, id, &handle_status, m, friend_id); connection_data_handler(m->net_crypto, id, &handle_packet, m, friend_id); + connection_lossy_data_handler(m->net_crypto, id, &handle_custom_user_packet, m, friend_id); m->friendlist[friend_id].crypt_connection_id = id; set_friend_status(m, friend_id, FRIEND_CONFIRMED); return 0; @@ -2218,8 +2206,8 @@ static int friend_new_connection(Messenger *m, int32_t friendnumber, uint8_t *re m->friendlist[friendnumber].crypt_connection_id = id; connection_status_handler(m->net_crypto, id, &handle_status, m, friendnumber); connection_data_handler(m->net_crypto, id, &handle_packet, m, friendnumber); + connection_lossy_data_handler(m->net_crypto, id, &handle_custom_user_packet, m, friendnumber); return 0; - } /* TODO: Make this function not suck. */ diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index fb070607..e9447977 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -167,7 +167,10 @@ typedef struct { int invited_groups[MAX_INVITED_GROUPS]; uint16_t invited_groups_num; - Packet_Handles packethandlers[TOTAL_USERPACKETS]; + struct { + int (*function)(void *object, uint8_t *data, uint32_t len); + void *object; + } packethandlers[PACKET_ID_LOSSY_RANGE_SIZE]; } Friend; typedef struct { @@ -697,8 +700,8 @@ int m_msi_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t len * return -1 on failure. * return 0 on success. */ -int custom_user_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, packet_handler_callback cb, - void *object); +int custom_user_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, + int (*packet_handler_callback)(void *object, uint8_t *data, uint32_t len), void *object); /* High level function to send custom user packets. * diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 875c639f..2269e041 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1079,7 +1079,7 @@ static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uin } else if (real_data[0] == PACKET_ID_KILL) { conn->killed = 1; return 0; - } else { + } else if (real_data[0] >= CRYPTO_RESERVED_PACKETS && real_data[0] < PACKET_ID_LOSSY_RANGE_START) { Packet_Data dt; dt.time = current_time_monotonic(); dt.length = real_length; @@ -1096,6 +1096,16 @@ static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uin /* Packet counter. */ ++conn->packet_counter; + } else if (real_data[0] >= PACKET_ID_LOSSY_RANGE_START && + real_data[0] < (PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE)) { + + if (conn->connection_lossy_data_callback) + conn->connection_lossy_data_callback(conn->connection_lossy_data_callback_object, + conn->connection_lossy_data_callback_id, real_data, real_length); + + set_buffer_end(&conn->recv_array, num); + } else { + return -1; } if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { @@ -2050,6 +2060,28 @@ int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connec return 0; } +/* Set function to be called when connection with crypt_connection_id receives a lossy data packet of length. + * + * The set function should return -1 on failure and 0 on success. + * Object and id will be passed to this function untouched. + * + * return -1 on failure. + * return 0 on success. + */ +int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, + int (*connection_lossy_data_callback)(void *object, int id, uint8_t *data, uint16_t length), void *object, int id) +{ + Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + + if (conn == 0) + return -1; + + conn->connection_lossy_data_callback = connection_lossy_data_callback; + conn->connection_lossy_data_callback_object = object; + conn->connection_lossy_data_callback_id = id; + return 0; +} + /* Get the crypto connection id from the ip_port. * * return -1 on failure. @@ -2211,8 +2243,12 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) -/* return -1 if data could not be put in packet queue. - * return positive packet number if data was put into the queue. +/* Sends a lossless cryptopacket. + * + * return -1 if data could not be put in packet queue. + * return positive packet number if data was put into the queue. + * + * The first byte of data must be in the CRYPTO_RESERVED_PACKETS to PACKET_ID_LOSSY_RANGE_START range. */ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) { @@ -2222,6 +2258,9 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, if (data[0] < CRYPTO_RESERVED_PACKETS) return -1; + if (data[0] >= PACKET_ID_LOSSY_RANGE_START) + return -1; + Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == 0) @@ -2243,6 +2282,31 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, return ret; } +/* return -1 on failure. + * return 0 on success. + * + * Sends a lossy cryptopacket. (first byte must in the PACKET_ID_LOSSY_RANGE_*) + */ +int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) +{ + if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) + return -1; + + if (data[0] < PACKET_ID_LOSSY_RANGE_START) + return -1; + + if (data[0] >= (PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE)) + return -1; + + Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + + if (conn == 0) + return -1; + + return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end, data, + length); +} + /* Kill a crypto connection. * * return -1 on failure. diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 25f8c2f7..938046f1 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -69,6 +69,10 @@ #define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */ #define STATUS_TCP_ONLINE 3 +/* All packets starting with a byte in this range are considered lossy packets. */ +#define PACKET_ID_LOSSY_RANGE_START 192 +#define PACKET_ID_LOSSY_RANGE_SIZE 63 + typedef struct { uint64_t time; uint16_t length; @@ -119,6 +123,10 @@ typedef struct { void *connection_data_callback_object; int connection_data_callback_id; + int (*connection_lossy_data_callback)(void *object, int id, uint8_t *data, uint16_t length); + void *connection_lossy_data_callback_object; + int connection_lossy_data_callback_id; + uint64_t last_request_packet_sent; uint32_t packet_counter; @@ -231,7 +239,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port); int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object, int id, uint8_t status), void *object, int id); -/* Set function to be called when connection with crypt_connection_id receives a data packet of length. +/* Set function to be called when connection with crypt_connection_id receives a lossless data packet of length. * * The set function should return -1 on failure and 0 on success. * Object and id will be passed to this function untouched. @@ -243,16 +251,38 @@ int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connec int id, uint8_t *data, uint16_t length), void *object, int id); +/* Set function to be called when connection with crypt_connection_id receives a lossy data packet of length. + * + * The set function should return -1 on failure and 0 on success. + * Object and id will be passed to this function untouched. + * + * return -1 on failure. + * return 0 on success. + */ +int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, + int (*connection_lossy_data_callback)(void *object, int id, uint8_t *data, uint16_t length), void *object, int id); + /* returns the number of packet slots left in the sendbuffer. * return 0 if failure. */ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id); -/* return -1 if data could not be put in packet queue. - * return positive packet number if data was put into the queue. +/* Sends a lossless cryptopacket. + * + * return -1 if data could not be put in packet queue. + * return positive packet number if data was put into the queue. + * + * The first byte of data must be in the CRYPTO_RESERVED_PACKETS to PACKET_ID_LOSSY_RANGE_START range. */ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); +/* return -1 on failure. + * return 0 on success. + * + * Sends a lossy cryptopacket. (first byte must in the PACKET_ID_LOSSY_RANGE_*) + */ +int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); + /* Add a tcp relay, associating it to a crypt_connection_id. * * return 0 if it was added. diff --git a/toxcore/network.h b/toxcore/network.h index 0eb7bbd0..633f8010 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -122,12 +122,6 @@ typedef int sock_t; #define NET_PACKET_LAN_DISCOVERY 33 /* LAN discovery packet ID. */ #define NET_PACKET_GROUP_CHATS 48 /* Group chats packet ID. */ -/* Range of ids that custom user packets can use. */ -#define NET_PACKET_CUSTOM_RANGE_START 64 -#define NET_PACKET_CUSTOM_RANGE_END 96 - -#define TOTAL_USERPACKETS (NET_PACKET_CUSTOM_RANGE_END - NET_PACKET_CUSTOM_RANGE_START) - /* See: docs/Prevent_Tracking.txt and onion.{c, h} */ #define NET_PACKET_ONION_SEND_INITIAL 128 #define NET_PACKET_ONION_SEND_1 129 -- cgit v1.2.3