Blame SOURCES/sendmail-8.15.2-qos.patch

95f7f3
diff --git a/cf/cf/submit.mc b/cf/cf/submit.mc
95f7f3
index b9dfb16..cb325cc 100644
95f7f3
--- a/cf/cf/submit.mc
95f7f3
+++ b/cf/cf/submit.mc
95f7f3
@@ -22,6 +22,8 @@ define(`__OSTYPE__',`')dnl dirty hack to keep proto.m4 from complaining
95f7f3
 define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet
95f7f3
 define(`confTIME_ZONE', `USE_TZ')dnl
95f7f3
 define(`confDONT_INIT_GROUPS', `True')dnl
95f7f3
+dnl # If you're operating in a DSCP/RFC-4594 environment with QoS
95f7f3
+dnl define(`confINET_QOS', `AF11')dnl
95f7f3
 define(`confPID_FILE', `/run/sm-client.pid')dnl
95f7f3
 dnl define(`confDIRECT_SUBMISSION_MODIFIERS',`C')dnl
95f7f3
 FEATURE(`use_ct_file')dnl
95f7f3
diff --git a/cf/m4/proto.m4 b/cf/m4/proto.m4
95f7f3
index 5a5963b..0df3416 100644
95f7f3
--- a/cf/m4/proto.m4
95f7f3
+++ b/cf/m4/proto.m4
95f7f3
@@ -251,6 +251,9 @@ _OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
95f7f3
 # 8-bit data handling
95f7f3
 _OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
95f7f3
 
95f7f3
+# DSCP marking of traffic (IP_TOS)
95f7f3
+_OPTION(InetQoS, `confINET_QOS', `none')
95f7f3
+
95f7f3
 # wait for alias file rebuild (default units: minutes)
95f7f3
 _OPTION(AliasWait, `confALIAS_WAIT', `5m')
95f7f3
 
95f7f3
diff --git a/sendmail/conf.c b/sendmail/conf.c
95f7f3
index cbb9c76..1b55533 100644
95f7f3
--- a/sendmail/conf.c
95f7f3
+++ b/sendmail/conf.c
95f7f3
@@ -6430,6 +6430,10 @@ char	*FFRCompileOptions[] =
95f7f3
 #if _FFR_QF_PARANOIA
95f7f3
 	"_FFR_QF_PARANOIA",
95f7f3
 #endif
95f7f3
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
95f7f3
+	/* QoS */
95f7f3
+	"_FFR_QOS",
95f7f3
+#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */
95f7f3
 #if _FFR_QUEUE_GROUP_SORTORDER
95f7f3
 	/* Allow QueueSortOrder per queue group. */
95f7f3
 /* XXX: Still need to actually use qgrp->qg_sortorder */
95f7f3
diff --git a/sendmail/daemon.c b/sendmail/daemon.c
95f7f3
index 4288365..86fe319 100644
95f7f3
--- a/sendmail/daemon.c
95f7f3
+++ b/sendmail/daemon.c
95f7f3
@@ -104,6 +104,10 @@ static int	NDaemons = 0;			/* actual number of daemons */
95f7f3
 
95f7f3
 static time_t	NextDiskSpaceCheck = 0;
95f7f3
 
95f7f3
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
95f7f3
+int		InetQoS = 0;			/* none by default */
95f7f3
+#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */
95f7f3
+
95f7f3
 /*
95f7f3
 **  GETREQUESTS -- open mail IPC port and get requests.
95f7f3
 **
95f7f3
@@ -1139,6 +1143,16 @@ opendaemonsocket(d, firsttime)
95f7f3
 			(void) setsockopt(d->d_socket, SOL_SOCKET,
95f7f3
 					  SO_KEEPALIVE, (char *)&on, sizeof(on));
95f7f3
 
95f7f3
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
95f7f3
+			if (InetQoS != 0x00
95f7f3
+			 && (d->d_addr.sa.sa_family == AF_INET
95f7f3
+			  || (d->d_addr.sin6.sin6_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(d->d_addr.sin6.sin6_addr.s6_addr32)))) {
95f7f3
+				if (setsockopt(d->d_socket, SOL_IP,
95f7f3
+						  IP_TOS, (char *)&InetQoS, sizeof(InetQoS)) < 0)
95f7f3
+					syserr("opendaemonsock: daemon %s: setsockopt(IP_TOS)", d->d_name);
95f7f3
+			}
95f7f3
+#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */
95f7f3
+
95f7f3
 #ifdef SO_RCVBUF
95f7f3
 			if (d->d_tcprcvbufsize > 0)
95f7f3
 			{
95f7f3
@@ -2571,6 +2585,16 @@ gothostent:
95f7f3
 			return EX_TEMPFAIL;
95f7f3
 		}
95f7f3
 
95f7f3
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
95f7f3
+		if (InetQoS != 0x00
95f7f3
+		 && (family == AF_INET
95f7f3
+		  || (family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(addr.sin6.sin6_addr.s6_addr32))))
95f7f3
+		{
95f7f3
+			if (setsockopt(s, SOL_IP, IP_TOS,
95f7f3
+					  (char *)&InetQoS, sizeof(InetQoS)) < 0)
95f7f3
+				syserr("makeconnection: setsockopt(IP_TOS)");
95f7f3
+		}
95f7f3
+#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */
95f7f3
 #ifdef SO_SNDBUF
95f7f3
 		if (ClientSettings[family].d_tcpsndbufsize > 0)
95f7f3
 		{
95f7f3
diff --git a/sendmail/readcf.c b/sendmail/readcf.c
95f7f3
index 2b0fbf7..86892f5 100644
95f7f3
--- a/sendmail/readcf.c
95f7f3
+++ b/sendmail/readcf.c
95f7f3
@@ -18,6 +18,7 @@ SM_RCSID("@(#)$Id: readcf.c,v 8.692 2013-11-22 20:51:56 ca Exp $")
95f7f3
 
95f7f3
 #if NETINET || NETINET6
95f7f3
 # include <arpa/inet.h>
95f7f3
+# include <netinet/ip.h>
95f7f3
 #endif /* NETINET || NETINET6 */
95f7f3
 
95f7f3
 
95f7f3
@@ -2888,8 +2889,8 @@ static struct optioninfo
95f7f3
 # define O_RCPTTHROTDELAY	0xe6
95f7f3
 	{ "BadRcptThrottleDelay",	O_RCPTTHROTDELAY,	OI_SAFE	},
95f7f3
 #endif /* _FFR_RCPTTHROTDELAY */
95f7f3
-#if 0 && _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
95f7f3
-# define O_INETQOS	0xe7	/* reserved for FFR_QOS */
95f7f3
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
95f7f3
+# define O_INETQOS		0xe7
95f7f3
 	{ "InetQoS",			O_INETQOS,	OI_NONE },
95f7f3
 #endif
95f7f3
 #if STARTTLS && _FFR_FIPSMODE
95f7f3
@@ -2914,6 +2915,77 @@ static struct optioninfo
95f7f3
 	{ NULL,				'\0',		OI_NONE	}
95f7f3
 };
95f7f3
 
95f7f3
+#ifdef O_INETQOS
95f7f3
+static struct qosmap
95f7f3
+{
95f7f3
+	char	*name;		/* name of the setting */
95f7f3
+	int	value;		/* corresponding setsockopt() value */
95f7f3
+} QoSMap[] = {
95f7f3
+#ifdef IPTOS_CLASS_CS0
95f7f3
+	{ "CS0",	IPTOS_CLASS_CS0 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_CLASS_CS1
95f7f3
+	{ "CS1",	IPTOS_CLASS_CS1 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF11
95f7f3
+	{ "AF11",	IPTOS_DSCP_AF11 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF12
95f7f3
+	{ "AF12",	IPTOS_DSCP_AF12 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF13
95f7f3
+	{ "AF13",	IPTOS_DSCP_AF13 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_CLASS_CS2
95f7f3
+	{ "CS2",	IPTOS_CLASS_CS2 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF21
95f7f3
+	{ "AF21",	IPTOS_DSCP_AF21 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF22
95f7f3
+	{ "AF22",	IPTOS_DSCP_AF22 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF23
95f7f3
+	{ "AF23",	IPTOS_DSCP_AF23 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_CLASS_CS3
95f7f3
+	{ "CS3",	IPTOS_CLASS_CS3 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF31
95f7f3
+	{ "AF31",	IPTOS_DSCP_AF31 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF32
95f7f3
+	{ "AF32",	IPTOS_DSCP_AF32 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF33
95f7f3
+	{ "AF33",	IPTOS_DSCP_AF33 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_CLASS_CS4
95f7f3
+	{ "CS4",	IPTOS_CLASS_CS4 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF41
95f7f3
+	{ "AF41",	IPTOS_DSCP_AF41 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF42
95f7f3
+	{ "AF42",	IPTOS_DSCP_AF42 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_DSCP_AF43
95f7f3
+	{ "AF43",	IPTOS_DSCP_AF43 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_CLASS_CS5
95f7f3
+	{ "CS5",	IPTOS_CLASS_CS5 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_CLASS_CS6
95f7f3
+	{ "CS6",	IPTOS_CLASS_CS6 },
95f7f3
+#endif
95f7f3
+#ifdef IPTOS_CLASS_CS7
95f7f3
+	{ "CS7",	IPTOS_CLASS_CS7 },
95f7f3
+#endif
95f7f3
+	{ "none",	0x00 },
95f7f3
+	{ NULL,		0    }
95f7f3
+};
95f7f3
+#endif
95f7f3
+
95f7f3
 # define CANONIFY(val)
95f7f3
 
95f7f3
 # define SET_OPT_DEFAULT(opt, val)	opt = val
95f7f3
@@ -4540,6 +4612,33 @@ setoption(opt, val, safe, sticky, e)
95f7f3
 		UseCompressedIPv6Addresses = atobool(val);
95f7f3
 		break;
95f7f3
 
95f7f3
+#ifdef O_INETQOS
95f7f3
+	  case O_INETQOS:
95f7f3
+		{
95f7f3
+			struct qosmap *qmp;
95f7f3
+			InetQoS = -1;
95f7f3
+
95f7f3
+			for (qmp = QoSMap; qmp->name != NULL; ++qmp) {
95f7f3
+				if (!strcmp(val, qmp->name)) {
95f7f3
+					InetQoS = qmp->value;
95f7f3
+					break;
95f7f3
+				}
95f7f3
+			}
95f7f3
+
95f7f3
+			/*
95f7f3
+			** we could allow writing it as a hex value, but
95f7f3
+			** we don't at this time.
95f7f3
+			**/
95f7f3
+			if (qmp->name == NULL) {
95f7f3
+				(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
95f7f3
+						     "Warning: Option: %s unknown parameter '%s'\n",
95f7f3
+						     OPTNAME, val);
95f7f3
+				break;
95f7f3
+			}
95f7f3
+			break;
95f7f3
+		}
95f7f3
+#endif
95f7f3
+
95f7f3
 	  default:
95f7f3
 		if (tTd(37, 1))
95f7f3
 		{
95f7f3
diff --git a/sendmail/sendmail.h b/sendmail/sendmail.h
95f7f3
index b2d0211..3bcc2e2 100644
95f7f3
--- a/sendmail/sendmail.h
95f7f3
+++ b/sendmail/sendmail.h
95f7f3
@@ -2537,7 +2537,14 @@ EXTERN struct termescape	TermEscape;	/* terminal escape codes */
95f7f3
 EXTERN SOCKADDR	ConnectOnlyTo;	/* override connection address (for testing) */
95f7f3
 EXTERN SOCKADDR RealHostAddr;	/* address of host we are talking to */
95f7f3
 extern const SM_EXC_TYPE_T EtypeQuickAbort; /* type of a QuickAbort exception */
95f7f3
-
95f7f3
+#if _FFR_QOS
95f7f3
+# if !defined(SOL_IP) && defined(IPPROTO_IP)
95f7f3
+#  define SOL_IP IPPROTO_IP
95f7f3
+# endif
95f7f3
+# if defined(SOL_IP) && defined(IP_TOS)
95f7f3
+EXTERN int	InetQoS;	/* QoS mapping */
95f7f3
+# endif
95f7f3
+#endif
95f7f3
 
95f7f3
 EXTERN int ConnectionRateWindowSize;
95f7f3
 #if STARTTLS && USE_OPENSSL_ENGINE