|
|
|
|
@ -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) |
|
|
|
|
{ |
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
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; |
|
|
|
|
while ((n = tun_platform_read(tun, buf, sizeof(buf))) > 0) { |
|
|
|
|
got_packet = 1; |
|
|
|
|
if (size == 0) { |
|
|
|
|
WintunReleaseReceivePacket(session, wintun_pkt); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t* data = malloc(n); |
|
|
|
|
if (!data) { tun->read_errors++; continue; } |
|
|
|
|
memcpy(data, buf, n); |
|
|
|
|
/* === ОДНО копирование === */ |
|
|
|
|
uint8_t* data = malloc(size); |
|
|
|
|
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); |
|
|
|
|
if (!pkt) { |
|
|
|
|
@ -276,9 +279,8 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pkt->ll.dgram = data; |
|
|
|
|
pkt->ll.len = n; |
|
|
|
|
pkt->ll.len = size; |
|
|
|
|
|
|
|
|
|
// Создать структуру для передачи в main thread
|
|
|
|
|
struct tun_packet_data* pd = malloc(sizeof(*pd)); |
|
|
|
|
if (!pd) { |
|
|
|
|
free(data); |
|
|
|
|
@ -286,17 +288,15 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
|
|
|
|
|
tun->read_errors++; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
pd->tun = tun; |
|
|
|
|
|
|
|
|
|
pd->tun = tun; |
|
|
|
|
pd->entry = (struct ll_entry*)pkt; |
|
|
|
|
|
|
|
|
|
// Статистика
|
|
|
|
|
tun->bytes_read += n; |
|
|
|
|
tun->packets_read++; |
|
|
|
|
tun->bytes_read += size; |
|
|
|
|
tun->packets_read ++; |
|
|
|
|
|
|
|
|
|
// Дамп пакета
|
|
|
|
|
// dump_ip_packet("TUN->", buf, n);
|
|
|
|
|
// dump_ip_packet("TUN->", data, size); // теперь data вместо buf
|
|
|
|
|
|
|
|
|
|
// Передать данные в main thread через uasync_post
|
|
|
|
|
uasync_post(tun->ua, tun_packet_handler, pd); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|