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