From c1beceb24b4a7a6b984c5f7ff5f251f83d03d869 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 28 Jun 2022 12:50:48 +0300 Subject: [PATCH] Support IP_BOUND_IF on MacOS --- src/common.c | 10 ++++++++++ src/proxymain.c | 26 ++++++++++++++++++++++---- src/structures.h | 2 +- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/common.c b/src/common.c index b4e85d5..d584632 100644 --- a/src/common.c +++ b/src/common.c @@ -436,6 +436,16 @@ int doconnect(struct clientparam * param){ if(so._setsockopt(param->remsock, SOL_SOCKET, SO_BINDTODEVICE, param->srv->obindtodevice, strlen(param->srv->obindtodevice) + 1)) return 12; } +#elseif IP_BOUND_IF + if(param->srv->obindtodevice) { + int idx; + idx = if_nametoindex(param->srv->obindtodevice) + if(!idx || so._setsockopt(param->remsock, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx))) + return 12; +#ifndef NOIPV6 + if(param->srv->family != 4 && so._setsockopt(param->remsock, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx))) return 12; +#endif + } #endif if(SAISNULL(¶m->sinsl)){ #ifndef NOIPV6 diff --git a/src/proxymain.c b/src/proxymain.c index e5cdda1..1312e9d 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -216,7 +216,7 @@ int MODULEMAINFUNC (int argc, char** argv){ " -u never ask for username\n" " -u2 always ask for username\n" #endif -#ifdef SO_BINDTODEVICE +#if defined SO_BINDTODEVICE || defined IP_BOUND_IF " -Di(DEVICENAME) bind internal interface to device, e.g. eth1\n" " -De(DEVICENAME) bind external interface to device, e.g. eth1\n" #endif @@ -323,7 +323,7 @@ int MODULEMAINFUNC (int argc, char** argv){ if(!conf.demon)daemonize(); conf.demon = 1; break; -#ifdef SO_BINDTODEVICE +#if defined SO_BINDTODEVICE || defined IP_BOUND_IF case 'D': if(argv[i][2] == 'i') srv.ibindtodevice = mystrdup(argv[i] + 3); else srv.obindtodevice = mystrdup(argv[i] + 3); @@ -611,7 +611,25 @@ int MODULEMAINFUNC (int argc, char** argv){ so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int)); #endif #ifdef SO_BINDTODEVICE - if(srv.ibindtodevice) so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv.ibindtodevice, strlen(srv.ibindtodevice) + 1); + if(srv.ibindtodevice && so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv.ibindtodevice, strlen(srv.ibindtodevice) + 1)) { + dolog(&defparam, "failed to bind device"); + return -12; + } +#elseif IP_BOUND_IF + if(srv.ibindtodevice){ + int idx; + idx = if_nametoindex(srv.ibindtodevice); + if(!idx || setsockopt(sockfd, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx))) { + dolog(&defparam, "failed to bind device"); + return -12; + } +#ifndef NOIPV6 + if(so._setsockopt(param->remsock, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx))) { + dolog(&defparam, "failed to bind device"); + return -12; + } +#endif + } #endif } size = sizeof(srv.intsa); @@ -974,7 +992,7 @@ void srvfree(struct srvparam * srv){ if(srv->logtarget) myfree(srv->logtarget); if(srv->logformat) myfree(srv->logformat); if(srv->nonprintable) myfree(srv->nonprintable); -#ifdef SO_BINDTODEVICE +#if defined SO_BINDTODEVICE || defined IP_BOUND_IF if(srv->ibindtodevice) myfree(srv->ibindtodevice); if(srv->obindtodevice) myfree(srv->obindtodevice); #endif diff --git a/src/structures.h b/src/structures.h index 3de7795..0423ff2 100644 --- a/src/structures.h +++ b/src/structures.h @@ -457,7 +457,7 @@ struct srvparam { struct pollfd fds; FILE *stdlog; unsigned char * target; -#ifdef SO_BINDTODEVICE +#if defined SO_BINDTODEVICE || defined IP_BOUND_IF char * ibindtodevice; char * obindtodevice; #endif