summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libmilter/listener.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libmilter/listener.c')
-rw-r--r--contrib/sendmail/libmilter/listener.c119
1 files changed, 81 insertions, 38 deletions
diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c
index 3661488..03d8acd 100644
--- a/contrib/sendmail/libmilter/listener.c
+++ b/contrib/sendmail/libmilter/listener.c
@@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: listener.c,v 1.1.1.7 2002/04/10 03:05:00 gshapiro Exp $")
+SM_RCSID("@(#)$Id: listener.c,v 8.85 2002/05/28 18:17:41 gshapiro Exp $")
/*
** listener.c -- threaded network listener
@@ -24,6 +24,58 @@ SM_RCSID("@(#)$Id: listener.c,v 1.1.1.7 2002/04/10 03:05:00 gshapiro Exp $")
# endif /* NETINET || NETINET6 */
static smutex_t L_Mutex;
+static int L_family;
+static SOCKADDR_LEN_T L_socksize;
+static socket_t listenfd = INVALID_SOCKET;
+
+static socket_t mi_milteropen __P((char *, int, char *));
+
+/*
+** MI_OPENSOCKET -- create the socket where this filter and the MTA will meet
+**
+** Parameters:
+** conn -- connection description
+** backlog -- listen backlog
+** dbg -- debug level
+** smfi -- filter structure to use
+**
+** Return value:
+** MI_SUCCESS/MI_FAILURE
+*/
+
+int
+mi_opensocket(conn, backlog, dbg, smfi)
+ char *conn;
+ int backlog;
+ int dbg;
+ smfiDesc_ptr smfi;
+{
+ if (smfi == NULL || conn == NULL)
+ return MI_FAILURE;
+
+ if (ValidSocket(listenfd))
+ return MI_SUCCESS;
+
+ if (dbg > 0)
+ {
+ smi_log(SMI_LOG_DEBUG,
+ "%s: Opening listen socket on conn %s",
+ smfi->xxfi_name, conn);
+ }
+ (void) smutex_init(&L_Mutex);
+ (void) smutex_lock(&L_Mutex);
+ listenfd = mi_milteropen(conn, backlog, smfi->xxfi_name);
+ if (!ValidSocket(listenfd))
+ {
+ smi_log(SMI_LOG_FATAL,
+ "%s: Unable to create listening socket on conn %s",
+ smfi->xxfi_name, conn);
+ (void) smutex_unlock(&L_Mutex);
+ return MI_FAILURE;
+ }
+
+ return MI_SUCCESS;
+}
/*
** MI_MILTEROPEN -- setup socket to listen on
@@ -31,8 +83,6 @@ static smutex_t L_Mutex;
** Parameters:
** conn -- connection description
** backlog -- listen backlog
-** socksize -- socksize of created socket
-** family -- family of created socket
** name -- name for logging
**
** Returns:
@@ -47,15 +97,14 @@ static char *sockpath = NULL;
#endif /* NETUNIX */
static socket_t
-mi_milteropen(conn, backlog, socksize, family, name)
+mi_milteropen(conn, backlog, name)
char *conn;
int backlog;
- SOCKADDR_LEN_T *socksize;
- int *family;
char *name;
{
socket_t sock;
int sockopt = 1;
+ int fdflags;
size_t len = 0;
char *p;
char *colon;
@@ -82,17 +131,17 @@ mi_milteropen(conn, backlog, socksize, family, name)
#if NETUNIX
/* default to AF_UNIX */
addr.sa.sa_family = AF_UNIX;
- *socksize = sizeof (struct sockaddr_un);
+ L_socksize = sizeof (struct sockaddr_un);
#else /* NETUNIX */
# if NETINET
/* default to AF_INET */
addr.sa.sa_family = AF_INET;
- *socksize = sizeof addr.sin;
+ L_socksize = sizeof addr.sin;
# else /* NETINET */
# if NETINET6
/* default to AF_INET6 */
addr.sa.sa_family = AF_INET6;
- *socksize = sizeof addr.sin6;
+ L_socksize = sizeof addr.sin6;
# else /* NETINET6 */
/* no protocols available */
smi_log(SMI_LOG_ERR,
@@ -108,21 +157,21 @@ mi_milteropen(conn, backlog, socksize, family, name)
strcasecmp(p, "local") == 0)
{
addr.sa.sa_family = AF_UNIX;
- *socksize = sizeof (struct sockaddr_un);
+ L_socksize = sizeof (struct sockaddr_un);
}
#endif /* NETUNIX */
#if NETINET
else if (strcasecmp(p, "inet") == 0)
{
addr.sa.sa_family = AF_INET;
- *socksize = sizeof addr.sin;
+ L_socksize = sizeof addr.sin;
}
#endif /* NETINET */
#if NETINET6
else if (strcasecmp(p, "inet6") == 0)
{
addr.sa.sa_family = AF_INET6;
- *socksize = sizeof addr.sin6;
+ L_socksize = sizeof addr.sin6;
}
#endif /* NETINET6 */
else
@@ -139,17 +188,17 @@ mi_milteropen(conn, backlog, socksize, family, name)
#if NETUNIX
/* default to AF_UNIX */
addr.sa.sa_family = AF_UNIX;
- *socksize = sizeof (struct sockaddr_un);
+ L_socksize = sizeof (struct sockaddr_un);
#else /* NETUNIX */
# if NETINET
/* default to AF_INET */
addr.sa.sa_family = AF_INET;
- *socksize = sizeof addr.sin;
+ L_socksize = sizeof addr.sin;
# else /* NETINET */
# if NETINET6
/* default to AF_INET6 */
addr.sa.sa_family = AF_INET6;
- *socksize = sizeof addr.sin6;
+ L_socksize = sizeof addr.sin6;
# else /* NETINET6 */
smi_log(SMI_LOG_ERR, "%s: unknown socket type %s",
name, p);
@@ -380,6 +429,16 @@ mi_milteropen(conn, backlog, socksize, family, name)
return INVALID_SOCKET;
}
+ if ((fdflags = fcntl(sock, F_GETFD, 0)) == -1 ||
+ fcntl(sock, F_SETFD, fdflags | FD_CLOEXEC) == -1)
+ {
+ smi_log(SMI_LOG_ERR,
+ "%s: Unable to set close-on-exec: %s", name,
+ sm_errstring(errno));
+ (void) closesocket(sock);
+ return INVALID_SOCKET;
+ }
+
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt,
sizeof(sockopt)) == -1)
{
@@ -390,7 +449,7 @@ mi_milteropen(conn, backlog, socksize, family, name)
return INVALID_SOCKET;
}
- if (bind(sock, &addr.sa, *socksize) < 0)
+ if (bind(sock, &addr.sa, L_socksize) < 0)
{
smi_log(SMI_LOG_ERR,
"%s: Unable to bind to port %s: %s",
@@ -429,7 +488,7 @@ mi_milteropen(conn, backlog, socksize, family, name)
}
}
#endif /* NETUNIX */
- *family = addr.sa.sa_family;
+ L_family = addr.sa.sa_family;
return sock;
}
/*
@@ -449,8 +508,6 @@ mi_thread_handle_wrapper(arg)
return (void *) mi_handle_session(arg);
}
-static socket_t listenfd = INVALID_SOCKET;
-
/*
** MI_CLOSENER -- close listen socket
**
@@ -528,6 +585,7 @@ mi_closener()
** dbg -- debug level
** smfi -- filter structure to use
** timeout -- timeout for reads/writes
+** backlog -- listen queue backlog size
**
** Returns:
** MI_SUCCESS -- Exited normally
@@ -584,7 +642,6 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
int backlog;
{
socket_t connfd = INVALID_SOCKET;
- int family = AF_UNSPEC;
int sockopt = 1;
int r;
int ret = MI_SUCCESS;
@@ -595,29 +652,15 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
int save_errno = 0;
sthread_t thread_id;
_SOCK_ADDR cliaddr;
- SOCKADDR_LEN_T socksize;
SOCKADDR_LEN_T clilen;
SMFICTX_PTR ctx;
fd_set readset, excset;
struct timeval chktime;
- if (dbg > 0)
- smi_log(SMI_LOG_DEBUG,
- "%s: Opening listen socket on conn %s",
- smfi->xxfi_name, conn);
- (void) smutex_init(&L_Mutex);
- (void) smutex_lock(&L_Mutex);
- listenfd = mi_milteropen(conn, backlog, &socksize, &family,
- smfi->xxfi_name);
- if (!ValidSocket(listenfd))
- {
- smi_log(SMI_LOG_FATAL,
- "%s: Unable to create listening socket on conn %s",
- smfi->xxfi_name, conn);
- (void) smutex_unlock(&L_Mutex);
+ if (mi_opensocket(conn, backlog, dbg, smfi) == MI_FAILURE)
return MI_FAILURE;
- }
- clilen = socksize;
+
+ clilen = L_socksize;
if (listenfd >= FD_SETSIZE)
{
@@ -698,7 +741,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
# ifdef BSD4_4_SOCKADDR
cliaddr.sa.sa_len == 0 ||
# endif /* BSD4_4_SOCKADDR */
- cliaddr.sa.sa_family != family))
+ cliaddr.sa.sa_family != L_family))
{
(void) closesocket(connfd);
connfd = INVALID_SOCKET;
OpenPOWER on IntegriCloud