redirect.c (xinetd-2.3.15) | : | redirect.c (xinetd-2.3.15.4.tar.xz) | ||
---|---|---|---|---|
/* | /* | |||
* (c) Copyright 1998-2001 by Rob Braun | * (c) Copyright 1998-2001 by Rob Braun | |||
* All rights reserved. The file named COPYRIGHT specifies the terms | * All rights reserved. The file named COPYRIGHT specifies the terms | |||
* and conditions for redistribution. | * and conditions for redistribution. | |||
*/ | */ | |||
#include "config.h" | #include "config.h" | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#include <sys/socket.h> | #include <sys/socket.h> | |||
#include <sys/time.h> | #include <sys/time.h> | |||
#ifdef HAVE_SYS_RESOURCE_H | ||||
#include <sys/resource.h> | #include <sys/resource.h> | |||
#endif | ||||
#include <sys/wait.h> | #include <sys/wait.h> | |||
#include <netinet/in.h> | #include <netinet/in.h> | |||
#include <errno.h> | #include <errno.h> | |||
#include <pwd.h> | #include <pwd.h> | |||
#include <fcntl.h> | #include <fcntl.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
#include <sys/wait.h> | #include <sys/wait.h> | |||
#include <signal.h> | #include <signal.h> | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <netinet/tcp.h> | #include <netinet/tcp.h> | |||
#ifdef HAVE_ARPA_INET_H | ||||
#include <arpa/inet.h> | #include <arpa/inet.h> | |||
#endif | ||||
#ifdef HAVE_SYS_SIGNAL_H | ||||
#include <sys/signal.h> | #include <sys/signal.h> | |||
#endif | ||||
#include "redirect.h" | #include "redirect.h" | |||
#include "service.h" | #include "service.h" | |||
#include "log.h" | #include "log.h" | |||
#include "sconf.h" | #include "sconf.h" | |||
#include "msg.h" | #include "msg.h" | |||
#define NET_BUFFER 1500 | #define NET_BUFFER 1500 | |||
static int RedirServerFd = -1; | static int RedirServerFd = -1; | |||
skipping to change at line 61 | skipping to change at line 55 | |||
_exit(0); | _exit(0); | |||
} | } | |||
/* Do the redirection of a service */ | /* Do the redirection of a service */ | |||
/* This function gets called from child.c after we have been forked */ | /* This function gets called from child.c after we have been forked */ | |||
void redir_handler( struct server *serp ) | void redir_handler( struct server *serp ) | |||
{ | { | |||
struct service *sp = SERVER_SERVICE( serp ); | struct service *sp = SERVER_SERVICE( serp ); | |||
struct service_config *scp = SVC_CONF( sp ); | struct service_config *scp = SVC_CONF( sp ); | |||
int RedirDescrip = SERVER_FD( serp ); | int RedirDescrip = SERVER_FD( serp ); | |||
int maxfd; | ||||
ssize_t num_read, num_wrote=0, ret=0; | ssize_t num_read, num_wrote=0, ret=0; | |||
unsigned int sin_len = 0; | unsigned int sin_len = 0; | |||
unsigned long bytes_in = 0, bytes_out = 0; | unsigned long bytes_in = 0, bytes_out = 0; | |||
int no_to_nagle = 1; | int no_to_nagle = 1; | |||
int on = 1, v6on; | int on = 1, v6on; | |||
char buff[NET_BUFFER]; | char buff[NET_BUFFER]; | |||
#ifdef HAVE_POLL | ||||
struct pollfd *pfd_array; | ||||
int pfds_last = 0; | ||||
#else | ||||
fd_set rdfd, msfd; | fd_set rdfd, msfd; | |||
int maxfd; | ||||
struct timeval *timep = NULL; | struct timeval *timep = NULL; | |||
#endif | ||||
const char *func = "redir_handler"; | const char *func = "redir_handler"; | |||
union xsockaddr serveraddr ; | union xsockaddr serveraddr ; | |||
if( signal(SIGPIPE, redir_sigpipe) == SIG_ERR ) | if( signal(SIGPIPE, redir_sigpipe) == SIG_ERR ) | |||
msg(LOG_ERR, func, "unable to setup signal handler"); | msg(LOG_ERR, func, "unable to setup signal handler"); | |||
close_all_svc_descriptors(); | close_all_svc_descriptors(); | |||
/* If it's a tcp service we are redirecting */ | /* If it's a tcp service we are redirecting */ | |||
if( SC_PROTOVAL(scp) == IPPROTO_TCP ) | if( SC_PROTOVAL(scp) == IPPROTO_TCP ) | |||
skipping to change at line 144 | skipping to change at line 143 | |||
msg(LOG_ERR, func, "setsockopt RedirServerFd failed: %m"); | msg(LOG_ERR, func, "setsockopt RedirServerFd failed: %m"); | |||
} | } | |||
if (setsockopt(RedirDescrip, IPPROTO_TCP, TCP_NODELAY, | if (setsockopt(RedirDescrip, IPPROTO_TCP, TCP_NODELAY, | |||
(char *) &no_to_nagle, sizeof( on ) ) < 0) { | (char *) &no_to_nagle, sizeof( on ) ) < 0) { | |||
msg(LOG_ERR, func, "setsockopt RedirDescrip failed: %m"); | msg(LOG_ERR, func, "setsockopt RedirDescrip failed: %m"); | |||
} | } | |||
#ifdef HAVE_POLL | ||||
#define REDIR_DESCRIP_INDEX 0 | ||||
#define REDIR_SERVER_INDEX 1 | ||||
pfd_array = (struct pollfd *)calloc(sizeof(struct pollfd),MAX_FDS); | ||||
if (pfd_array == NULL) | ||||
{ | ||||
msg( LOG_ERR, func, "Cannot allocate memory for file descriptors!\n"); | ||||
exit( 1 ); | ||||
} | ||||
pfd_array[ REDIR_DESCRIP_INDEX ].fd = RedirDescrip; | ||||
pfd_array[ REDIR_DESCRIP_INDEX ].events = POLLIN; | ||||
pfd_array[ REDIR_SERVER_INDEX ].fd = RedirServerFd; | ||||
pfd_array[ REDIR_SERVER_INDEX ].events = POLLIN; | ||||
pfds_last += 2; | ||||
#else | ||||
maxfd = (RedirServerFd > RedirDescrip)?RedirServerFd:RedirDescrip; | maxfd = (RedirServerFd > RedirDescrip)?RedirServerFd:RedirDescrip; | |||
FD_ZERO(&msfd); | FD_ZERO(&msfd); | |||
FD_SET(RedirDescrip, &msfd); | FD_SET(RedirDescrip, &msfd); | |||
FD_SET(RedirServerFd, &msfd); | FD_SET(RedirServerFd, &msfd); | |||
#endif | ||||
while(1) { | while(1) { | |||
#ifdef HAVE_POLL | ||||
if ( poll( pfd_array, pfds_last, -1 ) <= 0 ) { | ||||
#else | ||||
memcpy(&rdfd, &msfd, sizeof(rdfd)); | memcpy(&rdfd, &msfd, sizeof(rdfd)); | |||
if (select(maxfd + 1, &rdfd, (fd_set *)0, (fd_set *)0, timep) <= 0) { | if (select(maxfd + 1, &rdfd, (fd_set *)0, (fd_set *)0, timep) <= 0) { | |||
#endif | ||||
/* place for timeout code, currently does not time out */ | /* place for timeout code, currently does not time out */ | |||
break; | break; | |||
} | } | |||
#ifdef HAVE_POLL | ||||
if ( pfd_array[REDIR_DESCRIP_INDEX].revents ) { | ||||
#else | ||||
if (FD_ISSET(RedirDescrip, &rdfd)) { | if (FD_ISSET(RedirDescrip, &rdfd)) { | |||
#endif | ||||
do { | do { | |||
num_read = read(RedirDescrip, | num_read = read(RedirDescrip, | |||
buff, sizeof(buff)); | buff, sizeof(buff)); | |||
if (num_read == (ssize_t)-1 && errno == EINTR) | if (num_read == (ssize_t)-1 && errno == EINTR) | |||
continue; | continue; | |||
if (num_read <= 0) | if (num_read <= 0) | |||
goto REDIROUT; | goto REDIROUT; | |||
bytes_in += num_read; | bytes_in += num_read; | |||
} while (num_read < 0); | } while (num_read < 0); | |||
skipping to change at line 182 | skipping to change at line 205 | |||
buff + num_wrote, | buff + num_wrote, | |||
num_read - num_wrote); | num_read - num_wrote); | |||
if (ret == -1 && errno == EINTR) | if (ret == -1 && errno == EINTR) | |||
continue; | continue; | |||
if (ret <= 0) | if (ret <= 0) | |||
goto REDIROUT; | goto REDIROUT; | |||
num_wrote += ret; | num_wrote += ret; | |||
} | } | |||
} | } | |||
#ifdef HAVE_POLL | ||||
if ( pfd_array[REDIR_SERVER_INDEX].revents ) { | ||||
#else | ||||
if (FD_ISSET(RedirServerFd, &rdfd)) { | if (FD_ISSET(RedirServerFd, &rdfd)) { | |||
#endif | ||||
do { | do { | |||
num_read = read(RedirServerFd, | num_read = read(RedirServerFd, | |||
buff, sizeof(buff)); | buff, sizeof(buff)); | |||
if (num_read == -1 && errno == EINTR) | if (num_read == -1 && errno == EINTR) | |||
continue; | continue; | |||
if (num_read <= 0) | if (num_read <= 0) | |||
goto REDIROUT; | goto REDIROUT; | |||
bytes_out += num_read; | bytes_out += num_read; | |||
} while (num_read < 0); | } while (num_read < 0); | |||
End of changes. 17 change blocks. | ||||
7 lines changed or deleted | 34 lines changed or added |