From 5529d0ae25289843c5a238da24aceffba4c5a73b Mon Sep 17 00:00:00 2001 From: Er2 Date: Sun, 11 Aug 2024 12:55:12 +0300 Subject: [PATCH] FreeBSD support --- Makefile | 2 +- desync.c | 36 +++++++++++++++++++++++++++++------- extend.c | 7 ++++--- main.c | 8 ++++++-- packets.c | 4 ++++ params.h | 8 ++++++++ proxy.c | 11 +++++------ proxy.h | 1 + 8 files changed, 58 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 40f6708..5338798 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TARGET = ciadpi -CPPFLAGS = -D_XOPEN_SOURCE=500 +CPPFLAGS = -D_XOPEN_SOURCE=600 -D__BSD_VISIBLE=1 CFLAGS += -I. -std=c99 -Wall -Wno-unused -O2 WIN_LDFLAGS = -lws2_32 -lmswsock diff --git a/desync.c b/desync.c index a87496a..8884a9b 100644 --- a/desync.c +++ b/desync.c @@ -12,13 +12,14 @@ #include #include #include - - #ifdef __linux__ + #include - #include + #ifdef __linux__ + #include + #endif #include - + #ifdef __linux__ #ifdef MFD_CLOEXEC #include #define memfd_create(name, flags) syscall(__NR_memfd_create, name, flags); @@ -83,7 +84,7 @@ static inline void delay(long ms) #define delay(ms) Sleep(ms) #endif -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) void wait_send(int sfd) { for (int i = 0; params.wait_send && i < 500; i++) { @@ -119,7 +120,7 @@ void wait_send(int sfd) #define wait_send_if_support(sfd) // :( #endif -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) ssize_t send_fake(int sfd, char *buffer, int cnt, long pos, int fa, struct desync_params *opt) { @@ -166,11 +167,18 @@ ssize_t send_fake(int sfd, char *buffer, break; } if (opt->md5sig) { +#ifdef __linux__ struct tcp_md5sig md5 = { .tcpm_keylen = 5 }; memcpy(&md5.tcpm_addr, &addr, addr_size); - +#elif defined(__FreeBSD__) + // FIXME: Should be struct tcpmd5_support + // but netipsec/ipsec_support.h hides this under ifdef KERNEL + int md5 = 1; +#else +#error +#endif if (setsockopt(sfd, IPPROTO_TCP, TCP_MD5SIG, (char *)&md5, sizeof(md5)) < 0) { uniperror("setsockopt TCP_MD5SIG"); @@ -184,7 +192,15 @@ ssize_t send_fake(int sfd, char *buffer, break; } +#ifdef __linux__ len = sendfile(sfd, ffd, 0, pos); +#else + int ret = sendfile(ffd, sfd, 0, pos, NULL, &len, 0); + if (ret < 0) { + uniperror("sendfile"); + break; + } +#endif if (len < 0) { uniperror("sendfile"); break; @@ -202,10 +218,16 @@ ssize_t send_fake(int sfd, char *buffer, break; } if (opt->md5sig) { +#ifdef __linux__ struct tcp_md5sig md5 = { .tcpm_keylen = 0 }; memcpy(&md5.tcpm_addr, &addr, addr_size); +#elif defined(__FreeBSD__) + int md5 = 0; +#else +#error +#endif if (setsockopt(sfd, IPPROTO_TCP, TCP_MD5SIG, (char *)&md5, sizeof(md5)) < 0) { diff --git a/extend.c b/extend.c index d5d6d59..56f2d35 100644 --- a/extend.c +++ b/extend.c @@ -33,15 +33,16 @@ int set_timeout(int fd, unsigned int s) uniperror("setsockopt TCP_USER_TIMEOUT"); return -1; } - #else - #ifdef _WIN32 + #elif defined(__FreeBSD__) + // https://wiki.freebsd.org/CatalinNicutar/TCPUTO + // sadly not yet available + #elif defined(_WIN32) if (setsockopt(fd, IPPROTO_TCP, TCP_MAXRT, (char *)&s, sizeof(s))) { uniperror("setsockopt TCP_MAXRT"); return -1; } #endif - #endif return 0; } diff --git a/main.c b/main.c index 19e0c2b..6ec35bf 100644 --- a/main.c +++ b/main.c @@ -24,6 +24,10 @@ #define close(fd) closesocket(fd) #endif +#ifdef __FreeBSD__ + #include +#endif + #define VERSION "12" char oob_char[1] = "a"; @@ -94,7 +98,7 @@ const char help_text[] = { #ifdef FAKE_SUPPORT " -f, --fake Split and send fake packet\n" " -t, --ttl TTL of fake packets, default 8\n" - #ifdef __linux__ + #if defined(__linux__) || defined(__FreeBSD__) " -k, --ip-opt[=f|:str] IP options of fake packets\n" " -S, --md5sig Add MD5 Signature option for fake packets\n" #endif @@ -138,7 +142,7 @@ const struct option options[] = { #ifdef FAKE_SUPPORT {"fake", 1, 0, 'f'}, {"ttl", 1, 0, 't'}, - #ifdef __linux__ + #if defined(__linux__) || defined(__FreeBSD__) {"ip-opt", 2, 0, 'k'}, {"md5sig", 0, 0, 'S'}, #endif diff --git a/packets.c b/packets.c index ebe4d39..2b0ea48 100644 --- a/packets.c +++ b/packets.c @@ -15,6 +15,10 @@ #include #endif +#ifdef __FreeBSD__ + #include +#endif + #define ANTOHS(data, i) \ (uint16_t)((data[i] << 8) + (uint8_t)data[i + 1]) diff --git a/params.h b/params.h index a8ff74b..5e4b542 100644 --- a/params.h +++ b/params.h @@ -9,12 +9,20 @@ #ifdef _WIN32 #include #else + #include #include #endif +#ifdef __FreeBSD__ + #include +#endif + #if defined(__linux__) || defined(_WIN32) #define FAKE_SUPPORT 1 #define TIMEOUT_SUPPORT 1 +#elif defined(__FreeBSD__) +#define FAKE_SUPPORT 1 +// TIMEOUT_SUPPORT can't be used #endif #define OFFSET_SNI 1 diff --git a/proxy.c b/proxy.c index c938857..a9c7b7c 100644 --- a/proxy.c +++ b/proxy.c @@ -82,7 +82,7 @@ static inline char addr_equ( static inline int nb_socket(int domain, int type) { - #ifdef __linux__ + #if defined(__linux__) || defined(__FreeBSD__) int fd = socket(domain, type | SOCK_NONBLOCK, 0); #else int fd = socket(domain, type, 0); @@ -98,15 +98,13 @@ static inline int nb_socket(int domain, int type) close(fd); return -1; } - #else - #ifndef __linux__ + #elif !defined(__linux__) if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { uniperror("fcntl"); close(fd); return -1; } #endif - #endif return fd; } @@ -517,7 +515,7 @@ static inline int on_accept(struct poolhd *pool, struct eval *val) while (1) { socklen_t len = sizeof(client); - #ifdef __linux__ + #if defined(__linux__) || defined(__FreeBSD__) int c = accept4(val->fd, &client.sa, &len, SOCK_NONBLOCK); #else int c = accept(val->fd, &client.sa, &len); @@ -940,7 +938,8 @@ int listen_socket(struct sockaddr_ina *srv) close(srvfd); return -1; } - if (bind(srvfd, &srv->sa, sizeof(*srv)) < 0) { + size_t size = srv->sa.sa_family == AF_INET6 ? sizeof(srv->in6) : sizeof(srv->in); + if (bind(srvfd, &srv->sa, size) < 0) { uniperror("bind"); close(srvfd); return -1; diff --git a/proxy.h b/proxy.h index 43e5756..ee43834 100644 --- a/proxy.h +++ b/proxy.h @@ -7,6 +7,7 @@ #include #else #include + #include #endif #include "conev.h"