From 1930984106282abbd161bd88a08c91828aaeb6f2 Mon Sep 17 00:00:00 2001 From: Andrew Gree Date: Thu, 10 Jun 2021 08:01:03 -0700 Subject: [PATCH 1/2] add SO_MARK support as compile-time flag --- README.md | 14 ++++++++++++++ sockssrv.c | 23 +++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/README.md b/README.md index cc5b9a3..ecfa550 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,17 @@ Supported SOCKS5 Features - IPv4, IPv6, DNS - TCP (no UDP at this time) +compile time options +-------------------- + + make CFLAGS=-DSOMARK + +microsocks can be compiled with SO_MARK support on linux 2.6.25+. This +enables 'marking' of outgoing packets for use with policy-based routing +which allows to route packets through a non-default interface. E.g.: + + ip rule add fwmark 1000 table 200 + ip route add default dev tun1 table 200 + microsocks -m 1000 + +will route all connections through device `tun1` \ No newline at end of file diff --git a/sockssrv.c b/sockssrv.c index 98e4622..5ae1114 100644 --- a/sockssrv.c +++ b/sockssrv.c @@ -54,6 +54,10 @@ #define THREAD_STACK_SIZE 32*1024 #endif +#if defined(SOMARK) +int somark; /* mark outgoing connections' packets for adv. routing */ +#endif + static const char* auth_user; static const char* auth_pass; static sblist* auth_ips; @@ -167,6 +171,11 @@ static int connect_socks_target(unsigned char *buf, size_t n, struct client *cli } if(SOCKADDR_UNION_AF(&bind_addr) != AF_UNSPEC && bindtoip(fd, &bind_addr) == -1) goto eval_errno; +#if defined(SOMARK) + if(somark != 0) { + setsockopt(fd, SOL_SOCKET, SO_MARK, &somark, sizeof(somark)); + } +#endif if(connect(fd, remote->ai_addr, remote->ai_addrlen) == -1) goto eval_errno; @@ -364,10 +373,16 @@ static int usage(void) { "MicroSocks SOCKS5 Server\n" "------------------------\n" "usage: microsocks -1 -i listenip -p port -u user -P password -b bindaddr\n" +#if defined(SOMARK) + " -m mark\n" +#endif "all arguments are optional.\n" "by default listenip is 0.0.0.0 and port 1080.\n\n" "option -b specifies which ip outgoing connections are bound to\n" "option -1 activates auth_once mode: once a specific ip address\n" +#if defined(SOMARK) + "option -m marks outgoing connections' packets with specified SO_MARK id\n" +#endif "authed successfully with user/pass, it is added to a whitelist\n" "and may use the proxy without auth.\n" "this is handy for programs like firefox that don't support\n" @@ -387,6 +402,9 @@ int main(int argc, char** argv) { int ch; const char *listenip = "0.0.0.0"; unsigned port = 1080; +#if defined(SOMARK) + somark = 0; +#endif while((ch = getopt(argc, argv, ":1b:i:p:u:P:")) != -1) { switch(ch) { case '1': @@ -409,6 +427,11 @@ int main(int argc, char** argv) { case 'p': port = atoi(optarg); break; +#if defined(SOMARK) + case 'm': + somark = atoi(optarg); + break; +#endif case ':': dprintf(2, "error: option -%c requires an operand\n", optopt); /* fall through */ From e74a563cef81a8f5f4de3563ced1c614cda8b764 Mon Sep 17 00:00:00 2001 From: Andrew Gree Date: Sat, 12 Jun 2021 08:24:49 -0700 Subject: [PATCH 2/2] fixed forgotten getopt def for -m --- sockssrv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sockssrv.c b/sockssrv.c index 5ae1114..a8f5fe4 100644 --- a/sockssrv.c +++ b/sockssrv.c @@ -404,8 +404,10 @@ int main(int argc, char** argv) { unsigned port = 1080; #if defined(SOMARK) somark = 0; -#endif + while((ch = getopt(argc, argv, ":1b:i:m:p:u:P:")) != -1) { +#else while((ch = getopt(argc, argv, ":1b:i:p:u:P:")) != -1) { +#endif switch(ch) { case '1': auth_ips = sblist_new(sizeof(union sockaddr_union), 8);