feat: publish Android 1.0.1 candidate source and acceptance evidence
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-compiler.h
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2019 - 2023 hev
|
||||
Description : Compiler
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __HEV_COMPILER_H__
|
||||
#define __HEV_COMPILER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ALIGN_UP(addr, align) \
|
||||
((addr + (typeof (addr))align - 1) & ~((typeof (addr))align - 1))
|
||||
|
||||
#define ALIGN_DOWN(addr, align) ((addr) & ~((typeof (addr))align - 1))
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
|
||||
#endif
|
||||
|
||||
#ifndef EXPORT_SYMBOL
|
||||
#define EXPORT_SYMBOL __attribute__ ((visibility ("default")))
|
||||
#endif
|
||||
|
||||
#define barrier() __asm__ __volatile__ ("" : : : "memory")
|
||||
|
||||
static inline void
|
||||
__read_once_size (void *dst, const volatile void *src, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case sizeof (char):
|
||||
*(char *)dst = *(volatile char *)src;
|
||||
break;
|
||||
case sizeof (short):
|
||||
*(short *)dst = *(volatile short *)src;
|
||||
break;
|
||||
case sizeof (int):
|
||||
*(int *)dst = *(volatile int *)src;
|
||||
break;
|
||||
default:
|
||||
barrier ();
|
||||
__builtin_memcpy ((void *)dst, (const void *)src, size);
|
||||
barrier ();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
__write_once_size (volatile void *dst, const void *src, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case sizeof (char):
|
||||
*(volatile char *)dst = *(char *)src;
|
||||
break;
|
||||
case sizeof (short):
|
||||
*(volatile short *)dst = *(short *)src;
|
||||
break;
|
||||
case sizeof (int):
|
||||
*(volatile int *)dst = *(int *)src;
|
||||
break;
|
||||
default:
|
||||
barrier ();
|
||||
__builtin_memcpy ((void *)dst, (const void *)src, size);
|
||||
barrier ();
|
||||
}
|
||||
}
|
||||
|
||||
#define READ_ONCE(x) \
|
||||
({ \
|
||||
union \
|
||||
{ \
|
||||
typeof (x) __val; \
|
||||
char __c[1]; \
|
||||
} __u; \
|
||||
__read_once_size (__u.__c, &(x), sizeof (x)); \
|
||||
__u.__val; \
|
||||
})
|
||||
|
||||
#define WRITE_ONCE(x, val) \
|
||||
({ \
|
||||
union \
|
||||
{ \
|
||||
typeof (x) __val; \
|
||||
char __c[1]; \
|
||||
} __u = { .__val = (typeof (x))(val) }; \
|
||||
__write_once_size (&(x), __u.__c, sizeof (x)); \
|
||||
__u.__val; \
|
||||
})
|
||||
|
||||
#ifndef container_of
|
||||
#define container_of(ptr, type, member) \
|
||||
({ \
|
||||
void *__mptr = (void *)(ptr); \
|
||||
((type *)(__mptr - offsetof (type, member))); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HEV_COMPILER_H__ */
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-exec.c
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2023 hev
|
||||
Description : Exec
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <Availability.h>
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#include "hev-logger.h"
|
||||
|
||||
#include "hev-exec.h"
|
||||
|
||||
#if TARGET_OS_TV
|
||||
void
|
||||
hev_exec_run (const char *script_path, const char *tun_name,
|
||||
const char *tun_index, int wait)
|
||||
{
|
||||
}
|
||||
#else
|
||||
static void
|
||||
signal_handler (int signum)
|
||||
{
|
||||
waitpid (-1, NULL, WNOHANG);
|
||||
}
|
||||
|
||||
void
|
||||
hev_exec_run (const char *script_path, const char *tun_name,
|
||||
const char *tun_index, int wait)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
signal (SIGCHLD, signal_handler);
|
||||
|
||||
pid = fork ();
|
||||
if (pid < 0) {
|
||||
LOG_E ("exec fork");
|
||||
return;
|
||||
} else if (pid != 0) {
|
||||
if (wait)
|
||||
waitpid (pid, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
execl (script_path, script_path, tun_name, tun_index, NULL);
|
||||
|
||||
LOG_E ("exec %s %s %s", script_path, tun_name, tun_index);
|
||||
exit (-1);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-exec.h
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2023 - 2025 hev
|
||||
Description : Exec
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __HEV_EXEC_H__
|
||||
#define __HEV_EXEC_H__
|
||||
|
||||
void hev_exec_run (const char *script_path, const char *tun_name,
|
||||
const char *tun_index, int wait);
|
||||
|
||||
#endif /* __HEV_EXEC_H__ */
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-list.c
|
||||
Authors : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2019 - 2023 hev
|
||||
Description : Double-linked List
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "hev-list.h"
|
||||
|
||||
void
|
||||
hev_list_add_tail (HevList *self, HevListNode *new_)
|
||||
{
|
||||
new_->prev = self->tail;
|
||||
new_->next = NULL;
|
||||
|
||||
if (self->tail)
|
||||
self->tail->next = new_;
|
||||
else
|
||||
self->head = new_;
|
||||
self->tail = new_;
|
||||
}
|
||||
|
||||
void
|
||||
hev_list_del (HevList *self, HevListNode *node)
|
||||
{
|
||||
if (node->prev)
|
||||
node->prev->next = node->next;
|
||||
else
|
||||
self->head = node->next;
|
||||
|
||||
if (node->next)
|
||||
node->next->prev = node->prev;
|
||||
else
|
||||
self->tail = node->prev;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-list.h
|
||||
Authors : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2019 - 2023 hev
|
||||
Description : Double-linked List
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __HEV_LIST_H__
|
||||
#define __HEV_LIST_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _HevList HevList;
|
||||
typedef struct _HevListNode HevListNode;
|
||||
|
||||
struct _HevList
|
||||
{
|
||||
HevListNode *head;
|
||||
HevListNode *tail;
|
||||
};
|
||||
|
||||
struct _HevListNode
|
||||
{
|
||||
HevListNode *next;
|
||||
HevListNode *prev;
|
||||
};
|
||||
|
||||
static inline HevListNode *
|
||||
hev_list_node_prev (HevListNode *node)
|
||||
{
|
||||
return node->prev;
|
||||
}
|
||||
|
||||
static inline HevListNode *
|
||||
hev_list_node_next (HevListNode *node)
|
||||
{
|
||||
return node->next;
|
||||
}
|
||||
|
||||
static inline HevListNode *
|
||||
hev_list_first (HevList *self)
|
||||
{
|
||||
return self->head;
|
||||
}
|
||||
|
||||
static inline HevListNode *
|
||||
hev_list_last (HevList *self)
|
||||
{
|
||||
return self->tail;
|
||||
}
|
||||
|
||||
void hev_list_add_tail (HevList *self, HevListNode *new_);
|
||||
void hev_list_del (HevList *self, HevListNode *node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HEV_LIST_H__ */
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-logger.c
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2019 - 2023 hev
|
||||
Description : Logger
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "hev-logger.h"
|
||||
|
||||
static int fd = -1;
|
||||
static HevLoggerLevel req_level;
|
||||
|
||||
int
|
||||
hev_logger_init (HevLoggerLevel level, const char *path)
|
||||
{
|
||||
req_level = level;
|
||||
|
||||
if (0 == strcmp (path, "stdout"))
|
||||
fd = dup (1);
|
||||
else if (0 == strcmp (path, "stderr"))
|
||||
fd = dup (2);
|
||||
else
|
||||
fd = open (path, O_WRONLY | O_APPEND | O_CREAT, 0640);
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hev_logger_fini (void)
|
||||
{
|
||||
close (fd);
|
||||
}
|
||||
|
||||
int
|
||||
hev_logger_enabled (HevLoggerLevel level)
|
||||
{
|
||||
if (level >= req_level && fd >= 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hev_logger_log (HevLoggerLevel level, const char *fmt, ...)
|
||||
{
|
||||
struct iovec iov[4];
|
||||
const char *ts_fmt;
|
||||
char msg[1024];
|
||||
struct tm *ti;
|
||||
char ts[32];
|
||||
time_t now;
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
if (level < req_level || fd < 0)
|
||||
return;
|
||||
|
||||
time (&now);
|
||||
ti = localtime (&now);
|
||||
|
||||
ts_fmt = "[%04u-%02u-%02u %02u:%02u:%02u] ";
|
||||
len = snprintf (ts, sizeof (ts), ts_fmt, 1900 + ti->tm_year, 1 + ti->tm_mon,
|
||||
ti->tm_mday, ti->tm_hour, ti->tm_min, ti->tm_sec);
|
||||
|
||||
iov[0].iov_base = ts;
|
||||
iov[0].iov_len = len;
|
||||
|
||||
switch (level) {
|
||||
case HEV_LOGGER_DEBUG:
|
||||
iov[1].iov_base = "[D] ";
|
||||
break;
|
||||
case HEV_LOGGER_INFO:
|
||||
iov[1].iov_base = "[I] ";
|
||||
break;
|
||||
case HEV_LOGGER_WARN:
|
||||
iov[1].iov_base = "[W] ";
|
||||
break;
|
||||
case HEV_LOGGER_ERROR:
|
||||
iov[1].iov_base = "[E] ";
|
||||
break;
|
||||
case HEV_LOGGER_UNSET:
|
||||
iov[1].iov_base = "[?] ";
|
||||
break;
|
||||
}
|
||||
iov[1].iov_len = 4;
|
||||
|
||||
va_start (ap, fmt);
|
||||
iov[2].iov_base = msg;
|
||||
iov[2].iov_len = vsnprintf (msg, 1024, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
iov[3].iov_base = "\n";
|
||||
iov[3].iov_len = 1;
|
||||
|
||||
if (writev (fd, iov, 4)) {
|
||||
/* ignore return value */
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-logger.h
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2019 - 2023 hev
|
||||
Description : Logger
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __HEV_LOGGER_H__
|
||||
#define __HEV_LOGGER_H__
|
||||
|
||||
#define LOG_D(fmt...) hev_logger_log (HEV_LOGGER_DEBUG, fmt)
|
||||
#define LOG_I(fmt...) hev_logger_log (HEV_LOGGER_INFO, fmt)
|
||||
#define LOG_W(fmt...) hev_logger_log (HEV_LOGGER_WARN, fmt)
|
||||
#define LOG_E(fmt...) hev_logger_log (HEV_LOGGER_ERROR, fmt)
|
||||
|
||||
#define LOG_ON() hev_logger_enabled (HEV_LOGGER_UNSET)
|
||||
#define LOG_ON_D() hev_logger_enabled (HEV_LOGGER_DEBUG)
|
||||
#define LOG_ON_I() hev_logger_enabled (HEV_LOGGER_INFO)
|
||||
#define LOG_ON_W() hev_logger_enabled (HEV_LOGGER_WARN)
|
||||
#define LOG_ON_E() hev_logger_enabled (HEV_LOGGER_ERROR)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HEV_LOGGER_DEBUG,
|
||||
HEV_LOGGER_INFO,
|
||||
HEV_LOGGER_WARN,
|
||||
HEV_LOGGER_ERROR,
|
||||
HEV_LOGGER_UNSET,
|
||||
} HevLoggerLevel;
|
||||
|
||||
int hev_logger_init (HevLoggerLevel level, const char *path);
|
||||
void hev_logger_fini (void);
|
||||
|
||||
int hev_logger_enabled (HevLoggerLevel level);
|
||||
void hev_logger_log (HevLoggerLevel level, const char *fmt, ...);
|
||||
|
||||
#endif /* __HEV_LOGGER_H__ */
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-ring-buffer.c
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2023 hev
|
||||
Description : Ring buffer
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include "hev-compiler.h"
|
||||
#include "hev-ring-buffer.h"
|
||||
|
||||
size_t
|
||||
hev_ring_buffer_get_max_size (HevRingBuffer *self)
|
||||
{
|
||||
return self->max_size;
|
||||
}
|
||||
|
||||
size_t
|
||||
hev_ring_buffer_get_use_size (HevRingBuffer *self)
|
||||
{
|
||||
return self->use_size;
|
||||
}
|
||||
|
||||
int
|
||||
hev_ring_buffer_reading (HevRingBuffer *self, struct iovec *iov)
|
||||
{
|
||||
size_t upper_size;
|
||||
|
||||
if (0 == self->rda_size)
|
||||
return 0;
|
||||
|
||||
upper_size = self->max_size - self->rp;
|
||||
|
||||
iov[0].iov_base = self->data + self->rp;
|
||||
if (self->rda_size <= upper_size) {
|
||||
iov[0].iov_len = self->rda_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
iov[0].iov_len = upper_size;
|
||||
iov[1].iov_base = self->data;
|
||||
iov[1].iov_len = self->rda_size - upper_size;
|
||||
return 2;
|
||||
}
|
||||
|
||||
void
|
||||
hev_ring_buffer_read_finish (HevRingBuffer *self, size_t size)
|
||||
{
|
||||
self->rp = (self->rp + size) % self->max_size;
|
||||
self->rda_size -= size;
|
||||
}
|
||||
|
||||
void
|
||||
hev_ring_buffer_read_release (HevRingBuffer *self, size_t size)
|
||||
{
|
||||
self->use_size -= size;
|
||||
if (!self->use_size) {
|
||||
self->rp = 0;
|
||||
self->wp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hev_ring_buffer_writing (HevRingBuffer *self, struct iovec *iov)
|
||||
{
|
||||
size_t upper_size, spc_size;
|
||||
|
||||
if (self->use_size == self->max_size)
|
||||
return 0;
|
||||
|
||||
upper_size = self->max_size - self->wp;
|
||||
spc_size = self->max_size - self->use_size;
|
||||
|
||||
iov[0].iov_base = self->data + self->wp;
|
||||
if (spc_size <= upper_size) {
|
||||
iov[0].iov_len = spc_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
iov[0].iov_len = upper_size;
|
||||
iov[1].iov_base = self->data;
|
||||
iov[1].iov_len = spc_size - upper_size;
|
||||
return 2;
|
||||
}
|
||||
|
||||
void
|
||||
hev_ring_buffer_write_finish (HevRingBuffer *self, size_t size)
|
||||
{
|
||||
self->wp = (self->wp + size) % self->max_size;
|
||||
self->use_size += size;
|
||||
self->rda_size += size;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-ring-buffer.h
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2023 hev
|
||||
Description : Ring buffer
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __HEV_RING_BUFFER_H__
|
||||
#define __HEV_RING_BUFFER_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct _HevRingBuffer HevRingBuffer;
|
||||
|
||||
struct _HevRingBuffer
|
||||
{
|
||||
size_t rp;
|
||||
size_t wp;
|
||||
size_t rda_size;
|
||||
size_t use_size;
|
||||
size_t max_size;
|
||||
|
||||
unsigned char data[0];
|
||||
};
|
||||
|
||||
#define hev_ring_buffer_alloca(s) \
|
||||
({ \
|
||||
HevRingBuffer *__self; \
|
||||
\
|
||||
__self = alloca (sizeof (HevRingBuffer) + s); \
|
||||
if (!__self) \
|
||||
NULL; \
|
||||
\
|
||||
__self->rp = 0; \
|
||||
__self->wp = 0; \
|
||||
__self->rda_size = 0; \
|
||||
__self->use_size = 0; \
|
||||
__self->max_size = s; \
|
||||
\
|
||||
__self; \
|
||||
})
|
||||
|
||||
size_t hev_ring_buffer_get_max_size (HevRingBuffer *self);
|
||||
size_t hev_ring_buffer_get_use_size (HevRingBuffer *self);
|
||||
|
||||
int hev_ring_buffer_reading (HevRingBuffer *self, struct iovec *iov);
|
||||
void hev_ring_buffer_read_finish (HevRingBuffer *self, size_t size);
|
||||
void hev_ring_buffer_read_release (HevRingBuffer *self, size_t size);
|
||||
|
||||
int hev_ring_buffer_writing (HevRingBuffer *self, struct iovec *iov);
|
||||
void hev_ring_buffer_write_finish (HevRingBuffer *self, size_t size);
|
||||
|
||||
#endif /* __HEV_RING_BUFFER_H__ */
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-utils.c
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2023 hev
|
||||
Description : Utils
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <Availability.h>
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#include <hev-socks5-misc.h>
|
||||
|
||||
#include "hev-logger.h"
|
||||
#include "hev-mapped-dns.h"
|
||||
|
||||
#include "hev-utils.h"
|
||||
|
||||
void
|
||||
run_as_daemon (const char *pid_file)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen (pid_file, "w+");
|
||||
if (!fp) {
|
||||
LOG_E ("open pid file %s", pid_file);
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#if !(TARGET_OS_TV)
|
||||
if (daemon (0, 0)) {
|
||||
/* ignore return value */
|
||||
}
|
||||
#endif
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
fprintf (fp, "%u\n", getpid ());
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
int
|
||||
set_limit_nofile (int limit_nofile)
|
||||
{
|
||||
struct rlimit limit;
|
||||
int res;
|
||||
|
||||
res = getrlimit (RLIMIT_NOFILE, &limit);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
limit.rlim_cur = limit.rlim_max;
|
||||
res = setrlimit (RLIMIT_NOFILE, &limit);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
limit.rlim_cur = limit_nofile;
|
||||
limit.rlim_max = limit_nofile;
|
||||
return setrlimit (RLIMIT_NOFILE, &limit);
|
||||
}
|
||||
|
||||
int
|
||||
set_sock_mark (int fd, unsigned int mark)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
return setsockopt (fd, SOL_SOCKET, SO_MARK, &mark, sizeof (mark));
|
||||
#elif defined(__FreeBSD__)
|
||||
return setsockopt (fd, SOL_SOCKET, SO_USER_COOKIE, &mark, sizeof (mark));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hev_socks5_addr_from_lwip (HevSocks5Addr *addr, const ip_addr_t *ip, u16_t port)
|
||||
{
|
||||
switch (ip->type) {
|
||||
case IPADDR_TYPE_V4: {
|
||||
HevMappedDNS *dns = hev_mapped_dns_get ();
|
||||
const char *name = NULL;
|
||||
if (dns)
|
||||
name = hev_mapped_dns_lookup (dns, ntohl (ip_2_ip4 (ip)->addr));
|
||||
if (name)
|
||||
hev_socks5_addr_from_name (addr, name, htons (port));
|
||||
else
|
||||
hev_socks5_addr_from_ipv4 (addr, ip, htons (port));
|
||||
return 0;
|
||||
}
|
||||
case IPADDR_TYPE_V6:
|
||||
hev_socks5_addr_from_ipv6 (addr, ip, htons (port));
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hev_socks5_addr_into_lwip (const HevSocks5Addr *addr, ip_addr_t *ip,
|
||||
u16_t *port)
|
||||
{
|
||||
switch (addr->atype) {
|
||||
case HEV_SOCKS5_ADDR_TYPE_IPV4:
|
||||
memcpy (ip, addr->ipv4.addr, 4);
|
||||
*port = ntohs (addr->ipv4.port);
|
||||
ip->type = IPADDR_TYPE_V4;
|
||||
return 0;
|
||||
case HEV_SOCKS5_ADDR_TYPE_IPV6:
|
||||
memcpy (ip, addr->ipv6.addr, 16);
|
||||
*port = ntohs (addr->ipv6.port);
|
||||
ip->type = IPADDR_TYPE_V6;
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-utils.h
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2023 hev
|
||||
Description : Utils
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __HEV_UTILS_H__
|
||||
#define __HEV_UTILS_H__
|
||||
|
||||
#include <lwip/ip_addr.h>
|
||||
#include <hev-socks5-proto.h>
|
||||
|
||||
void run_as_daemon (const char *pid_file);
|
||||
int set_limit_nofile (int limit_nofile);
|
||||
int set_sock_mark (int fd, unsigned int mark);
|
||||
|
||||
int hev_socks5_addr_from_lwip (HevSocks5Addr *addr, const ip_addr_t *ip,
|
||||
u16_t port);
|
||||
int hev_socks5_addr_into_lwip (const HevSocks5Addr *addr, ip_addr_t *ip,
|
||||
u16_t *port);
|
||||
|
||||
#endif /* __HEV_UTILS_H__ */
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-wintun.c
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2025 hev
|
||||
Description : Wintun utils
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#if defined(__MSYS__)
|
||||
|
||||
#include <wintun.h>
|
||||
#include <netioapi.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#include "hev-wintun.h"
|
||||
|
||||
static WINTUN_CREATE_ADAPTER_FUNC *WintunCreateAdapter;
|
||||
static WINTUN_CLOSE_ADAPTER_FUNC *WintunCloseAdapter;
|
||||
static WINTUN_GET_ADAPTER_LUID_FUNC *WintunGetAdapterLUID;
|
||||
static WINTUN_START_SESSION_FUNC *WintunStartSession;
|
||||
static WINTUN_END_SESSION_FUNC *WintunEndSession;
|
||||
static WINTUN_GET_READ_WAIT_EVENT_FUNC *WintunGetReadWaitEvent;
|
||||
static WINTUN_RECEIVE_PACKET_FUNC *WintunReceivePacket;
|
||||
static WINTUN_RELEASE_RECEIVE_PACKET_FUNC *WintunReleaseReceivePacket;
|
||||
static WINTUN_ALLOCATE_SEND_PACKET_FUNC *WintunAllocateSendPacket;
|
||||
static WINTUN_SEND_PACKET_FUNC *WintunSendPacket;
|
||||
|
||||
HevWinTun *
|
||||
hev_wintun_open (void)
|
||||
{
|
||||
HMODULE self;
|
||||
|
||||
self = LoadLibraryExW (L"wintun.dll", NULL,
|
||||
LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress (self, #Name)) == NULL)
|
||||
if (X (WintunCreateAdapter) || X (WintunCloseAdapter) ||
|
||||
X (WintunGetAdapterLUID) || X (WintunStartSession) ||
|
||||
X (WintunEndSession) || X (WintunGetReadWaitEvent) ||
|
||||
X (WintunReceivePacket) || X (WintunReleaseReceivePacket) ||
|
||||
X (WintunAllocateSendPacket) || X (WintunSendPacket))
|
||||
goto free;
|
||||
#undef X
|
||||
|
||||
return self;
|
||||
|
||||
free:
|
||||
FreeLibrary (self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
hev_wintun_close (HevWinTun *self)
|
||||
{
|
||||
FreeLibrary (self);
|
||||
}
|
||||
|
||||
HevWinTunAdapter *
|
||||
hev_wintun_adapter_create (const char *name)
|
||||
{
|
||||
wchar_t tun[256];
|
||||
int len;
|
||||
|
||||
len = MultiByteToWideChar (CP_UTF8, 0, name, -1, NULL, 0);
|
||||
if (len >= 256)
|
||||
return NULL;
|
||||
|
||||
MultiByteToWideChar (CP_UTF8, 0, name, -1, tun, len);
|
||||
return WintunCreateAdapter (tun, L"Socks5", NULL);
|
||||
}
|
||||
|
||||
void
|
||||
hev_wintun_adapter_close (HevWinTunAdapter *adapter)
|
||||
{
|
||||
WintunCloseAdapter (adapter);
|
||||
}
|
||||
|
||||
int
|
||||
hev_wintun_adapter_get_index (HevWinTunAdapter *adapter)
|
||||
{
|
||||
NET_LUID Luid;
|
||||
NET_IFINDEX index;
|
||||
|
||||
WintunGetAdapterLUID (adapter, &Luid);
|
||||
|
||||
if (ConvertInterfaceLuidToIndex (&Luid, &index) != NO_ERROR)
|
||||
return -1;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int
|
||||
hev_wintun_adapter_set_mtu (HevWinTunAdapter *adapter, int mtu)
|
||||
{
|
||||
NET_LUID Luid;
|
||||
MIB_IFROW IfRow;
|
||||
|
||||
WintunGetAdapterLUID (adapter, &Luid);
|
||||
|
||||
if (ConvertInterfaceLuidToIndex (&Luid, &IfRow.dwIndex) != NO_ERROR)
|
||||
return -1;
|
||||
|
||||
if (GetIfEntry (&IfRow) != NO_ERROR)
|
||||
return -1;
|
||||
|
||||
IfRow.dwMtu = mtu;
|
||||
|
||||
if (SetIfEntry (&IfRow) != NO_ERROR)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hev_wintun_adapter_set_ipv4 (HevWinTunAdapter *adapter, char addr[4],
|
||||
unsigned int prefix)
|
||||
{
|
||||
MIB_UNICASTIPADDRESS_ROW AddressRow;
|
||||
DWORD LastError;
|
||||
|
||||
InitializeUnicastIpAddressEntry (&AddressRow);
|
||||
WintunGetAdapterLUID (adapter, &AddressRow.InterfaceLuid);
|
||||
|
||||
AddressRow.Address.Ipv4.sin_family = AF_INET;
|
||||
memcpy (&AddressRow.Address.Ipv4.sin_addr, addr, 4);
|
||||
AddressRow.OnLinkPrefixLength = prefix;
|
||||
AddressRow.DadState = IpDadStatePreferred;
|
||||
|
||||
LastError = CreateUnicastIpAddressEntry (&AddressRow);
|
||||
if (LastError != ERROR_SUCCESS && LastError != ERROR_OBJECT_ALREADY_EXISTS)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hev_wintun_adapter_set_ipv6 (HevWinTunAdapter *adapter, char addr[16],
|
||||
unsigned int prefix)
|
||||
{
|
||||
MIB_UNICASTIPADDRESS_ROW AddressRow;
|
||||
DWORD LastError;
|
||||
|
||||
InitializeUnicastIpAddressEntry (&AddressRow);
|
||||
WintunGetAdapterLUID (adapter, &AddressRow.InterfaceLuid);
|
||||
|
||||
AddressRow.Address.Ipv6.sin6_family = AF_INET6;
|
||||
memcpy (&AddressRow.Address.Ipv6.sin6_addr, addr, 16);
|
||||
AddressRow.OnLinkPrefixLength = prefix;
|
||||
AddressRow.DadState = IpDadStatePreferred;
|
||||
|
||||
LastError = CreateUnicastIpAddressEntry (&AddressRow);
|
||||
if (LastError != ERROR_SUCCESS && LastError != ERROR_OBJECT_ALREADY_EXISTS)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HevWinTunSession *
|
||||
hev_wintun_session_start (HevWinTunAdapter *adapter)
|
||||
{
|
||||
return WintunStartSession (adapter, 0x400000);
|
||||
}
|
||||
|
||||
void
|
||||
hev_wintun_session_stop (HevWinTunSession *session)
|
||||
{
|
||||
WintunEndSession (session);
|
||||
}
|
||||
|
||||
void *
|
||||
hev_wintun_session_get_read_wait_event (HevWinTunSession *session)
|
||||
{
|
||||
return WintunGetReadWaitEvent (session);
|
||||
}
|
||||
|
||||
void *
|
||||
hev_wintun_session_receive (HevWinTunSession *session, int *size)
|
||||
{
|
||||
return WintunReceivePacket (session, (DWORD *)size);
|
||||
}
|
||||
|
||||
void
|
||||
hev_wintun_session_release (HevWinTunSession *session, void *packet)
|
||||
{
|
||||
WintunReleaseReceivePacket (session, packet);
|
||||
}
|
||||
|
||||
void *
|
||||
hev_wintun_session_allocate (HevWinTunSession *session, int size)
|
||||
{
|
||||
return WintunAllocateSendPacket (session, size);
|
||||
}
|
||||
|
||||
void
|
||||
hev_wintun_session_send (HevWinTunSession *session, void *packet)
|
||||
{
|
||||
WintunSendPacket (session, packet);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hev_wintun_get_last_error (void)
|
||||
{
|
||||
return GetLastError ();
|
||||
}
|
||||
|
||||
#endif /* __MSYS__ */
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
============================================================================
|
||||
Name : hev-wintun.h
|
||||
Author : hev <r@hev.cc>
|
||||
Copyright : Copyright (c) 2025 hev
|
||||
Description : Wintun utils
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __HEV_WINTUN_H__
|
||||
#define __HEV_WINTUN_H__
|
||||
|
||||
#define HEV_WINTUN_EAGAIN (259)
|
||||
|
||||
typedef void HevWinTun;
|
||||
typedef void HevWinTunAdapter;
|
||||
typedef void HevWinTunSession;
|
||||
|
||||
HevWinTun *hev_wintun_open (void);
|
||||
void hev_wintun_close (HevWinTun *self);
|
||||
|
||||
HevWinTunAdapter *hev_wintun_adapter_create (const char *name);
|
||||
void hev_wintun_adapter_close (HevWinTunAdapter *adapter);
|
||||
|
||||
int hev_wintun_adapter_get_index (HevWinTunAdapter *adapter);
|
||||
int hev_wintun_adapter_set_mtu (HevWinTunAdapter *adapter, int mtu);
|
||||
int hev_wintun_adapter_set_ipv4 (HevWinTunAdapter *adapter, char addr[4],
|
||||
unsigned int prefix);
|
||||
int hev_wintun_adapter_set_ipv6 (HevWinTunAdapter *adapter, char addr[16],
|
||||
unsigned int prefix);
|
||||
|
||||
HevWinTunSession *hev_wintun_session_start (HevWinTunAdapter *adapter);
|
||||
void hev_wintun_session_stop (HevWinTunSession *session);
|
||||
|
||||
void *hev_wintun_session_get_read_wait_event (HevWinTunSession *session);
|
||||
|
||||
void *hev_wintun_session_receive (HevWinTunSession *session, int *size);
|
||||
void hev_wintun_session_release (HevWinTunSession *session, void *packet);
|
||||
|
||||
void *hev_wintun_session_allocate (HevWinTunSession *session, int size);
|
||||
void hev_wintun_session_send (HevWinTunSession *session, void *packet);
|
||||
|
||||
unsigned int hev_wintun_get_last_error (void);
|
||||
|
||||
#endif /* __HEV_WINTUN_H__ */
|
||||
Reference in New Issue
Block a user