From 00d391705c713b06b2c80f0b36724f9bb4d806ae Mon Sep 17 00:00:00 2001 From: james Date: Wed, 12 Oct 2005 15:26:59 +0000 Subject: version 2.1_beta2 git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@601 e7ae566f-a301-0410-adde-c780ea21d3b5 --- ChangeLog | 6 ++++++ configure.ac | 2 +- init.c | 17 ++++++++++++++++- openvpn.8 | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++--- options.c | 19 +++++++++++++++++-- options.h | 5 +++++ socket.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- socket.h | 9 ++++++++- syshead.h | 4 ++++ 9 files changed, 169 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f4943a..a960cfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,12 @@ Copyright (C) 2002-2005 OpenVPN Solutions LLC $Id$ +2005.10.13 -- Version 2.1-beta2 + +* Added --socket-flags directive with TCP_NODELAY + flag (pushable). +* Made --sndbuf and --rcvbuf pushable. + 2005.10.01 -- Version 2.1-beta1 * Made LZO setting pushable. diff --git a/configure.ac b/configure.ac index 8df15eb..f7cf49f 100644 --- a/configure.ac +++ b/configure.ac @@ -25,7 +25,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT([OpenVPN], [2.1_beta1], [openvpn-users@lists.sourceforge.net], [openvpn]) +AC_INIT([OpenVPN], [2.1_beta2], [openvpn-users@lists.sourceforge.net], [openvpn]) AM_CONFIG_HEADER(config.h) AC_CONFIG_SRCDIR(syshead.h) diff --git a/init.c b/init.c index f6e125c..a0fce65 100644 --- a/init.c +++ b/init.c @@ -953,6 +953,8 @@ pull_permission_mask (const struct context *c) OPT_P_UP | OPT_P_ROUTE_EXTRAS | OPT_P_IPWIN32 + | OPT_P_SOCKBUF + | OPT_P_SOCKFLAGS | OPT_P_SETENV | OPT_P_SHAPER | OPT_P_TIMER @@ -1016,6 +1018,18 @@ do_deferred_options (struct context *c, const unsigned int found) do_init_traffic_shaper (c); } + if (found & OPT_P_SOCKBUF) + { + msg (D_PUSH, "OPTIONS IMPORT: --sndbuf/--rcvbuf options modified"); + link_socket_update_buffer_sizes (c->c2.link_socket, c->options.rcvbuf, c->options.sndbuf); + } + + if (found & OPT_P_SOCKFLAGS) + { + msg (D_PUSH, "OPTIONS IMPORT: --socket-flags option modified"); + link_socket_update_flags (c->c2.link_socket, c->options.sockflags); + } + if (found & OPT_P_PERSIST) msg (D_PUSH, "OPTIONS IMPORT: --persist options modified"); if (found & OPT_P_UP) @@ -1751,7 +1765,8 @@ do_init_socket_1 (struct context *c, int mode) c->options.connect_retry_seconds, c->options.mtu_discover_type, c->options.rcvbuf, - c->options.sndbuf); + c->options.sndbuf, + c->options.sockflags); } /* diff --git a/openvpn.8 b/openvpn.8 index 987b042..5a7a070 100644 --- a/openvpn.8 +++ b/openvpn.8 @@ -114,7 +114,7 @@ openvpn \- secure IP tunnel daemon. [\ \fB\-\-client\-disconnect\fR\ ] [\ \fB\-\-client\-to\-client\fR\ ] [\ \fB\-\-client\fR\ ] -[\ \fB\-\-comp\-lzo\fR\ ] +[\ \fB\-\-comp\-lzo\fR\ \fI[mode]\fR\ ] [\ \fB\-\-comp\-noadapt\fR\ ] [\ \fB\-\-config\fR\ \fIfile\fR\ ] [\ \fB\-\-connect\-freq\fR\ \fIn\ sec\fR\ ] @@ -245,6 +245,7 @@ openvpn \- secure IP tunnel daemon. [\ \fB\-\-show\-valid\-subnets\fR\ ] [\ \fB\-\-single\-session\fR\ ] [\ \fB\-\-sndbuf\fR\ \fIsize\fR\ ] +[\ \fB\-\-socket\-flags\fR\ \fI[flags,\ ...]\fR\ ] [\ \fB\-\-socks\-proxy\-retry\fR\ ] [\ \fB\-\-socks\-proxy\fR\ \fIserver\ [port]\fR\ ] [\ \fB\-\-status\fR\ \fIfile\ [n]\fR\ ] @@ -1309,6 +1310,15 @@ Set the TCP/UDP socket receive buffer size. Currently defaults to 65536 bytes. .\"********************************************************* .TP +.B --socket-flags [flags, ...] +Set one or more of the following socket flags: + +.B TCP_NODELAY -- +Optimize latency in TCP mode tunnels. + +This directive is pushable. +.\"********************************************************* +.TP .B --txqueuelen n (Linux only) Set the TX queue length on the TUN/TAP interface. Currently defaults to 100. @@ -2089,9 +2099,45 @@ consecutive messages in the same category. This is useful to limit repetitive logging of similar message types. .\"********************************************************* .TP -.B --comp-lzo +.B --comp-lzo [mode] Use fast LZO compression -- may add up to 1 byte per packet for incompressible data. +.B mode +may be "yes", "no", or "adaptive" (default). + +In a server mode setup, it is possible to selectively turn +compression on or off for individual clients. + +First, make sure the client-side config file enables selective +compression by having at least one +.B --comp-lzo +directive, such as +.B --comp-lzo no. +This will turn off compression by default, +but allow a future directive push from the server to +dynamically change the +on/off/adaptive setting. + +Next in a +.B --client-config-dir +file, specify the compression setting for the client, +for example: + +.RS +.ft 3 +.nf +.sp +comp-lzo yes +push "comp-lzo yes" +.ft +.LP +.RE +.fi + +The first line sets the +.B comp-lzo +setting for the server +side of the link, the second sets the client side. .\"********************************************************* .TP .B --comp-noadapt @@ -2341,7 +2387,10 @@ This is a partial list of options which can currently be pushed: .B --ip-win32, --dhcp-option, .B --inactive, --ping, --ping-exit, --ping-restart, .B --setenv, -.B --persist-key, --persist-tun, --echo +.B --persist-key, --persist-tun, --echo, +.B --comp-lzo, +.B --socket-flags, +.B --sndbuf, --rcvbuf .\"********************************************************* .TP .B --push-reset diff --git a/options.c b/options.c index f2a7af7..c4a1b20 100644 --- a/options.c +++ b/options.c @@ -206,6 +206,7 @@ static const char usage_message[] = " or --fragment max value, whichever is lower.\n" "--sndbuf size : Set the TCP/UDP send buffer size.\n" "--rcvbuf size : Set the TCP/UDP receive buffer size.\n" + "--socket-flags f: Set socket flags, currently 'TCP_NODELAY' supported.\n" "--txqueuelen n : Set the tun/tap TX queue length to n (Linux only).\n" "--mlock : Disable Paging -- ensures key material and tunnel\n" " data will never be written to disk.\n" @@ -1044,6 +1045,7 @@ show_settings (const struct options *o) #endif SHOW_INT (rcvbuf); SHOW_INT (sndbuf); + SHOW_INT (sockflags); #ifdef ENABLE_HTTP_PROXY if (o->http_proxy_options) @@ -3270,15 +3272,28 @@ add_option (struct options *options, else if (streq (p[0], "rcvbuf") && p[1]) { ++i; - VERIFY_PERMISSION (OPT_P_GENERAL); + VERIFY_PERMISSION (OPT_P_SOCKBUF); options->rcvbuf = positive_atoi (p[1]); } else if (streq (p[0], "sndbuf") && p[1]) { ++i; - VERIFY_PERMISSION (OPT_P_GENERAL); + VERIFY_PERMISSION (OPT_P_SOCKBUF); options->sndbuf = positive_atoi (p[1]); } + else if (streq (p[0], "socket-flags")) + { + int j; + VERIFY_PERMISSION (OPT_P_SOCKFLAGS); + for (j = 1; j < MAX_PARMS && p[j]; ++j) + { + ++i; + if (streq (p[j], "TCP_NODELAY")) + options->sockflags |= SF_TCP_NODELAY; + else + msg (msglevel, "unknown socket flag: %s", p[j]); + } + } else if (streq (p[0], "txqueuelen") && p[1]) { ++i; diff --git a/options.h b/options.h index 7c1ae02..c4d21ab 100644 --- a/options.h +++ b/options.h @@ -233,6 +233,9 @@ struct options int rcvbuf; int sndbuf; + /* socket flags */ + unsigned int sockflags; + /* route management */ const char *route_script; const char *route_default_gateway; @@ -448,6 +451,8 @@ struct options #define OPT_P_ROUTE_EXTRAS (1<<22) #define OPT_P_PULL_MODE (1<<23) #define OPT_P_PLUGIN (1<<24) +#define OPT_P_SOCKBUF (1<<25) +#define OPT_P_SOCKFLAGS (1<<26) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/socket.c b/socket.c index 8e56896..c7172ac 100644 --- a/socket.c +++ b/socket.c @@ -331,6 +331,59 @@ socket_set_buffers (int fd, const struct socket_buffer_size *sbs) } } +/* + * Set other socket options + */ + +static bool +socket_set_tcp_nodelay (int sd, int state) +{ +#if defined(HAVE_SETSOCKOPT) && defined(IPPROTO_TCP) && defined(TCP_NODELAY) + if (setsockopt (sd, IPPROTO_TCP, TCP_NODELAY, (void *) &state, sizeof (state)) != 0) + { + msg (M_WARN, "NOTE: setsockopt TCP_NODELAY=%d failed", state); + return false; + } + else + { + dmsg (D_OSBUF, "Socket flags: TCP_NODELAY=%d succeeded", state); + return true; + } +#else + msg (M_WARN, "NOTE: setsockopt TCP_NODELAY=%d failed (No kernel support)", state); + return false; +#endif +} + +static bool +socket_set_flags (int sd, unsigned int sockflags) +{ + if (sockflags & SF_TCP_NODELAY) + return socket_set_tcp_nodelay (sd, 1); + else + return true; +} + +bool +link_socket_update_flags (struct link_socket *ls, unsigned int sockflags) +{ + if (ls && socket_defined (ls->sd)) + return socket_set_flags (ls->sd, ls->sockflags = sockflags); + else + return false; +} + +void +link_socket_update_buffer_sizes (struct link_socket *ls, int rcvbuf, int sndbuf) +{ + if (ls && socket_defined (ls->sd)) + { + ls->socket_buffer_sizes.sndbuf = sndbuf; + ls->socket_buffer_sizes.rcvbuf = rcvbuf; + socket_set_buffers (ls->sd, &ls->socket_buffer_sizes); + } +} + /* * Remote list code allows clients to specify a list of * potential remote server addresses. @@ -893,7 +946,8 @@ link_socket_init_phase1 (struct link_socket *sock, int connect_retry_seconds, int mtu_discover_type, int rcvbuf, - int sndbuf) + int sndbuf, + unsigned int sockflags) { const char *remote_host; int remote_port; @@ -929,6 +983,8 @@ link_socket_init_phase1 (struct link_socket *sock, sock->socket_buffer_sizes.rcvbuf = rcvbuf; sock->socket_buffer_sizes.sndbuf = sndbuf; + sock->sockflags = sockflags; + sock->info.proto = proto; sock->info.remote_float = remote_float; sock->info.lsa = lsa; @@ -1188,6 +1244,9 @@ link_socket_init_phase2 (struct link_socket *sock, /* set socket buffers based on --sndbuf and --rcvbuf options */ socket_set_buffers (sock->sd, &sock->socket_buffer_sizes); + /* set misc socket parameters */ + socket_set_flags (sock->sd, sock->sockflags); + /* set socket to non-blocking mode */ set_nonblock (sock->sd); diff --git a/socket.h b/socket.h index b1510c3..4efcfcf 100644 --- a/socket.h +++ b/socket.h @@ -180,6 +180,9 @@ struct link_socket bool did_resolve_remote; +# define SF_TCP_NODELAY (1<<0) + unsigned int sockflags; + /* for stream sockets */ struct stream_buf stream_buf; struct buffer stream_buf_data; @@ -276,7 +279,8 @@ link_socket_init_phase1 (struct link_socket *sock, int connect_retry_seconds, int mtu_discover_type, int rcvbuf, - int sndbuf); + int sndbuf, + unsigned int sockflags); void link_socket_init_phase2 (struct link_socket *sock, const struct frame *frame, @@ -335,6 +339,9 @@ void setenv_trusted (struct env_set *es, const struct link_socket_info *info); void remote_list_randomize (struct remote_list *l); +bool link_socket_update_flags (struct link_socket *ls, unsigned int sockflags); +void link_socket_update_buffer_sizes (struct link_socket *ls, int rcvbuf, int sndbuf); + /* * Low-level functions */ diff --git a/syshead.h b/syshead.h index 0712a87..e354ef4 100644 --- a/syshead.h +++ b/syshead.h @@ -181,6 +181,10 @@ #include #endif +#ifdef HAVE_NETINET_TCP_H +#include +#endif + #endif /* TARGET_LINUX */ #ifdef TARGET_SOLARIS -- cgit