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