Hello list, we actively use openvpn between our offices and it work fine, except for the following situation: - one of our providers .. a service that requires to mark packets in tos/dscp field, for example BE, CS1,CS3,CS5 - each class of traffic has its guarantied packet loss, speed, jitter etc. - we marks packet at tun interfaces and use openvpn passtos option to save tos/dscp field - but when BE class reaches it upper limit providers equipment starts to drop packets. unfortunatelly openvpn ping and tls packets has tos field 0x0 (BE). in this situation this packets are also dropped from time to time by providers equipment. this leads to openvpn ping timeout and as a result to connection loss. it is almost impossible to classify openvpn ping and tls packets by its signature as far as they are encrypted.
the proposed patch solves the problem by specifying tos value for ping & tls packets and works together with passtos feature. best regards, Vadim
Only in openvpn-2.0.9.tos: Doxyfile diff -ur openvpn-2.0.9/forward.c openvpn-2.0.9.tos/forward.c --- openvpn-2.0.9/forward.c 2005-12-13 20:09:13.000000000 +0300 +++ openvpn-2.0.9.tos/forward.c 2009-08-27 15:59:37.790869347 +0400 @@ -978,7 +978,7 @@ #if PASSTOS_CAPABILITY /* Set TOS */ - link_socket_set_tos (c->c2.link_socket); + link_socket_set_tos (c->c2.link_socket, c->options.tos ); #endif /* Log packet send */ diff -ur openvpn-2.0.9/openvpn.8 openvpn-2.0.9.tos/openvpn.8 --- openvpn-2.0.9/openvpn.8 2005-11-03 04:16:43.000000000 +0300 +++ openvpn-2.0.9.tos/openvpn.8 2009-08-27 16:20:34.702875534 +0400 @@ -192,6 +192,7 @@ [\ \fB\-\-nobind\fR\ ] [\ \fB\-\-ns\-cert\-type\fR\ \fIclient|server\fR\ ] [\ \fB\-\-passtos\fR\ ] +[\ \fB\-\-tos\fR\ n\fR\ ] [\ \fB\-\-pause\-exit\fR\ ] [\ \fB\-\-persist\-key\fR\ ] [\ \fB\-\-persist\-local\-ip\fR\ ] @@ -1810,6 +1811,12 @@ Set the TOS field of the tunnel packet to what the payload's TOS is. .\"********************************************************* .TP +.B --tos n +Set the TOS field of outgoing packets such as openvpn ping and tls to the +specified value. +.B n +must be a hexadecimal value between 0x0 and 0xfc. +.TP .B --inetd [wait|nowait] [progname] Use this option when OpenVPN is being run from the inetd or .BR xinetd(8) Only in openvpn-2.0.9: openvpn.kdevelop Only in openvpn-2.0.9: openvpn.kdevelop.pcs Only in openvpn-2.0.9: openvpn.kdevses diff -ur openvpn-2.0.9/options.c openvpn-2.0.9.tos/options.c --- openvpn-2.0.9/options.c 2005-12-13 02:50:43.000000000 +0300 +++ openvpn-2.0.9.tos/options.c 2009-08-27 16:42:52.567862396 +0400 @@ -179,6 +179,7 @@ "--persist-key : Don't re-read key files across SIGUSR1 or --ping-restart.\n" #if PASSTOS_CAPABILITY "--passtos : TOS passthrough (applies to IPv4 only).\n" + "--tos n : default TOS for outgoing packets (must be specified in hex)\n" #endif "--tun-mtu n : Take the tun/tap device MTU to be n and derive the\n" " TCP/UDP MTU from it (default=%d).\n" @@ -581,6 +582,9 @@ #if P2MP o->scheduled_exit_interval = 5; #endif +#if PASSTOS_CAPABILITY + o->tos = 0xa0; +#endif #ifdef USE_CRYPTO o->ciphername = "BF-CBC"; o->ciphername_defined = true; @@ -612,6 +616,7 @@ #define SHOW_PARM(name, value, format) msg(D_SHOW_PARMS, " " #name " = " format, (value)) #define SHOW_STR(var) SHOW_PARM(var, (o->var ? o->var : "[UNDEF]"), "'%s'") #define SHOW_INT(var) SHOW_PARM(var, o->var, "%d") +#define SHOW_INTH(var) SHOW_PARM(var, o->var, "0x%x") #define SHOW_UINT(var) SHOW_PARM(var, o->var, "%u") #define SHOW_UNSIGNED(var) SHOW_PARM(var, o->var, "0x%08x") #define SHOW_BOOL(var) SHOW_PARM(var, (o->var ? "ENABLED" : "DISABLED"), "%s"); @@ -1007,6 +1012,7 @@ #if PASSTOS_CAPABILITY SHOW_BOOL (passtos); + SHOW_INTH (tos); #endif SHOW_INT (resolve_retry_seconds); @@ -4153,6 +4159,19 @@ VERIFY_PERMISSION (OPT_P_GENERAL); options->passtos = true; } + else if (streq (p[0], "tos") && p[1]) + { + int s; + ++i; + s = strtol(p[1], (char **)NULL, 16); + VERIFY_PERMISSION (OPT_P_GENERAL); + if (s < 0 || s > 0xfc) + { + msg (msglevel, "--tos parameter must be between 0x00 and 0xfc"); + goto err; + } + options->tos = s; + } #endif #ifdef USE_LZO else if (streq (p[0], "comp-lzo")) diff -ur openvpn-2.0.9/options.h openvpn-2.0.9.tos/options.h --- openvpn-2.0.9/options.h 2005-11-01 14:06:11.000000000 +0300 +++ openvpn-2.0.9.tos/options.h 2009-08-27 15:52:00.339864207 +0400 @@ -181,6 +181,7 @@ #if PASSTOS_CAPABILITY bool passtos; + uint8_t tos; #endif int resolve_retry_seconds; /* If hostname resolve fails, retry for n seconds */ diff -ur openvpn-2.0.9/socket.h openvpn-2.0.9.tos/socket.h --- openvpn-2.0.9/socket.h 2005-11-01 14:06:11.000000000 +0300 +++ openvpn-2.0.9.tos/socket.h 2009-08-27 15:59:21.419861840 +0400 @@ -746,10 +746,17 @@ * from tunnel packet. */ static inline void -link_socket_set_tos (struct link_socket *ls) +link_socket_set_tos (struct link_socket *ls,const uint8_t tos ) { if (ls && ls->ptos_defined) - setsockopt (ls->sd, IPPROTO_IP, IP_TOS, &ls->ptos, sizeof (ls->ptos)); + { + setsockopt (ls->sd, IPPROTO_IP, IP_TOS, &ls->ptos, sizeof (ls->ptos)); + ls->ptos_defined = false; + } + else + { + setsockopt (ls->sd, IPPROTO_IP, IP_TOS, &tos, sizeof (tos)); + } } #endif