From 44b8f1360a19c0737f4d58d2b814d18fb44ed1bd Mon Sep 17 00:00:00 2001 From: Andreas Hrubak Date: Tue, 24 Aug 2021 14:57:26 +0200 Subject: [PATCH] use CONNREDIR_TO_FD=1 instead of CONNREDIR_TO=stdout and support error reporting in error cases --- src/connredir.c | 55 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/src/connredir.c b/src/connredir.c index 6a40b15..9a73434 100644 --- a/src/connredir.c +++ b/src/connredir.c @@ -6,7 +6,7 @@ USAGE LD_PRELOAD=$PWD/connredir.so CONNREDIR_ORIG_IP=169.254.169.254 CONNREDIR_ORIG_PORT=80 CONNREDIR_TO_IP=127.0.0.1 CONNREDIR_TO_PORT=8080 wget ... - LD_PRELOAD=$PWD/connredir.so CONNREDIR_ORIG_IP=127.0.0.1 CONNREDIR_ORIG_PORT=25 CONNREDIR_TO=stdout sendmail ... + LD_PRELOAD=$PWD/connredir.so CONNREDIR_ORIG_IP=127.0.0.1 CONNREDIR_ORIG_PORT=25 CONNREDIR_TO_FD=1 sendmail ... DESCRIPTION @@ -19,10 +19,14 @@ DESCRIPTION Leave CONNREDIR_ORIG_PORT unset to override all ports. Leave CONNREDIR_TO_PORT unset to not override the destination port number. - If CONNREDIR_TO is set, then it's evaluated before CONNREDIR_TO_IP. - Valid values for CONNREDIR_TO: stdout. - When CONNREDIR_TO is 'stdout', connredir replaces the socket's FD, which is about to be connected, to the STDOUT, so you can - make your program communicate on STDIO instead of INET. Useful when combined with socat(1). + If CONNREDIR_TO_FD is set, then it's evaluated before CONNREDIR_TO_IP. CONNREDIR_TO_FD is a file descriptor number which + replaces the socket's FD which is about to be connected; so you can make your program communicate on an arbitrary pre-opened + file descriptor instead of INET. Useful when combined with socat(1). + + By default, connredir does not cause exception in the caller process in error cases (eg. ip address parse error, invalid port number, + closed file descriptor), rather falls back to system's connect(2) call. + However if CONNREDIR_ERRNO is set, the it sets errno to that value and returns -1 in the above error cases. + You may set CONNREDIR_ERRNO to 5 to report IO Error in such cases. COMPATIBILITY @@ -33,9 +37,10 @@ ENVIRONMENT VARIABLES CONNREDIR_ORIG_IP CONNREDIR_ORIG_PORT - CONNREDIR_TO + CONNREDIR_TO_FD CONNREDIR_TO_IP CONNREDIR_TO_PORT + CONNREDIR_ERRNO COMPILE @@ -63,17 +68,21 @@ int connect(int sockfd, const struct sockaddr_in *orig_sockaddr, socklen_t addrl char *orig_port_str; in_port_t orig_port = 0; - char *redir_to; + char *to_fd_str; + int to_fd; char *to_ip_str; struct in_addr to_ip; char *to_port_str; in_port_t to_port = 0; + char *connredir_errno_str; + struct sockaddr_in to_sockaddr; int (*orig_connect)(int, const struct sockaddr_in *, socklen_t) = dlsym(RTLD_NEXT, "connect"); + if(orig_sockaddr->sin_family != AF_INET) goto stdlib; orig_ip_str = getenv("CONNREDIR_ORIG_IP"); @@ -82,7 +91,7 @@ int connect(int sockfd, const struct sockaddr_in *orig_sockaddr, socklen_t addrl if(inet_aton(orig_ip_str, &orig_ip) == 0) { _connredir_ip_parse_error(orig_ip_str); - goto stdlib; + goto error_case; } if(ntohl(orig_sockaddr->sin_addr.s_addr) != ntohl(orig_ip.s_addr)) goto stdlib; @@ -91,20 +100,13 @@ int connect(int sockfd, const struct sockaddr_in *orig_sockaddr, socklen_t addrl if(orig_port != 0 && orig_port != ntohs(orig_sockaddr->sin_port)) goto stdlib; - redir_to = getenv("CONNREDIR_TO"); - if(redir_to != NULL) + to_fd_str = getenv("CONNREDIR_TO_FD"); + if(to_fd_str != NULL) { - if(strcmp(redir_to, "stdout")==0) - { - if(dup2(fileno(stdout), sockfd) == -1) { perror("connredir: dup2"); goto stdlib; } - fprintf(stderr, "connredir: redirecting %s:%d -> stdout\n", inet_ntoa(orig_sockaddr->sin_addr), ntohs(orig_sockaddr->sin_port)); - return 0; - } - else - { - fprintf(stderr, "connredir: unknown redirection '%s'\n", redir_to); - goto stdlib; - } + to_fd = atoi(to_fd_str); + if(dup2(to_fd, sockfd) == -1) { perror("connredir: dup2"); goto error_case; } + fprintf(stderr, "connredir: redirecting %s:%d -> fd#%d\n", inet_ntoa(orig_sockaddr->sin_addr), ntohs(orig_sockaddr->sin_port), to_fd); + return 0; } to_ip_str = getenv("CONNREDIR_TO_IP"); @@ -113,7 +115,7 @@ int connect(int sockfd, const struct sockaddr_in *orig_sockaddr, socklen_t addrl if(inet_aton(to_ip_str, &to_ip) == 0) { _connredir_ip_parse_error(to_ip_str); - goto stdlib; + goto error_case; } to_port_str = getenv("CONNREDIR_TO_PORT"); @@ -126,6 +128,15 @@ int connect(int sockfd, const struct sockaddr_in *orig_sockaddr, socklen_t addrl fprintf(stderr, "connredir: redirecting %s:%d -> ", inet_ntoa(orig_sockaddr->sin_addr), ntohs(orig_sockaddr->sin_port)); fprintf(stderr, "%s:%d\n", inet_ntoa(to_sockaddr.sin_addr), ntohs(to_sockaddr.sin_port)); orig_sockaddr = &to_sockaddr; + goto stdlib; + + error_case: + connredir_errno_str = getenv("CONNREDIR_ERRNO"); + if(connredir_errno_str) + { + errno = atoi(connredir_errno_str); + return -1; + } stdlib: return orig_connect(sockfd, orig_sockaddr, addrlen); -- 2.11.4.GIT