1 /*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
5 * Function:..WorldWideWeb-X.500-Gateway - Server-Funktions *
6 * Based on web500gw.c 1.3 written by Frank Richter, TU Chemmniz *
7 * which is based on go500gw by Tim Howes, University of *
8 * Michigan - All rights reserved *
10 * Authors:...Dr. Kurt Spanier & Bernhard Winkler, *
11 * Zentrum fuer Datenverarbeitung, Bereich Entwicklung *
12 * neuer Dienste, Universitaet Tuebingen, GERMANY *
15 * Creation date: Z D D V V *
16 * August 16 1995 Z D D V V *
17 * Last modification: Z D D V V *
18 * May 6 1999 ZZZZ DDD V *
20 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
23 * $Id: server.c,v 1.6 1999/09/10 15:01:19 zrnsk01 Exp $
30 #include "checkclient_exp.h"
32 #include "charray_exp.h"
34 #if defined( TUE_TEL ) || defined( AMBIXGW )
35 #include "tueTest_exp.h"
42 ** Start the Web-X.500-Server.
45 PUBLIC void start_server(glob)
54 struct sockaddr_in from;
59 glob->stat_slice = time(&glob->stat_slice);
60 stat_slice = &glob->stat_slice;
61 /* if logging is desired via syslog establish connection to syslogd
62 and write first log-message */
65 openlog( glob->myname, LOG_PID | LOG_NOWAIT, dosyslog );
66 syslog( LOG_INFO, "initializing" );
70 /* set up the socket to listen on */
71 /* the actual port to listen is composed by the base-port
72 and the language-offset */
73 s = set_socket( glob->webport + atoi(glob->lang) );
75 /* arrange to reap children */
76 (void) signal( SIGCHLD, wait4child );
79 syslog (LOG_INFO, "socket: %d", s);
81 /* Read LDAP-filter for search-operations */
82 if ( (filtd = ldap_init_getfilter( glob->filterfile )) == NULL ) {
83 fprintf(stderr,"Cannot open filter file (%s)\n", glob->filterfile );
87 /* ### Code for the static server ### */
89 tblsize = getdtablesize();
90 syslog (LOG_INFO, "listening for calls...");
92 /* Initialisation of the Anti-Hack-code */
94 if (glob->comrefuse) hackTimer();
95 bzero((char *) conArr, CARRSIZE * sizeof(int));
96 bzero((char *) shadowconArr, CARRSIZE * sizeof(long int));
97 bzero((char *) sumconArr, CARRSIZE * sizeof(long int));
100 /* initialisation of dit_config 1st time */
101 if(glob->dit_config) {
106 /* initialisation of ip_refuse 1st time */
107 if(glob->ip_refuse) {
108 get_ip_refuse_clients(glob);
111 /* the server runs in an infinite loop !!! */
114 /* listen on the server-port for incoming connections */
116 FD_SET( s, &readfds );
118 if ((rc=select(tblsize,(fd_set *)&readfds,NULL,NULL,0))==-1) {
119 if ( debug ) perror( "select" );
121 } else if ( rc == 0 ) {
125 if ( ! FD_ISSET( s, &readfds ) )
129 /* got connection for the server: get data */
130 fromlen = sizeof(from);
132 /* increment the counter for total connections */
135 /* get new file-descriptors for the connection */
136 if ( (ns = accept( s, (struct sockaddr *) &from, &fromlen )) == -1 ) {
138 /* new fd could not be assigned -> log & bye */
139 if ( debug ) perror( "accept" );
142 "problem with accept, errno=%d, %s <%08d>",
143 errno, strerror(errno), glob->svc_cnt);
148 /* get time for performance log */
149 gettimeofday(×tore[0], NULL);
151 /* get client-address via DNS */
152 hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
153 sizeof(from.sin_addr.s_addr), AF_INET );
155 /* check ip-address for ip_refuse and bye if matched */
156 if ( check_ip_denial( &from, glob ) == NOTOK ) {
159 syslog( LOG_INFO, "IP-REFUSE: access denied for %s <%08d>",
160 inet_ntoa( from.sin_addr ), glob->svc_cnt);
167 /* get time for performance log */
168 gettimeofday(×tore[1], NULL);
172 /* divide Host-IP-addresses in index-groups and count connection */
173 idx = IP_HACK(from.sin_addr.s_addr);
176 /* count try if already locked and bye */
177 if(conArr[idx] < 0) {
185 /* if not yet locked and maximum amount of connections is exeeded ->
188 if (glob->comrefuse && (++conArr[idx] > glob->comrefuse->maxAccept)){
192 "connection refused for %s (IDX=%d): %d attempts, %d cycles suspended <%08d>",
193 hp ? hp->h_name : "unknown", idx, conArr[idx],
194 glob->comrefuse->suspendCycle, glob->svc_cnt);
196 /* lock for x timecycles */
197 conArr[idx] = glob->comrefuse->suspendCycle;
205 /* END of Anti-Hack-part */
207 /* Log the connection */
211 sprintf(msg, "TCP connection from %s (%s,%u)",
212 (hp == NULL) ? "unknown" : hp->h_name,
213 inet_ntoa( from.sin_addr ), from.sin_port );
214 glob->server_connection_msg = strdup(msg);
218 fprintf( stderr, "connection from %s (%s)\n",
219 (hp == NULL) ? "unknown" : hp->h_name,
220 inet_ntoa( from.sin_addr ) );
223 glob->unknown_host = !hp;
225 /* OK, now fork a sub-process performing the further communication
226 to the client; the father-process is listening for further
228 switch( pid = fork() ) {
231 /* the connection to the client should last at most OUT_TIME
232 thereafter terminate connection */
233 signal(SIGALRM, timeoutf);
236 /* the s-filedescriptor is not needed any more */
239 /* Serve client-request */
240 do_queries( ns, glob , inet_ntoa( from.sin_addr ), from.sin_port, hp);
243 case -1: /* failed */
245 syslog (LOG_INFO, "%s <%08d>",
246 glob->server_connection_msg, glob->svc_cnt);
250 default: /* parent */
251 /* the father-process continues listening */
254 fprintf( stderr, "forked child %d\n", pid );
260 /* end of function: start_server */
266 ** Initialise socket to listen on and assign dedicated FD
269 PRIVATE int set_socket(port)
273 struct sockaddr_in addr;
275 if ( (s = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) {
280 /* set option so clients can't keep us from coming back up */
282 if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
283 sizeof(one) ) < 0 ) {
284 perror( "setsockopt" );
289 addr.sin_family = AF_INET;
290 addr.sin_addr.s_addr = INADDR_ANY;
291 addr.sin_port = htons( port );
292 if ( bind( s, (struct sockaddr *) &addr, sizeof(addr) ) ) {
297 /* listen for connections */
298 if ( listen( s, 512 ) == -1 ) {
304 printf( "web500gw listening on port %d\n", port );
308 /* end of function: set_socket */
310 /* If a sub-daemon exists, remove from Process list */
311 PRIVATE void wait4child(arg)
316 if ( debug ) printf( "parent: catching child status\n" );
317 while ( wait3( &status, WNOHANG | WUNTRACED, 0 ) > 0 )
319 (void) signal( SIGCHLD, wait4child );
321 /* end of function: wait4child */
323 /* set signal-handler for Anti-Hack */
324 PRIVATE void hackTimer()
326 static time_t timer = (time_t) 0;
327 time_t now = time (&now);
329 /* re-read IP-REFUSE file if necessary */
330 re_readIPrefuse( globP );
332 /* re-read INDEX-URL file if necessary */
333 re_read_index_url_rules( globP );
337 timer = now + comRefuseP->statCycle;
341 signal(SIGALRM, reset_conMem);
342 alarm((rand() % comRefuseP->tdiff) + comRefuseP->tmin);
344 if (now + comRefuseP->tmin > timer) {
346 timer = put_hackStats (NULL, now) + comRefuseP->statCycle;
352 /* end of function: hackTimer */
355 /* Signal-handler for Anti-Hack-code */
356 PRIVATE void reset_conMem()
362 for(i=0; i< 8192; i++)
363 if(conArr[i] >= 0) conArr[i] = 0;
365 if(++conArr[i] == 0){
367 syslog(LOG_INFO, "connection accept resumed for IDX=%d; \
368 %u connection attempts during suspension <%08d>", i, shadowconArr[i],
375 /* end of function: reset_conMem */
378 /* regular output of the access-statistic */
379 PUBLIC time_t put_hackStats (fp, now)
384 int is_html = (fp != NULL);
385 char *eol = is_html ? "<BR>\n" : "\n";
386 unsigned long int gesamt = 0;
388 if (!now) now = time (&now);
390 if (!fp) fp = fopen (comRefuseP->statFile, "w");
394 if (is_html) fprintf (fp, "<PRE><BR>\n");
396 fprintf (fp, "Access-Statistic TWEB%s", eol);
397 fprintf (fp, "======================%s", eol);
398 if (comRefuseP) fprintf (fp, "FILE : %s%s", comRefuseP->statFile, eol);
399 fprintf (fp, "START: %s%s", format_time (*stat_slice), eol);
400 fprintf (fp, "END : %s%s%s%s", format_time (now), eol, eol, eol);
402 for (i = 0, bereiche = 0; i < CARRSIZE; i++) {
405 fprintf (fp, "IP-IDX %5d: %8lu%s", i, sumconArr[i], eol);
406 gesamt += sumconArr[i];
412 fprintf (fp, "----------------------%s", eol);
413 fprintf (fp, "Total: %8lu ( from %d IP-Ranges )%s",
414 gesamt, bereiche, eol);
419 fprintf (fp, "</PRE><BR>\n");
423 bzero((char *) sumconArr, CARRSIZE * sizeof(long int));
432 } /* put_hackStats */