--- httpd-2.3.4-alpha/server/listen.c.orig 2009-08-19 16:55:14.000000000 -0700 +++ httpd-2.3.4-alpha/server/listen.c.orig 2009-12-09 18:55:49.000000000 -0800 @@ -34,6 +34,7 @@ static ap_listen_rec *old_listeners; static int ap_listenbacklog; static int send_buffer_size; static int receive_buffer_size; +static int qos_marking = 0; /* TODO: make_sock is just begging and screaming for APR abstraction */ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) @@ -122,6 +123,16 @@ static apr_status_t make_sock(apr_pool_t /* not a fatal error */ } } + if (qos_marking) { + stat = apr_socket_opt_set(s, APR_SO_IPTOS, qos_marking); + if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { + ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, + "make_sock: failed to set IP ToS for " + "address %pI, using default", + server->bind_addr); + /* not a fatal error */ + } + } #if APR_TCP_NODELAY_INHERITED ap_sock_disable_nagle(s); @@ -720,3 +731,42 @@ AP_DECLARE_NONSTD(const char *) ap_set_r receive_buffer_size = s; return NULL; } + +AP_DECLARE_NONSTD(const char *) ap_set_qos_marking(cmd_parms *cmd, + void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + /* might be more legible to use netinet/ip.h constants here, but that + * would be less portable for a long time to come. + */ + static const char cs[8] = {0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0}; + static const char af[12] = {0x28, 0x30, 0x38, + 0x48, 0x50, 0x58, + 0x68, 0x70, 0x78, + 0x88, 0x90, 0x98}; + static const char ef = 0xb8; + + if (err != NULL) { + return err; + } + +#define __in_range(c,s,e) ((s) <= (c) && (c) <= (e)) + + if (arg[0] == 'c' && arg[1] == 's' && __in_range(arg[2], '0', '7') && + arg[3] == '\0') { + qos_marking = cs[arg[2] - '0']; + } else if (arg[0] == 'a' && arg[1] == 'f' && + __in_range(arg[2], '1', '4') && __in_range(arg[3], '1', '3') && + arg[4] == '\0') { + qos_marking = af[(3 * (arg[2] - '1')) + (arg[3] - '1')]; + } else if (arg[0] == 'e' && arg[1] == 'f' && arg[2] == '\0') { + qos_marking = ef; + } else { + return "QoSMarking must be cs0..cs7, af11..af43, or ef"; + } + +#undef __in_range + + return NULL; +} --- httpd-2.3.4-alpha/include/ap_listen.h.orig 2009-08-20 12:25:49.000000000 -0700 +++ httpd-2.3.4-alpha/include/ap_listen.h.orig 2009-12-09 18:10:26.000000000 -0800 @@ -116,6 +116,8 @@ AP_DECLARE_NONSTD(const char *) ap_set_s AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, void *dummy, const char *arg); +AP_DECLARE_NONSTD(const char *) ap_set_qos_marking(cmd_parms *cmd, void *dummy, + const char *arg); #define LISTEN_COMMANDS \ AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \ @@ -125,7 +127,9 @@ AP_INIT_TAKE_ARGV("Listen", ap_set_liste AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \ "Send buffer size in bytes"), \ AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \ - RSRC_CONF, "Receive buffer size in bytes") + RSRC_CONF, "Receive buffer size in bytes"), \ +AP_INIT_TAKE1("QoSMarking", ap_set_qos_marking, NULL, RSRC_CONF, \ + "IP QoS marking as a DiffServ/DSCP code-point name") #ifdef __cplusplus }