mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-30 05:50:53 +03:00
tpws: fix possible address unavailable error after reboot
This commit is contained in:
parent
4a54b217e2
commit
00ca862068
@ -30,23 +30,45 @@ char *strncasestr(const char *s,const char *find, size_t slen)
|
|||||||
return (char *)s;
|
return (char *)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_sockaddr(const struct sockaddr *sa)
|
void ntop46(const struct sockaddr *sa, char *str, size_t len)
|
||||||
{
|
{
|
||||||
char str[64];
|
if (!len) return;
|
||||||
|
*str=0;
|
||||||
switch (sa->sa_family)
|
switch (sa->sa_family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
if (inet_ntop(sa->sa_family, &((struct sockaddr_in*)sa)->sin_addr, str, sizeof(str)))
|
inet_ntop(sa->sa_family, &((struct sockaddr_in*)sa)->sin_addr, str, len);
|
||||||
printf("%s:%d", str, ntohs(((struct sockaddr_in*)sa)->sin_port));
|
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
if (inet_ntop(sa->sa_family, &((struct sockaddr_in6*)sa)->sin6_addr, str, sizeof(str)))
|
inet_ntop(sa->sa_family, &((struct sockaddr_in6*)sa)->sin6_addr, str, len);
|
||||||
printf("%s:%d", str, ntohs(((struct sockaddr_in6*)sa)->sin6_port));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("UNKNOWN_FAMILY_%d", sa->sa_family);
|
snprintf(str,len,"UNKNOWN_FAMILY_%d",sa->sa_family);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void ntop46_port(const struct sockaddr *sa, char *str, size_t len)
|
||||||
|
{
|
||||||
|
char ip[40];
|
||||||
|
ntop46(sa,ip,sizeof(ip));
|
||||||
|
switch (sa->sa_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
snprintf(str,len,"%s:%u",ip,ntohs(((struct sockaddr_in*)sa)->sin_port));
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
snprintf(str,len,"[%s]:%u",ip,ntohs(((struct sockaddr_in6*)sa)->sin6_port));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(str,len,"%s",ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void print_sockaddr(const struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
char ip_port[48];
|
||||||
|
|
||||||
|
ntop46_port(sa,ip_port,sizeof(ip_port));
|
||||||
|
printf("%s",ip_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -1 = error, 0 = not local, 1 = local
|
// -1 = error, 0 = not local, 1 = local
|
||||||
@ -128,6 +150,17 @@ bool saconvmapped(struct sockaddr_storage *a)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_linklocal(const struct sockaddr_in6* a)
|
||||||
|
{
|
||||||
|
// fe80::/10
|
||||||
|
return a->sin6_addr.s6_addr[0]==0xFE && (a->sin6_addr.s6_addr[1] & 0xC0)==0x80;
|
||||||
|
}
|
||||||
|
bool is_private6(const struct sockaddr_in6* a)
|
||||||
|
{
|
||||||
|
// fdf0::/8
|
||||||
|
return a->sin6_addr.s6_addr[0]==0xFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int set_keepalive(int fd)
|
int set_keepalive(int fd)
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
char *strncasestr(const char *s,const char *find, size_t slen);
|
char *strncasestr(const char *s,const char *find, size_t slen);
|
||||||
|
|
||||||
|
void ntop46(const struct sockaddr *sa, char *str, size_t len);
|
||||||
|
void ntop46_port(const struct sockaddr *sa, char *str, size_t len);
|
||||||
void print_sockaddr(const struct sockaddr *sa);
|
void print_sockaddr(const struct sockaddr *sa);
|
||||||
void print_addrinfo(const struct addrinfo *ai);
|
void print_addrinfo(const struct addrinfo *ai);
|
||||||
bool check_local_ip(const struct sockaddr *saddr);
|
bool check_local_ip(const struct sockaddr *saddr);
|
||||||
@ -19,5 +21,8 @@ uint16_t saport(const struct sockaddr *sa);
|
|||||||
// true = was converted
|
// true = was converted
|
||||||
bool saconvmapped(struct sockaddr_storage *a);
|
bool saconvmapped(struct sockaddr_storage *a);
|
||||||
|
|
||||||
|
bool is_linklocal(const struct sockaddr_in6* a);
|
||||||
|
bool is_private6(const struct sockaddr_in6* a);
|
||||||
|
|
||||||
int set_keepalive(int fd);
|
int set_keepalive(int fd);
|
||||||
int get_so_error(int fd);
|
int get_so_error(int fd);
|
||||||
|
@ -46,7 +46,7 @@ static bool redir_open_private(const char *fname, int flags)
|
|||||||
redirector_fd = open(fname, flags);
|
redirector_fd = open(fname, flags);
|
||||||
if (redirector_fd < 0)
|
if (redirector_fd < 0)
|
||||||
{
|
{
|
||||||
perror("redir_openv_private: ");
|
perror("redir_openv_private");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DBGPRINT("opened redirector %s",fname);
|
DBGPRINT("opened redirector %s",fname);
|
||||||
@ -179,7 +179,7 @@ bool get_dest_addr(int sockfd, const struct sockaddr *accept_sa, struct sockaddr
|
|||||||
r=getsockname(sockfd, (struct sockaddr*) orig_dst, &addrlen);
|
r=getsockname(sockfd, (struct sockaddr*) orig_dst, &addrlen);
|
||||||
if (r<0)
|
if (r<0)
|
||||||
{
|
{
|
||||||
perror("getsockname: ");
|
perror("getsockname");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (orig_dst->ss_family==AF_INET6)
|
if (orig_dst->ss_family==AF_INET6)
|
||||||
|
10
tpws/sec.c
10
tpws/sec.c
@ -88,24 +88,24 @@ bool droproot(uid_t uid, gid_t gid)
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (prctl(PR_SET_KEEPCAPS, 1L))
|
if (prctl(PR_SET_KEEPCAPS, 1L))
|
||||||
{
|
{
|
||||||
perror("prctl(PR_SET_KEEPCAPS): ");
|
perror("prctl(PR_SET_KEEPCAPS)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// drop all SGIDs
|
// drop all SGIDs
|
||||||
if (setgroups(0,NULL))
|
if (setgroups(0,NULL))
|
||||||
{
|
{
|
||||||
perror("setgroups: ");
|
perror("setgroups");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (setgid(gid))
|
if (setgid(gid))
|
||||||
{
|
{
|
||||||
perror("setgid: ");
|
perror("setgid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (setuid(uid))
|
if (setuid(uid))
|
||||||
{
|
{
|
||||||
perror("setuid: ");
|
perror("setuid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -138,7 +138,7 @@ void daemonize()
|
|||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
{
|
{
|
||||||
perror("fork: ");
|
perror("fork");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
else if (pid != 0)
|
else if (pid != 0)
|
||||||
|
66
tpws/tpws.c
66
tpws/tpws.c
@ -35,6 +35,7 @@
|
|||||||
#include "params.h"
|
#include "params.h"
|
||||||
#include "sec.h"
|
#include "sec.h"
|
||||||
#include "redirect.h"
|
#include "redirect.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
struct params_s params;
|
struct params_s params;
|
||||||
|
|
||||||
@ -496,10 +497,6 @@ void parse_params(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool is_linklocal(const struct sockaddr_in6* a)
|
|
||||||
{
|
|
||||||
return a->sin6_addr.s6_addr[0]==0xFE && (a->sin6_addr.s6_addr[1] & 0xC0)==0x80;
|
|
||||||
}
|
|
||||||
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, bool bindll, int *if_index)
|
||||||
{
|
{
|
||||||
struct ifaddrs *addrs,*a;
|
struct ifaddrs *addrs,*a;
|
||||||
@ -508,8 +505,10 @@ static bool find_listen_addr(struct sockaddr_storage *salisten, const char *bind
|
|||||||
if (getifaddrs(&addrs)<0)
|
if (getifaddrs(&addrs)<0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int maxpass = (bind_if6 && !bindll) ? 2 : 1;
|
// for ipv6 preference order
|
||||||
for(int pass=0;pass<maxpass;pass++)
|
// bind-linklocal-1 : link-local,private,global
|
||||||
|
// bind-linklocal=0 : private,global,link-local
|
||||||
|
for(int pass=0;pass<3;pass++)
|
||||||
{
|
{
|
||||||
a = addrs;
|
a = addrs;
|
||||||
while (a)
|
while (a)
|
||||||
@ -531,7 +530,7 @@ static bool find_listen_addr(struct sockaddr_storage *salisten, const char *bind
|
|||||||
*bindiface && bind_if6 && !strcmp(a->ifa_name, bindiface))
|
*bindiface && bind_if6 && !strcmp(a->ifa_name, bindiface))
|
||||||
&&
|
&&
|
||||||
(bindll && is_linklocal((struct sockaddr_in6*)a->ifa_addr) ||
|
(bindll && is_linklocal((struct sockaddr_in6*)a->ifa_addr) ||
|
||||||
!bindll && (pass || !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)))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
salisten->ss_family = AF_INET6;
|
salisten->ss_family = AF_INET6;
|
||||||
@ -639,11 +638,13 @@ struct salisten_s
|
|||||||
struct sockaddr_storage salisten;
|
struct sockaddr_storage salisten;
|
||||||
socklen_t salisten_len;
|
socklen_t salisten_len;
|
||||||
int ipv6_only;
|
int ipv6_only;
|
||||||
|
int bind_wait_ip_left; // how much seconds left from bind_wait_ip
|
||||||
};
|
};
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, listen_fd[MAX_BINDS], yes = 1, retval = 0, if_index, exit_v=EXIT_FAILURE;
|
int i, listen_fd[MAX_BINDS], yes = 1, retval = 0, if_index, exit_v=EXIT_FAILURE;
|
||||||
struct salisten_s list[MAX_BINDS];
|
struct salisten_s list[MAX_BINDS];
|
||||||
|
char ip_port[48];
|
||||||
|
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
parse_params(argc, argv);
|
parse_params(argc, argv);
|
||||||
@ -692,6 +693,7 @@ int main(int argc, char *argv[])
|
|||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
list[i].bind_wait_ip_left = params.binds[i].bind_wait_ip;
|
||||||
if (*params.binds[i].bindaddr)
|
if (*params.binds[i].bindaddr)
|
||||||
{
|
{
|
||||||
if (inet_pton(AF_INET, params.binds[i].bindaddr, &((struct sockaddr_in*)(&list[i].salisten))->sin_addr))
|
if (inet_pton(AF_INET, params.binds[i].bindaddr, &((struct sockaddr_in*)(&list[i].salisten))->sin_addr))
|
||||||
@ -747,6 +749,7 @@ int main(int argc, char *argv[])
|
|||||||
printf("suitable ip address not found\n");
|
printf("suitable ip address not found\n");
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
|
list[i].bind_wait_ip_left = params.binds[i].bind_wait_ip - sec;
|
||||||
list[i].ipv6_only=1;
|
list[i].ipv6_only=1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -771,7 +774,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (params.bind_wait_only)
|
if (params.bind_wait_only)
|
||||||
{
|
{
|
||||||
printf("bind wait condition satisfied. exiting.\n");
|
printf("bind wait condition satisfied\n");
|
||||||
exit_v = 0;
|
exit_v = 0;
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
@ -784,24 +787,28 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
for(i=0;i<=params.binds_last;i++)
|
for(i=0;i<=params.binds_last;i++)
|
||||||
{
|
{
|
||||||
VPRINT("Binding %d",i);
|
if (params.debug)
|
||||||
|
{
|
||||||
|
ntop46_port((struct sockaddr *)&list[i].salisten, ip_port, sizeof(ip_port));
|
||||||
|
VPRINT("Binding %d to %s",i,ip_port);
|
||||||
|
}
|
||||||
|
|
||||||
if ((listen_fd[i] = socket(list[i].salisten.ss_family, SOCK_STREAM, 0)) == -1) {
|
if ((listen_fd[i] = socket(list[i].salisten.ss_family, SOCK_STREAM, 0)) == -1) {
|
||||||
perror("socket: ");
|
perror("socket");
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
#ifndef __OpenBSD__
|
#ifndef __OpenBSD__
|
||||||
// in OpenBSD always IPV6_ONLY for wildcard sockets
|
// in OpenBSD always IPV6_ONLY for wildcard sockets
|
||||||
if ((list[i].salisten.ss_family == AF_INET6) && setsockopt(listen_fd[i], IPPROTO_IPV6, IPV6_V6ONLY, &list[i].ipv6_only, sizeof(int)) == -1)
|
if ((list[i].salisten.ss_family == AF_INET6) && setsockopt(listen_fd[i], IPPROTO_IPV6, IPV6_V6ONLY, &list[i].ipv6_only, sizeof(int)) == -1)
|
||||||
{
|
{
|
||||||
perror("setsockopt (IPV6_ONLY): ");
|
perror("setsockopt (IPV6_ONLY)");
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (setsockopt(listen_fd[i], SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
|
if (setsockopt(listen_fd[i], SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
|
||||||
{
|
{
|
||||||
perror("setsockopt (SO_REUSEADDR): ");
|
perror("setsockopt (SO_REUSEADDR)");
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,13 +819,13 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (setsockopt(listen_fd[i], SOL_IP, IP_TRANSPARENT, &yes, sizeof(yes)) == -1)
|
if (setsockopt(listen_fd[i], SOL_IP, IP_TRANSPARENT, &yes, sizeof(yes)) == -1)
|
||||||
{
|
{
|
||||||
perror("setsockopt (IP_TRANSPARENT): ");
|
perror("setsockopt (IP_TRANSPARENT)");
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
#elif defined(BSD) && defined(SO_BINDANY)
|
#elif defined(BSD) && defined(SO_BINDANY)
|
||||||
if (setsockopt(listen_fd[i], SOL_SOCKET, SO_BINDANY, &yes, sizeof(yes)) == -1)
|
if (setsockopt(listen_fd[i], SOL_SOCKET, SO_BINDANY, &yes, sizeof(yes)) == -1)
|
||||||
{
|
{
|
||||||
perror("setsockopt (SO_BINDANY): ");
|
perror("setsockopt (SO_BINDANY)");
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -837,12 +844,35 @@ int main(int argc, char *argv[])
|
|||||||
setsockopt(listen_fd[i],SOL_SOCKET,SO_RCVBUF,&v,sizeof(int));
|
setsockopt(listen_fd[i],SOL_SOCKET,SO_RCVBUF,&v,sizeof(int));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bind(listen_fd[i], (struct sockaddr *)&list[i].salisten, list[i].salisten_len) == -1) {
|
bool bBindBug=false;
|
||||||
perror("bind: ");
|
for(;;)
|
||||||
|
{
|
||||||
|
if (bind(listen_fd[i], (struct sockaddr *)&list[i].salisten, list[i].salisten_len) == -1)
|
||||||
|
{
|
||||||
|
// in linux strange behaviour was observed
|
||||||
|
// just after ifup and address assignment there's short window when bind() can't bind to addresses got from getifaddrs()
|
||||||
|
// it does not happen to transparent sockets because they cant bind to any non-existend ip
|
||||||
|
// also only ipv6 seem to be buggy this way
|
||||||
|
if (errno==EADDRNOTAVAIL && params.proxy_type!=CONN_TYPE_TRANSPARENT && list[i].bind_wait_ip_left)
|
||||||
|
{
|
||||||
|
if (!bBindBug)
|
||||||
|
{
|
||||||
|
ntop46_port((struct sockaddr *)&list[i].salisten, ip_port, sizeof(ip_port));
|
||||||
|
printf("address %s is not available. will retry for %d sec\n",ip_port,list[i].bind_wait_ip_left);
|
||||||
|
bBindBug=true;
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
list[i].bind_wait_ip_left--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
perror("bind");
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
if (listen(listen_fd[i], BACKLOG) == -1) {
|
break;
|
||||||
perror("listen: ");
|
}
|
||||||
|
if (listen(listen_fd[i], BACKLOG) == -1)
|
||||||
|
{
|
||||||
|
perror("listen");
|
||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,13 +272,13 @@ bool set_socket_buffers(int fd, int rcvbuf, int sndbuf)
|
|||||||
DBGPRINT("set_socket_buffers fd=%d rcvbuf=%d sndbuf=%d",fd,rcvbuf,sndbuf)
|
DBGPRINT("set_socket_buffers fd=%d rcvbuf=%d sndbuf=%d",fd,rcvbuf,sndbuf)
|
||||||
if (rcvbuf && setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(int)) <0)
|
if (rcvbuf && setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(int)) <0)
|
||||||
{
|
{
|
||||||
perror("setsockopt (SO_RCVBUF): ");
|
perror("setsockopt (SO_RCVBUF)");
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (sndbuf && setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(int)) <0)
|
if (sndbuf && setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(int)) <0)
|
||||||
{
|
{
|
||||||
perror("setsockopt (SO_SNDBUF): ");
|
perror("setsockopt (SO_SNDBUF)");
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -296,20 +296,20 @@ static int connect_remote(const struct sockaddr *remote_addr)
|
|||||||
|
|
||||||
if((remote_fd = socket(remote_addr->sa_family, SOCK_STREAM, 0)) < 0)
|
if((remote_fd = socket(remote_addr->sa_family, SOCK_STREAM, 0)) < 0)
|
||||||
{
|
{
|
||||||
perror("socket (connect_remote): ");
|
perror("socket (connect_remote)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// Use NONBLOCK to avoid slow connects affecting the performance of other connections
|
// Use NONBLOCK to avoid slow connects affecting the performance of other connections
|
||||||
// separate fcntl call to comply with macos
|
// separate fcntl call to comply with macos
|
||||||
if (fcntl(remote_fd, F_SETFL, O_NONBLOCK)<0)
|
if (fcntl(remote_fd, F_SETFL, O_NONBLOCK)<0)
|
||||||
{
|
{
|
||||||
perror("socket set O_NONBLOCK (connect_remote): ");
|
perror("socket set O_NONBLOCK (connect_remote)");
|
||||||
close(remote_fd);
|
close(remote_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(setsockopt(remote_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
|
if(setsockopt(remote_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
|
||||||
{
|
{
|
||||||
perror("setsockopt (SO_REUSEADDR, connect_remote): ");
|
perror("setsockopt (SO_REUSEADDR, connect_remote)");
|
||||||
close(remote_fd);
|
close(remote_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -317,13 +317,13 @@ static int connect_remote(const struct sockaddr *remote_addr)
|
|||||||
return -1;
|
return -1;
|
||||||
if(!set_keepalive(remote_fd))
|
if(!set_keepalive(remote_fd))
|
||||||
{
|
{
|
||||||
perror("set_keepalive: ");
|
perror("set_keepalive");
|
||||||
close(remote_fd);
|
close(remote_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (setsockopt(remote_fd, IPPROTO_TCP, TCP_NODELAY, params.skip_nodelay ? &no : &yes, sizeof(int)) <0)
|
if (setsockopt(remote_fd, IPPROTO_TCP, TCP_NODELAY, params.skip_nodelay ? &no : &yes, sizeof(int)) <0)
|
||||||
{
|
{
|
||||||
perror("setsockopt (SO_NODELAY, connect_remote): ");
|
perror("setsockopt (SO_NODELAY, connect_remote)");
|
||||||
close(remote_fd);
|
close(remote_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -331,7 +331,7 @@ static int connect_remote(const struct sockaddr *remote_addr)
|
|||||||
{
|
{
|
||||||
if(errno != EINPROGRESS)
|
if(errno != EINPROGRESS)
|
||||||
{
|
{
|
||||||
perror("connect (connect_remote): ");
|
perror("connect (connect_remote)");
|
||||||
close(remote_fd);
|
close(remote_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -466,7 +466,7 @@ static tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_list,int
|
|||||||
|
|
||||||
if(!set_keepalive(local_fd))
|
if(!set_keepalive(local_fd))
|
||||||
{
|
{
|
||||||
perror("set_keepalive: ");
|
perror("set_keepalive");
|
||||||
close(local_fd);
|
close(local_fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1177,7 +1177,7 @@ int event_loop(int *listen_fd, size_t listen_fd_ct)
|
|||||||
tmp_fd = accept(conn->fd, (struct sockaddr*)&accept_sa, &accept_salen);
|
tmp_fd = accept(conn->fd, (struct sockaddr*)&accept_sa, &accept_salen);
|
||||||
if (tmp_fd < 0)
|
if (tmp_fd < 0)
|
||||||
{
|
{
|
||||||
perror("Failed to accept connection : ");
|
perror("Failed to accept connection");
|
||||||
}
|
}
|
||||||
else if (legs_local >= params.maxconn) // each connection has 2 legs - local and remote
|
else if (legs_local >= params.maxconn) // each connection has 2 legs - local and remote
|
||||||
{
|
{
|
||||||
@ -1187,7 +1187,7 @@ int event_loop(int *listen_fd, size_t listen_fd_ct)
|
|||||||
// separate fcntl call to comply with macos
|
// separate fcntl call to comply with macos
|
||||||
else if (fcntl(tmp_fd, F_SETFL, O_NONBLOCK) < 0)
|
else if (fcntl(tmp_fd, F_SETFL, O_NONBLOCK) < 0)
|
||||||
{
|
{
|
||||||
perror("socket set O_NONBLOCK (accept): ");
|
perror("socket set O_NONBLOCK (accept)");
|
||||||
close(tmp_fd);
|
close(tmp_fd);
|
||||||
}
|
}
|
||||||
else if (!(conn=add_tcp_connection(efd, &conn_list, tmp_fd, (struct sockaddr*)&accept_sa, params.port, params.proxy_type)))
|
else if (!(conn=add_tcp_connection(efd, &conn_list, tmp_fd, (struct sockaddr*)&accept_sa, params.port, params.proxy_type)))
|
||||||
|
Loading…
Reference in New Issue
Block a user