2
* (c) Copyright 1992 by Panagiotis Tsirigotis
3
* (c) Sections Copyright 1998-2001 by Rob Braun
4
* All rights reserved. The file named COPYRIGHT specifies the terms
5
* and conditions for redistribution.
11
#include <sys/socket.h>
18
#include "intcommon.h"
21
#include "connection.h"
28
void int_fail( const struct intercept_s *ip, const char *lsyscall )
30
msg( LOG_ERR, "fail", "%s failed: %m", lsyscall ) ;
31
(*ip->int_ops->exit)() ;
37
* Returns either a positive number or -1
39
int int_select( int max, fd_set *read_mask )
41
const char *func = "int_select" ;
47
n_ready = select( max+1, read_mask,
48
FD_SET_NULL, FD_SET_NULL, TIMEVAL_NULL ) ;
51
else if ( n_ready == -1 ) {
56
msg( LOG_ERR, func, "select: %m" ) ;
64
void int_exit( struct intercept_s *ip )
66
int status = SERVER_EXITSTATUS( INT_SERVER( ip ) ) ;
67
const char *func = "int_exit" ;
71
if ( PROC_EXITED( status ) )
72
msg( LOG_DEBUG, func, "intercepted server died" ) ;
73
else if ( PROC_SIGNALED( status ) )
74
msg( LOG_DEBUG, func, "intercepted server received signal %s",
75
sig_name( (int) PROC_TERMSIG( status ) ) ) ;
77
_exit( (int) PROC_EXITSTATUS( status ) ) ;
82
* The ops vector must be installed before invoking this function
84
void int_init( struct intercept_s *ip, struct server *serp )
87
const char *func = "int_init" ;
92
if ( SERVER_SERVICE( serp ) != SERVER_CONNSERVICE( serp ) )
94
msg( LOG_ERR, func, "server service (%s) != connection service (%s)",
95
SVC_ID( SERVER_SERVICE( serp ) ),
96
SVC_ID( SERVER_CONNSERVICE( serp ) ) ) ;
101
* Close all unneeded descriptors
103
for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
105
struct service *sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
107
if ( sp == SERVER_SERVICE( serp ) )
109
if ( LOG_GET_TYPE( SC_LOG( SVC_CONF( sp ) ) ) == L_FILE )
110
xlog_destroy( SVC_LOG( sp ) ) ;
111
(void) Sclose( SVC_FD( sp ) ) ;
115
* Setup signal handling
117
if ( signal( SERVER_EXIT_SIG, int_sighandler ) == SIG_ERR )
118
int_fail( ip, "signal" ) ;
119
if ( signal( INTERCEPT_SIG, int_sighandler ) == SIG_ERR )
120
int_fail( ip, "signal" ) ;
121
if ( signal( SIGTERM, int_sighandler ) == SIG_ERR )
122
int_fail( ip, "signal" ) ;
127
INTERCEPT( ip ) = TRUE ;
128
*INT_SERVER( ip ) = *serp ;
129
INT_REMOTE( ip ) = SERVER_FD( serp ) ;
131
INT_CONNECTIONS( ip ) = pset_create( 0, 0 ) ;
132
if ( INT_CONNECTIONS( ip ) == NULL )
134
msg( LOG_ERR, func, ES_NOMEM ) ;
135
(*ip->int_ops->exit)() ;
141
* Make a new connection to the local server
143
channel_s *int_newconn( struct intercept_s *ip,
144
union xsockaddr *sinp,
147
struct service *sp = SERVER_SERVICE( INT_SERVER( ip ) ) ;
148
int socket_type = SVC_SOCKET_TYPE( sp ) ;
149
union xsockaddr *local = INT_LOCALADDR( ip ) ;
150
char *sid = SVC_ID( sp ) ;
153
const char *func = "int_newconn" ;
156
* Get a socket and connect it to the local address
159
if ( ( sd = socket( local->sa.sa_family, socket_type, SC_PROTOVAL(SVC_CONF(sp)) ) ) == -1 )
161
msg( LOG_ERR, func,"(intercepting %s) socket creation failed: %m", sid ) ;
162
return( CHANNEL_NULL ) ;
165
if ( connect( sd, SA( local ), sizeof( *local ) ) == -1 )
167
msg( LOG_ERR, func, "(intercepting %s) connect failed: %m", sid ) ;
168
(void) Sclose( sd ) ;
169
return( CHANNEL_NULL ) ;
172
chp = NEW_CHANNEL() ;
173
if ( chp == CHANNEL_NULL )
175
msg( LOG_ERR, func, ES_NOMEM ) ;
176
(void) Sclose( sd ) ;
177
return( CHANNEL_NULL ) ;
180
if ( pset_add( INT_CONNECTIONS( ip ), chp ) == NULL )
182
msg( LOG_ERR, func, ES_NOMEM ) ;
183
FREE_CHANNEL( chp ) ;
184
(void) Sclose( sd ) ;
185
return( CHANNEL_NULL ) ;
188
chp->ch_state = GOOD_CHANNEL ;
189
chp->ch_from = *sinp ;
190
chp->ch_local_socket = sd ;
191
chp->ch_remote_socket = remote_socket ;
198
* Check if the (address,port) in sinp is already in the connection table.
200
* a connection pointer if the address is found
201
* NULL if the address if not found
203
* *addr_checked is set to TRUE of FALSE depending on whether there
204
* is already a connection from the same IP address in the table.
206
channel_s *int_lookupconn( struct intercept_s *ip,
207
union xsockaddr *sinp,
208
bool_int *addr_checked )
211
pset_h conntab = INT_CONNECTIONS( ip ) ;
213
*addr_checked = FALSE ;
215
for ( u = 0 ; u < pset_count( conntab ) ; u++ )
217
register channel_s *chp = CHP( pset_pointer( conntab, u ) ) ;
219
if ( memcmp( &chp->ch_from, sinp, sizeof( *sinp ) ) == 0 )
221
*addr_checked = TRUE ;
222
if ( xaddrport(&chp->ch_from) == xaddrport(sinp) )
226
return( CHANNEL_NULL ) ;