diff --git a/binaries/aarch64/tpws b/binaries/aarch64/tpws index 3ed1b18..61209ec 100755 Binary files a/binaries/aarch64/tpws and b/binaries/aarch64/tpws differ diff --git a/binaries/arm/tpws b/binaries/arm/tpws index 25ca89d..2e1a020 100755 Binary files a/binaries/arm/tpws and b/binaries/arm/tpws differ diff --git a/binaries/mac64/tpws b/binaries/mac64/tpws index c44a6fd..6945635 100755 Binary files a/binaries/mac64/tpws and b/binaries/mac64/tpws differ diff --git a/binaries/mips32r1-lsb/tpws b/binaries/mips32r1-lsb/tpws index a33ea13..2f3c4ae 100755 Binary files a/binaries/mips32r1-lsb/tpws and b/binaries/mips32r1-lsb/tpws differ diff --git a/binaries/mips32r1-msb/tpws b/binaries/mips32r1-msb/tpws index 86ba961..bcef5b6 100755 Binary files a/binaries/mips32r1-msb/tpws and b/binaries/mips32r1-msb/tpws differ diff --git a/binaries/mips64r2-msb/tpws b/binaries/mips64r2-msb/tpws index 1f97eb7..84e5c2a 100755 Binary files a/binaries/mips64r2-msb/tpws and b/binaries/mips64r2-msb/tpws differ diff --git a/binaries/ppc/tpws b/binaries/ppc/tpws index 1cc9719..9ccd3a3 100755 Binary files a/binaries/ppc/tpws and b/binaries/ppc/tpws differ diff --git a/binaries/x86/tpws b/binaries/x86/tpws index 571bd38..4cf32a9 100755 Binary files a/binaries/x86/tpws and b/binaries/x86/tpws differ diff --git a/binaries/x86_64/tpws b/binaries/x86_64/tpws index 3742865..56637ac 100755 Binary files a/binaries/x86_64/tpws and b/binaries/x86_64/tpws differ diff --git a/docs/readme.eng.txt b/docs/readme.eng.txt index a3e268c..41a6219 100644 --- a/docs/readme.eng.txt +++ b/docs/readme.eng.txt @@ -260,7 +260,11 @@ tpws is transparent proxy. --bind-addr=|; for v6 link locals append %interface_name : fe80::1%br-lan --bind-iface4= ; bind to the first ipv4 addr of interface --bind-iface6= ; bind to the first ipv6 addr of interface - --bind-linklocal=prefer|force ; prefer or force ipv6 link local + --bind-linklocal=no|unwanted|prefer|force + ; no : bind only to global ipv6 + ; unwanted (default) : prefer global address, then LL + ; prefer : prefer LL, then global + ; force : LL only --bind-wait-ifup= ; wait for interface to appear and up --bind-wait-ip= ; after ifup wait for ip address to appear up to N seconds --bind-wait-ip-linklocal= ; accept only link locals first N seconds then any @@ -306,8 +310,12 @@ tpws can bind to multiple interfaces and IP addresses (up to 32). Port number is always the same. Parameters --bind-iface* и --bind-addr create new bind. Other parameters --bind-* are related to the last bind. ---bind-iface6 without --bind-linklocal first selects a private address fd00::/8 then a global address, and last link local. ---bind-iface6 with --bind-linklocal=prefer first selects link local then a private address fd00::/8 then a global address. +Выбор режима использования link local ipv6 адресов (fe80:://8) : +ipv6 link local usage modes : +--bind-iface6 --bind-linklocal=no : first selects private address fd00::/8, then global address +--bind-iface6 --bind-linklocal=unwanted : first selects private address fd00::/8, then global address, then LL +--bind-iface6 --bind-linklocal=prefer : first selects LL, then private address fd00::/8, then global address +--bind-iface6 --bind-linklocal=force : select only LL To bind to all ipv4 specify --bind-addr "0.0.0.0", all ipv6 - "::". --bind-addr="" - mean bind to all ipv4 and ipv6. If no binds are specified default bind to all ipv4 and ipv6 addresses is created. To bind to a specific link local address do : --bind-iface6=fe80::aaaa:bbbb:cccc:dddd%iface-name diff --git a/docs/readme.txt b/docs/readme.txt index a258145..3d4287a 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -313,13 +313,19 @@ tpws - это transparent proxy. --uid=uid[:gid] ; менять uid процесса --bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес ; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan - --bind-linklocal=prefer|force ; если prefer, то найти link local от iface6. если не найдено - использовать первый адрес любого типа. - ; если force и link local не найден - выход по ошибке. + --bind-linklocal=no|unwanted|prefer|force + ; no : биндаться только на global ipv6 + ; unwanted (default) : предпочтительно global, если нет - LL + ; prefer : предпочительно LL, если нет - global + ; force : биндаться только на LL --bind-iface4= ; слушать на первом ipv4 интерфейса iface --bind-iface6= ; слушать на первом ipv6 интерфейса iface --bind-wait-ifup= ; ждать до N секунд появления и поднятия интерфейса --bind-wait-ip= ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса) - --bind-wait-ip-linklocal= ; (только если заданы --bind-wait-ip и --bind-linklocal=prefer) согласиться на global address после N секунд + --bind-wait-ip-linklocal= + ; имеет смысл только при задании --bind-wait-ip + ; --bind-linklocal=unwanted : согласиться на LL после N секунд + ; --bind-linklocal=prefer : согласиться на global address после N секунд --bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0. --socks ; вместо прозрачного прокси реализовать socks4/5 proxy --no-resolve ; запретить ресолвинг имен через socks5 @@ -389,9 +395,11 @@ tpws может биндаться на множество интерфейсо Параметры --bind-iface* и --bind-addr создают новый бинд. Остальные параметры --bind-* относятся к последнему бинду. Для бинда на все ipv4 укажите --bind-addr "0.0.0.0", на все ipv6 - "::". --bind-addr="" - биндаемся на все ipv4 и ipv6. ---bind-iface6 без --bind-linklocal выбирает сначала приватный адрес fd00::/8, затем глобальный адрес, затем link local. ---bind-iface6 с --bind-linklocal=prefer выбирает сначала link local, затем приватный адрес fd00::/8, затем глобальный адрес. ---bind-iface6 с --bind-linklocal=force выбирает только link local +Выбор режима использования link local ipv6 адресов (fe80:://8) : +--bind-iface6 --bind-linklocal=no : сначала приватный адрес fd00::/8, затем глобальный адрес +--bind-iface6 --bind-linklocal=unwanted : сначала приватный адрес fd00::/8, затем глобальный адрес, затем link local. +--bind-iface6 --bind-linklocal=prefer : сначала link local, затем приватный адрес fd00::/8, затем глобальный адрес. +--bind-iface6 --bind-linklocal=force : только link local Если не указано ни одного бинда, то создается бинд по умолчанию на все адреса всех интерфейсов. Для бинда на конкретный link-local address делаем так : --bind-iface6=fe80::aaaa:bbbb:cccc:dddd%iface-name Параметры --bind-wait* могут помочь в ситуациях, когда нужно взять IP с интерфейса, но его еще нет, он не поднят diff --git a/tpws/params.h b/tpws/params.h index 9d10d04..546feea 100644 --- a/tpws/params.h +++ b/tpws/params.h @@ -6,13 +6,14 @@ #include "strpool.h" enum splithttpreq { split_none = 0, split_method, split_host }; +enum bindll { unwanted=0, no, prefer, force }; #define MAX_BINDS 32 struct bind_s { char bindaddr[64],bindiface[IF_NAMESIZE]; bool bind_if6; - bool bindll,bindll_force; + enum bindll bindll; int bind_wait_ifup,bind_wait_ip,bind_wait_ip_ll; }; diff --git a/tpws/tpws.c b/tpws/tpws.c index 270de1a..fe4298a 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -113,10 +113,11 @@ static void exithelp() " --bind-addr=|; for v6 link locals append %%interface_name\n" " --bind-iface4=\t; bind to the first ipv4 addr of interface\n" " --bind-iface6=\t; bind to the first ipv6 addr of interface\n" - " --bind-linklocal=prefer|force\t; prefer or force ipv6 link local\n" + " --bind-linklocal=no|unwanted|prefer|force\n" + "\t\t\t\t; prohibit, accept, prefer or force ipv6 link local bind\n" " --bind-wait-ifup=\t\t; wait for interface to appear and up\n" " --bind-wait-ip=\t\t; after ifup wait for ip address to appear up to N seconds\n" - " --bind-wait-ip-linklocal=\t; accept only link locals first N seconds then any\n" + " --bind-wait-ip-linklocal=\t; (prefer) accept only LL first N seconds then any (unwanted) accept only globals first N seconds then LL\n" " --bind-wait-only\t\t; wait for bind conditions satisfaction then exit. return code 0 if success.\n" " * multiple binds are supported. each bind-addr, bind-iface* start new bind\n" " --port=\t\t\t; only one port number for all binds is supported\n" @@ -290,9 +291,15 @@ void parse_params(int argc, char *argv[]) case 5: /* bind-linklocal */ checkbind_clean(); params.binds[params.binds_last].bindll = true; - if (!strcmp(optarg, "force")) - params.binds[params.binds_last].bindll_force=true; - else if (strcmp(optarg, "prefer")) + if (!strcmp(optarg, "no")) + params.binds[params.binds_last].bindll=no; + else if (!strcmp(optarg, "prefer")) + params.binds[params.binds_last].bindll=prefer; + else if (!strcmp(optarg, "force")) + params.binds[params.binds_last].bindll=force; + else if (!strcmp(optarg, "unwanted")) + params.binds[params.binds_last].bindll=unwanted; + else { fprintf(stderr, "invalid parameter in bind-linklocal : %s\n",optarg); exit_clean(1); @@ -497,10 +504,11 @@ void parse_params(int argc, char *argv[]) } -static bool find_listen_addr(struct sockaddr_storage *salisten, const char *bindiface, bool bind_if6, bool bindll, int *if_index) +static bool find_listen_addr(struct sockaddr_storage *salisten, const char *bindiface, bool bind_if6, enum bindll bindll, int *if_index) { struct ifaddrs *addrs,*a; bool found=false; + bool bindll_want = bindll==prefer || bindll==force; if (getifaddrs(&addrs)<0) return false; @@ -526,11 +534,13 @@ static bool find_listen_addr(struct sockaddr_storage *salisten, const char *bind // ipv6 links locals are fe80::/10 else if (a->ifa_addr->sa_family==AF_INET6 && - (!*bindiface && bindll || + (!*bindiface && (bindll==prefer || bindll==force) || *bindiface && bind_if6 && !strcmp(a->ifa_name, bindiface)) && - (bindll && is_linklocal((struct sockaddr_in6*)a->ifa_addr) || - !bindll && (pass==2 || pass==0 && is_private6((struct sockaddr_in6*)a->ifa_addr) || pass==1 && !is_linklocal((struct sockaddr_in6*)a->ifa_addr))) + (bindll==force && is_linklocal((struct sockaddr_in6*)a->ifa_addr) || + bindll==prefer && (pass==0 && is_linklocal((struct sockaddr_in6*)a->ifa_addr) || pass==1 && is_private6((struct sockaddr_in6*)a->ifa_addr) || pass==2) || + bindll==no && (pass==0 && is_private6((struct sockaddr_in6*)a->ifa_addr) || pass==1 && !is_linklocal((struct sockaddr_in6*)a->ifa_addr)) || + bindll==unwanted && (pass==0 && is_private6((struct sockaddr_in6*)a->ifa_addr) || pass==1 && !is_linklocal((struct sockaddr_in6*)a->ifa_addr) || pass==2)) ) { salisten->ss_family = AF_INET6; @@ -640,6 +650,7 @@ struct salisten_s int ipv6_only; int bind_wait_ip_left; // how much seconds left from bind_wait_ip }; +static const char *bindll_s[] = { "unwanted","no","prefer","force" }; int main(int argc, char *argv[]) { int i, listen_fd[MAX_BINDS], yes = 1, retval = 0, if_index, exit_v=EXIT_FAILURE; @@ -662,8 +673,8 @@ int main(int argc, char *argv[]) for(i=0;i<=params.binds_last;i++) { - VPRINT("Prepare bind %d : addr=%s iface=%s v6=%u link_local=%u link_local_force=%u wait_ifup=%d wait_ip=%d wait_ip_ll=%d",i, - params.binds[i].bindaddr,params.binds[i].bindiface,params.binds[i].bind_if6,params.binds[i].bindll,params.binds[i].bindll_force, + VPRINT("Prepare bind %d : addr=%s iface=%s v6=%u link_local=%s wait_ifup=%d wait_ip=%d wait_ip_ll=%d",i, + params.binds[i].bindaddr,params.binds[i].bindiface,params.binds[i].bind_if6,bindll_s[params.binds[i].bindll], params.binds[i].bind_wait_ifup,params.binds[i].bind_wait_ip,params.binds[i].bind_wait_ip_ll); if_index=0; if (*params.binds[i].bindiface) @@ -716,27 +727,37 @@ int main(int argc, char *argv[]) if (*params.binds[i].bindiface || params.binds[i].bindll) { bool found; + enum bindll bindll_1; int sec=0; if (params.binds[i].bind_wait_ip > 0) { printf("waiting for ip on %s for up to %d second(s)...\n", *params.binds[i].bindiface ? params.binds[i].bindiface : "", params.binds[i].bind_wait_ip); - if (params.binds[i].bindll && !params.binds[i].bindll_force && params.binds[i].bind_wait_ip_ll>0) - printf("during the first %d second(s) accepting only link locals...\n", params.binds[i].bind_wait_ip_ll); + if (params.binds[i].bind_wait_ip_ll>0) + { + if (params.binds[i].bindll==prefer) + printf("during the first %d second(s) accepting only link locals...\n", params.binds[i].bind_wait_ip_ll); + else if (params.binds[i].bindll==unwanted) + printf("during the first %d second(s) accepting only ipv6 globals...\n", params.binds[i].bind_wait_ip_ll); + } } for(;;) { - found = find_listen_addr(&list[i].salisten,params.binds[i].bindiface,params.binds[i].bind_if6,params.binds[i].bindll,&if_index); + // allow, no, prefer, force + bindll_1 = (params.binds[i].bindll==prefer && sec=params.binds[i].bind_wait_ip_ll) - if ((found = find_listen_addr(&list[i].salisten,params.binds[i].bindiface,params.binds[i].bind_if6,false,&if_index))) - { - printf("link local address wait timeout. using global address\n"); - break; - } - if (sec>=params.binds[i].bind_wait_ip) break;