]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Eliminated the limitation on the number of options that can be pushed
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Sun, 27 Sep 2009 02:12:15 +0000 (02:12 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Sun, 27 Sep 2009 02:12:15 +0000 (02:12 +0000)
to clients, including routes.  Previously, all pushed options needed
to fit within a 1024 byte options string.

Remember that to make use of this feature to allow many routes to
be pushed to clients, the client config file must specify the
max-routes option, and the number of pushed routes cannot exceed
this limit.  Also, both server and client must include this commit.

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@4991 e7ae566f-a301-0410-adde-c780ea21d3b5

16 files changed:
Makefile.am
common.h
crypto.c
crypto.h
error.h
init.c
openvpn.h
options.c
options.h
push.c
push.h
pushlist.h [new file with mode: 0644]
route.c
ssl.c
ssl.h
version.m4

index 5d90b838a26955f92f9c1811477edc713491b9d5..e1b28afc42a7236447b7f622443ad96c8d7adb20 100644 (file)
@@ -123,6 +123,7 @@ openvpn_SOURCES = \
        ieproxy.h ieproxy.c \
         ps.c ps.h \
        push.c push.h \
+       pushlist.h \
        reliable.c reliable.h \
        route.c route.h \
        schedule.c schedule.h \
index 03a8d50d7d8ec8955944b39180273ae7e5611d00..94da09e5b5f8abbede2822aff3508b73c83e85d7 100644 (file)
--- a/common.h
+++ b/common.h
@@ -74,12 +74,10 @@ typedef unsigned long ptr_type;
 #define CCD_DEFAULT "DEFAULT"
 
 /*
- * This parameter controls the TLS channel buffer size.  Among
- * other things, this buffer must be large enough to contain
- * the full --push/--pull list.  If you increase it, do so
- * on both server and client.
+ * This parameter controls the TLS channel buffer size and the
+ * maximum size of a single TLS message (cleartext).
  */
-#define TLS_CHANNEL_BUF_SIZE 2048
+#define TLS_CHANNEL_BUF_SIZE 1024
 
 /*
  * A sort of pseudo-filename for data provided inline within
index 10c0beedfe7ff79f7b65f06db4d4ba7d2d7e63f6..444f036a0d1ed4bc64a3bec62b785181c4464d45 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -1796,4 +1796,49 @@ free_ssl_lib (void)
 }
 
 #endif /* USE_SSL */
+
+/*
+ * md5 functions
+ */
+
+void
+md5_state_init (struct md5_state *s)
+{
+  MD5_Init (&s->ctx);
+}
+
+void
+md5_state_update (struct md5_state *s, void *data, size_t len)
+{
+  MD5_Update (&s->ctx, data, len);
+}
+
+void
+md5_state_final (struct md5_state *s, struct md5_digest *out)
+{
+  MD5_Final (out->digest, &s->ctx);
+}
+
+void
+md5_digest_clear (struct md5_digest *digest)
+{
+  CLEAR (*digest);
+}
+
+bool
+md5_digest_defined (const struct md5_digest *digest)
+{
+  int i;
+  for (i = 0; i < MD5_DIGEST_LENGTH; ++i)
+    if (digest->digest[i])
+      return true;
+  return false;
+}
+
+bool
+md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2)
+{
+  return memcmp(d1->digest, d2->digest, MD5_DIGEST_LENGTH) == 0;
+}
+
 #endif /* USE_CRYPTO */
index f0b49bbd086343ff2bd8999e4a7cf423cdbc61d5..3a5d5f2e03746c6717f9f17d9f4ab20a3b2ec3db 100644 (file)
--- a/crypto.h
+++ b/crypto.h
@@ -398,5 +398,24 @@ key_ctx_bi_defined(const struct key_ctx_bi* key)
   return key->encrypt.cipher || key->encrypt.hmac || key->decrypt.cipher || key->decrypt.hmac;
 }
 
+/*
+ * md5 functions
+ */
+
+struct md5_state {
+  MD5_CTX ctx;
+};
+
+struct md5_digest {
+  uint8_t digest [MD5_DIGEST_LENGTH];
+};
+
+void md5_state_init (struct md5_state *s);
+void md5_state_update (struct md5_state *s, void *data, size_t len);
+void md5_state_final (struct md5_state *s, struct md5_digest *out);
+void md5_digest_clear (struct md5_digest *digest);
+bool md5_digest_defined (const struct md5_digest *digest);
+bool md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2);
+
 #endif /* USE_CRYPTO */
 #endif /* CRYPTO_H */
diff --git a/error.h b/error.h
index 368aa623d51605793a3872549cf3d6701d8fe273..5c6659bd0a664850a62c1fe3f5c90489c4fe15af 100644 (file)
--- a/error.h
+++ b/error.h
@@ -33,7 +33,7 @@
 #ifdef ENABLE_PKCS11
 #define ERR_BUF_SIZE 8192
 #else
-#define ERR_BUF_SIZE 1024
+#define ERR_BUF_SIZE 1280
 #endif
 
 struct gc_arena;
diff --git a/init.c b/init.c
index a2821b9d9bf989bb755cd39cfcb39b087760e340..9d29af7035005caea21748feff110c6a9094f0b0 100644 (file)
--- a/init.c
+++ b/init.c
@@ -992,15 +992,12 @@ do_route (const struct options *options,
  */
 #if P2MP
 static void
-save_pulled_options_string (struct context *c, const char *newstring)
+save_pulled_options_digest (struct context *c, const struct md5_digest *newdigest)
 {
-  if (c->c1.pulled_options_string_save)
-    free (c->c1.pulled_options_string_save);
-
-  c->c1.pulled_options_string_save = NULL;
-
-  if (newstring)
-    c->c1.pulled_options_string_save = string_alloc (newstring, NULL);
+  if (newdigest)
+    c->c1.pulled_options_digest_save = *newdigest;
+  else
+    md5_digest_clear (&c->c1.pulled_options_digest_save);
 }
 #endif
 
@@ -1144,7 +1141,7 @@ do_close_tun_simple (struct context *c)
   c->c1.tuntap = NULL;
   c->c1.tuntap_owned = false;
 #if P2MP
-  save_pulled_options_string (c, NULL); /* delete C1-saved pulled_options_string */
+  save_pulled_options_digest (c, NULL); /* delete C1-saved pulled_options_digest */
 #endif
 }
 
@@ -1244,8 +1241,8 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
          if (!c->c2.did_open_tun
              && PULL_DEFINED (&c->options)
              && c->c1.tuntap
-             && (!c->c1.pulled_options_string_save || !c->c2.pulled_options_string
-                 || strcmp (c->c1.pulled_options_string_save, c->c2.pulled_options_string)))
+             && (!md5_digest_defined (&c->c1.pulled_options_digest_save) || !md5_digest_defined (&c->c2.pulled_options_digest)
+                 || !md5_digest_equal (&c->c1.pulled_options_digest_save, &c->c2.pulled_options_digest)))
            {
              /* if so, close tun, delete routes, then reinitialize tun and add routes */
              msg (M_INFO, "NOTE: Pulled options changed on restart, will need to close and reopen TUN/TAP device.");
@@ -1260,7 +1257,7 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
       if (c->c2.did_open_tun)
        {
 #if P2MP
-         save_pulled_options_string (c, c->c2.pulled_options_string);
+         save_pulled_options_digest (c, &c->c2.pulled_options_digest);
 #endif
 
          /* if --route-delay was specified, start timer */
index d7e8c5645c7c717294b09d2c8c8eeda68bf0c852..b850fd0745b64e6667b07bee3d4410ceb651b27f 100644 (file)
--- a/openvpn.h
+++ b/openvpn.h
@@ -189,8 +189,8 @@ struct context_1
   bool ifconfig_pool_persist_owned;
 #endif
 
-  /* if client mode, option strings we pulled from server */
-  char *pulled_options_string_save;
+  /* if client mode, hash of option strings we pulled from server */
+  struct md5_digest pulled_options_digest_save;
 
   /* save user/pass for authentication */
   struct user_pass *auth_user_pass;
@@ -427,7 +427,11 @@ struct context_2
 #endif
 
   struct event_timeout push_request_interval;
-  const char *pulled_options_string;
+  bool did_pre_pull_restore;
+
+  /* hash of pulled options, so we can compare when options change */
+  struct md5_state pulled_options_state;
+  struct md5_digest pulled_options_digest;
 
   struct event_timeout scheduled_exit;
 #endif
index c1692e7b639c6b1b18bacc7ba0ff9df1b9560950..ce16b56ffd2f5eeb0e89afbbac1e59df890cbb26 100644 (file)
--- a/options.c
+++ b/options.c
@@ -960,11 +960,15 @@ show_p2mp_parms (const struct options *o)
   msg (D_SHOW_PARMS, "  server_bridge_netmask = %s", print_in_addr_t (o->server_bridge_netmask, 0, &gc));
   msg (D_SHOW_PARMS, "  server_bridge_pool_start = %s", print_in_addr_t (o->server_bridge_pool_start, 0, &gc));
   msg (D_SHOW_PARMS, "  server_bridge_pool_end = %s", print_in_addr_t (o->server_bridge_pool_end, 0, &gc));
-  if (o->push_list)
+  if (o->push_list.head)
     {
-      const struct push_list *l = o->push_list;
-      const char *printable_push_list = l->options;
-      msg (D_SHOW_PARMS, "  push_list = '%s'", printable_push_list);
+      const struct push_entry *e = o->push_list.head;
+      while (e)
+       {
+         if (e->enable)
+           msg (D_SHOW_PARMS, "  push_entry = '%s'", e->option);
+         e = e->next;
+       }
     }
   SHOW_BOOL (ifconfig_pool_defined);
   msg (D_SHOW_PARMS, "  ifconfig_pool_start = %s", print_in_addr_t (o->ifconfig_pool_start, 0, &gc));
@@ -1065,12 +1069,7 @@ options_detach (struct options *o)
   gc_detach (&o->gc);
   o->routes = NULL;
 #if P2MP_SERVER
-  if (o->push_list) /* clone push_list */
-    {
-      const struct push_list *old = o->push_list;
-      ALLOC_OBJ_GC (o->push_list, struct push_list, &o->gc);
-      strcpy (o->push_list->options, old->options);
-    }
+  clone_push_list(o);
 #endif
 }
 
@@ -2190,6 +2189,8 @@ pre_pull_restore (struct options *o)
 
       o->foreign_option_index = pp->foreign_option_index;
     }
+
+  o->push_continuation = 0;
 }
 
 #endif
@@ -4881,6 +4882,11 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_GENERAL);
       options->pull = true;
     }
+  else if (streq (p[0], "push-continuation") && p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_PULL_MODE);
+      options->push_continuation = atoi(p[1]);
+    }
   else if (streq (p[0], "auth-user-pass"))
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
index 9210aca860e0b86d55c08cdae15ceb43ef9ffdb5..fbf0e3c3ce63f3674abc7c1cbea68fe5dd6a7636 100644 (file)
--- a/options.h
+++ b/options.h
@@ -40,6 +40,7 @@
 #include "manage.h"
 #include "proxy.h"
 #include "lzo.h"
+#include "pushlist.h"
 
 /*
  * Maximum number of parameters associated with an option,
@@ -57,17 +58,6 @@ extern const char title_string[];
 
 #if P2MP
 
-#if P2MP_SERVER
-/* parameters to be pushed to peer */
-
-#define MAX_PUSH_LIST_LEN TLS_CHANNEL_BUF_SIZE /* This parm is related to PLAINTEXT_BUFFER_SIZE in ssl.h */
-
-struct push_list {
-  /* newline delimited options, like config file */
-  char options[MAX_PUSH_LIST_LEN];
-};
-#endif
-
 /* certain options are saved before --pull modifications are applied */
 struct options_pre_pull
 {
@@ -362,7 +352,7 @@ struct options
   in_addr_t server_bridge_pool_start;
   in_addr_t server_bridge_pool_end;
 
-  struct push_list *push_list;
+  struct push_list push_list;
   bool ifconfig_pool_defined;
   in_addr_t ifconfig_pool_start;
   in_addr_t ifconfig_pool_end;
@@ -405,6 +395,7 @@ struct options
 
   bool client;
   bool pull; /* client pull of config options from server */
+  int push_continuation;
   const char *auth_user_pass_file;
   struct options_pre_pull *pre_pull;
 
diff --git a/push.c b/push.c
index cbc3c10ec3da6cdc9188fdeb8f486145df449d33..36febe1810b1e9ba25df74253697acbb5226ba4d 100644 (file)
--- a/push.c
+++ b/push.c
@@ -99,9 +99,10 @@ incoming_push_message (struct context *c, const struct buffer *buffer)
 
   if (status == PUSH_MSG_ERROR)
     msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", BSTR (buffer));
-  else if (status == PUSH_MSG_REPLY)
+  else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION)
     {
-      do_up (c, true, option_types_found); /* delay bringing tun/tap up until --push parms received from remote */
+      if (status == PUSH_MSG_REPLY)
+       do_up (c, true, option_types_found); /* delay bringing tun/tap up until --push parms received from remote */
       event_timeout_clear (&c->c2.push_request_interval);
     }
 
@@ -115,60 +116,114 @@ send_push_request (struct context *c)
 }
 
 #if P2MP_SERVER
+
 bool
 send_push_reply (struct context *c)
 {
   struct gc_arena gc = gc_new ();
-  struct buffer buf = alloc_buf_gc (MAX_PUSH_LIST_LEN + 256, &gc);
-  bool ret = false;
+  struct buffer buf = alloc_buf_gc (TLS_CHANNEL_BUF_SIZE, &gc);
+  struct push_entry *e = c->options.push_list.head;
+  bool multi_push = false;
+  static char cmd[] = "PUSH_REPLY";
+  const int extra = 64; /* extra space for possible trailing ifconfig and push-continuation */
+  const int safe_cap = BCAP (&buf) - extra;
 
-  buf_printf (&buf, "PUSH_REPLY");
+  buf_printf (&buf, cmd);
 
-  if (c->options.push_list && strlen (c->options.push_list->options))
-    buf_printf (&buf, ",%s", c->options.push_list->options);
+  while (e)
+    {
+      if (e->enable)
+       {
+         const int l = strlen (e->option);
+         if (BLEN (&buf) + l >= safe_cap)
+           {
+             buf_printf (&buf, ",push-continuation 2");
+             {
+               const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
+               if (!status)
+                 goto fail;
+               multi_push = true;
+               buf_reset_len (&buf);
+               buf_printf (&buf, cmd);
+             }
+           }
+         if (BLEN (&buf) + l >= safe_cap)
+           {
+             msg (M_WARN, "--push option is too long");
+             goto fail;
+           }
+         buf_printf (&buf, ",%s", e->option);
+       }
+      e = e->next;
+    }
 
   if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
     buf_printf (&buf, ",ifconfig %s %s",
                print_in_addr_t (c->c2.push_ifconfig_local, 0, &gc),
                print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));
+  if (multi_push)
+    buf_printf (&buf, ",push-continuation 1");
 
-  if (strlen (BSTR (&buf)) < MAX_PUSH_LIST_LEN)
-    ret = send_control_channel_string (c, BSTR (&buf), D_PUSH);
-  else
-    msg (M_WARN, "Maximum length of --push buffer (%d) has been exceeded", MAX_PUSH_LIST_LEN);
+  if (BLEN (&buf) > sizeof(cmd)-1)
+    {
+      const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
+      if (!status)
+       goto fail;
+    }
 
   gc_free (&gc);
-  return ret;
+  return true;
+
+ fail:
+  gc_free (&gc);
+  return false;
 }
 
-void
-push_option (struct options *o, const char *opt, int msglevel)
+static void
+push_option_ex (struct options *o, const char *opt, bool enable, int msglevel)
 {
-  int len;
-  bool first = false;
-
   if (!string_class (opt, CC_ANY, CC_COMMA))
     {
       msg (msglevel, "PUSH OPTION FAILED (illegal comma (',') in string): '%s'", opt);
     }
   else
     {
-      if (!o->push_list)
+      struct push_entry *e;
+      ALLOC_OBJ_CLEAR_GC (e, struct push_entry, &o->gc);
+      e->enable = true;
+      e->option = opt;
+      if (o->push_list.head)
        {
-         ALLOC_OBJ_CLEAR_GC (o->push_list, struct push_list, &o->gc);
-         first = true;
+         ASSERT(o->push_list.tail);
+         o->push_list.tail->next = e;
+         o->push_list.tail = e;
        }
-
-      len = strlen (o->push_list->options);
-      if (len + strlen (opt) + 2 >= MAX_PUSH_LIST_LEN)
+      else
        {
-         msg (msglevel, "Maximum length of --push buffer (%d) has been exceeded", MAX_PUSH_LIST_LEN);
+         ASSERT(!o->push_list.tail);
+         o->push_list.head = e;
+         o->push_list.tail = e;
        }
-      else
+    }
+}
+
+void
+push_option (struct options *o, const char *opt, int msglevel)
+{
+  push_option_ex (o, opt, true, msglevel);
+}
+
+void
+clone_push_list (struct options *o)
+{
+  if (o->push_list.head)
+    {
+      const struct push_entry *e = o->push_list.head;
+      push_reset (o);
+      while (e)
        {
-         if (!first)
-           strcat (o->push_list->options, ",");
-         strcat (o->push_list->options, opt);
+         push_option_ex (o, string_alloc (e->option, &o->gc), true, M_FATAL);
+         e = e->next;
        }
     }
 }
@@ -184,7 +239,7 @@ push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc)
 void
 push_reset (struct options *o)
 {
-  o->push_list = NULL;
+  CLEAR (o->push_list);
 }
 #endif
 
@@ -224,14 +279,31 @@ process_incoming_push_msg (struct context *c,
       const uint8_t ch = buf_read_u8 (&buf);
       if (ch == ',')
        {
-         pre_pull_restore (&c->options);
-         c->c2.pulled_options_string = string_alloc (BSTR (&buf), &c->c2.gc);
+         struct buffer buf_orig = buf;
+         if (!c->c2.did_pre_pull_restore)
+           {
+             pre_pull_restore (&c->options);
+             md5_state_init (&c->c2.pulled_options_state);
+             c->c2.did_pre_pull_restore = true;
+           }
          if (apply_push_options (&c->options,
                                  &buf,
                                  permission_mask,
                                  option_types_found,
                                  c->c2.es))
-           ret = PUSH_MSG_REPLY;
+           switch (c->options.push_continuation)
+             {
+             case 0:
+             case 1:
+               md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig));
+               md5_state_final (&c->c2.pulled_options_state, &c->c2.pulled_options_digest);
+               ret = PUSH_MSG_REPLY;
+               break;
+             case 2:
+               md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig));
+               ret = PUSH_MSG_CONTINUATION;
+               break;
+             }
        }
       else if (ch == '\0')
        {
@@ -243,36 +315,27 @@ process_incoming_push_msg (struct context *c,
 }
 
 #if P2MP_SERVER
+
 /*
  * Remove iroutes from the push_list.
  */
 void
 remove_iroutes_from_push_route_list (struct options *o)
 {
-  if (o && o->push_list && o->iroutes)
+  if (o && o->push_list.head && o->iroutes)
     {
       struct gc_arena gc = gc_new ();
-      struct push_list *pl;
-      struct buffer in, out;
-      char *line;
-      bool first = true;
-
-      /* prepare input and output buffers */
-      ALLOC_OBJ_CLEAR_GC (pl, struct push_list, &gc);
-      ALLOC_ARRAY_CLEAR_GC (line, char, MAX_PUSH_LIST_LEN, &gc);
-
-      buf_set_read (&in, (const uint8_t*) o->push_list->options, strlen (o->push_list->options));
-      buf_set_write (&out, (uint8_t*) pl->options, sizeof (pl->options));
+      struct push_entry *e = o->push_list.head;
 
       /* cycle through the push list */
-      while (buf_parse (&in, ',', line, MAX_PUSH_LIST_LEN))
+      while (e)
        {
          char *p[MAX_PARMS];
-         bool copy = true;
+         bool enable = true;
 
          /* parse the push item */
          CLEAR (p);
-         if (parse_line (line, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
+         if (parse_line (e->option, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
            {
              /* is the push item a route directive? */
              if (p[0] && !strcmp (p[0], "route") && !p[3])
@@ -292,7 +355,7 @@ remove_iroutes_from_push_route_list (struct options *o)
                        {
                          if (network == ir->network && netmask == netbits_to_netmask (ir->netbits >= 0 ? ir->netbits : 32))
                            {
-                             copy = false;
+                             enable = false;
                              break;
                            }
                        }
@@ -301,28 +364,17 @@ remove_iroutes_from_push_route_list (struct options *o)
            }
 
          /* should we copy the push item? */
-         if (copy)
-           {
-             if (!first)
-               buf_printf (&out, ",");
-             buf_printf (&out, "%s", line);
-             first = false;
-           }
-         else
-           msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", line);
-       }
-
-#if 0
-      msg (M_INFO, "BEFORE: '%s'", o->push_list->options);
-      msg (M_INFO, "AFTER:  '%s'", pl->options);
-#endif
+         e->enable = enable;
+         if (!enable)
+           msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option);
 
-      /* copy new push list back to options */
-      *o->push_list = *pl;
+         e = e->next;
+       }
 
       gc_free (&gc);
     }
 }
+
 #endif
 
 #endif
diff --git a/push.h b/push.h
index 30ecb6a3f73d5026009ce193d1b19b0257d956b6..a48b0777b6de3e31650e169b37c42a092dd3c741 100644 (file)
--- a/push.h
+++ b/push.h
@@ -34,6 +34,7 @@
 #define PUSH_MSG_REPLY            2
 #define PUSH_MSG_REQUEST_DEFERRED 3
 #define PUSH_MSG_AUTH_FAILURE     4
+#define PUSH_MSG_CONTINUATION     5
 
 void incoming_push_message (struct context *c,
                            const struct buffer *buffer);
@@ -50,6 +51,8 @@ void receive_auth_failed (struct context *c, const struct buffer *buffer);
 
 #if P2MP_SERVER
 
+void clone_push_list (struct options *o);
+
 void push_option (struct options *o, const char *opt, int msglevel);
 void push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc);
 
diff --git a/pushlist.h b/pushlist.h
new file mode 100644 (file)
index 0000000..1c2f4e0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  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-2009 OpenVPN Technologies, 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
+ */
+
+#if !defined(PUSHLIST_H) && P2MP && P2MP_SERVER
+#define PUSHLIST_H
+
+/* parameters to be pushed to peer */
+
+struct push_entry {
+  struct push_entry *next;
+  bool enable;
+  const char *option;
+};
+
+struct push_list {
+  struct push_entry *head;
+  struct push_entry *tail;
+};
+
+
+#endif
diff --git a/route.c b/route.c
index 988c7ab46ed686bcae208f001932fb00d251d925..24d4bd8f7aaae0d289bece8d35f95169e7cc4727 100644 (file)
--- a/route.c
+++ b/route.c
@@ -740,7 +740,7 @@ delete_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flag
     }
   undo_redirect_default_route_to_vpn (rl, tt, flags, es);
 
-  CLEAR (*rl);
+  clear_route_list (rl);
 }
 
 #ifdef ENABLE_DEBUG
diff --git a/ssl.c b/ssl.c
index 687c3f3dd2301ff89fdf7574e28aa942b235c9df..224721a71e89bc744662e7e74d20750d5fd30bc0 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -2069,8 +2069,8 @@ key_state_init (struct tls_session *session, struct key_state *ks)
   ALLOC_OBJ_CLEAR (ks->rec_ack, struct reliable_ack);
 
   /* allocate buffers */
-  ks->plaintext_read_buf = alloc_buf (PLAINTEXT_BUFFER_SIZE);
-  ks->plaintext_write_buf = alloc_buf (PLAINTEXT_BUFFER_SIZE);
+  ks->plaintext_read_buf = alloc_buf (TLS_CHANNEL_BUF_SIZE);
+  ks->plaintext_write_buf = alloc_buf (TLS_CHANNEL_BUF_SIZE);
   ks->ack_write_buf = alloc_buf (BUF_SIZE (&session->opt->frame));
   reliable_init (ks->send_reliable, BUF_SIZE (&session->opt->frame),
                 FRAME_HEADROOM (&session->opt->frame), TLS_RELIABLE_N_SEND_BUFFERS,
@@ -3750,7 +3750,7 @@ tls_process (struct tls_multi *multi,
              int status;
 
              ASSERT (buf_init (buf, 0));
-             status = key_state_read_plaintext (multi, ks, buf, PLAINTEXT_BUFFER_SIZE);
+             status = key_state_read_plaintext (multi, ks, buf, TLS_CHANNEL_BUF_SIZE);
              update_time ();
              if (status == -1)
                {
diff --git a/ssl.h b/ssl.h
index 7d4404baf2d72d1541727ceb06b9c1c0607997ca..910c77c219c795a541560d8d022bafbbf1404388 100644 (file)
--- a/ssl.h
+++ b/ssl.h
  * Buffer sizes (also see mtu.h).
  */
 
-#define PLAINTEXT_BUFFER_SIZE TLS_CHANNEL_BUF_SIZE
-
 /* Maximum length of common name */
 #define TLS_CN_LEN 64
 
index 887de1efe7a7b33bf59f95d2d502cac4d4df235e..61bdb7d4b17a9f553b1fc6e6f5e521109b6a0aab 100644 (file)
@@ -1,5 +1,5 @@
 dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1_rc19d])
+define(PRODUCT_VERSION,[2.1_rc19e])
 dnl define the TAP version
 define(PRODUCT_TAP_ID,[tap0901])
 define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])