--- sendmail-8.14.4/cf/m4/proto.m4.orig 2011-01-11 20:02:14.000000000 -0700 +++ sendmail-8.14.4/cf/m4/proto.m4 2011-01-11 20:02:14.000000000 -0700 @@ -251,6 +251,9 @@ _OPTION(SevenBitInput, `confSEVEN_BIT_IN # 8-bit data handling _OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8') +# DSCP marking of traffic (IP_TOS) +_OPTION(InetQoS, `confINET_QOS', `none') + # wait for alias file rebuild (default units: minutes) _OPTION(AliasWait, `confALIAS_WAIT', `5m') --- sendmail-8.14.4/cf/cf/submit.mc.orig 2011-01-11 20:02:14.000000000 -0700 +++ sendmail-8.14.4/cf/cf/submit.mc 2011-01-11 20:02:14.000000000 -0700 @@ -22,6 +22,8 @@ define(`__OSTYPE__',`')dnl dirty hack to define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet define(`confTIME_ZONE', `USE_TZ')dnl define(`confDONT_INIT_GROUPS', `True')dnl +dnl # If you're operating in a DSCP/RFC-4594 environment with QoS +dnl define(`confINET_QOS', `AF11')dnl define(`confPID_FILE', `/run/sm-client.pid')dnl dnl define(`confDIRECT_SUBMISSION_MODIFIERS',`C')dnl FEATURE(`use_ct_file')dnl --- sendmail-8.14.4/sendmail/sendmail.h.orig 2009-12-18 10:08:01.000000000 -0700 +++ sendmail-8.14.4/sendmail/sendmail.h 2011-01-11 20:39:35.000000000 -0700 @@ -2387,7 +2387,14 @@ EXTERN struct termescape TermEscape; /* EXTERN SOCKADDR ConnectOnlyTo; /* override connection address (for testing) */ EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */ extern const SM_EXC_TYPE_T EtypeQuickAbort; /* type of a QuickAbort exception */ - +#if _FFR_QOS +# if !defined(SOL_IP) && defined(IPPROTO_IP) +# define SOL_IP IPPROTO_IP +# endif +# if defined(SOL_IP) && defined(IP_TOS) +EXTERN int InetQoS; /* QoS mapping */ +# endif +#endif EXTERN int ConnectionRateWindowSize; #if STARTTLS && USE_OPENSSL_ENGINE --- sendmail-8.14.4/sendmail/conf.c.orig 2011-01-11 20:02:14.000000000 -0700 +++ sendmail-8.14.4/sendmail/conf.c 2011-01-11 20:24:29.000000000 -0700 @@ -6298,6 +6298,10 @@ char *FFRCompileOptions[] = #if _FFR_QF_PARANOIA "_FFR_QF_PARANOIA", #endif /* _FFR_QF_PARANOIA */ +#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) + /* QoS */ + "_FFR_QOS", +#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */ #if _FFR_QUEUEDELAY /* Exponential queue delay; disabled in 8.13 since it isn't used. */ "_FFR_QUEUEDELAY", --- sendmail-8.14.4/sendmail/daemon.c.orig 2009-12-17 18:12:40.000000000 -0700 +++ sendmail-8.14.4/sendmail/daemon.c 2011-01-11 20:46:37.000000000 -0700 @@ -104,6 +104,10 @@ static int NDaemons = 0; /* actual num static time_t NextDiskSpaceCheck = 0; +#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) +int InetQoS = 0; /* none by default */ +#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */ + /* ** GETREQUESTS -- open mail IPC port and get requests. ** @@ -1131,6 +1135,16 @@ opendaemonsocket(d, firsttime) (void) setsockopt(d->d_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on)); +#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) + if (InetQoS != 0x00 + && (d->d_addr.sa.sa_family == AF_INET + || (d->d_addr.sin6.sin6_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(d->d_addr.sin6.sin6_addr.s6_addr32)))) { + if (setsockopt(d->d_socket, SOL_IP, + IP_TOS, (char *)&InetQoS, sizeof(InetQoS)) < 0) + syserr("opendaemonsock: daemon %s: setsockopt(IP_TOS)", d->d_name); + } +#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */ + #ifdef SO_RCVBUF if (d->d_tcprcvbufsize > 0) { @@ -2565,6 +2579,16 @@ gothostent: return EX_TEMPFAIL; } +#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) + if (InetQoS != 0x00 + && (family == AF_INET + || (family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(addr.sin6.sin6_addr.s6_addr32)))) + { + if (setsockopt(s, SOL_IP, IP_TOS, + (char *)&InetQoS, sizeof(InetQoS)) < 0) + syserr("makeconnection: setsockopt(IP_TOS)"); + } +#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */ #ifdef SO_SNDBUF if (ClientSettings[family].d_tcpsndbufsize > 0) { --- sendmail-8.14.7/sendmail/readcf.c.orig 2013-03-15 18:54:12.000000000 +0100 +++ sendmail-8.14.7/sendmail/readcf.c 2013-04-21 17:58:19.000000000 +0200 @@ -18,6 +18,7 @@ #if NETINET || NETINET6 # include +# include #endif /* NETINET || NETINET6 */ @@ -2280,8 +2281,8 @@ # define O_RCPTTHROTDELAY 0xe6 { "BadRcptThrottleDelay", O_RCPTTHROTDELAY, OI_SAFE }, #endif /* _FFR_RCPTTHROTDELAY */ -#if 0 && _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) -# define O_INETQOS 0xe7 /* reserved for FFR_QOS */ +#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) +# define O_INETQOS 0xe7 { "InetQoS", O_INETQOS, OI_NONE }, #endif #if STARTTLS && _FFR_FIPSMODE @@ -2389,6 +2390,77 @@ }; #endif /* STARTTLS && _FFR_TLS_1 */ +#ifdef O_INETQOS +static struct qosmap +{ + char *name; /* name of the setting */ + int value; /* corresponding setsockopt() value */ +} QoSMap[] = { +#ifdef IPTOS_CLASS_CS0 + { "CS0", IPTOS_CLASS_CS0 }, +#endif +#ifdef IPTOS_CLASS_CS1 + { "CS1", IPTOS_CLASS_CS1 }, +#endif +#ifdef IPTOS_DSCP_AF11 + { "AF11", IPTOS_DSCP_AF11 }, +#endif +#ifdef IPTOS_DSCP_AF12 + { "AF12", IPTOS_DSCP_AF12 }, +#endif +#ifdef IPTOS_DSCP_AF13 + { "AF13", IPTOS_DSCP_AF13 }, +#endif +#ifdef IPTOS_CLASS_CS2 + { "CS2", IPTOS_CLASS_CS2 }, +#endif +#ifdef IPTOS_DSCP_AF21 + { "AF21", IPTOS_DSCP_AF21 }, +#endif +#ifdef IPTOS_DSCP_AF22 + { "AF22", IPTOS_DSCP_AF22 }, +#endif +#ifdef IPTOS_DSCP_AF23 + { "AF23", IPTOS_DSCP_AF23 }, +#endif +#ifdef IPTOS_CLASS_CS3 + { "CS3", IPTOS_CLASS_CS3 }, +#endif +#ifdef IPTOS_DSCP_AF31 + { "AF31", IPTOS_DSCP_AF31 }, +#endif +#ifdef IPTOS_DSCP_AF32 + { "AF32", IPTOS_DSCP_AF32 }, +#endif +#ifdef IPTOS_DSCP_AF33 + { "AF33", IPTOS_DSCP_AF33 }, +#endif +#ifdef IPTOS_CLASS_CS4 + { "CS4", IPTOS_CLASS_CS4 }, +#endif +#ifdef IPTOS_DSCP_AF41 + { "AF41", IPTOS_DSCP_AF41 }, +#endif +#ifdef IPTOS_DSCP_AF42 + { "AF42", IPTOS_DSCP_AF42 }, +#endif +#ifdef IPTOS_DSCP_AF43 + { "AF43", IPTOS_DSCP_AF43 }, +#endif +#ifdef IPTOS_CLASS_CS5 + { "CS5", IPTOS_CLASS_CS5 }, +#endif +#ifdef IPTOS_CLASS_CS6 + { "CS6", IPTOS_CLASS_CS6 }, +#endif +#ifdef IPTOS_CLASS_CS7 + { "CS7", IPTOS_CLASS_CS7 }, +#endif + { "none", 0x00 }, + { NULL, 0 } +}; +#endif + # define CANONIFY(val) @@ -4035,6 +4107,33 @@ break; #endif /* _FFR_REJECT_NUL_BYTE */ +#ifdef O_INETQOS + case O_INETQOS: + { + struct qosmap *qmp; + InetQoS = -1; + + for (qmp = QoSMap; qmp->name != NULL; ++qmp) { + if (!strcmp(val, qmp->name)) { + InetQoS = qmp->value; + break; + } + } + + /* + ** we could allow writing it as a hex value, but + ** we don't at this time. + **/ + if (qmp->name == NULL) { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Warning: Option: %s unknown parameter '%s'\n", + OPTNAME, val); + break; + } + break; + } +#endif + default: if (tTd(37, 1)) {