support operation of both TCP and Unix domain sockets simultaneously

git-svn: trunk@1626
remotes/push_mirror/metadata
Tomasz Kojm 20 years ago
parent 6d5c43a147
commit 57358cc80f
  1. 5
      clamav-devel/ChangeLog
  2. 29
      clamav-devel/clamd/clamd.c
  3. 6
      clamav-devel/clamd/localserver.c
  4. 2
      clamav-devel/clamd/localserver.h
  5. 60
      clamav-devel/clamd/others.c
  6. 1
      clamav-devel/clamd/others.h
  7. 40
      clamav-devel/clamd/server-th.c
  8. 3
      clamav-devel/clamd/server.h
  9. 10
      clamav-devel/clamd/tcpserver.c
  10. 2
      clamav-devel/clamd/tcpserver.h
  11. 5
      clamav-devel/clamdscan/client.c
  12. 5
      clamav-devel/freshclam/notify.c

@ -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 <clamav-devel*subscriptions.pizzolato.net>
Wed Jun 22 16:43:43 CEST 2005 (tk)
----------------------------------
* clamd: limit the internal queue of requests to MaxConnectionQueueLength

@ -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)

@ -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;
}

@ -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

@ -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<nfds; i++) {
poll_data[i].fd = fds[i];
poll_data[i].events = POLLIN;
poll_data[i].revents = 0;
}
if (timeout_sec > 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<nfds; i++) {
if (poll_data[i].revents) {
retval = i+1;
break;
}
}
}
free(poll_data);
}
return retval;
}
#else
fd_set rfds;
struct timeval tv;
int maxfd = 0;
if (fd >= DEFAULT_FD_SETSIZE) {
return -1;
for (i=0; i<nfds; i++) {
if (fds[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; i<nfds; i++)
FD_SET(fds[i], &rfds);
tv.tv_sec = timeout_sec;
tv.tv_usec = 0;
retval = select(fd+1, &rfds, NULL, NULL,
retval = select(maxfd+1, &rfds, NULL, NULL,
(timeout_sec>0 ? &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<nfds; i++) {
if (FD_ISSET(fds[i],&rfds)) {
retval = i+1;
break;
}
}
}
return retval;
}
#endif
@ -179,6 +212,11 @@ int poll_fd(int fd, int timeout_sec)
return -1;
}
int poll_fd(int fd, int timeout_sec)
{
return poll_fds(&fd, 1, timeout_sec);
}
int is_fd_connected(int fd)
{
#ifdef HAVE_POLL

@ -26,6 +26,7 @@
#include <stdlib.h>
#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);

@ -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)

@ -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);

@ -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;
}

@ -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

@ -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));

@ -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));

Loading…
Cancel
Save