mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
tpws: more bind-linklocal modes
This commit is contained in:
@@ -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
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;
|
||||
|
||||
|
Reference in New Issue
Block a user