[exim-cvs] DSCP: take numeric values too.

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] DSCP: take numeric values too.
Gitweb: http://git.exim.org/exim.git/commitdiff/2a1b36b3082412c6723ec29c1fc1ef02589bd3b3
Commit:     2a1b36b3082412c6723ec29c1fc1ef02589bd3b3
Parent:     2126b083f98d6322d94cb7465c3c6669cb5878c9
Author:     Phil Pennock <pdp@???>
AuthorDate: Sat Jun 2 14:45:26 2012 -0400
Committer:  Phil Pennock <pdp@???>
CommitDate: Sat Jun 2 14:45:26 2012 -0400


    DSCP: take numeric values too.


    Also fix doc claim that value is unexpanded.
    Also strip affix whitespace before numeric conversion and fixed string comparison.
---
 doc/doc-docbook/spec.xfpt |    9 +++++----
 doc/doc-txt/NewStuff      |    1 +
 src/src/ip.c              |   32 ++++++++++++++++++++++++++++++--
 3 files changed, 36 insertions(+), 6 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 15a8f35..d370cbc 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -22102,13 +22102,14 @@ details.


.new
-.option dscp smtp string unset
+.option dscp smtp string&!! unset
.cindex "DCSP"
.cindex "DiffServ"
This option causes the DSCP value associated with a socket to be set to one
-of a number of fixed strings. The &%-bI:dscp%& option may be used to ask
-Exim which values it knows of. Common values include &`throughput`&,
-&`mincost`&, and on newer systems &`ef`&, &`af41`&, ...
+of a number of fixed strings or to numeric value.
+The &%-bI:dscp%& option may be used to ask Exim which names it knows of.
+Common values include &`throughput`&, &`mincost`&, and on newer systems
+&`ef`&, &`af41`&, etc. Numeric values may be in the range 0 to 0x3F.

 The outbound packets from Exim will be marked with this value in the header
 (for IPv4, the TOS field; for IPv6, the TCLASS field); there is no guarantee
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 2aaf562..e33d285 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -43,6 +43,7 @@ Version 4.81
     set "dscp = ef", for instance, to cause the connections to have the relevant
     DSCP (IPv4 TOS or IPv6 TCLASS) value in the header.  Supported values depend
     upon system libraries.  "exim -bI:dscp" to list the ones Exim knows of.
+    You can also set a raw number 0..0x3F.



Version 4.80
diff --git a/src/src/ip.c b/src/src/ip.c
index be4511d..2be6824 100644
--- a/src/src/ip.c
+++ b/src/src/ip.c
@@ -400,7 +400,11 @@ static int dscp_table_size =
sizeof(dscp_table) / sizeof(struct dscp_name_tableentry);

/* DSCP values change by protocol family, and so do the options used for
-setsockopt(); this utility does all the lookups.
+setsockopt(); this utility does all the lookups. It takes an unexpanded
+option string, expands it, strips off affix whitespace, then checks if it's
+a number. If all of what's left is a number, then that's how the option will
+be parsed and success/failure is a range check. If it's not all a number,
+then it must be a supported keyword.

Arguments:
dscp_name a string, so far unvalidated
@@ -410,14 +414,17 @@ Arguments:
dscp_value value for dscp_name

Returns: TRUE if okay to setsockopt(), else FALSE
+
+*level and *optname may be set even if FALSE is returned
*/

 BOOL
 dscp_lookup(const uschar *dscp_name, int af,
     int *level, int *optname, int *dscp_value)
 {
-uschar *dscp_lookup;
+uschar *dscp_lookup, *p;
 int first, last;
+long rawlong;


if (af == AF_INET)
{
@@ -445,6 +452,27 @@ dscp_lookup = expand_string(US dscp_name);
if (dscp_lookup == NULL || *dscp_lookup == '\0')
return FALSE;

+p = dscp_lookup + Ustrlen(dscp_lookup) - 1;
+while (isspace(*p)) *p-- = '\0';
+while (isspace(*dscp_lookup) && dscp_lookup < p) dscp_lookup++;
+if (*dscp_lookup == '\0')
+  return FALSE;
+
+rawlong = Ustrtol(dscp_lookup, &p, 0);
+if (p != dscp_lookup && *p == '\0')
+  {
+  /* We have six bits available, which will end up shifted to fit in 0xFC mask.
+  RFC 2597 defines the values unshifted. */
+  if (rawlong < 0 || rawlong > 0x3F)
+    {
+    DEBUG(D_transport)
+      debug_printf("DSCP value %ld out of range, ignored.\n", rawlong);
+    return FALSE;
+    }
+  *dscp_value = rawlong << 2;
+  return TRUE;
+  }
+
 first = 0;
 last = dscp_table_size;
 while (last > first)