niklata / muonsocks

SOCKS5 and SOCKS4a proxy server
MIT License
12 stars 0 forks source link

Fails to build on Mac OSX #4

Open XeonG opened 2 months ago

XeonG commented 2 months ago
make                                                                                                                                                                               ─╯
cc -MMD -O2 -flto -s -std=c17 -I. -Wall -pedantic -Wextra -Wformat=2 -Wformat-nonliteral -Wformat-security -Wshadow -Wpointer-arith -Wmissing-prototypes -Wcast-qual -Wsign-conversion -Wstrict-overflow=5 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -D_GNU_SOURCE   -c -o main.o main.c
clang: warning: argument unused during compilation: '-s' [-Wunused-command-line-argument]
main.c:154:17: warning: format string is not a string literal [-Wformat-nonliteral]
    vdprintf(2, format, args);
                ^~~~~~
main.c:313:61: error: use of undeclared identifier 'SOCK_CLOEXEC'
        if ((listenfd = socket(p->ai_family, p->ai_socktype|SOCK_CLOEXEC|SOCK_NONBLOCK, p->ai_protocol)) < 0)
                                                            ^
main.c:313:74: error: use of undeclared identifier 'SOCK_NONBLOCK'
        if ((listenfd = socket(p->ai_family, p->ai_socktype|SOCK_CLOEXEC|SOCK_NONBLOCK, p->ai_protocol)) < 0)
                                                                         ^
main.c:358:16: error: call to undeclared function 'reallocarray'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    auth_ips = reallocarray(auth_ips, nauth_ips + 1, sizeof(union sockaddr_union));
               ^
main.c:358:14: error: incompatible integer to pointer conversion assigning to 'union sockaddr_union *' from 'int' [-Wint-conversion]
    auth_ips = reallocarray(auth_ips, nauth_ips + 1, sizeof(union sockaddr_union));
             ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:470:39: error: use of undeclared identifier 'MSG_DONTWAIT'
        n = recv(infd, buf, BUF_SIZE, MSG_DONTWAIT);
                                      ^
main.c:760:37: error: use of undeclared identifier 'SOCK_CLOEXEC'
    fd = socket(family, SOCK_STREAM|SOCK_CLOEXEC, 0);
                                    ^
main.c:762:20: warning: implicit conversion changes signedness: 'enum errorcode' to 'int' [-Wsign-conversion]
        ctx.errc = errno_to_sockscode();
                 ~ ^~~~~~~~~~~~~~~~~~~~
main.c:770:20: warning: implicit conversion changes signedness: 'enum errorcode' to 'int' [-Wsign-conversion]
        ctx.errc = errno_to_sockscode();
                 ~ ^~~~~~~~~~~~~~~~~~~~
main.c:775:20: warning: implicit conversion changes signedness: 'enum errorcode' to 'int' [-Wsign-conversion]
        ctx.errc = errno_to_sockscode();
                 ~ ^~~~~~~~~~~~~~~~~~~~
main.c:798:46: warning: implicit conversion changes signedness: 'int' to 'enum errorcode' [-Wsign-conversion]
    send_error(&t->client, t->client.fd, ctx.errc);
    ~~~~~~~~~~                           ~~~~^~~~
main.c:838:16: error: call to undeclared function 'reallocarray'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    ban_dest = reallocarray(ban_dest, nban_dest + 1, sizeof(struct bandst));
               ^
main.c:838:14: error: incompatible integer to pointer conversion assigning to 'struct bandst *' from 'int' [-Wint-conversion]
    ban_dest = reallocarray(ban_dest, nban_dest + 1, sizeof(struct bandst));
             ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:889:21: error: call to undeclared function 'reallocarray'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
            srvrs = reallocarray(srvrs, nsrvrs + 1, sizeof(struct server));
                    ^
main.c:889:19: error: incompatible integer to pointer conversion assigning to 'struct server *' from 'int' [-Wint-conversion]
            srvrs = reallocarray(srvrs, nsrvrs + 1, sizeof(struct server));
                  ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:917:17: error: call to undeclared function 'reallocarray'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
        srvrs = reallocarray(srvrs, nsrvrs + 1, sizeof(struct server));
                ^
main.c:917:15: error: incompatible integer to pointer conversion assigning to 'struct server *' from 'int' [-Wint-conversion]
        srvrs = reallocarray(srvrs, nsrvrs + 1, sizeof(struct server));
              ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings and 12 errors generated.
make: *** [main.o] Error 1
niklata commented 1 month ago

(replied by email yesterday but it didn't appear here in the tracker, so I'm duplicating it)

reallocarray() is present on glibc >=2.26 and originated from OpenBSD. SOCK_CLOEXEC is a Linux and BSD extension that is a few years old as well. MSG_DONTWAIT is around since Linux 2.2 (from the 90s) and is also present in the BSDs. How old is the system that you're trying to build on, and what OS is it running?

rofl0r commented 1 month ago

according to the issue he opened on my repo, he's using a mac, and it seems likely he won't respond anymore.

niklata commented 1 month ago

Thanks, I'll close out the bug then. I would have expected Mac to more closely conform to the BSDs, but it's not a platform that I can easily test against, anyway.

XeonG commented 1 month ago

I didn't see it, yes it was on a OSX Mac is always updated but I'm not into build scripts, if there is something I can do to update the build pipeline let me know as I'm trying to get this working.. @rofl0r just seen the reply

niklata commented 1 month ago

It's an issue of OSX lacking features that are present on other commonly-used platforms and isn't simply a build system fix. Most of these have been around for quite a number of years and I'm surprised OSX lacks support.

For muonsocks, you'd need to:

1) Reimplement reallocarray() or find a library that provides it (maybe libbsd?). The tricky thing in implementing reallocarray() is avoiding UB from integer overflows that is easiest to do by using compiler built-ins (present on gcc and clang or standardized in C23) or relatively tricky checks written in pure pre-C23 C.

The other missing syscall flags are used for various reasons, often to avoid syscall overheads.

2) MSG_DONTWAIT is used so that reads are non-blocking while allowing writes to block; this allows the buffer size within muonsocks to be controlled and bounded and also avoids calls to poll(). This is a non-trivial change and requires restructuring the core loop that proxies reads and writes between client and server, and would come at the cost of more syscalls [both fcntl() per-connection and more poll() calls for every read/write cycle]. I don't know if a similar but differently named flag exists on OSX, but if it did, that would also be a solution.

3) SOCK_CLOEXEC is a way to avoid another syscall, it could be worked around but would have to be conditional to OSX as it's a performance pessimization on other platforms.

I think it's probably better to use microsocks instead, as these changes would remove a lot of the optimizations that have been done in muonsocks.