summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src/milter.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/milter.c')
-rw-r--r--contrib/sendmail/src/milter.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c
index f4ce5b8..5d5d260 100644
--- a/contrib/sendmail/src/milter.c
+++ b/contrib/sendmail/src/milter.c
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: milter.c,v 8.50.4.46 2001/05/11 18:11:36 gshapiro Exp $";
+static char id[] = "@(#)$Id: milter.c,v 8.50.4.51 2001/07/20 00:53:01 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -26,6 +26,7 @@ static char id[] = "@(#)$Id: milter.c,v 8.50.4.46 2001/05/11 18:11:36 gshapiro E
# define SM_FD_ISSET FD_ISSET
# define SM_FD_SETSIZE FD_SETSIZE
+static void milter_connect_timeout __P((void));
static void milter_error __P((struct milter *));
static int milter_open __P((struct milter *, bool, ENVELOPE *));
static void milter_parse_timeouts __P((char *, struct milter *));
@@ -511,6 +512,8 @@ milter_write(m, cmd, buf, len, to, e)
** -1 otherwise.
*/
+static jmp_buf MilterConnectTimeout;
+
static int
milter_open(m, parseonly, e)
struct milter *m;
@@ -950,8 +953,23 @@ milter_open(m, parseonly, e)
return -1;
}
- if (connect(sock, (struct sockaddr *) &addr, addrlen) >= 0)
- break;
+ if (setjmp(MilterConnectTimeout) == 0)
+ {
+ EVENT *ev = NULL;
+ int i;
+
+ if (m->mf_timeout[SMFTO_CONNECT] > 0)
+ ev = setevent(m->mf_timeout[SMFTO_CONNECT],
+ milter_connect_timeout, 0);
+
+ i = connect(sock, (struct sockaddr *) &addr, addrlen);
+ save_errno = errno;
+ if (ev != NULL)
+ clrevent(ev);
+ errno = save_errno;
+ if (i >= 0)
+ break;
+ }
/* couldn't connect.... try next address */
save_errno = errno;
@@ -1006,6 +1024,8 @@ milter_open(m, parseonly, e)
}
continue;
}
+ p = CurHostName;
+ CurHostName = at;
if (tTd(64, 5))
dprintf("X%s: error connecting to filter: %s\n",
m->mf_name, errstring(save_errno));
@@ -1013,6 +1033,7 @@ milter_open(m, parseonly, e)
sm_syslog(LOG_ERR, e->e_id,
"X%s: error connecting to filter: %s",
m->mf_name, errstring(save_errno));
+ CurHostName = p;
milter_error(m);
# if _FFR_FREEHOSTENT && NETINET6
if (hp != NULL)
@@ -1030,6 +1051,19 @@ milter_open(m, parseonly, e)
# endif /* _FFR_FREEHOSTENT && NETINET6 */
return sock;
}
+
+static void
+milter_connect_timeout()
+{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
+ longjmp(MilterConnectTimeout, 1);
+}
/*
** MILTER_SETUP -- setup structure for a mail filter
**
@@ -1066,6 +1100,7 @@ milter_setup(line)
m->mf_name = newstr(line);
m->mf_state = SMFS_READY;
m->mf_sock = -1;
+ m->mf_timeout[SMFTO_CONNECT] = (time_t) 0;
m->mf_timeout[SMFTO_WRITE] = (time_t) 10;
m->mf_timeout[SMFTO_READ] = (time_t) 10;
m->mf_timeout[SMFTO_EOM] = (time_t) 300;
@@ -1097,6 +1132,10 @@ milter_setup(line)
/* install the field into the filter struct */
switch (fcode)
{
+ case 'C':
+ m->mf_timeout[SMFTO_CONNECT] = convtime(p, 's');
+ break;
+
case 'S': /* socket */
if (p == NULL)
m->mf_conn = NULL;
@@ -2851,7 +2890,10 @@ milter_connect(hostname, addr, e, state)
# if NETINET6
case AF_INET6:
- family = SMFIA_INET6;
+ if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr))
+ family = SMFIA_INET;
+ else
+ family = SMFIA_INET6;
port = htons(addr.sin6.sin6_port);
sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
sizeof buf6);
OpenPOWER on IntegriCloud