i'd like to port mod_iptos to 2.x <http://arctic.org/~dean/mod_iptos/>...
and i need apr_socket_opt_set support for IP_TOS. so here's a patch.
sorry it's against 1.2.7 but that's what debian is still using. i'm sure
there'll be feedback and i'll rebase against whatever you want after
feedback.
i find it odd and confusing that apr_socket_opt_set tries to pretend that
socket options are all boolean... and for options like SO_RCVBUF there
isn't even any attempt to get the right answer in apr_socket_opt_get. so
following that example i didn't even bother with apr_socket_opt_get
support for the new APR_SO_IP_TOS.
note that if you go about reading man pages regarding IP_TOS you'll
probably be mislead into thinking that you can set one and only one bit.
that's false -- the entire byte is generally available. the IP TOS field
is a source of much disagreement and overloaded behaviour on the internet
at large -- i reference a few of the other attempts to make use of this
byte on my mod_iptos page above. there's a quote somewhere about how many
hours of time have been wasted trying to come up with the one and only
definition of this field...
however none of this should stop anyone from using it within their own
adminstrative domain... (you can strip it as it leaves your network if you
want to do even more crazy things with it than i propose in the mod_iptos
README).
anyhow, here's my patch... feedback welcome.
thanks
-dean
Index: apr-1.2.7/include/apr_network_io.h
===================================================================
--- apr-1.2.7.orig/include/apr_network_io.h 2007-01-13 17:21:25.000000000
-0800
+++ apr-1.2.7/include/apr_network_io.h 2007-01-13 17:35:27.000000000 -0800
@@ -99,6 +99,18 @@
* until data is available.
* @see apr_socket_accept_filter
*/
+#define APR_SO_IP_TOS 65536 /**< IP Type-of-Service field */
+
+/** @} */
+
+/**
+ * @defgroup APR_SO_IP_TOS option convenience definitions
+ * @{
+ */
+#define APR_IPTOS_LOWDELAY 0x10 /**< Low Delay */
+#define APR_IPTOS_THROUGHPUT 0x08 /**< Throughput */
+#define APR_IPTOS_RELIABILITY 0x04 /**< Reliability */
+#define APR_IPTOS_LOWCOST 0x02 /**< Lowest Cost */
/** @} */
@@ -589,6 +601,11 @@
* of local addresses.
* APR_SO_SNDBUF -- Set the SendBufferSize
* APR_SO_RCVBUF -- Set the ReceiveBufferSize
+ * APR_SO_IP_TOS -- Set the IP Type-of-Service byte (any byte
+ * value can be used subject to many
+ * conflicting RFCs and proposals too numerous
+ * to detail here, or use one of the four
+ * convenience definitions).
* </PRE>
* @param on Value for the option.
*/
Index: apr-1.2.7/network_io/unix/sockopt.c
===================================================================
--- apr-1.2.7.orig/network_io/unix/sockopt.c 2007-01-13 17:36:42.000000000
-0800
+++ apr-1.2.7/network_io/unix/sockopt.c 2007-01-13 17:47:29.000000000 -0800
@@ -318,6 +318,17 @@
return APR_ENOTIMPL;
#endif
break;
+ case APR_SO_IP_TOS:
+#ifdef IP_TOS
+ {
+ int value = on;
+ if (setsockopt(sock->socketdes, IPPROTO_IP, IP_TOS,
+ (void*)&value, sizeof(value)) == -1) {
+ return errno;
+ }
+ }
+#endif
+ break;
default:
return APR_EINVAL;
}
Index: apr-1.2.7/configure.in
===================================================================
--- apr-1.2.7.orig/configure.in 2007-01-13 17:44:31.000000000 -0800
+++ apr-1.2.7/configure.in 2007-01-13 17:44:58.000000000 -0800
@@ -1015,6 +1015,7 @@
kernel/OS.h \
net/errno.h \
netinet/in.h \
+ netinet/ip.h \
netinet/sctp.h \
netinet/sctp_uio.h \
sys/file.h \
Index: apr-1.2.7/include/arch/unix/apr_arch_networkio.h
===================================================================
--- apr-1.2.7.orig/include/arch/unix/apr_arch_networkio.h 2007-01-13
17:45:05.000000000 -0800
+++ apr-1.2.7/include/arch/unix/apr_arch_networkio.h 2007-01-13
17:45:16.000000000 -0800
@@ -61,6 +61,9 @@
#if APR_HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
+#if APR_HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
#if APR_HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
Index: apr-1.2.7/test/testsockopt.c
===================================================================
--- apr-1.2.7.orig/test/testsockopt.c 2007-01-13 17:36:08.000000000 -0800
+++ apr-1.2.7/test/testsockopt.c 2007-01-13 17:56:39.000000000 -0800
@@ -115,6 +115,19 @@
#endif
}
+static void set_ip_tos(abts_case *tc, void *data)
+{
+ apr_status_t rv;
+
+ /* can't really check if it was set easily, but at least we're
+ * checking that setting it doesn't cause the world to end.
+ */
+ rv = apr_socket_opt_set(sock, APR_SO_IP_TOS, APR_IPTOS_THROUGHPUT);
+ if (rv != APR_EINVAL) {
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+ }
+}
+
static void close_socket(abts_case *tc, void *data)
{
apr_status_t rv;
@@ -132,6 +145,7 @@
abts_run_test(suite, set_debug, NULL);
abts_run_test(suite, remove_keepalive, NULL);
abts_run_test(suite, corkable, NULL);
+ abts_run_test(suite, set_ip_tos, NULL);
abts_run_test(suite, close_socket, NULL);
return suite;