feat: publish Android 1.0.1 candidate source and acceptance evidence
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-tunnel-windows.c
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2025 hev
|
||||
Description : Tunnel on Windows
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#if defined(__MSYS__)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <hev-task.h>
|
||||
#include <hev-task-io.h>
|
||||
#include <hev-memory-allocator.h>
|
||||
|
||||
#include "hev-wintun.h"
|
||||
|
||||
#include "hev-tunnel.h"
|
||||
|
||||
typedef struct _HevPBuf HevPBuf;
|
||||
|
||||
struct _HevPBuf
|
||||
{
|
||||
struct pbuf_custom base;
|
||||
void *mem;
|
||||
};
|
||||
|
||||
static HevWinTun *wintun;
|
||||
static HevWinTunAdapter *adapter;
|
||||
static HevWinTunSession *session;
|
||||
static char tun_name[IFNAMSIZ];
|
||||
|
||||
static void
|
||||
hev_pbuf_free (struct pbuf *p)
|
||||
{
|
||||
HevPBuf *buf = (HevPBuf *)p;
|
||||
|
||||
hev_wintun_session_release (session, buf->mem);
|
||||
hev_free (buf);
|
||||
}
|
||||
|
||||
int
|
||||
hev_tunnel_open (const char *name, int multi_queue)
|
||||
{
|
||||
wintun = hev_wintun_open ();
|
||||
if (!wintun)
|
||||
return -1;
|
||||
|
||||
adapter = hev_wintun_adapter_create (name);
|
||||
if (!adapter)
|
||||
goto free;
|
||||
|
||||
strncpy (tun_name, name, IFNAMSIZ - 1);
|
||||
return 0;
|
||||
|
||||
free:
|
||||
hev_wintun_close (wintun);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
hev_tunnel_close (int fd)
|
||||
{
|
||||
if (session)
|
||||
hev_wintun_session_stop (session);
|
||||
hev_wintun_adapter_close (adapter);
|
||||
hev_wintun_close (wintun);
|
||||
}
|
||||
|
||||
int
|
||||
hev_tunnel_set_mtu (int mtu)
|
||||
{
|
||||
return hev_wintun_adapter_set_mtu (adapter, mtu);
|
||||
}
|
||||
|
||||
int
|
||||
hev_tunnel_set_state (int state)
|
||||
{
|
||||
if (state) {
|
||||
session = hev_wintun_session_start (adapter);
|
||||
if (!session)
|
||||
return -1;
|
||||
} else {
|
||||
if (session) {
|
||||
hev_wintun_session_stop (session);
|
||||
session = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hev_tunnel_set_ipv4 (const char *addr, unsigned int prefix)
|
||||
{
|
||||
char ipv4[4];
|
||||
int res;
|
||||
|
||||
res = inet_pton (AF_INET, addr, ipv4);
|
||||
if (!res)
|
||||
return -1;
|
||||
|
||||
return hev_wintun_adapter_set_ipv4 (adapter, ipv4, prefix);
|
||||
}
|
||||
|
||||
int
|
||||
hev_tunnel_set_ipv6 (const char *addr, unsigned int prefix)
|
||||
{
|
||||
char ipv6[16];
|
||||
int res;
|
||||
|
||||
res = inet_pton (AF_INET6, addr, ipv6);
|
||||
if (!res)
|
||||
return -1;
|
||||
|
||||
return hev_wintun_adapter_set_ipv6 (adapter, ipv6, prefix);
|
||||
}
|
||||
|
||||
const char *
|
||||
hev_tunnel_get_name (void)
|
||||
{
|
||||
return tun_name;
|
||||
}
|
||||
|
||||
const char *
|
||||
hev_tunnel_get_index (void)
|
||||
{
|
||||
static char tun_index[16];
|
||||
int index;
|
||||
|
||||
index = hev_wintun_adapter_get_index (adapter);
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
|
||||
snprintf (tun_index, sizeof (tun_index) - 1, "%d", index);
|
||||
return tun_index;
|
||||
}
|
||||
|
||||
int
|
||||
hev_tunnel_add_task (int fd, HevTask *task)
|
||||
{
|
||||
void *handle = hev_wintun_session_get_read_wait_event (session);
|
||||
return hev_task_add_whandle (task, handle);
|
||||
}
|
||||
|
||||
void
|
||||
hev_tunnel_del_task (int fd, HevTask *task)
|
||||
{
|
||||
void *handle = hev_wintun_session_get_read_wait_event (session);
|
||||
hev_task_del_whandle (task, handle);
|
||||
}
|
||||
|
||||
struct pbuf *
|
||||
hev_tunnel_read (int fd, int mtu, HevTaskIOYielder yielder, void *yielder_data)
|
||||
{
|
||||
HevPBuf *buf;
|
||||
void *packet;
|
||||
int spin = 0;
|
||||
int size;
|
||||
|
||||
retry:
|
||||
packet = hev_wintun_session_receive (session, &size);
|
||||
if (!packet) {
|
||||
if (hev_wintun_get_last_error () == HEV_WINTUN_EAGAIN) {
|
||||
if (spin++ < 1000) {
|
||||
hev_task_yield (HEV_TASK_YIELD);
|
||||
} else if (yielder) {
|
||||
if (yielder (HEV_TASK_WAITIO, yielder_data))
|
||||
return NULL;
|
||||
} else {
|
||||
hev_task_yield (HEV_TASK_WAITIO);
|
||||
}
|
||||
goto retry;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
buf = hev_malloc (sizeof (HevPBuf));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
buf->mem = packet;
|
||||
buf->base.custom_free_function = hev_pbuf_free;
|
||||
pbuf_alloced_custom (PBUF_RAW, size, PBUF_RAM, &buf->base, packet, size);
|
||||
|
||||
return &buf->base.pbuf;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
hev_tunnel_write (int fd, struct pbuf *buf)
|
||||
{
|
||||
struct pbuf *p = buf;
|
||||
void *packet;
|
||||
size_t size;
|
||||
|
||||
packet = hev_wintun_session_allocate (session, p->tot_len);
|
||||
if (!packet)
|
||||
return -1;
|
||||
|
||||
for (size = 0; p; p = p->next) {
|
||||
memcpy (packet + size, p->payload, p->len);
|
||||
size += p->len;
|
||||
}
|
||||
|
||||
hev_wintun_session_send (session, packet);
|
||||
return size;
|
||||
}
|
||||
|
||||
#endif /* __MSYS__ */
|
||||
Reference in New Issue
Block a user