Closed jadeblaquiere closed 6 years ago
The interface has been simplified down to:
int socks5_client_connect(int s, const char *username, const char *password,
struct ipaddr *addr, int64_t deadline);
int socks5_client_connectbyname(int s, const char *username, const char *password,
const char *hostname, int port, int64_t deadline);
username and password can be null, and if hostname is provide the hostname is passed on to the proxy for the proxy to resolve.
Nice! That looks much cleaner.
So here's the proxy API:
typedef int socks5_auth_function(const char *username, const char *password);
int socks5_proxy_auth(int s, socks5_auth_function *auth_fn, int64_t deadline);
int socks5_proxy_recvcommand(int s, struct ipaddr *ipaddr, int64_t deadline);
int socks5_proxy_recvcommandbyname(int s, char *host, int *port, int64_t deadline);
int socks5_proxy_sendreply(int s, int reply, struct ipaddr *ipaddr, int64_t deadline);
I intentionally left these calls separate as the proxy either must or may have some actions between the calls (e.g. log "auth" for a specific user before command or after receiving a CONNECT request, the proxy needs to establish the connection before replying SUCCESS). Also, as the proxy may have it's own custom name resolution there is the option to receive the name the client requested instead of an IP address.
I've also added man page and website updates.
Review welcome.
I am mystified by the Travis failures. It seems to be hanging on tests/socks5 but no meaningful error condition. I've run these build configs on OSX 10.13.6 for 10000 iterations and no failures (or even slowness... it's a quick test case). Any ideas?
I added a fully functional SOCKS5 proxy as examples/socks5proxy.c to illustrate the API. It works nicely with Firefox, curl and tutorial/sockets/step5.c wget client. This example also brings together the network and concurrency APIs. I personally find an example often makes things much clearer.
OK, I've read the RFC and I have some questions for you.
As I see, the protocold uses 2 or 3 handshakes:
That's pretty flexible. But the RFC is 20 years old, so I guess the usage has already stabilized on subset of possible functionality:
Yes, some implementations (e.g. ss5, Dante) support passing and validating a token via GSS-API (typically backed by Kerberos).
All three in practice. Every implementation supports connect, but I would say most also support bind. udp associate is supported in more than half the implementations.
There are a number of implementations (ss5, shadowsocks, Dante) and even a number of providers that support socks5 as a lightweight VPN (e.g. NordVPN, BTGuard) targeted at specific use cases (e.g. bittorrent, gaming).
OK, fair enough. At the moment I have no concrete proposal of how to improve the API. I will merge it in as experimental feature, subject to future change.
Btw, the socks5 test isn't hermetic (it tries to connect to libdill.org). Can you rather create your own local server and connect to that, so that the test is not affected by extrinsic factors?
Another test failure:
tests/socks5.log: Assertion failed: (cmd > 0), function proxy, file tests/socks5.c, line 77. testing IP, NO AUTH FAIL tests/socks5 (exit status: 134)
While this is far from a complete work (still working on server side protocol, tests and man page entries, for instance...), I wanted to push this out for review and comment.
The client example in tutorial/sockets/step5.c does work nicely with the two different SOCKS5 implementations (microsocks and tor) that I have tested against manually.
I've tried to follow style and naming but I won't be at all offended if you suggest some changes.