diff --git a/clamav-devel/ChangeLog b/clamav-devel/ChangeLog index 1ddfa3e01..8d6515fcb 100644 --- a/clamav-devel/ChangeLog +++ b/clamav-devel/ChangeLog @@ -1,3 +1,8 @@ +Wed Jun 22 17:52:08 CEST 2005 (tk) +---------------------------------- + * clamd: support operation of both TCP and Unix domain sockets simultaneously + Patch by Mark Pizzolato + Wed Jun 22 16:43:43 CEST 2005 (tk) ---------------------------------- * clamd: limit the internal queue of requests to MaxConnectionQueueLength diff --git a/clamav-devel/clamd/clamd.c b/clamav-devel/clamd/clamd.c index 6d02882a3..eef803f98 100644 --- a/clamav-devel/clamd/clamd.c +++ b/clamav-devel/clamd/clamd.c @@ -69,7 +69,8 @@ void clamd(struct optstruct *opt) time_t currtime; struct cl_node *root = NULL; const char *dbdir, *cfgfile; - int ret, virnum = 0, tcpsock; + int ret, virnum = 0, tcpsock = 0, localsock = 0; + int lsockets[2], nlsockets = 0; #ifdef C_LINUX struct stat sb; #endif @@ -213,15 +214,13 @@ void clamd(struct optstruct *opt) /* check socket type */ - if(cfgopt(copt, "TCPSocket")->enabled && cfgopt(copt, "LocalSocket")->enabled) { - fprintf(stderr, "ERROR: You can only select one mode (local or TCP).\n"); - logg("!Two modes (local and TCP) selected.\n"); - exit(1); - } else if(cfgopt(copt, "TCPSocket")->enabled) { + if(cfgopt(copt, "TCPSocket")->enabled) tcpsock = 1; - } else if(cfgopt(copt, "LocalSocket")->enabled) { - tcpsock = 0; - } else { + + if(cfgopt(copt, "LocalSocket")->enabled) + localsock = 1; + + if(!tcpsock && !localsock) { fprintf(stderr, "ERROR: You must select server type (local/tcp).\n"); logg("!Please select server type (local/TCP).\n"); exit(1); @@ -265,15 +264,15 @@ void clamd(struct optstruct *opt) foreground = 1; if(tcpsock) - ret = tcpserver(opt, copt, root); - else - ret = localserver(opt, copt, root); + lsockets[nlsockets++] = tcpserver(copt, root); + + if(localsock) + lsockets[nlsockets++] = localserver(copt, root); + + ret = acceptloop_th(lsockets, nlsockets, root, copt); - printf("server ended; result=%d\n", ret); logg_close(); freecfg(copt); - printf("free() copt\n"); - } void help(void) diff --git a/clamav-devel/clamd/localserver.c b/clamav-devel/clamd/localserver.c index 082bcab70..62094ce60 100644 --- a/clamav-devel/clamd/localserver.c +++ b/clamav-devel/clamd/localserver.c @@ -35,7 +35,7 @@ #include "server.h" #include "output.h" -int localserver(const struct optstruct *opt, const struct cfgstruct *copt, struct cl_node *root) +int localserver(const struct cfgstruct *copt, struct cl_node *root) { struct sockaddr_un server; int sockfd, backlog; @@ -100,7 +100,5 @@ int localserver(const struct optstruct *opt, const struct cfgstruct *copt, struc exit(1); } - acceptloop_th(sockfd, root, copt); - - return 0; + return sockfd; } diff --git a/clamav-devel/clamd/localserver.h b/clamav-devel/clamd/localserver.h index 40f8b2f63..c7f0a9dae 100644 --- a/clamav-devel/clamd/localserver.h +++ b/clamav-devel/clamd/localserver.h @@ -19,6 +19,6 @@ #ifndef __LOCALSERVER_H #define __LOCALSERVER_H -int localserver(const struct optstruct *opt, const struct cfgstruct *copt, struct cl_node *root); +int localserver(const struct cfgstruct *copt, struct cl_node *root); #endif diff --git a/clamav-devel/clamd/others.c b/clamav-devel/clamd/others.c index 6994a2152..8e8ef7805 100644 --- a/clamav-devel/clamd/others.c +++ b/clamav-devel/clamd/others.c @@ -126,45 +126,70 @@ void virusaction(const char *filename, const char *virname, const struct cfgstru } } -int poll_fd(int fd, int timeout_sec) +int poll_fds(int *fds, int nfds, int timeout_sec) { int retval; + int i; #ifdef HAVE_POLL - struct pollfd poll_data[1]; - - poll_data[0].fd = fd; - poll_data[0].events = POLLIN; - poll_data[0].revents = 0; + struct pollfd poll_1[1]; + struct pollfd *poll_data = poll_1; + + if (nfds>1) + poll_data = malloc(nfds*sizeof(*poll_data)); + for (i=0; i 0) { timeout_sec *= 1000; } while (1) { - retval = poll(poll_data, 1, timeout_sec); + retval = poll(poll_data, nfds, timeout_sec); if (retval == -1) { if (errno == EINTR) { continue; } + if (nfds>1) + free(poll_data); return -1; } + if (nfds>1) { + if (retval>0) { + for (i=0; i= DEFAULT_FD_SETSIZE) { - return -1; + for (i=0; i= DEFAULT_FD_SETSIZE) { + return -1; + } + if (fds[i] > maxfd) + maxfd = fds[i]; } while (1) { FD_ZERO(&rfds); - FD_SET(fd, &rfds); + for (i=0; i0 ? &tv : NULL)); if (retval == -1) { if (errno == EINTR) { @@ -172,6 +197,14 @@ int poll_fd(int fd, int timeout_sec) } return -1; } + if ((nfds>1) && (retval>0)) { + for (i=0; i #include "cfgparser.h" +int poll_fds(int *fds, int nfds, int timeout_sec); int poll_fd(int fd, int timeout_sec); int is_fd_connected(int fd); void virusaction(const char *filename, const char *virname, const struct cfgstruct *copt); diff --git a/clamav-devel/clamd/server-th.c b/clamav-devel/clamd/server-th.c index 73bb2e242..4238207ce 100644 --- a/clamav-devel/clamd/server-th.c +++ b/clamav-devel/clamd/server-th.c @@ -62,14 +62,15 @@ typedef struct client_conn_tag { time_t root_timestamp; time_t queue_time; const struct cl_limits *limits; - pid_t mainpid; + int *socketds; + int nsockets; } client_conn_t; void scanner_thread(void *arg) { client_conn_t *conn = (client_conn_t *) arg; sigset_t sigset; - int ret, timeout, session=FALSE; + int ret, timeout, i, session=FALSE; struct cfgstruct *cpt; @@ -109,7 +110,10 @@ void scanner_thread(void *arg) case COMMAND_SHUTDOWN: pthread_mutex_lock(&exit_mutex); progexit = 1; - kill(conn->mainpid, SIGTERM); + for(i = 0; i < conn->nsockets; i++) { + shutdown(conn->socketds[i], 2); + close(conn->socketds[i]); + } pthread_mutex_unlock(&exit_mutex); break; @@ -258,9 +262,9 @@ static struct cl_node *reload_db(struct cl_node *root, const struct cfgstruct *c return root; } -int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *copt) +int acceptloop_th(int *socketds, int nsockets, struct cl_node *root, const struct cfgstruct *copt) { - int new_sd, max_threads, max_queue_size; + int new_sd, max_threads, max_queue_size, i; unsigned int options = 0; threadpool_t *thr_pool; struct sigaction sigact; @@ -485,8 +489,20 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop time(&start_time); for(;;) { + int socketd = socketds[0]; + if(nsockets > 1) { + int pollret = poll_fds(socketds, nsockets, -1); + if(pollret > 0) { + socketd = socketds[pollret - 1]; + } else { + socketd = socketds[0]; /* on a poll error use the first socket */ + } + } new_sd = accept(socketd, NULL, NULL); if((new_sd == -1) && (errno != EINTR)) { + if(progexit) { + break; + } /* very bad - need to exit or restart */ #ifdef HAVE_STRERROR_R logg("!accept() failed: %s\n", strerror_r(errno, buff, BUFFSIZE)); @@ -513,7 +529,8 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop client_conn->root_timestamp = reloaded_time; time(&client_conn->queue_time); client_conn->limits = &limits; - client_conn->mainpid = mainpid; + client_conn->socketds = socketds; + client_conn->nsockets = nsockets; if (!thrmgr_dispatch(thr_pool, client_conn)) { close(client_conn->sd); free(client_conn); @@ -577,11 +594,12 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop } #endif cl_free(root); - logg("*Shutting down the main socket.\n"); - shutdown(socketd, 2); - logg("*Closing the main socket.\n"); - close(socketd); - + logg("*Shutting down the main socket%s.\n", (nsockets > 1) ? "s" : ""); + for (i = 0; i < nsockets; i++) + shutdown(socketds[i], 2); + logg("*Closing the main socket%s.\n", (nsockets > 1) ? "s" : ""); + for (i = 0; i < nsockets; i++) + close(socketds[i]); #ifndef C_OS2 if((cpt = cfgopt(copt, "LocalSocket"))->enabled) { if(unlink(cpt->strarg) == -1) diff --git a/clamav-devel/clamd/server.h b/clamav-devel/clamd/server.h index 031fcbda3..60d257a45 100644 --- a/clamav-devel/clamd/server.h +++ b/clamav-devel/clamd/server.h @@ -48,8 +48,7 @@ struct thrwarg { int options; }; -int acceptloop_proc(int socketd, struct cl_node *root, const struct cfgstruct *copt); -int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *copt); +int acceptloop_th(int *socketds, int nsockets, struct cl_node *root, const struct cfgstruct *copt); void sighandler(int sig); void sighandler_th(int sig); void daemonize(void); diff --git a/clamav-devel/clamd/tcpserver.c b/clamav-devel/clamd/tcpserver.c index f9df2bf05..31e73a27a 100644 --- a/clamav-devel/clamd/tcpserver.c +++ b/clamav-devel/clamd/tcpserver.c @@ -36,7 +36,7 @@ #include "server.h" #include "output.h" -int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct cl_node *root) +int tcpserver(const struct cfgstruct *copt, struct cl_node *root) { struct sockaddr_in server; int sockfd, backlog; @@ -76,9 +76,9 @@ int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct exit(1); } else { if(taddr->enabled) - logg("Bound to address %s on port %d\n", taddr->strarg, cfgopt(copt, "TCPSocket")->numarg); + logg("Bound to address %s on tcp port %d\n", taddr->strarg, cfgopt(copt, "TCPSocket")->numarg); else - logg("Bound to port %d\n", cfgopt(copt, "TCPSocket")->numarg); + logg("Bound to tcp port %d\n", cfgopt(copt, "TCPSocket")->numarg); } backlog = cfgopt(copt, "MaxConnectionQueueLength")->numarg; @@ -90,7 +90,5 @@ int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct exit(1); } - acceptloop_th(sockfd, root, copt); - - return 0; + return sockfd; } diff --git a/clamav-devel/clamd/tcpserver.h b/clamav-devel/clamd/tcpserver.h index 44f1a8684..b6f94b094 100644 --- a/clamav-devel/clamd/tcpserver.h +++ b/clamav-devel/clamd/tcpserver.h @@ -22,6 +22,6 @@ #include "options.h" #include "cfgparser.h" -int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct cl_node *root); +int tcpserver(const struct cfgstruct *copt, struct cl_node *root); #endif diff --git a/clamav-devel/clamdscan/client.c b/clamav-devel/clamdscan/client.c index 26bfff936..2530e7cf9 100644 --- a/clamav-devel/clamdscan/client.c +++ b/clamav-devel/clamdscan/client.c @@ -324,10 +324,7 @@ int dconnect(const struct optstruct *opt) /* Set default address to connect to */ server2.sin_addr.s_addr = inet_addr("127.0.0.1"); - if(cfgopt(copt, "TCPSocket")->enabled && cfgopt(copt, "LocalSocket")->enabled) { - logg("^Clamd is not configured properly.\n"); - return -1; - } else if((cpt = cfgopt(copt, "LocalSocket"))->enabled) { + if((cpt = cfgopt(copt, "LocalSocket"))->enabled) { server.sun_family = AF_UNIX; strncpy(server.sun_path, cpt->strarg, sizeof(server.sun_path)); diff --git a/clamav-devel/freshclam/notify.c b/clamav-devel/freshclam/notify.c index fb60f3978..1bee3117d 100644 --- a/clamav-devel/freshclam/notify.c +++ b/clamav-devel/freshclam/notify.c @@ -52,10 +52,7 @@ int notify(const char *cfgfile) return 1; } - if(cfgopt(copt, "TCPSocket")->enabled && cfgopt(copt, "LocalSocket")->enabled) { - logg("^Clamd was NOT notified: Both socket types (TCP and local) declared in %s\n", cfgfile); - return 1; - } else if((cpt = cfgopt(copt, "LocalSocket"))->enabled) { + if((cpt = cfgopt(copt, "LocalSocket"))->enabled) { socktype = "UNIX"; server.sun_family = AF_UNIX; strncpy(server.sun_path, cpt->strarg, sizeof(server.sun_path));