mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Connection between toxes is lossless once again.
This commit is contained in:
parent
9fccb80eec
commit
98f20c76de
|
@ -1582,7 +1582,7 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
|
|||
/* Send the following packet to everyone who tells us they are connected to friend_id.
|
||||
*
|
||||
* return ip for friend.
|
||||
* return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 2).
|
||||
* return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 4).
|
||||
*/
|
||||
int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length)
|
||||
{
|
||||
|
|
|
@ -398,12 +398,13 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, Packet_Data
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Copy data with packet number to data.
|
||||
/* Get pointer of data with packet number.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
* return 0 if data at number is empty.
|
||||
* return 1 if data pointer was put in data.
|
||||
*/
|
||||
static int copy_data_number(Packets_Array *array, Packet_Data *data, uint32_t number)
|
||||
static int get_data_pointer(Packets_Array *array, Packet_Data **data, uint32_t number)
|
||||
{
|
||||
uint32_t num_spots = array->buffer_end - array->buffer_start;
|
||||
|
||||
|
@ -413,10 +414,10 @@ static int copy_data_number(Packets_Array *array, Packet_Data *data, uint32_t nu
|
|||
uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
|
||||
|
||||
if (!array->buffer[num])
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
memcpy(data, array->buffer[num], sizeof(Packet_Data));
|
||||
return 0;
|
||||
*data = array->buffer[num];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add data to end of array.
|
||||
|
@ -490,10 +491,126 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number)
|
|||
array->buffer_start = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a packet request packet from recv_array and send_buffer_end into
|
||||
* data of length.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return length of packet on success.
|
||||
*/
|
||||
static int generate_request_packet(uint8_t *data, uint16_t length, Packets_Array *recv_array, uint32_t send_buffer_end)
|
||||
{
|
||||
if (length <= (sizeof(uint32_t) * 2))
|
||||
return -1;
|
||||
|
||||
uint32_t recv_buffer_start = htonl(recv_array->buffer_start);
|
||||
send_buffer_end = htonl(send_buffer_end);
|
||||
memcpy(data, &recv_buffer_start, sizeof(uint32_t));
|
||||
memcpy(data + sizeof(uint32_t), &send_buffer_end, sizeof(uint32_t));
|
||||
data[sizeof(uint32_t) * 2] = PACKET_ID_REQUEST;
|
||||
|
||||
uint16_t cur_len = sizeof(uint32_t) * 2 + 1;
|
||||
|
||||
if (recv_array->buffer_start == recv_array->buffer_end)
|
||||
return cur_len;
|
||||
|
||||
if (length <= cur_len)
|
||||
return cur_len;
|
||||
|
||||
uint32_t i, n = 1;
|
||||
|
||||
for (i = recv_array->buffer_start; i != recv_array->buffer_end; ++i) {
|
||||
uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
|
||||
|
||||
if (!recv_array->buffer[num]) {
|
||||
data[cur_len] = n;
|
||||
n = 0;
|
||||
++cur_len;
|
||||
|
||||
if (length <= cur_len)
|
||||
return cur_len;
|
||||
|
||||
} else if (n == 255) {
|
||||
data[cur_len] = 0;
|
||||
n = 0;
|
||||
++cur_len;
|
||||
|
||||
if (length <= cur_len)
|
||||
return cur_len;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
return cur_len;
|
||||
}
|
||||
|
||||
/* Handle a request data packet.
|
||||
* Remove all the packets the other recieved from the array.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
static int handle_request_packet(Packets_Array *send_array, uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length < 1)
|
||||
return -1;
|
||||
|
||||
if (data[0] != PACKET_ID_REQUEST)
|
||||
return -1;
|
||||
|
||||
if (length == 1)
|
||||
return 0;
|
||||
|
||||
++data;
|
||||
--length;
|
||||
|
||||
uint32_t i, n = 1;
|
||||
|
||||
for (i = send_array->buffer_start; i != send_array->buffer_end; ++i) {
|
||||
if (length == 0)
|
||||
break;
|
||||
|
||||
uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
|
||||
|
||||
if (n == data[0]) {
|
||||
if (send_array->buffer[num]) {
|
||||
send_array->buffer[num]->time = 0;
|
||||
}
|
||||
|
||||
++data;
|
||||
--length;
|
||||
n = 0;
|
||||
} else {
|
||||
free(send_array->buffer[num]);
|
||||
send_array->buffer[num] = NULL;
|
||||
}
|
||||
|
||||
if (n == 255) {
|
||||
n = 1;
|
||||
|
||||
if (data[0] != 0)
|
||||
return -1;
|
||||
|
||||
++data;
|
||||
--length;
|
||||
} else {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** END: Array Related functions **/
|
||||
|
||||
#define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES))
|
||||
|
||||
/* Creates and sends a data packet to the peer using the fastest route.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length == 0 || length + (1 + sizeof(uint16_t) + crypto_box_MACBYTES) > MAX_CRYPTO_PACKET_SIZE)
|
||||
|
@ -517,6 +634,11 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *dat
|
|||
return send_packet_to(c, crypt_connection_id, packet, sizeof(packet));
|
||||
}
|
||||
|
||||
/* Creates and sends a data packet with buffer_start and num to the peer using the fastest route.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num,
|
||||
uint8_t *data, uint32_t length)
|
||||
{
|
||||
|
@ -608,6 +730,64 @@ static int handle_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *d
|
|||
return len;
|
||||
}
|
||||
|
||||
/* Send a request packet.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
|
||||
{
|
||||
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
|
||||
|
||||
if (conn == 0)
|
||||
return -1;
|
||||
|
||||
uint8_t packet[MAX_DATA_DATA_PACKET_SIZE];
|
||||
int len = generate_request_packet(packet, sizeof(packet), &conn->recv_array, conn->send_array.buffer_end);
|
||||
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
return send_data_packet(c, crypt_connection_id, packet, len);
|
||||
}
|
||||
|
||||
/* Send up to max num previously requested data packets.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num)
|
||||
{
|
||||
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
|
||||
|
||||
if (conn == 0)
|
||||
return -1;
|
||||
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < max_num; ++i) {
|
||||
Packet_Data *dt;
|
||||
uint32_t packet_num = (i + conn->send_array.buffer_start);
|
||||
int ret = get_data_pointer(&conn->send_array, &dt, packet_num);
|
||||
|
||||
if (ret == -1) {
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dt->time != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dt->time = current_time_monotonic();
|
||||
|
||||
if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data,
|
||||
dt->length) != 0)
|
||||
printf("send_data_packet failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add a new temp packet to send repeatedly.
|
||||
*
|
||||
|
@ -754,11 +934,12 @@ static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uin
|
|||
}
|
||||
|
||||
if (real_data[0] == PACKET_ID_REQUEST) {
|
||||
if (real_length <= 1)
|
||||
if (handle_request_packet(&conn->send_array, real_data, real_length) != 0) {
|
||||
printf("fail %u %u\n", real_data[0], real_length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//TODO
|
||||
//TODO: use num.
|
||||
} else {
|
||||
Packet_Data dt;
|
||||
dt.time = current_time_monotonic();
|
||||
|
@ -773,6 +954,16 @@ static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uin
|
|||
conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data,
|
||||
dt.length);
|
||||
}
|
||||
|
||||
//send a data request packet for every x number of data packets recieved.
|
||||
++conn->packet_counter;
|
||||
|
||||
if (conn->packet_counter > (CRYPTO_PACKET_BUFFER_SIZE / 4)) {
|
||||
if (send_request_packet(c, crypt_connection_id) != 0)
|
||||
return -1;
|
||||
|
||||
conn->packet_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
|
||||
|
@ -1285,10 +1476,12 @@ static void send_crypto_packets(Net_Crypto *c)
|
|||
}
|
||||
|
||||
if (conn->status >= CRYPTO_CONN_NOT_CONFIRMED
|
||||
&& (500ULL + conn->last_data_packet_sent) < temp_time) {//TODO remove this.
|
||||
uint8_t data[4] = {5, 2};
|
||||
send_lossless_packet(c, i, data, 4);
|
||||
&& (CRYPTO_SEND_PACKET_INTERVAL + conn->last_data_packet_sent) < temp_time) {
|
||||
send_request_packet(c, i);
|
||||
}
|
||||
|
||||
//TODO
|
||||
send_requested_packets(c, i, ~0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define CRYPTO_CONN_ESTABLISHED 4
|
||||
#define CRYPTO_CONN_TIMED_OUT 5
|
||||
|
||||
#define CRYPTO_PACKET_BUFFER_SIZE 64 /* Must be a power of 2 */
|
||||
#define CRYPTO_PACKET_BUFFER_SIZE 128 /* Must be a power of 2 */
|
||||
|
||||
#define MAX_CRYPTO_PACKET_SIZE 1400
|
||||
|
||||
|
@ -105,6 +105,8 @@ typedef struct {
|
|||
int connection_data_callback_id;
|
||||
|
||||
uint64_t last_data_packet_sent;
|
||||
|
||||
uint32_t packet_counter;
|
||||
} Crypto_Connection;
|
||||
|
||||
typedef struct {
|
||||
|
|
Loading…
Reference in New Issue
Block a user