summaryrefslogtreecommitdiff
path: root/usr.sbin/sendmail/src/domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/domain.c')
-rw-r--r--usr.sbin/sendmail/src/domain.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c
index f446e741821da..ca2d8f8d86e9f 100644
--- a/usr.sbin/sendmail/src/domain.c
+++ b/usr.sbin/sendmail/src/domain.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1986, 1995 Eric P. Allman
+ * Copyright (c) 1986, 1995, 1996 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -36,9 +36,9 @@
#ifndef lint
#if NAMED_BIND
-static char sccsid[] = "@(#)domain.c 8.54.1.2 (Berkeley) 9/16/96 (with name server)";
+static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (with name server)";
#else
-static char sccsid[] = "@(#)domain.c 8.54.1.2 (Berkeley) 9/16/96 (without name server)";
+static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (without name server)";
#endif
#endif /* not lint */
@@ -46,21 +46,39 @@ static char sccsid[] = "@(#)domain.c 8.54.1.2 (Berkeley) 9/16/96 (without name s
#include <errno.h>
#include <resolv.h>
+#include <arpa/inet.h>
+
+/*
+** The standard udp packet size PACKETSZ (512) is not sufficient for some
+** nameserver answers containing very many resource records. The resolver
+** may switch to tcp and retry if it detects udp packet overflow.
+** Also note that the resolver routines res_query and res_search return
+** the size of the *un*truncated answer in case the supplied answer buffer
+** it not big enough to accommodate the entire answer.
+*/
+
+#ifndef MAXPACKET
+# define MAXPACKET 8192 /* max packet size used internally by BIND */
+#endif
typedef union
{
HEADER qb1;
- u_char qb2[PACKETSZ];
+ u_char qb2[MAXPACKET];
} querybuf;
-static char MXHostBuf[MAXMXHOSTS*PACKETSZ];
+#ifndef MXHOSTBUFSIZE
+# define MXHOSTBUFSIZE (128 * MAXMXHOSTS)
+#endif
+
+static char MXHostBuf[MXHOSTBUFSIZE];
#ifndef MAXDNSRCH
-#define MAXDNSRCH 6 /* number of possible domains to search */
+# define MAXDNSRCH 6 /* number of possible domains to search */
#endif
#ifndef MAX
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
+# define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef NO_DATA
@@ -114,32 +132,21 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
u_short pref, type;
u_short localpref = 256;
char *fallbackMX = FallBackMX;
- static bool firsttime = TRUE;
bool trycanon = FALSE;
int (*resfunc)();
extern int res_query(), res_search();
u_short prefer[MAXMXHOSTS];
int weight[MAXMXHOSTS];
- extern bool getcanonname();
+ extern int mxrand __P((char *));
if (tTd(8, 2))
printf("getmxrr(%s, droplocalhost=%d)\n", host, droplocalhost);
- if (fallbackMX != NULL)
+ if (fallbackMX != NULL && droplocalhost &&
+ wordinclass(fallbackMX, 'w'))
{
- if (firsttime &&
- res_query(FallBackMX, C_IN, T_A,
- (u_char *) &answer, sizeof answer) < 0)
- {
- /* this entry is bogus */
- fallbackMX = FallBackMX = NULL;
- }
- else if (droplocalhost && wordinclass(fallbackMX, 'w'))
- {
- /* don't use fallback for this pass */
- fallbackMX = NULL;
- }
- firsttime = FALSE;
+ /* don't use fallback for this pass */
+ fallbackMX = NULL;
}
*rcode = EX_OK;
@@ -212,6 +219,10 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
return (-1);
}
+ /* avoid problems after truncation in tcp packets */
+ if (n > sizeof(answer))
+ n = sizeof(answer);
+
/* find first satisfactory answer */
hp = (HEADER *)&answer;
cp = (u_char *)&answer + HFIXEDSZ;
@@ -356,8 +367,11 @@ punt:
if (p != NULL)
{
*p = '\0';
- if (inet_addr(&MXHostBuf[1]) != -1)
+ if (inet_addr(&MXHostBuf[1]) != INADDR_NONE)
+ {
+ nmx++;
*p = ']';
+ }
else
{
trycanon = TRUE;
@@ -518,7 +532,7 @@ dns_getcanonname(host, hbsize, trymx, statp)
int qtype;
int loopcnt;
char *xp;
- char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)];
+ char nbuf[MAX(MAXPACKET, MAXDNAME*2+2)];
char *searchlist[MAXDNSRCH+2];
extern char *gethostalias();
@@ -651,6 +665,10 @@ cnameloop:
else if (tTd(8, 7))
printf("\tYES\n");
+ /* avoid problems after truncation in tcp packets */
+ if (ret > sizeof(answer))
+ ret = sizeof(answer);
+
/*
** Appear to have a match. Confirm it by searching for A or
** CNAME records. If we don't have a local domain