Browse Source

len fix

nodeinfo-routing-update
jeka 7 months ago
parent
commit
32090cfa1d
  1. 2
      lib/ll_queue.c
  2. 2
      lib/ll_queue.h
  3. 17
      src/etcp.c
  4. 10
      src/etcp_connections.c
  5. 2
      src/packet_dump.h
  6. 66
      src/tun_windows.c

2
lib/ll_queue.c

@ -153,7 +153,7 @@ void queue_dgram_free(struct ll_entry* entry) {
if (entry->dgram) { if (entry->dgram) {
if (entry->dgram_free_fn) { if (entry->dgram_free_fn) {
entry->dgram_free_fn(entry->dgram, NULL); // arg=NULL, если не задан entry->dgram_free_fn(entry->dgram); // arg=NULL, если не задан
} else if (entry->dgram_pool) { } else if (entry->dgram_pool) {
memory_pool_free(entry->dgram_pool, entry->dgram); memory_pool_free(entry->dgram_pool, entry->dgram);
} else { } else {

2
lib/ll_queue.h

@ -50,7 +50,7 @@ struct ll_entry {
uint16_t memlen; ///< Выделенный размер под dgram uint16_t memlen; ///< Выделенный размер под dgram
uint16_t int_len; ///< Внутреннее (не использовать) uint16_t int_len; ///< Внутреннее (не использовать)
uint8_t* dgram; ///< Указатель на данные пакета uint8_t* dgram; ///< Указатель на данные пакета
void (*dgram_free_fn)(uint8_t* data, void* arg); ///< Кастомная функция освобождения dgram void (*dgram_free_fn)(uint8_t* data); ///< Кастомная функция освобождения dgram
struct memory_pool* dgram_pool; ///< Пул для dgram (если используется) struct memory_pool* dgram_pool; ///< Пул для dgram (если используется)
uint32_t id; ///< Идентификатор для поиска (задаётся при добавлении) uint32_t id; ///< Идентификатор для поиска (задаётся при добавлении)
struct ll_entry* hash_next; ///< Следующий в хеш-цепочке struct ll_entry* hash_next; ///< Следующий в хеш-цепочке

17
src/etcp.c

@ -602,9 +602,17 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
dgram->data[ptr++]=etcp->last_delivered_id>>16; dgram->data[ptr++]=etcp->last_delivered_id>>16;
dgram->data[ptr++]=etcp->last_delivered_id>>24; dgram->data[ptr++]=etcp->last_delivered_id>>24;
// тут (потом) добавим опциональные заголовки int data_len=0;
if (inf_pkt) data_len=inf_pkt->ll.len;
int remain_len=link->mtu -28/*udp headers*/ -13-8-4/*sc_nonce+tag size+crc*/ -9/*hdr[3] + min ack[6]*/ -5/*payload hdr*/ - data_len;
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "remain_len= %d pl=%d", remain_len, data_len);
// добавим опциональные заголовки
struct ACK_PACKET* ack_pkt; struct ACK_PACKET* ack_pkt;
while ((ack_pkt = (struct ACK_PACKET*)queue_data_get(etcp->ack_q))) { while (remain_len>=8) {
ack_pkt = (struct ACK_PACKET*)queue_data_get(etcp->ack_q);
if (!ack_pkt) break;
remain_len-=8;
// seq 4 байта // seq 4 байта
dgram->data[ptr++]=ack_pkt->seq; dgram->data[ptr++]=ack_pkt->seq;
dgram->data[ptr++]=ack_pkt->seq>>8; dgram->data[ptr++]=ack_pkt->seq>>8;
@ -629,7 +637,7 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
dgram->data[1]=ptr/8; dgram->data[1]=ptr/8;
if (link->last_recv_updated) {// если есть данные - добавим channel_timestamp if (link->last_recv_updated && remain_len>=5) {// если есть данные - добавим channel_timestamp
uint64_t now=get_time_tb(); uint64_t now=get_time_tb();
uint64_t dt=now - link->last_recv_local_time; uint64_t dt=now - link->last_recv_local_time;
link->last_recv_updated=0; link->last_recv_updated=0;
@ -643,9 +651,12 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
t=link->last_recv_local_time - link->last_recv_timestamp; t=link->last_recv_local_time - link->last_recv_timestamp;
dgram->data[ptr++]=t; dgram->data[ptr++]=t;
dgram->data[ptr++]=t>>8; dgram->data[ptr++]=t>>8;
remain_len-=5;
} }
} }
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "remain_len(2)= %d", remain_len);
if (inf_pkt) { if (inf_pkt) {
// фрейм data (0) обязательно в конец // фрейм data (0) обязательно в конец
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] add DATA (seq=%u, len=%u), ack_size=%d", etcp->log_name, inf_pkt->seq, inf_pkt->ll.len, dgram->data[1]); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] add DATA (seq=%u, len=%u), ack_size=%d", etcp->log_name, inf_pkt->seq, inf_pkt->ll.len, dgram->data[1]);

10
src/etcp_connections.c

@ -694,11 +694,11 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
// Mark that packet was sent (for keepalive logic) // Mark that packet was sent (for keepalive logic)
dgram->link->pkt_sent_since_keepalive = 1; dgram->link->pkt_sent_since_keepalive = 1;
dgram->flag_up=dgram->link->recv_keepalive; dgram->flag_up=dgram->link->recv_keepalive;
// 28 байт = udp headers. MTU=UDP payload+28 (1472 bytes max)
int errcode=0; int errcode=0;
sc_context_t* sc = &dgram->link->etcp->crypto_ctx; sc_context_t* sc = &dgram->link->etcp->crypto_ctx;
int len=dgram->data_len-dgram->noencrypt_len;// не забываем добавить timestamp (2 bytes) int len=dgram->data_len-dgram->noencrypt_len;// не забываем добавить timestamp (2 bytes)
if (len<0 || len>1480) { dgram->link->send_errors++; errcode=1; goto es_err; } if (len<0 || len>1472) { dgram->link->send_errors++; errcode=1; goto es_err; }
uint8_t enc_buf[1600]; uint8_t enc_buf[1600];
size_t enc_buf_len=0; size_t enc_buf_len=0;
dgram->timestamp=get_current_timestamp(); dgram->timestamp=get_current_timestamp();
@ -714,7 +714,9 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
errcode=2; errcode=2;
goto es_err; goto es_err;
} }
if (enc_buf_len + dgram->noencrypt_len > 1480) { dgram->link->send_errors++; errcode=2; goto es_err; } if (enc_buf_len + dgram->noencrypt_len > 1472) { dgram->link->send_errors++;
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "packet too long len=%d ne_len=%d", enc_buf_len, dgram->noencrypt_len);
errcode=3; goto es_err; }
memcpy(enc_buf+enc_buf_len, dgram->data+len, dgram->noencrypt_len); memcpy(enc_buf+enc_buf_len, dgram->data+len, dgram->noencrypt_len);
// DUMP: Show complete packet before sending // DUMP: Show complete packet before sending
@ -733,7 +735,7 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
(struct sockaddr*)addr, addr_len); (struct sockaddr*)addr, addr_len);
if (sent < 0) { if (sent < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "sendto failed, sock_err=%d", socket_get_error()); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "sendto failed, sock_err=%d", socket_get_error());
dgram->link->send_errors++; errcode=3; goto es_err; dgram->link->send_errors++; errcode=4; goto es_err;
} else { } else {
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "sendto succeeded, sent=%zd bytes to port %d", sent, ntohs(((struct sockaddr_in*)addr)->sin_port)); // DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "sendto succeeded, sent=%zd bytes to port %d", sent, ntohs(((struct sockaddr_in*)addr)->sin_port));
dgram->link->total_encrypted += sent; dgram->link->total_encrypted += sent;

2
src/packet_dump.h

@ -4,7 +4,7 @@
#include "../lib/platform_compat.h" #include "../lib/platform_compat.h"
// Packet dump function for debugging // Packet dump function for debugging
static void dump_packet(const char* direction, const uint8_t* data, size_t len, struct sockaddr_storage* addr) { static void x_dump_packet(const char* direction, const uint8_t* data, size_t len, struct sockaddr_storage* addr) {
printf("[DUMP] %s packet: %zd bytes ", direction, len); printf("[DUMP] %s packet: %zd bytes ", direction, len);
// Print address if provided // Print address if provided

66
src/tun_windows.c

@ -200,21 +200,6 @@ void tun_platform_cleanup(struct tun_if* tun)
} }
} }
ssize_t tun_platform_read(struct tun_if* tun, uint8_t* buf, size_t len)
{
if (!tun->platform_handle) return -1;
DWORD size;
BYTE* pkt = WintunReceivePacket((WINTUN_SESSION_HANDLE)tun->platform_handle, &size);
if (!pkt) {
if (GetLastError() == ERROR_NO_MORE_ITEMS) return 0;
return -1;
}
if (size > len) size = (DWORD)len;
memcpy(buf, pkt, size);
WintunReleaseReceivePacket((WINTUN_SESSION_HANDLE)tun->platform_handle, pkt);
return (ssize_t)size;
}
ssize_t tun_platform_write(struct tun_if* tun, const uint8_t* buf, size_t len) ssize_t tun_platform_write(struct tun_if* tun, const uint8_t* buf, size_t len)
{ {
if (!tun->platform_handle) return -1; if (!tun->platform_handle) return -1;
@ -248,7 +233,10 @@ static void tun_output_notify(void* arg)
DWORD WINAPI tun_read_thread_proc(LPVOID arg) DWORD WINAPI tun_read_thread_proc(LPVOID arg)
{ {
struct tun_if* tun = (struct tun_if*)arg; struct tun_if* tun = (struct tun_if*)arg;
HANDLE event = WintunGetReadWaitEvent((WINTUN_SESSION_HANDLE)tun->platform_handle); WINTUN_SESSION_HANDLE session = (WINTUN_SESSION_HANDLE)tun->platform_handle;
if (!session) return 1;
HANDLE event = WintunGetReadWaitEvent(session);
if (!event) return 1; if (!event) return 1;
HANDLE handles[2] = {event, tun->stop_event}; HANDLE handles[2] = {event, tun->stop_event};
@ -257,16 +245,31 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
if (WaitForMultipleObjects(2, handles, FALSE, INFINITE) != WAIT_OBJECT_0) if (WaitForMultipleObjects(2, handles, FALSE, INFINITE) != WAIT_OBJECT_0)
break; break;
uint8_t buf[TUN_MAX_PACKET_SIZE]; /* Дренаж всех готовых пакетов */
int got_packet = 0; for (;;) {
DWORD size;
BYTE* wintun_pkt = WintunReceivePacket(session, &size);
if (!wintun_pkt) {
if (GetLastError() == ERROR_NO_MORE_ITEMS)
break; /* нормально — пакетов больше нет */
tun->read_errors++;
break;
}
ssize_t n; if (size == 0) {
while ((n = tun_platform_read(tun, buf, sizeof(buf))) > 0) { WintunReleaseReceivePacket(session, wintun_pkt);
got_packet = 1; continue;
}
uint8_t* data = malloc(n); /* === ОДНО копирование === */
if (!data) { tun->read_errors++; continue; } uint8_t* data = malloc(size);
memcpy(data, buf, n); if (!data) {
WintunReleaseReceivePacket(session, wintun_pkt);
tun->read_errors++;
continue;
}
memcpy(data, wintun_pkt, size);
WintunReleaseReceivePacket(session, wintun_pkt); /* сразу отдаём кольцо */
struct ETCP_FRAGMENT* pkt = (struct ETCP_FRAGMENT*)queue_entry_new_from_pool(tun->pool); struct ETCP_FRAGMENT* pkt = (struct ETCP_FRAGMENT*)queue_entry_new_from_pool(tun->pool);
if (!pkt) { if (!pkt) {
@ -276,9 +279,8 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
} }
pkt->ll.dgram = data; pkt->ll.dgram = data;
pkt->ll.len = n; pkt->ll.len = size;
// Создать структуру для передачи в main thread
struct tun_packet_data* pd = malloc(sizeof(*pd)); struct tun_packet_data* pd = malloc(sizeof(*pd));
if (!pd) { if (!pd) {
free(data); free(data);
@ -286,17 +288,15 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
tun->read_errors++; tun->read_errors++;
continue; continue;
} }
pd->tun = tun;
pd->tun = tun;
pd->entry = (struct ll_entry*)pkt; pd->entry = (struct ll_entry*)pkt;
// Статистика tun->bytes_read += size;
tun->bytes_read += n; tun->packets_read ++;
tun->packets_read++;
// Дамп пакета // dump_ip_packet("TUN->", data, size); // теперь data вместо buf
// dump_ip_packet("TUN->", buf, n);
// Передать данные в main thread через uasync_post
uasync_post(tun->ua, tun_packet_handler, pd); uasync_post(tun->ua, tun_packet_handler, pd);
} }
} }

Loading…
Cancel
Save