I'm working with openssh-5.4p1 on Linux, however the following code
should be portable.

All that's really happening is:

(1) add new options to define the DSCP/Class-Selector values;

(2) add name-to-value mappings for the DSCP/Class-Selector values;

(3) add a parameter to keywords[] to specify whether an option can be
    user-specified (QoS bits usually should be set site-wide only by the
site's
    network administrator);

(4) rather than passing in the interactive/non-interactive to
packet_set_tos(), just
    pass in the desired QoS marking instead.

Signed-off-by: Philip Prindeville <[email protected]>
----

Index: defines.h
===================================================================
RCS file: /cvs/openssh/defines.h,v
retrieving revision 1.160
diff -u -p -r1.160 defines.h
--- defines.h   9 Apr 2010 08:13:27 -0000       1.160
+++ defines.h   16 Apr 2010 17:21:43 -0000
@@ -50,6 +50,35 @@ enum
 # define IPTOS_MINCOST           IPTOS_LOWCOST
 #endif /* IPTOS_LOWDELAY */
 +/* in glibc 2.12 */
+#ifndef IPTOS_CLASS_CS0
+#define IPTOS_CLASS_CS0         0x00
+#define IPTOS_CLASS_CS1         0x20
+#define IPTOS_CLASS_CS2         0x40
+#define IPTOS_CLASS_CS3         0x60
+#define IPTOS_CLASS_CS4         0x80
+#define IPTOS_CLASS_CS5         0xa0
+#define IPTOS_CLASS_CS6         0xc0
+#define IPTOS_CLASS_CS7         0xe0
+#endif
+
+/* in glibc 2.11 */
+#ifndef IPTOS_DSCP_AF11
+#define IPTOS_DSCP_AF11         0x28
+#define IPTOS_DSCP_AF12         0x30
+#define IPTOS_DSCP_AF13         0x38
+#define IPTOS_DSCP_AF21         0x48
+#define IPTOS_DSCP_AF22         0x50
+#define IPTOS_DSCP_AF23         0x58
+#define IPTOS_DSCP_AF31         0x68
+#define IPTOS_DSCP_AF32         0x70
+#define IPTOS_DSCP_AF33         0x78
+#define IPTOS_DSCP_AF41         0x88
+#define IPTOS_DSCP_AF42         0x90
+#define IPTOS_DSCP_AF43         0x98
+#define IPTOS_DSCP_EF           0xb8
+#endif
+
 #ifndef MAXPATHLEN
 # ifdef PATH_MAX
 #  define MAXPATHLEN PATH_MAX
Index: packet.c
===================================================================
RCS file: /cvs/openssh/packet.c,v
retrieving revision 1.169
diff -u -p -r1.169 packet.c
--- packet.c    2 Oct 2009 01:49:04 -0000       1.169
+++ packet.c    16 Apr 2010 17:21:43 -0000
@@ -78,6 +78,7 @@
 #include "misc.h"
 #include "ssh.h"
 #include "roaming.h"
+#include "readconf.h"
  #ifdef PACKET_DEBUG
 #define DBG(x) x
@@ -1728,11 +1729,9 @@ packet_not_very_much_data_to_write(void)
 }
  static void
-packet_set_tos(int interactive)
+packet_set_tos(int tos)
 {
 #if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
-       int tos = interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT;
-
        if (!packet_connection_is_on_socket() ||
            !packet_connection_is_ipv4())
                return;
@@ -1746,7 +1745,7 @@ packet_set_tos(int interactive)
 /* Informs that the current session is interactive.  Sets IP flags for that. */
  void
-packet_set_interactive(int interactive)
+packet_set_interactive(int interactive, u_char qos[2])
 {
        if (active_state->set_interactive_called)
                return;
@@ -1759,7 +1758,7 @@ packet_set_interactive(int interactive)
        if (!packet_connection_is_on_socket())
                return;
        set_nodelay(active_state->connection_in);
-       packet_set_tos(interactive);
+       packet_set_tos(interactive ? qos[1] : qos[0]);
 }
  /* Returns true if the current connection is interactive. */
Index: packet.h
===================================================================
RCS file: /cvs/openssh/packet.h,v
retrieving revision 1.54
diff -u -p -r1.54 packet.h
--- packet.h    5 Jul 2009 21:11:13 -0000       1.54
+++ packet.h    16 Apr 2010 17:21:43 -0000
@@ -31,7 +31,7 @@ u_int  packet_get_encryption_key(u_char  void     
packet_set_protocol_flags(u_int);
 u_int   packet_get_protocol_flags(void);
 void     packet_start_compression(int);
-void     packet_set_interactive(int);
+void     packet_set_interactive(int, u_char []);
 int      packet_is_interactive(void);
 void     packet_set_server(void);
 void     packet_set_authenticated(void);
Index: readconf.c
===================================================================
RCS file: /cvs/openssh/readconf.c,v
retrieving revision 1.162
diff -u -p -r1.162 readconf.c
--- readconf.c  11 Feb 2010 22:21:03 -0000      1.162
+++ readconf.c  16 Apr 2010 17:21:43 -0000
@@ -131,6 +131,7 @@ typedef enum {
        oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
        oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
        oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
+       oUseQoS,
        oDeprecated, oUnsupported
 } OpCodes;
 @@ -138,107 +139,109 @@ typedef enum {
  static struct {
        const char *name;
+       int restricted;
        OpCodes opcode;
 } keywords[] = {
-       { "forwardagent", oForwardAgent },
-       { "forwardx11", oForwardX11 },
-       { "forwardx11trusted", oForwardX11Trusted },
-       { "exitonforwardfailure", oExitOnForwardFailure },
-       { "xauthlocation", oXAuthLocation },
-       { "gatewayports", oGatewayPorts },
-       { "useprivilegedport", oUsePrivilegedPort },
-       { "rhostsauthentication", oDeprecated },
-       { "passwordauthentication", oPasswordAuthentication },
-       { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
-       { "kbdinteractivedevices", oKbdInteractiveDevices },
-       { "rsaauthentication", oRSAAuthentication },
-       { "pubkeyauthentication", oPubkeyAuthentication },
-       { "dsaauthentication", oPubkeyAuthentication },             /* alias */
-       { "rhostsrsaauthentication", oRhostsRSAAuthentication },
-       { "hostbasedauthentication", oHostbasedAuthentication },
-       { "challengeresponseauthentication", oChallengeResponseAuthentication },
-       { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
-       { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
-       { "kerberosauthentication", oUnsupported },
-       { "kerberostgtpassing", oUnsupported },
-       { "afstokenpassing", oUnsupported },
+       { "forwardagent",               0, oForwardAgent },
+       { "forwardx11",                 0, oForwardX11 },
+       { "forwardx11trusted",          0, oForwardX11Trusted },
+       { "exitonforwardfailure",       0, oExitOnForwardFailure },
+       { "xauthlocation",              0, oXAuthLocation },
+       { "gatewayports",               0, oGatewayPorts },
+       { "useprivilegedport",          0, oUsePrivilegedPort },
+       { "rhostsauthentication",       0, oDeprecated },
+       { "passwordauthentication",     0, oPasswordAuthentication },
+       { "kbdinteractiveauthentication", 0, oKbdInteractiveAuthentication },
+       { "kbdinteractivedevices",      0, oKbdInteractiveDevices },
+       { "rsaauthentication",          0, oRSAAuthentication },
+       { "pubkeyauthentication",       0, oPubkeyAuthentication },
+       { "dsaauthentication",          0, oPubkeyAuthentication },             
    /* alias */
+       { "rhostsrsaauthentication",    0, oRhostsRSAAuthentication },
+       { "hostbasedauthentication",    0, oHostbasedAuthentication },
+       { "challengeresponseauthentication", 0, 
oChallengeResponseAuthentication },
+       { "skeyauthentication",         0, oChallengeResponseAuthentication }, 
/* alias */
+       { "tisauthentication",          0, oChallengeResponseAuthentication },  
/* alias */
+       { "kerberosauthentication",     0, oUnsupported },
+       { "kerberostgtpassing",         0, oUnsupported },
+       { "afstokenpassing",            0, oUnsupported },
 #if defined(GSSAPI)
-       { "gssapiauthentication", oGssAuthentication },
-       { "gssapidelegatecredentials", oGssDelegateCreds },
+       { "gssapiauthentication",       0, oGssAuthentication },
+       { "gssapidelegatecredentials",  0, oGssDelegateCreds },
 #else
-       { "gssapiauthentication", oUnsupported },
-       { "gssapidelegatecredentials", oUnsupported },
+       { "gssapiauthentication",       0, oUnsupported },
+       { "gssapidelegatecredentials",  0, oUnsupported },
 #endif
-       { "fallbacktorsh", oDeprecated },
-       { "usersh", oDeprecated },
-       { "identityfile", oIdentityFile },
-       { "identityfile2", oIdentityFile },                     /* obsolete */
-       { "identitiesonly", oIdentitiesOnly },
-       { "hostname", oHostName },
-       { "hostkeyalias", oHostKeyAlias },
-       { "proxycommand", oProxyCommand },
-       { "port", oPort },
-       { "cipher", oCipher },
-       { "ciphers", oCiphers },
-       { "macs", oMacs },
-       { "protocol", oProtocol },
-       { "remoteforward", oRemoteForward },
-       { "localforward", oLocalForward },
-       { "user", oUser },
-       { "host", oHost },
-       { "escapechar", oEscapeChar },
-       { "globalknownhostsfile", oGlobalKnownHostsFile },
-       { "globalknownhostsfile2", oGlobalKnownHostsFile2 },    /* obsolete */
-       { "userknownhostsfile", oUserKnownHostsFile },
-       { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
-       { "connectionattempts", oConnectionAttempts },
-       { "batchmode", oBatchMode },
-       { "checkhostip", oCheckHostIP },
-       { "stricthostkeychecking", oStrictHostKeyChecking },
-       { "compression", oCompression },
-       { "compressionlevel", oCompressionLevel },
-       { "tcpkeepalive", oTCPKeepAlive },
-       { "keepalive", oTCPKeepAlive },                         /* obsolete */
-       { "numberofpasswordprompts", oNumberOfPasswordPrompts },
-       { "loglevel", oLogLevel },
-       { "dynamicforward", oDynamicForward },
-       { "preferredauthentications", oPreferredAuthentications },
-       { "hostkeyalgorithms", oHostKeyAlgorithms },
-       { "bindaddress", oBindAddress },
+       { "fallbacktorsh",              0, oDeprecated },
+       { "usersh",                     0, oDeprecated },
+       { "identityfile",               0, oIdentityFile },
+       { "identityfile2",              0, oIdentityFile },                     
/* obsolete */
+       { "identitiesonly",             0, oIdentitiesOnly },
+       { "hostname",                   0, oHostName },
+       { "hostkeyalias",               0, oHostKeyAlias },
+       { "proxycommand",               0, oProxyCommand },
+       { "port",                       0, oPort },
+       { "cipher",                     0, oCipher },
+       { "ciphers",                    0, oCiphers },
+       { "macs",                       0, oMacs },
+       { "protocol",                   0, oProtocol },
+       { "remoteforward",              0, oRemoteForward },
+       { "localforward",               0, oLocalForward },
+       { "user",                       0, oUser },
+       { "host",                       0, oHost },
+       { "escapechar",                 0, oEscapeChar },
+       { "globalknownhostsfile",       0, oGlobalKnownHostsFile },
+       { "globalknownhostsfile2",      0, oGlobalKnownHostsFile2 },    /* 
obsolete */
+       { "userknownhostsfile",         0, oUserKnownHostsFile },
+       { "userknownhostsfile2",        0, oUserKnownHostsFile2 },      /* 
obsolete */
+       { "connectionattempts",         0, oConnectionAttempts },
+       { "batchmode",                  0, oBatchMode },
+       { "checkhostip",                0, oCheckHostIP },
+       { "stricthostkeychecking",      0, oStrictHostKeyChecking },
+       { "compression",                0, oCompression },
+       { "compressionlevel",           0, oCompressionLevel },
+       { "tcpkeepalive",               0, oTCPKeepAlive },
+       { "keepalive",                  0, oTCPKeepAlive },                     
        /* obsolete */
+       { "numberofpasswordprompts",    0, oNumberOfPasswordPrompts },
+       { "loglevel",                   0, oLogLevel },
+       { "dynamicforward",             0, oDynamicForward },
+       { "preferredauthentications",   0, oPreferredAuthentications },
+       { "hostkeyalgorithms",          0, oHostKeyAlgorithms },
+       { "bindaddress",                0, oBindAddress },
 #ifdef ENABLE_PKCS11
-       { "smartcarddevice", oPKCS11Provider },
-       { "pkcs11provider", oPKCS11Provider },
+       { "smartcarddevice",            0, oPKCS11Provider },
+       { "pkcs11provider",             0, oPKCS11Provider },
 #else
-       { "smartcarddevice", oUnsupported },
-       { "pkcs11provider", oUnsupported },
+       { "smartcarddevice",            0, oUnsupported },
+       { "pkcs11provider",             0, oUnsupported },
 #endif
-       { "clearallforwardings", oClearAllForwardings },
-       { "enablesshkeysign", oEnableSSHKeysign },
-       { "verifyhostkeydns", oVerifyHostKeyDNS },
-       { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost 
},
-       { "rekeylimit", oRekeyLimit },
-       { "connecttimeout", oConnectTimeout },
-       { "addressfamily", oAddressFamily },
-       { "serveraliveinterval", oServerAliveInterval },
-       { "serveralivecountmax", oServerAliveCountMax },
-       { "sendenv", oSendEnv },
-       { "controlpath", oControlPath },
-       { "controlmaster", oControlMaster },
-       { "hashknownhosts", oHashKnownHosts },
-       { "tunnel", oTunnel },
-       { "tunneldevice", oTunnelDevice },
-       { "localcommand", oLocalCommand },
-       { "permitlocalcommand", oPermitLocalCommand },
-       { "visualhostkey", oVisualHostKey },
-       { "useroaming", oUseRoaming },
+       { "clearallforwardings",        0, oClearAllForwardings },
+       { "enablesshkeysign",           0, oEnableSSHKeysign },
+       { "verifyhostkeydns",           0, oVerifyHostKeyDNS },
+       { "nohostauthenticationforlocalhost", 0, 
oNoHostAuthenticationForLocalhost },
+       { "rekeylimit",                 0, oRekeyLimit },
+       { "connecttimeout",             0, oConnectTimeout },
+       { "addressfamily",              0, oAddressFamily },
+       { "serveraliveinterval",        0, oServerAliveInterval },
+       { "serveralivecountmax",        0, oServerAliveCountMax },
+       { "sendenv",                    0, oSendEnv },
+       { "controlpath",                0, oControlPath },
+       { "controlmaster",              0, oControlMaster },
+       { "hashknownhosts",             0, oHashKnownHosts },
+       { "tunnel",                     0, oTunnel },
+       { "tunneldevice",               0, oTunnelDevice },
+       { "localcommand",               0, oLocalCommand },
+       { "permitlocalcommand",         0, oPermitLocalCommand },
+       { "visualhostkey",              0, oVisualHostKey },
+       { "useroaming",                 0, oUseRoaming },
+       { "useqos",                     1, oUseQoS},
 #ifdef JPAKE
-       { "zeroknowledgepasswordauthentication",
+       { "zeroknowledgepasswordauthentication", 0,
            oZeroKnowledgePasswordAuthentication },
 #else
-       { "zeroknowledgepasswordauthentication", oUnsupported },
+       { "zeroknowledgepasswordauthentication", 0, oUnsupported },
 #endif
 -      { NULL, oBadOption }
+       { NULL,                         0, oBadOption }
 };
  /*
@@ -310,19 +313,65 @@ clear_forwardings(Options *options)
  */
  static OpCodes
-parse_token(const char *cp, const char *filename, int linenum)
+parse_token(const char *cp, const char *filename, int linenum, int *restricted)
 {
        u_int i;
        for (i = 0; keywords[i].name; i++)
-               if (strcasecmp(cp, keywords[i].name) == 0)
+               if (strcasecmp(cp, keywords[i].name) == 0) {
+                       *restricted= keywords[i].restricted;
                        return keywords[i].opcode;
+               }
        error("%s: line %d: Bad configuration option: %s",
            filename, linenum, cp);
        return oBadOption;
 }
 +struct {
+       const char *name;
+       int value;
+} qos[] = {
+       { "cs0",        IPTOS_CLASS_CS0 },
+       { "cs1",        IPTOS_CLASS_CS1 },
+       { "cs2",        IPTOS_CLASS_CS2 },
+       { "cs3",        IPTOS_CLASS_CS3 },
+       { "cs4",        IPTOS_CLASS_CS4 },
+       { "cs5",        IPTOS_CLASS_CS5 },
+       { "cs6",        IPTOS_CLASS_CS6 },
+       { "cs7",        IPTOS_CLASS_CS7 },
+       { "af11",       IPTOS_DSCP_AF11 },
+       { "af12",       IPTOS_DSCP_AF12 },
+       { "af13",       IPTOS_DSCP_AF13 },
+       { "af21",       IPTOS_DSCP_AF21 },
+       { "af22",       IPTOS_DSCP_AF22 },
+       { "af23",       IPTOS_DSCP_AF23 },
+       { "af31",       IPTOS_DSCP_AF31 },
+       { "af32",       IPTOS_DSCP_AF32 },
+       { "af33",       IPTOS_DSCP_AF33 },
+       { "af41",       IPTOS_DSCP_AF41 },
+       { "af42",       IPTOS_DSCP_AF42 },
+       { "af43",       IPTOS_DSCP_AF43 },
+       { "ef",         IPTOS_DSCP_EF   },
+       { "lowdelay",   IPTOS_LOWDELAY  },
+       { "throughput", IPTOS_THROUGHPUT },
+       { "reliability", IPTOS_RELIABILITY },
+       { "lowcost",    IPTOS_LOWCOST   },
+       { "mincost",    IPTOS_MINCOST   },
+       { "none",       IPTOS_CLASS_CS0 },
+       { NULL,         -1              },
+};
+
+static int parse_qos(const char *cp)
+{
+       u_int i;
+
+       for (i = 0; qos[i].name; i++)
+               if (strcasecmp(cp, qos[i].name) == 0)
+                       return qos[i].value;
+       return -1;
+}
+
 /*
  * Processes a single option line as used in the configuration files. This
  * only sets those values that have not already been set.
@@ -332,10 +381,10 @@ parse_token(const char *cp, const char *
 int
 process_config_line(Options *options, const char *host,
                    char *line, const char *filename, int linenum,
-                   int *activep)
+                   int *activep, int systemwide)
 {
        char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
-       int opcode, *intptr, value, value2, scale;
+       int opcode, *intptr, value, value2, scale, restricted;
        LogLevel *log_level_ptr;
        long long orig, val64;
        size_t len;
@@ -358,7 +407,11 @@ process_config_line(Options *options, co
        if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
                return 0;
 -      opcode = parse_token(keyword, filename, linenum);
+       opcode = parse_token(keyword, filename, linenum, &restricted);
+
+       if (restricted && !systemwide) {
+               fatal("%s line %d: not permitted in user profile.", filename, 
linenum);
+       }
        switch (opcode) {
        case oBadOption:
@@ -921,6 +974,27 @@ parse_int:
                intptr = &options->use_roaming;
                goto parse_flag;
 +      case oUseQoS:
+               arg = strdelim(&s);
+               if (arg == NULL || *arg == '\0')
+                       fatal("%.200s line %d: Missing non-interactive QoS 
argument.",
+                           filename, linenum);
+
+               arg2 = strdelim(&s);
+               if (arg2 == NULL || *arg2 == '\0')
+                       fatal("%.200s line %d: Missing interactive QoS 
argument.",
+                           filename, linenum);
+
+               value = parse_qos(arg);
+               value2 = parse_qos(arg2);
+               if (value == -1 || value2 == -1)
+                       fatal("%.200s line %d: Bad QoS argument.",
+                           filename, linenum);
+
+               options->use_qos[0] = value;
+               options->use_qos[1] = value2;
+               break;
+
        case oDeprecated:
                debug("%s line %d: Deprecated option \"%s\"",
                    filename, linenum, keyword);
@@ -952,7 +1026,7 @@ parse_int:
  int
 read_config_file(const char *filename, const char *host, Options *options,
-    int checkperm)
+    int checkperm, int systemwide)
 {
        FILE *f;
        char line[1024];
@@ -983,7 +1057,7 @@ read_config_file(const char *filename, c
        while (fgets(line, sizeof(line), f)) {
                /* Update line number counter. */
                linenum++;
-               if (process_config_line(options, host, line, filename, linenum, 
&active) != 0)
+               if (process_config_line(options, host, line, filename, linenum, 
&active, systemwide) != 0)
                        bad_options++;
        }
        fclose(f);
@@ -1071,6 +1145,8 @@ initialize_options(Options * options)
        options->local_command = NULL;
        options->permit_local_command = -1;
        options->use_roaming = -1;
+       options->use_qos[0] = -1;
+       options->use_qos[1] = -1;
        options->visual_host_key = -1;
        options->zero_knowledge_password_authentication = -1;
 }
@@ -1219,6 +1295,10 @@ fill_default_options(Options * options)
        /* options->hostname will be set in the main program if appropriate */
        /* options->host_key_alias should not be set by default */
        /* options->preferred_authentications will be set in ssh */
+       if (options->use_qos[0] == -1)
+               options->use_qos[0] = IPTOS_THROUGHPUT;
+       if (options->use_qos[1] == -1)
+               options->use_qos[1] = IPTOS_LOWDELAY;
 }
  /*
Index: readconf.h
===================================================================
RCS file: /cvs/openssh/readconf.h,v
retrieving revision 1.74
diff -u -p -r1.74 readconf.h
--- readconf.h  11 Feb 2010 22:21:03 -0000      1.74
+++ readconf.h  16 Apr 2010 17:21:43 -0000
@@ -125,6 +125,8 @@ typedef struct {
        int     use_roaming;
 +      u_char  use_qos[2];
+
 }       Options;
  #define SSHCTL_MASTER_NO      0
@@ -135,11 +137,11 @@ typedef struct {
  void     initialize_options(Options *);
 void     fill_default_options(Options *);
-int     read_config_file(const char *, const char *, Options *, int);
+int     read_config_file(const char *, const char *, Options *, int, int);
 int     parse_forward(Forward *, const char *, int, int);
  int
-process_config_line(Options *, const char *, char *, const char *, int, int *);
+process_config_line(Options *, const char *, char *, const char *, int, int *, 
int);
  void   add_local_forward(Options *, const Forward *);
 void    add_remote_forward(Options *, const Forward *);
Index: servconf.c
===================================================================
RCS file: /cvs/openssh/servconf.c,v
retrieving revision 1.202
diff -u -p -r1.202 servconf.c
--- servconf.c  25 Mar 2010 23:40:04 -0000      1.202
+++ servconf.c  16 Apr 2010 17:21:44 -0000
@@ -131,6 +131,8 @@ initialize_server_options(ServerOptions     
options->zero_knowledge_password_authentication = -1;
        options->revoked_keys_file = NULL;
        options->trusted_user_ca_keys = NULL;
+       options->use_qos[0] = -1;
+       options->use_qos[1] = -1;
 }
  void
@@ -265,6 +267,10 @@ fill_default_server_options(ServerOption
                options->permit_tun = SSH_TUNMODE_NO;
        if (options->zero_knowledge_password_authentication == -1)
                options->zero_knowledge_password_authentication = 0;
+       if (options->use_qos[0] == -1)
+               options->use_qos[0] = IPTOS_THROUGHPUT;
+       if (options->use_qos[1] == -1)
+               options->use_qos[1] = IPTOS_LOWDELAY;
        /* Turn privilege separation on by default */
        if (use_privsep == -1)
@@ -310,7 +316,7 @@ typedef enum {
        sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
        sUsePrivilegeSeparation, sAllowAgentForwarding,
        sZeroKnowledgePasswordAuthentication, sHostCertificate,
-       sRevokedKeys, sTrustedUserCAKeys,
+       sRevokedKeys, sTrustedUserCAKeys, sUseQoS,
        sDeprecated, sUnsupported
 } ServerOpCodes;
 @@ -432,6 +438,7 @@ static struct {
        { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
        { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
        { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
+       { "useqos", sUseQoS, SSHCFG_ALL },
        { NULL, sBadOption, 0 }
 };
 @@ -467,6 +474,50 @@ parse_token(const char *cp, const char *
        return sBadOption;
 }
 +struct {
+       const char *name;
+       int value;
+} qos[] = {
+       { "cs0",        IPTOS_CLASS_CS0 },
+       { "cs1",        IPTOS_CLASS_CS1 },
+       { "cs2",        IPTOS_CLASS_CS2 },
+       { "cs3",        IPTOS_CLASS_CS3 },
+       { "cs4",        IPTOS_CLASS_CS4 },
+       { "cs5",        IPTOS_CLASS_CS5 },
+       { "cs6",        IPTOS_CLASS_CS6 },
+       { "cs7",        IPTOS_CLASS_CS7 },
+       { "af11",       IPTOS_DSCP_AF11 },
+       { "af12",       IPTOS_DSCP_AF12 },
+       { "af13",       IPTOS_DSCP_AF13 },
+       { "af21",       IPTOS_DSCP_AF21 },
+       { "af22",       IPTOS_DSCP_AF22 },
+       { "af23",       IPTOS_DSCP_AF23 },
+       { "af31",       IPTOS_DSCP_AF31 },
+       { "af32",       IPTOS_DSCP_AF32 },
+       { "af33",       IPTOS_DSCP_AF33 },
+       { "af41",       IPTOS_DSCP_AF41 },
+       { "af42",       IPTOS_DSCP_AF42 },
+       { "af43",       IPTOS_DSCP_AF43 },
+       { "ef",         IPTOS_DSCP_EF   },
+       { "lowdelay",   IPTOS_LOWDELAY  },
+       { "throughput", IPTOS_THROUGHPUT },
+       { "reliability", IPTOS_RELIABILITY },
+       { "lowcost",    IPTOS_LOWCOST   },
+       { "mincost",    IPTOS_MINCOST   },
+       { "none",       IPTOS_CLASS_CS0 },
+       { NULL,         -1              },
+};
+
+static int parse_qos(const char *cp)
+{
+       u_int i;
+
+       for (i = 0; qos[i].name; i++)
+               if (strcasecmp(cp, qos[i].name) == 0)
+                       return qos[i].value;
+       return -1;
+}
+
 char *
 derelativise_path(const char *path)
 {
@@ -660,8 +711,8 @@ process_server_config_line(ServerOptions
     const char *filename, int linenum, int *activep, const char *user,
     const char *host, const char *address)
 {
-       char *cp, **charptr, *arg, *p;
-       int cmdline = 0, *intptr, value, n;
+       char *cp, **charptr, *arg, *arg2, *p;
+       int cmdline = 0, *intptr, value, value2, n;
        SyslogFacility *log_facility_ptr;
        LogLevel *log_level_ptr;
        ServerOpCodes opcode;
@@ -1344,6 +1395,27 @@ process_server_config_line(ServerOptions
        case sRevokedKeys:
                charptr = &options->revoked_keys_file;
                goto parse_filename;
+
+       case sUseQoS:
+               arg = strdelim(&cp);
+               if (arg == NULL || *arg == '\0')
+                       fatal("%.200s line %d: Missing non-interactive QoS 
argument.",
+                           filename, linenum);
+
+               arg2 = strdelim(&cp);
+               if (arg2 == NULL || *arg2 == '\0')
+                       fatal("%.200s line %d: Missing interactive QoS 
argument.",
+                           filename, linenum);
+
+               value = parse_qos(arg);
+               value2 = parse_qos(arg2);
+               if (value == -1 || value2 == -1)
+                       fatal("%.200s line %d: Bad QoS argument.",
+                           filename, linenum);
+
+               options->use_qos[0] = value;
+               options->use_qos[1] = value2;
+               break;
        case sDeprecated:
                logit("%s line %d: Deprecated option %s",
Index: servconf.h
===================================================================
RCS file: /cvs/openssh/servconf.h,v
retrieving revision 1.84
diff -u -p -r1.84 servconf.h
--- servconf.h  4 Mar 2010 10:53:35 -0000       1.84
+++ servconf.h  16 Apr 2010 17:21:44 -0000
@@ -156,6 +156,8 @@ typedef struct {
        char   *chroot_directory;
        char   *revoked_keys_file;
        char   *trusted_user_ca_keys;
+
+       u_char  use_qos[2];
 }       ServerOptions;
  void   initialize_server_options(ServerOptions *);
Index: session.c
===================================================================
RCS file: /cvs/openssh/session.c,v
retrieving revision 1.394
diff -u -p -r1.394 session.c
--- session.c   26 Mar 2010 00:04:09 -0000      1.394
+++ session.c   16 Apr 2010 17:21:44 -0000
@@ -579,7 +579,7 @@ do_exec_no_pty(Session *s, const char *c
        s->pid = pid;
        /* Set interactive/non-interactive mode. */
-       packet_set_interactive(s->display != NULL);
+       packet_set_interactive(s->display != NULL, options.use_qos);
        /*
         * Clear loginmsg, since it's the child's responsibility to display
@@ -738,7 +738,7 @@ do_exec_pty(Session *s, const char *comm
        /* Enter interactive session. */
        s->ptymaster = ptymaster;
-       packet_set_interactive(1);
+       packet_set_interactive(1, options.use_qos);
        if (compat20) {
                session_set_fds(s, ptyfd, fdout, -1, 1);
        } else {
Index: ssh-keysign.c
===================================================================
RCS file: /cvs/openssh/ssh-keysign.c,v
retrieving revision 1.38
diff -u -p -r1.38 ssh-keysign.c
--- ssh-keysign.c       13 Jan 2010 11:43:34 -0000      1.38
+++ ssh-keysign.c       16 Apr 2010 17:21:44 -0000
@@ -185,7 +185,7 @@ main(int argc, char **argv)
        /* verify that ssh-keysign is enabled by the admin */
        initialize_options(&options);
-       (void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options, 0);
+       (void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options, 0, 1);
        fill_default_options(&options);
        if (options.enable_ssh_keysign != 1)
                fatal("ssh-keysign not enabled in %s",
Index: ssh.c
===================================================================
RCS file: /cvs/openssh/ssh.c,v
retrieving revision 1.328
diff -u -p -r1.328 ssh.c
--- ssh.c       16 Apr 2010 05:52:43 -0000      1.328
+++ ssh.c       16 Apr 2010 17:21:44 -0000
@@ -533,7 +533,7 @@ main(int ac, char **av)
                        dummy = 1;
                        line = xstrdup(optarg);
                        if (process_config_line(&options, host ? host : "",
-                           line, "command-line", 0, &dummy) != 0)
+                           line, "command-line", 0, &dummy, 0) != 0)
                                exit(255);
                        xfree(line);
                        break;
@@ -643,18 +643,18 @@ main(int ac, char **av)
         * file if the user specifies a config file on the command line.
         */
        if (config != NULL) {
-               if (!read_config_file(config, host, &options, 0))
+               if (!read_config_file(config, host, &options, 0, 0))
                        fatal("Can't open user config file %.100s: "
                            "%.100s", config, strerror(errno));
        } else {
                r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
                    _PATH_SSH_USER_CONFFILE);
                if (r > 0 && (size_t)r < sizeof(buf))
-                       (void)read_config_file(buf, host, &options, 1);
+                       (void)read_config_file(buf, host, &options, 1, 0);
                /* Read systemwide configuration file after use config. */
                (void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
-                   &options, 0);
+                   &options, 0, 1);
        }
        /* Fill configuration defaults. */
@@ -1111,7 +1111,7 @@ ssh_session(void)
                }
        }
        /* Tell the packet module whether this is an interactive session. */
-       packet_set_interactive(interactive);
+       packet_set_interactive(interactive, options.use_qos);
        /* Request authentication agent forwarding if appropriate. */
        check_agent_present();
@@ -1205,7 +1205,7 @@ ssh_session2_setup(int id, void *arg)
        client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
            NULL, fileno(stdin), &command, environ);
 -      packet_set_interactive(interactive);
+       packet_set_interactive(interactive, options.use_qos);
 }
  /* open new channel for a session */
Index: ssh_config
===================================================================
RCS file: /cvs/openssh/ssh_config,v
retrieving revision 1.28
diff -u -p -r1.28 ssh_config
--- ssh_config  12 Jan 2010 08:40:27 -0000      1.28
+++ ssh_config  16 Apr 2010 17:21:44 -0000
@@ -45,3 +45,4 @@
 #   PermitLocalCommand no
 #   VisualHostKey no
 #   ProxyCommand ssh -q -W %h:%p gateway.example.com
+#   UseQoS throughput lowdelay
Index: sshd_config
===================================================================
RCS file: /cvs/openssh/sshd_config,v
retrieving revision 1.83
diff -u -p -r1.83 sshd_config
--- sshd_config 11 Oct 2009 10:51:09 -0000      1.83
+++ sshd_config 16 Apr 2010 17:21:44 -0000
@@ -107,6 +107,9 @@
 # no default banner path
 #Banner none
 +# traditional ToS (deprecated: consider using af12 and cs2)
+#UseQoS throughput lowdelay
+
 # override default of no subsystems
 Subsystem      sftp    /usr/libexec/sftp-server

Reply via email to