Added functions to send and receive lossy encrypted packets over

the Tox connection.

A/V should now work over TCP.
This commit is contained in:
irungentoo 2014-05-21 15:28:14 -04:00
parent 248fd212ba
commit f818c1a197
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
8 changed files with 125 additions and 52 deletions

View File

@ -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;

View File

@ -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;

View File

@ -75,7 +75,6 @@ typedef struct _RTPMessage {
uint8_t data[MAX_RTP_SIZE];
uint32_t length;
IP_Port from;
struct _RTPMessage *next;
} RTPMessage;

View File

@ -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;
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);
if (byte >= (PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE))
return -1;
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. */

View File

@ -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.
*

View File

@ -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.

View File

@ -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.

View File

@ -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