aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--dhcp.c183
-rw-r--r--dhcp.h87
-rw-r--r--forward.c12
-rw-r--r--forward.h1
-rw-r--r--helper.c52
-rw-r--r--openvpn.838
-rw-r--r--options.c27
-rw-r--r--options.h3
-rw-r--r--route.c10
-rw-r--r--route.h13
-rw-r--r--sample-config-files/client.conf2
-rw-r--r--sample-config-files/server.conf30
-rw-r--r--version.m42
14 files changed, 427 insertions, 34 deletions
diff --git a/Makefile.am b/Makefile.am
index 16ed4e3..b4da771 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -79,6 +79,7 @@ openvpn_SOURCES = \
circ_list.h \
common.h \
crypto.c crypto.h \
+ dhcp.c dhcp.h \
errlevel.h \
error.c error.h \
event.c event.h \
diff --git a/dhcp.c b/dhcp.c
new file mode 100644
index 0000000..5f1694c
--- /dev/null
+++ b/dhcp.c
@@ -0,0 +1,183 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2008 Telethra, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "syshead.h"
+
+#include "dhcp.h"
+#include "socket.h"
+#include "error.h"
+
+#include "memdbg.h"
+
+static int
+get_dhcp_message_type (const struct dhcp *dhcp, const int optlen)
+{
+ const uint8_t *p = (uint8_t *) (dhcp + 1);
+ int i;
+
+ for (i = 0; i < optlen; ++i)
+ {
+ const uint8_t type = p[i];
+ const int room = optlen - i;
+ if (type == DHCP_END) /* didn't find what we were looking for */
+ return -1;
+ else if (type == DHCP_PAD) /* no-operation */
+ ;
+ else if (type == DHCP_MSG_TYPE) /* what we are looking for */
+ {
+ if (room >= 3)
+ {
+ if (p[i+1] == 1) /* option length should be 1 */
+ return p[i+2]; /* return message type */
+ }
+ return -1;
+ }
+ else /* some other option */
+ {
+ if (room >= 2)
+ {
+ const int len = p[i+1]; /* get option length */
+ i += (len + 1); /* advance to next option */
+ }
+ }
+ }
+ return -1;
+}
+
+static in_addr_t
+do_extract (struct dhcp *dhcp, const int optlen)
+{
+ uint8_t *p = (uint8_t *) (dhcp + 1);
+ int i;
+ in_addr_t ret = 0;
+
+ for (i = 0; i < optlen; ++i)
+ {
+ const uint8_t type = p[i];
+ const int room = optlen - i;
+ if (type == DHCP_END)
+ break;
+ else if (type == DHCP_PAD)
+ ;
+ else if (type == DHCP_ROUTER)
+ {
+ if (room >= 2)
+ {
+ const int len = p[i+1]; /* get option length */
+ if (len <= (room-2))
+ {
+ if (!ret && len >= 4 && (len & 3) == 0)
+ {
+ memcpy (&ret, p+i+2, 4); /* get router IP address */
+ ret = ntohl (ret);
+ }
+ memset (p+i, DHCP_PAD, len+2); /* delete the router option by padding it out */
+ }
+ i += (len + 1); /* advance to next option */
+ }
+ }
+ else /* some other option */
+ {
+ if (room >= 2)
+ {
+ const int len = p[i+1]; /* get option length */
+ i += (len + 1); /* advance to next option */
+ }
+ }
+ }
+ return ret;
+}
+
+static uint16_t
+udp_checksum (const uint8_t *buf,
+ const int len_udp,
+ const uint8_t *src_addr,
+ const uint8_t *dest_addr)
+{
+ uint16_t word16;
+ uint32_t sum = 0;
+ int i;
+
+ /* make 16 bit words out of every two adjacent 8 bit words and */
+ /* calculate the sum of all 16 bit words */
+ for (i = 0; i < len_udp; i += 2){
+ word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0);
+ sum += word16;
+ }
+
+ /* add the UDP pseudo header which contains the IP source and destination addresses */
+ for (i = 0; i < 4; i += 2){
+ word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF);
+ sum += word16;
+ }
+ for (i = 0; i < 4; i += 2){
+ word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF);
+ sum += word16;
+ }
+
+ /* the protocol number and the length of the UDP packet */
+ sum += (uint16_t) OPENVPN_IPPROTO_UDP + (uint16_t) len_udp;
+
+ /* keep only the last 16 bits of the 32 bit calculated sum and add the carries */
+ while (sum >> 16)
+ sum = (sum & 0xFFFF) + (sum >> 16);
+
+ /* Take the one's complement of sum */
+ return ((uint16_t) ~sum);
+}
+
+in_addr_t
+dhcp_extract_router_msg (struct buffer *ipbuf)
+{
+ struct dhcp_full *df = (struct dhcp_full *) BPTR (ipbuf);
+ const int optlen = BLEN (ipbuf) - (sizeof (struct openvpn_iphdr) + sizeof (struct openvpn_udphdr) + sizeof (struct dhcp));
+
+ if (optlen >= 0
+ && df->ip.protocol == OPENVPN_IPPROTO_UDP
+ && df->udp.source == htons (BOOTPS_PORT)
+ && df->udp.dest == htons (BOOTPC_PORT)
+ && df->dhcp.op == BOOTREPLY
+ && get_dhcp_message_type (&df->dhcp, optlen) == DHCPACK)
+ {
+ /* get the router IP address while padding out all DHCP router options */
+ const in_addr_t ret = do_extract (&df->dhcp, optlen);
+
+ /* recompute the UDP checksum */
+ df->udp.check = htons (udp_checksum ((uint8_t *) &df->udp,
+ sizeof (struct openvpn_udphdr) + sizeof (struct dhcp) + optlen,
+ (uint8_t *)&df->ip.saddr,
+ (uint8_t *)&df->ip.daddr));
+
+ if (ret)
+ {
+ struct gc_arena gc = gc_new ();
+ msg (D_ROUTE, "Extracted DHCP router address: %s", print_in_addr_t (ret, 0, &gc));
+ gc_free (&gc);
+ }
+
+ return ret;
+ }
+ else
+ return 0;
+}
diff --git a/dhcp.h b/dhcp.h
new file mode 100644
index 0000000..aff5909
--- /dev/null
+++ b/dhcp.h
@@ -0,0 +1,87 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2008 Telethra, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DHCP_H
+#define DHCP_H
+
+#include "common.h"
+#include "buffer.h"
+#include "proto.h"
+
+#pragma pack(1)
+
+/* DHCP Option types */
+#define DHCP_PAD 0
+#define DHCP_ROUTER 3
+#define DHCP_MSG_TYPE 53 /* message type (u8) */
+#define DHCP_END 255
+
+/* DHCP Messages types */
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNAK 6
+#define DHCPRELEASE 7
+#define DHCPINFORM 8
+
+/* DHCP UDP port numbers */
+#define BOOTPS_PORT 67
+#define BOOTPC_PORT 68
+
+struct dhcp {
+# define BOOTREQUEST 1
+# define BOOTREPLY 2
+ uint8_t op; /* message op */
+
+ uint8_t htype; /* hardware address type (e.g. '1' = 10Mb Ethernet) */
+ uint8_t hlen; /* hardware address length (e.g. '6' for 10Mb Ethernet) */
+ uint8_t hops; /* client sets to 0, may be used by relay agents */
+ uint32_t xid; /* transaction ID, chosen by client */
+ uint16_t secs; /* seconds since request process began, set by client */
+ uint16_t flags;
+ uint32_t ciaddr; /* client IP address, client sets if known */
+ uint32_t yiaddr; /* 'your' IP address -- server's response to client */
+ uint32_t siaddr; /* server IP address */
+ uint32_t giaddr; /* relay agent IP address */
+ uint8_t chaddr[16]; /* client hardware address */
+ uint8_t sname[64]; /* optional server host name */
+ uint8_t file[128]; /* boot file name */
+ uint32_t magic; /* must be 0x63825363 (network order) */
+};
+
+struct dhcp_full {
+ struct openvpn_iphdr ip;
+ struct openvpn_udphdr udp;
+ struct dhcp dhcp;
+# define DHCP_OPTIONS_BUFFER_SIZE 256
+ uint8_t options[DHCP_OPTIONS_BUFFER_SIZE];
+};
+
+#pragma pack()
+
+in_addr_t dhcp_extract_router_msg (struct buffer *ipbuf);
+
+#endif
diff --git a/forward.c b/forward.c
index 045eb30..8967e6e 100644
--- a/forward.c
+++ b/forward.c
@@ -31,6 +31,7 @@
#include "mss.h"
#include "event.h"
#include "ps.h"
+#include "dhcp.h"
#include "memdbg.h"
@@ -976,6 +977,8 @@ process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf)
if (!c->options.passtos)
flags &= ~PIPV4_PASSTOS;
#endif
+ if (!c->options.route_gateway_via_dhcp || !route_list_default_gateway_needed (c->c1.route_list))
+ flags &= ~PIPV4_EXTRACT_DHCP_ROUTER;
if (buf->len > 0)
{
@@ -1001,6 +1004,13 @@ process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf)
/* possibly alter the TCP MSS */
if (flags & PIPV4_MSSFIX)
mss_fixup (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame)));
+
+ /* possibly extract a DHCP router message */
+ if (flags & PIPV4_EXTRACT_DHCP_ROUTER)
+ {
+ const in_addr_t dhcp_router = dhcp_extract_router_msg (&ipbuf);
+ route_list_add_default_gateway (c->c1.route_list, c->c2.es, dhcp_router);
+ }
}
}
}
@@ -1149,7 +1159,7 @@ process_outgoing_tun (struct context *c)
* The --mssfix option requires
* us to examine the IPv4 header.
*/
- process_ipv4_header (c, PIPV4_MSSFIX|PIPV4_OUTGOING, &c->c2.to_tun);
+ process_ipv4_header (c, PIPV4_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER|PIPV4_OUTGOING, &c->c2.to_tun);
if (c->c2.to_tun.len <= MAX_RW_SIZE_TUN (&c->c2.frame))
{
diff --git a/forward.h b/forward.h
index 6ed29b3..c5d5168 100644
--- a/forward.h
+++ b/forward.h
@@ -75,6 +75,7 @@ bool send_control_channel_string (struct context *c, const char *str, int msglev
#define PIPV4_PASSTOS (1<<0)
#define PIPV4_MSSFIX (1<<1)
#define PIPV4_OUTGOING (1<<2)
+#define PIPV4_EXTRACT_DHCP_ROUTER (1<<3)
void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf);
diff --git a/helper.c b/helper.c
index 2974f42..f21d07e 100644
--- a/helper.c
+++ b/helper.c
@@ -54,6 +54,14 @@ print_opt_route_gateway (const in_addr_t route_gateway, struct gc_arena *gc)
}
static const char *
+print_opt_route_gateway_dhcp (struct gc_arena *gc)
+{
+ struct buffer out = alloc_buf_gc (32, gc);
+ buf_printf (&out, "route-gateway dhcp");
+ return BSTR (&out);
+}
+
+static const char *
print_opt_route (const in_addr_t network, const in_addr_t netmask, struct gc_arena *gc)
{
struct buffer out = alloc_buf_gc (128, gc);
@@ -170,7 +178,7 @@ helper_client_server (struct options *o)
if (o->client)
msg (M_USAGE, "--server and --client cannot be used together");
- if (o->server_bridge_defined)
+ if (o->server_bridge_defined || o->server_bridge_proxy_dhcp)
msg (M_USAGE, "--server and --server-bridge cannot be used together");
if (o->shared_secret_file)
@@ -295,8 +303,19 @@ helper_client_server (struct options *o)
*
* ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
* push "route-gateway 10.8.0.4"
+ *
+ * OR
+ *
+ * server-bridge
+ *
+ * EXPANDS TO:
+ *
+ * mode server
+ * tls-server
+ *
+ * push "route-gateway dhcp"
*/
- else if (o->server_bridge_defined)
+ else if (o->server_bridge_defined | o->server_bridge_proxy_dhcp)
{
if (o->client)
msg (M_USAGE, "--server-bridge and --client cannot be used together");
@@ -310,18 +329,29 @@ helper_client_server (struct options *o)
if (dev != DEV_TYPE_TAP)
msg (M_USAGE, "--server-bridge directive only makes sense with --dev tap");
- verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_start, o->server_bridge_netmask);
- verify_common_subnet ("--server-bridge", o->server_bridge_pool_start, o->server_bridge_pool_end, o->server_bridge_netmask);
- verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_end, o->server_bridge_netmask);
+ if (o->server_bridge_defined)
+ {
+ verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_start, o->server_bridge_netmask);
+ verify_common_subnet ("--server-bridge", o->server_bridge_pool_start, o->server_bridge_pool_end, o->server_bridge_netmask);
+ verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_end, o->server_bridge_netmask);
+ }
o->mode = MODE_SERVER;
o->tls_server = true;
- o->ifconfig_pool_defined = true;
- o->ifconfig_pool_start = o->server_bridge_pool_start;
- o->ifconfig_pool_end = o->server_bridge_pool_end;
- ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
- o->ifconfig_pool_netmask = o->server_bridge_netmask;
- push_option (o, print_opt_route_gateway (o->server_bridge_ip, &o->gc), M_USAGE);
+
+ if (o->server_bridge_defined)
+ {
+ o->ifconfig_pool_defined = true;
+ o->ifconfig_pool_start = o->server_bridge_pool_start;
+ o->ifconfig_pool_end = o->server_bridge_pool_end;
+ ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
+ o->ifconfig_pool_netmask = o->server_bridge_netmask;
+ push_option (o, print_opt_route_gateway (o->server_bridge_ip, &o->gc), M_USAGE);
+ }
+ else if (o->server_bridge_proxy_dhcp)
+ {
+ push_option (o, print_opt_route_gateway_dhcp (&o->gc), M_USAGE);
+ }
}
else
#endif /* P2MP_SERVER */
diff --git a/openvpn.8 b/openvpn.8
index b9f0016..c9920c6 100644
--- a/openvpn.8
+++ b/openvpn.8
@@ -1214,11 +1214,18 @@ table (not supported on all OSes).
address if OpenVPN is being run in client mode, and is undefined in server mode.
.\"*********************************************************
.TP
-.B --route-gateway gw
+.B --route-gateway gw|'dhcp'
Specify a default gateway
.B gw
for use with
.B --route.
+
+If
+.B dhcp
+is specified as the parameter,
+the gateway address will be extracted from a DHCP
+negotiation with the OpenVPN server-side LAN.
+.\"*********************************************************
.TP
.B --route-metric m
Specify a default metric
@@ -2607,13 +2614,23 @@ if you are ethernet bridging. Use
instead.
.\"*********************************************************
.TP
-.B --server-bridge gateway netmask pool-start-IP pool-end-IP
+.B --server-bridge [ gateway netmask pool-start-IP pool-end-IP ]
A helper directive similar to
.B --server
which is designed to simplify the configuration
of OpenVPN's server mode in ethernet bridging configurations.
+If
+.B --server-bridge
+is used without any parameters, it will enable a DHCP-proxy
+mode, where connecting OpenVPN clients will receive an IP
+address for their TAP adapter from the DHCP server running
+on the OpenVPN server-side LAN.
+Note that only clients that support
+the binding of a DHCP client with the TAP adapter (such as
+Windows) can support this mode.
+
To configure ethernet bridging, you
must first use your OS's bridging capability
to bridge the TAP interface with the ethernet
@@ -2662,6 +2679,23 @@ push "route-gateway 10.8.0.4"
.LP
.RE
.fi
+
+In another example,
+.B --server-bridge
+(without parameters) expands as follows:
+
+.RS
+.ft 3
+.nf
+.sp
+mode server
+tls-server
+
+push "route-gateway dhcp"
+.ft
+.LP
+.RE
+.fi
.\"*********************************************************
.TP
.B --push "option"
diff --git a/options.c b/options.c
index 68a36c2..ccbbffa 100644
--- a/options.c
+++ b/options.c
@@ -169,7 +169,7 @@ static const char usage_message[] =
" netmask default: 255.255.255.255\n"
" gateway default: taken from --route-gateway or --ifconfig\n"
" Specify default by leaving blank or setting to \"nil\".\n"
- "--route-gateway gw : Specify a default gateway for use with --route.\n"
+ "--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n"
"--route-metric m : Specify a default metric for use with --route.\n"
"--route-delay n [w] : Delay n seconds after connection initiation before\n"
" adding routes (may be 0). If not specified, routes will\n"
@@ -339,7 +339,7 @@ static const char usage_message[] =
"\n"
"Multi-Client Server options (when --mode server is used):\n"
"--server network netmask : Helper option to easily configure server mode.\n"
- "--server-bridge IP netmask pool-start-IP pool-end-IP : Helper option to\n"
+ "--server-bridge [IP netmask pool-start-IP pool-end-IP] : Helper option to\n"
" easily configure ethernet bridging server mode.\n"
"--push \"option\" : Push a config file option back to the peer for remote\n"
" execution. Peer must specify --pull in its config file.\n"
@@ -1226,6 +1226,7 @@ show_settings (const struct options *o)
SHOW_INT (route_delay_window);
SHOW_BOOL (route_delay_defined);
SHOW_BOOL (route_nopull);
+ SHOW_BOOL (route_gateway_via_dhcp);
if (o->routes)
print_route_options (o->routes, D_SHOW_PARMS);
@@ -1888,7 +1889,7 @@ static void
options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce)
{
#if P2MP_SERVER
- if (o->server_defined || o->server_bridge_defined)
+ if (o->server_defined || o->server_bridge_defined || o->server_bridge_proxy_dhcp)
{
if (ce->proto == PROTO_TCPv4)
ce->proto = PROTO_TCPv4_SERVER;
@@ -4237,14 +4238,21 @@ add_option (struct options *options,
else if (streq (p[0], "route-gateway") && p[1])
{
VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
- if (ip_addr_dotted_quad_safe (p[1]) || is_special_addr (p[1]))
+ if (streq (p[1], "dhcp"))
{
- options->route_default_gateway = p[1];
+ options->route_gateway_via_dhcp = true;
}
else
{
- msg (msglevel, "route-gateway parm '%s' must be an IP address", p[1]);
- goto err;
+ if (ip_addr_dotted_quad_safe (p[1]) || is_special_addr (p[1]))
+ {
+ options->route_default_gateway = p[1];
+ }
+ else
+ {
+ msg (msglevel, "route-gateway parm '%s' must be an IP address", p[1]);
+ goto err;
+ }
}
}
else if (streq (p[0], "route-metric") && p[1])
@@ -4395,6 +4403,11 @@ add_option (struct options *options,
options->server_bridge_pool_start = pool_start;
options->server_bridge_pool_end = pool_end;
}
+ else if (streq (p[0], "server-bridge") && !p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->server_bridge_proxy_dhcp = true;
+ }
else if (streq (p[0], "push") && p[1])
{
VERIFY_PERMISSION (OPT_P_PUSH);
diff --git a/options.h b/options.h
index 34222e6..ea4d54e 100644
--- a/options.h
+++ b/options.h
@@ -302,6 +302,7 @@ struct options
bool route_delay_defined;
struct route_option_list *routes;
bool route_nopull;
+ bool route_gateway_via_dhcp;
#ifdef ENABLE_OCC
/* Enable options consistency check between peers */
@@ -340,6 +341,8 @@ struct options
# define SF_NOPOOL (1<<0)
unsigned int server_flags;
+ bool server_bridge_proxy_dhcp;
+
bool server_bridge_defined;
in_addr_t server_bridge_ip;
in_addr_t server_bridge_netmask;
diff --git a/route.c b/route.c
index bc312e8..e684d26 100644
--- a/route.c
+++ b/route.c
@@ -335,6 +335,16 @@ clear_route_list (struct route_list *rl)
CLEAR (*rl);
}
+void
+route_list_add_default_gateway (struct route_list *rl,
+ struct env_set *es,
+ const in_addr_t addr)
+{
+ rl->spec.remote_endpoint = addr;
+ rl->spec.remote_endpoint_defined = true;
+ setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1);
+}
+
bool
init_route_list (struct route_list *rl,
const struct route_option_list *opt,
diff --git a/route.h b/route.h
index 674d200..1a929bd 100644
--- a/route.h
+++ b/route.h
@@ -138,6 +138,10 @@ bool init_route_list (struct route_list *rl,
in_addr_t remote_host,
struct env_set *es);
+void route_list_add_default_gateway (struct route_list *rl,
+ struct env_set *es,
+ const in_addr_t addr);
+
void add_routes (struct route_list *rl,
const struct tuntap *tt,
unsigned int flags,
@@ -186,4 +190,13 @@ netbits_to_netmask (const int netbits)
return mask;
}
+static inline bool
+route_list_default_gateway_needed (const struct route_list *rl)
+{
+ if (!rl)
+ return false;
+ else
+ return !rl->spec.remote_endpoint_defined;
+}
+
#endif
diff --git a/sample-config-files/client.conf b/sample-config-files/client.conf
index 9dd3a65..58b2038 100644
--- a/sample-config-files/client.conf
+++ b/sample-config-files/client.conf
@@ -100,7 +100,7 @@ key client.key
# your server certificates with the nsCertType
# field set to "server". The build-key-server
# script in the easy-rsa folder will do this.
-;ns-cert-type server
+ns-cert-type server
# If a tls-auth key is used on the server
# then every client must also have the key.
diff --git a/sample-config-files/server.conf b/sample-config-files/server.conf
index f80ce8b..f483b6b 100644
--- a/sample-config-files/server.conf
+++ b/sample-config-files/server.conf
@@ -114,6 +114,18 @@ ifconfig-pool-persist ipp.txt
# out unless you are ethernet bridging.
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
+# Configure server mode for ethernet bridging
+# using a DHCP-proxy, where clients talk
+# to the OpenVPN server-side DHCP server
+# to receive their IP address allocation
+# and DNS server addresses. You must first use
+# your OS's bridging capability to bridge the TAP
+# interface with the ethernet NIC interface.
+# Note: this mode only works on clients (such as
+# Windows), where the client-side TAP adapter is
+# bound to a DHCP client.
+;server-bridge
+
# Push routes to the client to allow it
# to reach other private subnets behind
# the server. Remember that these
@@ -170,22 +182,18 @@ ifconfig-pool-persist ipp.txt
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
-# the TUN/TAP interface to the internet in
-# order for this to work properly).
-# CAVEAT: May break client's network config if
-# client's local DHCP server packets get routed
-# through the tunnel. Solution: make sure
-# client's local DHCP server is reachable via
-# a more specific route than the default route
-# of 0.0.0.0/0.0.0.0.
-;push "redirect-gateway"
+# or bridge the TUN/TAP interface to the internet
+# in order for this to work properly).
+;push "redirect-gateway def1 bypass-dhcp"
# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses. CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
-;push "dhcp-option DNS 10.8.0.1"
-;push "dhcp-option WINS 10.8.0.1"
+# The addresses below refer to the public
+# DNS servers provided by opendns.com.
+;push "dhcp-option DNS 208.67.222.222"
+;push "dhcp-option DNS 208.67.220.220"
# Uncomment this directive to allow different
# clients to be able to "see" each other.
diff --git a/version.m4 b/version.m4
index 2122551..4020bba 100644
--- a/version.m4
+++ b/version.m4
@@ -1,5 +1,5 @@
dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1_rc9])
+define(PRODUCT_VERSION,[2.1_rc9a])
dnl define the TAP version
define(PRODUCT_TAP_ID,[tap0901])
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])