Browse Source

tpws: more bind-linklocal modes

pull/65/head
bol-van 4 years ago
parent
commit
be0b76c02b
  1. BIN
      binaries/aarch64/tpws
  2. BIN
      binaries/arm/tpws
  3. BIN
      binaries/mac64/tpws
  4. BIN
      binaries/mips32r1-lsb/tpws
  5. BIN
      binaries/mips32r1-msb/tpws
  6. BIN
      binaries/mips64r2-msb/tpws
  7. BIN
      binaries/ppc/tpws
  8. BIN
      binaries/x86/tpws
  9. BIN
      binaries/x86_64/tpws
  10. 14
      docs/readme.eng.txt
  11. 20
      docs/readme.txt
  12. 3
      tpws/params.h
  13. 63
      tpws/tpws.c

BIN
binaries/aarch64/tpws

Binary file not shown.

BIN
binaries/arm/tpws

Binary file not shown.

BIN
binaries/mac64/tpws

Binary file not shown.

BIN
binaries/mips32r1-lsb/tpws

Binary file not shown.

BIN
binaries/mips32r1-msb/tpws

Binary file not shown.

BIN
binaries/mips64r2-msb/tpws

Binary file not shown.

BIN
binaries/ppc/tpws

Binary file not shown.

BIN
binaries/x86/tpws

Binary file not shown.

BIN
binaries/x86_64/tpws

Binary file not shown.

14
docs/readme.eng.txt

@ -260,7 +260,11 @@ tpws is transparent proxy.
--bind-addr=<v4_addr>|<v6_addr>; for v6 link locals append %interface_name : fe80::1%br-lan
--bind-iface4=<interface_name> ; bind to the first ipv4 addr of interface
--bind-iface6=<interface_name> ; 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=<sec> ; wait for interface to appear and up
--bind-wait-ip=<sec> ; after ifup wait for ip address to appear up to N seconds
--bind-wait-ip-linklocal=<sec> ; 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

20
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=<iface> ; слушать на первом ipv4 интерфейса iface
--bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface
--bind-wait-ifup=<sec> ; ждать до N секунд появления и поднятия интерфейса
--bind-wait-ip=<sec> ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса)
--bind-wait-ip-linklocal=<sec> ; (только если заданы --bind-wait-ip и --bind-linklocal=prefer) согласиться на global address после N секунд
--bind-wait-ip-linklocal=<sec>
; имеет смысл только при задании --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 с интерфейса, но его еще нет, он не поднят

3
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;
};

63
tpws/tpws.c

@ -113,10 +113,11 @@ static void exithelp()
" --bind-addr=<v4_addr>|<v6_addr>; for v6 link locals append %%interface_name\n"
" --bind-iface4=<interface_name>\t; bind to the first ipv4 addr of interface\n"
" --bind-iface6=<interface_name>\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=<sec>\t\t; wait for interface to appear and up\n"
" --bind-wait-ip=<sec>\t\t; after ifup wait for ip address to appear up to N seconds\n"
" --bind-wait-ip-linklocal=<sec>\t; accept only link locals first N seconds then any\n"
" --bind-wait-ip-linklocal=<sec>\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=<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 : "<any>", 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) ? force :
(params.binds[i].bindll==unwanted && sec<params.binds[i].bind_wait_ip_ll) ? no :
params.binds[i].bindll;
if (sec && sec==params.binds[i].bind_wait_ip_ll)
{
if (params.binds[i].bindll==prefer)
printf("link local address wait timeout. now accepting globals\n");
else if (params.binds[i].bindll==unwanted)
printf("global ipv6 address wait timeout. now accepting link locals\n");
}
found = find_listen_addr(&list[i].salisten,params.binds[i].bindiface,params.binds[i].bind_if6,bindll_1,&if_index);
if (found) break;
if (params.binds[i].bindll && !params.binds[i].bindll_force && 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;

Loading…
Cancel
Save