"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "xinetd/tcpint.c" between
xinetd-2.3.15.tar.gz and xinetd-2.3.15.4.tar.xz

About: xinetd is a secure replacement for inetd, the internet services daemon (openSUSE fork).

tcpint.c  (xinetd-2.3.15):tcpint.c  (xinetd-2.3.15.4.tar.xz)
skipping to change at line 18 skipping to change at line 18
#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>
#include <syslog.h> #include <syslog.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h> #include <sys/select.h>
#endif
#include "tcpint.h" #include "tcpint.h"
#include "intcommon.h" #include "intcommon.h"
#include "msg.h" #include "msg.h"
#include "log.h" #include "log.h"
#include "xconfig.h" #include "xconfig.h"
#include "sconf.h" #include "sconf.h"
typedef enum { S_OK, S_SERVER_ERR, S_CLIENT_ERR } stream_status_e ; typedef enum { S_OK, S_SERVER_ERR, S_CLIENT_ERR } stream_status_e ;
skipping to change at line 62 skipping to change at line 59
ip->int_socket_type = SOCK_STREAM ; ip->int_socket_type = SOCK_STREAM ;
ip->int_priv = (void *) &istream ; ip->int_priv = (void *) &istream ;
ip->int_ops = &istream_ops ; ip->int_ops = &istream_ops ;
int_init( ip, serp ) ; int_init( ip, serp ) ;
if ( signal( SIGPIPE, SIG_IGN ) == SIG_ERR ) if ( signal( SIGPIPE, SIG_IGN ) == SIG_ERR )
int_fail( ip, "signal" ) ; int_fail( ip, "signal" ) ;
return( ip ) ; return( ip ) ;
} }
#ifdef HAVE_POLL
static status_e handle_io( psi_h iter, channel_s *chp,
struct pollfd *pfd_handled,
struct pollfd *pfd_array,
int *pfds_last,
stream_status_e (*iofunc)() );
#else
static status_e handle_io( psi_h iter, channel_s *chp, fd_set *maskp, stream_sta tus_e (*iofunc)() ); static status_e handle_io( psi_h iter, channel_s *chp, fd_set *maskp, stream_sta tus_e (*iofunc)() );
#endif
static stream_status_e tcp_local_to_remote( channel_s *chp ); static stream_status_e tcp_local_to_remote( channel_s *chp );
static stream_status_e tcp_remote_to_local( channel_s *chp ); static stream_status_e tcp_remote_to_local( channel_s *chp );
static void connection_request( struct intercept_s *ip, channel_s **chpp ); static void connection_request( struct intercept_s *ip, channel_s **chpp );
/* Unfortunatly, this can't be private... */ /* Unfortunatly, this can't be private... */
void si_exit(void) void si_exit(void)
{ {
struct intercept_s *ip = &stream_intercept_state ; struct intercept_s *ip = &stream_intercept_state ;
if ( SIP( ip->int_priv )->accepted_connections == 0 ) if ( SIP( ip->int_priv )->accepted_connections == 0 )
(void) accept( INT_REMOTE( ip ), SA( NULL ), NULL ) ; (void) accept( INT_REMOTE( ip ), SA( NULL ), NULL ) ;
int_exit( ip ) ; int_exit( ip ) ;
} }
static void si_mux(void) static void si_mux(void)
{ {
struct intercept_s *ip = &stream_intercept_state ; struct intercept_s *ip = &stream_intercept_state ;
#ifdef HAVE_POLL
struct pollfd *pfd_array;
int pfds_last = 0;
#else
fd_set socket_mask ; fd_set socket_mask ;
int mask_max ; int mask_max ;
#endif
psi_h iter ; psi_h iter ;
const char *func = "si_mux" ; const char *func = "si_mux" ;
#ifdef HAVE_POLL
pfd_array = calloc(sizeof(struct pollfd),MAX_FDS);
pfd_array[ pfds_last ].fd = INT_REMOTE( ip ) ;
pfd_array[ pfds_last++ ].events = POLLIN | POLLOUT;
#else
FD_ZERO( &socket_mask ) ; FD_ZERO( &socket_mask ) ;
FD_SET( INT_REMOTE( ip ), &socket_mask ) ; FD_SET( INT_REMOTE( ip ), &socket_mask ) ;
mask_max = INT_REMOTE( ip ) ; mask_max = INT_REMOTE( ip ) ;
#endif
iter = psi_create( INT_CONNECTIONS( ip ) ) ; iter = psi_create( INT_CONNECTIONS( ip ) ) ;
if ( iter == NULL ) if ( iter == NULL )
{ {
msg( LOG_ERR, func, ES_NOMEM ) ; msg( LOG_ERR, func, ES_NOMEM ) ;
#ifdef HAVE_POLL
free( pfd_array ) ;
#endif
return ; return ;
} }
for ( ;; ) for ( ;; )
{ {
channel_s *chp ; channel_s *chp ;
#ifndef HAVE_POLL
fd_set read_mask ; fd_set read_mask ;
#endif
int n_ready ; int n_ready ;
#ifdef HAVE_POLL
n_ready = int_poll( pfds_last, pfd_array ) ;
#else
read_mask = socket_mask ; read_mask = socket_mask ;
n_ready = int_select( mask_max+1, &read_mask ) ; n_ready = int_select( mask_max+1, &read_mask ) ;
#endif
if ( n_ready == -1 ) if ( n_ready == -1 )
return ; goto free_iter ;
#ifdef HAVE_POLL
if ( pfd_array[0].revents & ( POLLIN | POLLOUT ) )
#else
if ( FD_ISSET( INT_REMOTE( ip ), &read_mask ) ) if ( FD_ISSET( INT_REMOTE( ip ), &read_mask ) )
#endif
{ {
connection_request( ip, &chp ) ; connection_request( ip, &chp ) ;
if ( chp != NULL ) if ( chp != NULL )
{ {
#ifdef HAVE_POLL
pfd_array[ pfds_last ].fd = chp->ch_local_socket ;
pfd_array[ pfds_last++ ].events = POLLIN | POLLOUT ;
pfd_array[ pfds_last ].fd = chp->ch_remote_socket ;
pfd_array[ pfds_last++ ].events = POLLIN | POLLOUT ;
#else
FD_SET( chp->ch_local_socket, &socket_mask ) ; FD_SET( chp->ch_local_socket, &socket_mask ) ;
if ( chp->ch_local_socket > mask_max ) if ( chp->ch_local_socket > mask_max )
mask_max = chp->ch_local_socket ; mask_max = chp->ch_local_socket ;
FD_SET( chp->ch_remote_socket, &socket_mask ) ; FD_SET( chp->ch_remote_socket, &socket_mask ) ;
if ( chp->ch_remote_socket > mask_max ) if ( chp->ch_remote_socket > mask_max )
mask_max = chp->ch_remote_socket ; mask_max = chp->ch_remote_socket ;
#endif
} }
if ( --n_ready == 0 ) if ( --n_ready == 0 )
continue ; continue ;
} }
for ( chp = CHP( psi_start(iter) ) ; chp ; chp = CHP( psi_next(iter) ) ) for ( chp = CHP( psi_start(iter) ) ; chp ; chp = CHP( psi_next(iter) ) )
{ {
#ifdef HAVE_POLL
int i;
struct pollfd *local_pfd = NULL, *remote_pfd = NULL;
/* TODO: detection with O(n)=1 */
for (i = 0 ; i < pfds_last ; i++ )
if (pfd_array[i].fd == chp->ch_local_socket)
local_pfd = &pfd_array[i];
else if (pfd_array[i] .fd== chp->ch_remote_socket)
remote_pfd = &pfd_array[i];
if ( local_pfd != NULL &&
local_pfd->revents & ( POLLIN | POLLOUT) )
#else
if ( FD_ISSET( chp->ch_local_socket, &read_mask ) ) if ( FD_ISSET( chp->ch_local_socket, &read_mask ) )
#endif
{ {
#ifdef DEBUG_TCPINT #ifdef DEBUG_TCPINT
if ( debug.on ) if ( debug.on )
msg( LOG_DEBUG, func, "Input available on local socket %d", msg( LOG_DEBUG, func, "Input available on local socket %d",
chp->ch_local_socket ) ; chp->ch_local_socket ) ;
#endif #endif
#ifdef HAVE_POLL
if ( handle_io( iter, chp, local_pfd, pfd_array,
&pfds_last, tcp_local_to_remote ) == FAILED )
#else
if ( handle_io( iter, chp, &socket_mask, tcp_local_to_remote ) == FA ILED ) if ( handle_io( iter, chp, &socket_mask, tcp_local_to_remote ) == FA ILED )
return ; #endif
goto free_iter ;
if ( --n_ready == 0 ) if ( --n_ready == 0 )
break ; goto free_iter ;
} }
#ifdef HAVE_POLL
if ( remote_pfd != NULL &&
remote_pfd->revents & ( POLLIN | POLLOUT) )
#else
if ( FD_ISSET( chp->ch_remote_socket, &read_mask ) ) if ( FD_ISSET( chp->ch_remote_socket, &read_mask ) )
#endif
{ {
#ifdef DEBUG_TCPINT #ifdef DEBUG_TCPINT
msg( LOG_DEBUG, func, "Input available on remote socket %d", msg( LOG_DEBUG, func, "Input available on remote socket %d",
chp->ch_remote_socket ) ; chp->ch_remote_socket ) ;
#endif #endif
#ifdef HAVE_POLL
if ( handle_io( iter, chp, remote_pfd, pfd_array,
&pfds_last, tcp_remote_to_local ) == FAILED )
#else
if ( handle_io( iter, chp, if ( handle_io( iter, chp,
&socket_mask, tcp_remote_to_local ) == FAILED ) &socket_mask, tcp_remote_to_local ) == FAILED )
return ; #endif
goto free_iter ;
if ( --n_ready == 0 ) if ( --n_ready == 0 )
break ; goto free_iter ;
} }
} }
} }
free_iter:
psi_destroy( iter ) ;
return ;
} }
#ifdef HAVE_POLL
static status_e handle_io( psi_h iter,
channel_s *chp,
struct pollfd *pfd_handled,
struct pollfd *pfd_array,
int *pfds_last,
stream_status_e (*iofunc)() )
#else
static status_e handle_io( psi_h iter, static status_e handle_io( psi_h iter,
channel_s *chp, channel_s *chp,
fd_set *maskp, fd_set *maskp,
stream_status_e (*iofunc)() ) stream_status_e (*iofunc)() )
#endif
{ {
const char *func = "handle_io" ; const char *func = "handle_io" ;
switch ( (*iofunc)( chp ) ) switch ( (*iofunc)( chp ) )
{ {
case S_SERVER_ERR: case S_SERVER_ERR:
return( FAILED ) ; return( FAILED ) ;
case S_CLIENT_ERR: case S_CLIENT_ERR:
if ( debug.on ) if ( debug.on )
msg( LOG_DEBUG, func, msg( LOG_DEBUG, func,
"Closing channel to %s,%d using sockets %d(l),%d(r)", "Closing channel to %s,%d using sockets %d(l),%d(r)",
xaddrname( &chp->ch_from ), ntohs(xaddrport( &chp->ch_from )), xaddrname( &chp->ch_from ), ntohs(xaddrport( &chp->ch_from )),
chp->ch_local_socket, chp->ch_remote_socket ) ; chp->ch_local_socket, chp->ch_remote_socket ) ;
#ifdef HAVE_POLL
if ( pfd_handled != NULL)
*pfd_handled = pfd_array[ --( *pfds_last ) ];
#else
FD_CLR( chp->ch_local_socket, maskp ) ; FD_CLR( chp->ch_local_socket, maskp ) ;
FD_CLR( chp->ch_remote_socket, maskp ) ; FD_CLR( chp->ch_remote_socket, maskp ) ;
#endif
(void) Sclose( chp->ch_remote_socket ) ; (void) Sclose( chp->ch_remote_socket ) ;
(void) Sclose( chp->ch_local_socket ) ; (void) Sclose( chp->ch_local_socket ) ;
psi_remove( iter ) ; psi_remove( iter ) ;
FREE_CHANNEL( chp ) ; FREE_CHANNEL( chp ) ;
break ; break ;
case S_OK: case S_OK:
break ; break ;
} }
return( OK ) ; return( OK ) ;
} }
skipping to change at line 349 skipping to change at line 432
break ; break ;
} }
for ( p = buf, left = rcc ; left ; p += wcc, left -= wcc ) for ( p = buf, left = rcc ; left ; p += wcc, left -= wcc )
{ {
wcc = send( chp->ch_local_socket, p, left, 0 ) ; wcc = send( chp->ch_local_socket, p, left, 0 ) ;
if ( wcc == 0 ) { if ( wcc == 0 ) {
return( S_SERVER_ERR ) ; return( S_SERVER_ERR ) ;
} else if ( wcc == (ssize_t)-1 ) { } else if ( wcc == (ssize_t)-1 ) {
if ( errno == EINTR ) { if ( errno == EINTR ) {
#ifdef DEBUG_TCPINT
rcc = 0 ; rcc = 0 ;
#endif
} else { } else {
msg( LOG_ERR, func, "send: %m" ) ; msg( LOG_ERR, func, "send: %m" ) ;
return( S_SERVER_ERR ) ; return( S_SERVER_ERR ) ;
} }
} }
} }
#ifdef DEBUG_TCPINT #ifdef DEBUG_TCPINT
if ( debug.on ) if ( debug.on )
msg( LOG_DEBUG, func, msg( LOG_DEBUG, func,
 End of changes. 35 change blocks. 
9 lines changed or deleted 94 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)