Browse code

Peer-id patch v7

Added new packet format P_DATA_V2, which includes peer-id. If server
supports, client sends all data packets in the new format. When data
packet arrives, server identifies peer by peer-id. If peer's ip/port has
changed, server assumes that client has floated, verifies HMAC and
updates ip/port in internal structs.

Changes in v7:
A few nitpicks.

Changes in v6:
Fixed: Make sure float won't happen if hmac check failed (regression).
Fixed: Access outside of bounds of array, which has caused memory
corruption and crash.
Various review fixes.

Changes in v5:
Protection agains replay attack by commiting float changes only after
existing packet processing flow has completed.

If peer floats to an address which is already taken by another active
session, drop float packet, otherwise disconnect existing session.

Changes in v4:
Handles correctly float to an address which is used by another peer.
This also has fixed crash on assert in multi_client_disconnect.

Changes in v3:
Bugfix: If float happens after TLS renegotiation and there are no
data packets between reneg and float, server will not recognize floated
client.
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1416755831-21250-1-git-send-email-lstipakov@gmail.com>
URL: http://article.gmane.org/gmane.network.openvpn.devel/9270

Signed-off-by: Gert Doering <gert@greenie.muc.de>

Lev Stipakov authored on 2014/11/24 00:17:11
Showing 13 changed files
... ...
@@ -722,20 +722,11 @@ read_incoming_link (struct context *c)
722 722
   perf_pop ();
723 723
 }
724 724
 
725
-/*
726
- * Input:  c->c2.buf
727
- * Output: c->c2.to_tun
728
- */
729
-
730
-void
731
-process_incoming_link (struct context *c)
725
+bool
726
+process_incoming_link_part1 (struct context *c, struct link_socket_info *lsi, bool floated)
732 727
 {
733 728
   struct gc_arena gc = gc_new ();
734
-  bool decrypt_status;
735
-  struct link_socket_info *lsi = get_link_socket_info (c);
736
-  const uint8_t *orig_buf = c->c2.buf.data;
737
-
738
-  perf_push (PERF_PROC_IN_LINK);
729
+  bool decrypt_status = false;
739 730
 
740 731
   if (c->c2.buf.len > 0)
741 732
     {
... ...
@@ -805,7 +796,7 @@ process_incoming_link (struct context *c)
805 805
 	   * will load crypto_options with the correct encryption key
806 806
 	   * and return false.
807 807
 	   */
808
-	  if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &c->c2.crypto_options))
808
+	  if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &c->c2.crypto_options, floated))
809 809
 	    {
810 810
 	      interval_action (&c->c2.tmp_int);
811 811
 
... ...
@@ -832,11 +823,25 @@ process_incoming_link (struct context *c)
832 832
 	  /* decryption errors are fatal in TCP mode */
833 833
 	  register_signal (c, SIGUSR1, "decryption-error"); /* SOFT-SIGUSR1 -- decryption error in TCP mode */
834 834
 	  msg (D_STREAM_ERRORS, "Fatal decryption error (process_incoming_link), restarting");
835
-	  goto done;
836 835
 	}
837
-
836
+#else /* ENABLE_CRYPTO */
837
+      decrypt_status = true;
838 838
 #endif /* ENABLE_CRYPTO */
839
+    }
840
+  else
841
+    {
842
+      buf_reset (&c->c2.to_tun);
843
+    }
844
+  gc_free (&gc);
839 845
 
846
+  return decrypt_status;
847
+}
848
+
849
+void
850
+process_incoming_link_part2 (struct context *c, struct link_socket_info *lsi, const uint8_t *orig_buf)
851
+{
852
+  if (c->c2.buf.len > 0)
853
+    {
840 854
 #ifdef ENABLE_FRAGMENT
841 855
       if (c->c2.fragment)
842 856
 	fragment_incoming (c->c2.fragment, &c->c2.buf, &c->c2.frame_fragment);
... ...
@@ -903,9 +908,20 @@ process_incoming_link (struct context *c)
903 903
     {
904 904
       buf_reset (&c->c2.to_tun);
905 905
     }
906
- done:
906
+}
907
+
908
+void
909
+process_incoming_link (struct context *c)
910
+{
911
+  perf_push (PERF_PROC_IN_LINK);
912
+
913
+  struct link_socket_info *lsi = get_link_socket_info (c);
914
+  const uint8_t *orig_buf = c->c2.buf.data;
915
+
916
+  process_incoming_link_part1(c, lsi, false);
917
+  process_incoming_link_part2(c, lsi, orig_buf);
918
+
907 919
   perf_pop ();
908
-  gc_free (&gc);
909 920
 }
910 921
 
911 922
 /*
... ...
@@ -127,12 +127,11 @@ void encrypt_sign (struct context *c, bool comp_frag);
127 127
  */
128 128
 void read_incoming_link (struct context *c);
129 129
 
130
-
131 130
 /**
132
- * Process a packet read from the external network interface.
131
+ * Starts processing a packet read from the external network interface.
133 132
  * @ingroup external_multiplexer
134 133
  *
135
- * This function controls the processing of a data channel packet which
134
+ * This function starts the processing of a data channel packet which
136 135
  * has come out of a VPN tunnel.  It's high-level structure is as follows:
137 136
  * - Verify that a nonzero length packet has been received from a valid
138 137
  *   source address for the given context \a c.
... ...
@@ -146,6 +145,25 @@ void read_incoming_link (struct context *c);
146 146
  * - Call \c openvpn_decrypt() of the \link data_crypto Data Channel
147 147
  *   Crypto module\endlink to authenticate and decrypt the packet using
148 148
  *   the security parameters loaded by \c tls_pre_decrypt() above.
149
+ *
150
+ * @param c - The context structure of the VPN tunnel associated with the
151
+ *     packet.
152
+ * @param lsi - link_socket_info obtained from context before processing.
153
+ * @param floated - Flag indicates that peer has floated.
154
+ *
155
+ * @return true if packet is authenticated, false otherwise.
156
+ */
157
+bool process_incoming_link_part1 (struct context *c, struct link_socket_info *lsi, bool floated);
158
+
159
+/**
160
+ * Continues processing a packet read from the external network interface.
161
+ * @ingroup external_multiplexer
162
+ *
163
+ * This function continues the processing of a data channel packet which
164
+ * has come out of a VPN tunnel. It must be called after
165
+ * \c process_incoming_link_part1() function.
166
+ *
167
+ * It's high-level structure is as follows:
149 168
  * - Call \c fragment_incoming() of the \link fragmentation Data Channel
150 169
  *   Fragmentation module\endlink to reassemble the packet if it's
151 170
  *   fragmented.
... ...
@@ -158,9 +176,11 @@ void read_incoming_link (struct context *c);
158 158
  *
159 159
  * @param c - The context structure of the VPN tunnel associated with the
160 160
  *     packet.
161
+ * @param lsi - link_socket_info obtained from context before processing.
162
+ * @param orig_buf - Pointer to a buffer data.
163
+ *
161 164
  */
162
-void process_incoming_link (struct context *c);
163
-
165
+void process_incoming_link_part2 (struct context *c, struct link_socket_info *lsi, const uint8_t *orig_buf);
164 166
 
165 167
 /**
166 168
  * Write a packet to the external network interface.
... ...
@@ -1718,7 +1718,8 @@ pull_permission_mask (const struct context *c)
1718 1718
     | OPT_P_MESSAGES
1719 1719
     | OPT_P_EXPLICIT_NOTIFY
1720 1720
     | OPT_P_ECHO
1721
-    | OPT_P_PULL_MODE;
1721
+    | OPT_P_PULL_MODE
1722
+    | OPT_P_PEER_ID;
1722 1723
 
1723 1724
   if (!c->options.route_nopull)
1724 1725
     flags |= (OPT_P_ROUTE | OPT_P_IPWIN32);
... ...
@@ -1795,6 +1796,15 @@ do_deferred_options (struct context *c, const unsigned int found)
1795 1795
     msg (D_PUSH, "OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified");
1796 1796
   if (found & OPT_P_SETENV)
1797 1797
     msg (D_PUSH, "OPTIONS IMPORT: environment modified");
1798
+
1799
+#ifdef ENABLE_SSL
1800
+  if (found & OPT_P_PEER_ID)
1801
+    {
1802
+      msg (D_PUSH, "OPTIONS IMPORT: peer-id set");
1803
+      c->c2.tls_multi->use_peer_id = true;
1804
+      c->c2.tls_multi->peer_id = c->options.peer_id;
1805
+    }
1806
+#endif
1798 1807
 }
1799 1808
 
1800 1809
 /*
... ...
@@ -33,6 +33,7 @@
33 33
 #if P2MP_SERVER
34 34
 
35 35
 #include "multi.h"
36
+#include <inttypes.h>
36 37
 #include "forward-inline.h"
37 38
 
38 39
 #include "memdbg.h"
... ...
@@ -44,7 +45,7 @@
44 44
  */
45 45
 
46 46
 struct multi_instance *
47
-multi_get_create_instance_udp (struct multi_context *m)
47
+multi_get_create_instance_udp (struct multi_context *m, bool *floated)
48 48
 {
49 49
   struct gc_arena gc = gc_new ();
50 50
   struct mroute_addr real;
... ...
@@ -56,15 +57,40 @@ multi_get_create_instance_udp (struct multi_context *m)
56 56
       struct hash_element *he;
57 57
       const uint32_t hv = hash_value (hash, &real);
58 58
       struct hash_bucket *bucket = hash_bucket (hash, hv);
59
-  
60
-      he = hash_lookup_fast (hash, bucket, &real, hv);
59
+      uint8_t* ptr = BPTR(&m->top.c2.buf);
60
+      uint8_t op = ptr[0] >> P_OPCODE_SHIFT;
61
+      uint32_t peer_id;
62
+      int i;
61 63
 
62
-      if (he)
64
+      /* make sure buffer has enough length to read opcode (1 byte) and peer-id (3 bytes) */
65
+      if (op == P_DATA_V2 && m->top.c2.buf.len >= (1 + 3))
63 66
 	{
64
-	  mi = (struct multi_instance *) he->value;
67
+	  peer_id = ntohl(*(uint32_t*)ptr) & 0xFFFFFF;
68
+	  if ((peer_id < m->max_clients) && (m->instances[peer_id]))
69
+	    {
70
+	      mi = m->instances[peer_id];
71
+
72
+	      *floated = !link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from);
73
+
74
+	      if (*floated)
75
+	      {
76
+		/* reset prefix, since here we are not sure peer is the one it claims to be */
77
+		ungenerate_prefix(mi);
78
+		msg (D_MULTI_ERRORS, "Untrusted peer %" PRIu32 " wants to float to %s", peer_id,
79
+			mroute_addr_print (&real, &gc));
80
+	      }
81
+	    }
65 82
 	}
66 83
       else
67 84
 	{
85
+	  he = hash_lookup_fast (hash, bucket, &real, hv);
86
+	  if (he)
87
+	    {
88
+	      mi = (struct multi_instance *) he->value;
89
+	    }
90
+	}
91
+      if (!mi)
92
+	{
68 93
 	  if (!m->top.c2.tls_auth_standalone
69 94
 	      || tls_pre_decrypt_lite (m->top.c2.tls_auth_standalone, &m->top.c2.from, &m->top.c2.buf))
70 95
 	    {
... ...
@@ -75,6 +101,16 @@ multi_get_create_instance_udp (struct multi_context *m)
75 75
 		    {
76 76
 		      hash_add_fast (hash, bucket, &mi->real, hv, mi);
77 77
 		      mi->did_real_hash = true;
78
+
79
+		      for (i = 0; i < m->max_clients; ++i)
80
+			{
81
+			  if (!m->instances[i])
82
+			    {
83
+			      mi->context.c2.tls_multi->peer_id = i;
84
+			      m->instances[i] = mi;
85
+			      break;
86
+			    }
87
+			}
78 88
 		    }
79 89
 		}
80 90
 	      else
... ...
@@ -89,15 +125,8 @@ multi_get_create_instance_udp (struct multi_context *m)
89 89
 #ifdef ENABLE_DEBUG
90 90
       if (check_debug_level (D_MULTI_DEBUG))
91 91
 	{
92
-	  const char *status;
93
-
94
-	  if (he && mi)
95
-	    status = "[succeeded]";
96
-	  else if (!he && mi)
97
-	    status = "[created]";
98
-	  else
99
-	    status = "[failed]";
100
-	
92
+	  const char *status = mi ? "[ok]" : "[failed]";
93
+
101 94
 	  dmsg (D_MULTI_DEBUG, "GET INST BY REAL: %s %s",
102 95
 	       mroute_addr_print (&real, &gc),
103 96
 	       status);
... ...
@@ -65,7 +65,7 @@ void tunnel_server_udp (struct context *top);
65 65
  *     packet's source address or if one was a newly created successfully.
66 66
  *      NULL if one did not yet exist and a new one was not created.
67 67
  */
68
-struct multi_instance *multi_get_create_instance_udp (struct multi_context *m);
68
+struct multi_instance *multi_get_create_instance_udp (struct multi_context *m, bool *floated);
69 69
 
70 70
 #endif
71 71
 #endif
... ...
@@ -39,6 +39,7 @@
39 39
 #include "gremlin.h"
40 40
 #include "mstats.h"
41 41
 #include "ssl_verify.h"
42
+#include <inttypes.h>
42 43
 
43 44
 #include "memdbg.h"
44 45
 
... ...
@@ -373,6 +374,8 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa
373 373
    */
374 374
   m->max_clients = t->options.max_clients;
375 375
 
376
+  m->instances = calloc(m->max_clients, sizeof(struct multi_instance*));
377
+
376 378
   /*
377 379
    * Initialize multi-socket TCP I/O wait object
378 380
    */
... ...
@@ -553,6 +556,8 @@ multi_close_instance (struct multi_context *m,
553 553
 	}
554 554
 #endif
555 555
 
556
+      m->instances[mi->context.c2.tls_multi->peer_id] = NULL;
557
+
556 558
       schedule_remove_entry (m->schedule, (struct schedule_entry *) mi);
557 559
 
558 560
       ifconfig_pool_release (m->ifconfig_pool, mi->vaddr_handle, false);
... ...
@@ -629,6 +634,8 @@ multi_uninit (struct multi_context *m)
629 629
 #endif
630 630
 	  m->hash = NULL;
631 631
 
632
+	  free(m->instances);
633
+
632 634
 	  schedule_free (m->schedule);
633 635
 	  mbuf_free (m->mbuf);
634 636
 	  ifconfig_pool_free (m->ifconfig_pool);
... ...
@@ -2100,6 +2107,70 @@ multi_process_post (struct multi_context *m, struct multi_instance *mi, const un
2100 2100
   return ret;
2101 2101
 }
2102 2102
 
2103
+void multi_process_float (struct multi_context* m, struct multi_instance* mi)
2104
+{
2105
+  struct mroute_addr real;
2106
+  struct hash *hash = m->hash;
2107
+  struct gc_arena gc = gc_new ();
2108
+
2109
+  if (!mroute_extract_openvpn_sockaddr (&real, &m->top.c2.from.dest, true))
2110
+    goto done;
2111
+
2112
+  const uint32_t hv = hash_value (hash, &real);
2113
+  struct hash_bucket *bucket = hash_bucket (hash, hv);
2114
+
2115
+  struct hash_element *he = hash_lookup_fast (hash, bucket, &real, hv);
2116
+  if (he)
2117
+    {
2118
+      struct multi_instance *ex_mi = (struct multi_instance *) he->value;
2119
+
2120
+      const char *cn = tls_common_name (mi->context.c2.tls_multi, true);
2121
+      const char *ex_cn = tls_common_name (ex_mi->context.c2.tls_multi, true);
2122
+      if (cn && ex_cn && strcmp (cn, ex_cn))
2123
+	{
2124
+	  msg (D_MULTI_MEDIUM, "prevent float to %s",
2125
+		multi_instance_string (ex_mi, false, &gc));
2126
+
2127
+	  mi->context.c2.buf.len = 0;
2128
+
2129
+	  goto done;
2130
+	}
2131
+
2132
+      msg (D_MULTI_MEDIUM, "closing instance %s", multi_instance_string (ex_mi, false, &gc));
2133
+      multi_close_instance(m, ex_mi, false);
2134
+    }
2135
+
2136
+    msg (D_MULTI_MEDIUM, "peer %" PRIu32 " floated from %s to %s", mi->context.c2.tls_multi->peer_id,
2137
+        mroute_addr_print (&mi->real, &gc), print_link_socket_actual (&m->top.c2.from, &gc));
2138
+
2139
+    ASSERT (hash_remove(m->hash, &mi->real));
2140
+    ASSERT (hash_remove(m->iter, &mi->real));
2141
+
2142
+    /* change external network address of the remote peer */
2143
+    mi->real = real;
2144
+    generate_prefix (mi);
2145
+
2146
+    mi->context.c2.from = m->top.c2.from;
2147
+    mi->context.c2.to_link_addr = &mi->context.c2.from;
2148
+
2149
+    /* inherit parent link_socket and link_socket_info */
2150
+    mi->context.c2.link_socket = m->top.c2.link_socket;
2151
+    mi->context.c2.link_socket_info->lsa->actual = m->top.c2.from;
2152
+
2153
+    tls_update_remote_addr (mi->context.c2.tls_multi, &mi->context.c2.from);
2154
+
2155
+    ASSERT (hash_add (m->hash, &mi->real, mi, false));
2156
+    ASSERT (hash_add (m->iter, &mi->real, mi, false));
2157
+
2158
+#ifdef MANAGEMENT_DEF_AUTH
2159
+    hash_remove (m->cid_hash, &mi->context.c2.mda_context.cid);
2160
+    hash_add (m->cid_hash, &mi->context.c2.mda_context.cid, mi, false);
2161
+#endif
2162
+
2163
+done:
2164
+    gc_free (&gc);
2165
+}
2166
+
2103 2167
 /*
2104 2168
  * Process packets in the TCP/UDP socket -> TUN/TAP interface direction,
2105 2169
  * i.e. client -> server direction.
... ...
@@ -2114,6 +2185,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
2114 2114
   unsigned int mroute_flags;
2115 2115
   struct multi_instance *mi;
2116 2116
   bool ret = true;
2117
+  bool floated = false;
2117 2118
 
2118 2119
   if (m->pending)
2119 2120
     return true;
... ...
@@ -2123,7 +2195,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
2123 2123
 #ifdef MULTI_DEBUG_EVENT_LOOP
2124 2124
       printf ("TCP/UDP -> TUN [%d]\n", BLEN (&m->top.c2.buf));
2125 2125
 #endif
2126
-      multi_set_pending (m, multi_get_create_instance_udp (m));
2126
+      multi_set_pending (m, multi_get_create_instance_udp (m, &floated));
2127 2127
     }
2128 2128
   else
2129 2129
     multi_set_pending (m, instance);
... ...
@@ -2141,13 +2213,30 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
2141 2141
 	  c->c2.buf = m->top.c2.buf;
2142 2142
 
2143 2143
 	  /* transfer from-addr from top-level context buffer to instance */
2144
-	  c->c2.from = m->top.c2.from;
2144
+	  if (!floated)
2145
+	    c->c2.from = m->top.c2.from;
2145 2146
 	}
2146 2147
 
2147 2148
       if (BLEN (&c->c2.buf) > 0)
2148 2149
 	{
2150
+	  struct link_socket_info *lsi;
2151
+	  const uint8_t *orig_buf;
2152
+
2149 2153
 	  /* decrypt in instance context */
2150
-	  process_incoming_link (c);
2154
+
2155
+	  perf_push (PERF_PROC_IN_LINK);
2156
+	  lsi = get_link_socket_info (c);
2157
+	  orig_buf = c->c2.buf.data;
2158
+	  if (process_incoming_link_part1(c, lsi, floated))
2159
+	    {
2160
+	      if (floated)
2161
+		{
2162
+		  multi_process_float (m, m->pending);
2163
+		}
2164
+
2165
+	      process_incoming_link_part2(c, lsi, orig_buf);
2166
+	    }
2167
+	  perf_pop ();
2151 2168
 
2152 2169
 	  if (TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TUN)
2153 2170
 	    {
... ...
@@ -125,6 +125,9 @@ struct multi_context {
125 125
 # define MC_WORK_THREAD                (MC_MULTI_THREADED_WORKER|MC_MULTI_THREADED_SCHEDULER)
126 126
   int thread_mode;
127 127
 
128
+  struct multi_instance** instances;    /**< Array of multi_instances. An instance can be
129
+                                         * accessed using peer-id as an index. */
130
+
128 131
   struct hash *hash;            /**< VPN tunnel instances indexed by real
129 132
                                  *   address of the remote peer. */
130 133
   struct hash *vhash;           /**< VPN tunnel instances indexed by
... ...
@@ -218,6 +221,16 @@ void multi_close_instance (struct multi_context *m, struct multi_instance *mi, b
218 218
 
219 219
 bool multi_process_timeout (struct multi_context *m, const unsigned int mpp_flags);
220 220
 
221
+/**
222
+ * Handles peer floating.
223
+ *
224
+ * If peer is floated to a taken address, either drops packet
225
+ * (if peer that owns address has different CN) or disconnects
226
+ * existing peer. Updates multi_instance with new address,
227
+ * updates hashtables in multi_context.
228
+ */
229
+void multi_process_float (struct multi_context* m, struct multi_instance* mi);
230
+
221 231
 #define MPP_PRE_SELECT             (1<<0)
222 232
 #define MPP_CONDITIONAL_PRE_SELECT (1<<1)
223 233
 #define MPP_CLOSE_ON_SIGNAL        (1<<2)
... ...
@@ -419,6 +432,12 @@ multi_route_defined (const struct multi_context *m,
419 419
 }
420 420
 
421 421
 /*
422
+ * Takes prefix away from multi_instance.
423
+ */
424
+void
425
+ungenerate_prefix (struct multi_instance *mi);
426
+
427
+/*
422 428
  * Set a msg() function prefix with our current client instance ID.
423 429
  */
424 430
 
... ...
@@ -7001,6 +7001,12 @@ add_option (struct options *options,
7001 7001
       options->persist_mode = 1;
7002 7002
     }
7003 7003
 #endif
7004
+  else if (streq (p[0], "peer-id"))
7005
+    {
7006
+      VERIFY_PERMISSION (OPT_P_PEER_ID);
7007
+      options->use_peer_id = true;
7008
+      options->peer_id = atoi(p[1]);
7009
+    }
7004 7010
   else
7005 7011
     {
7006 7012
       int i;
... ...
@@ -598,6 +598,9 @@ struct options
598 598
   bool show_net_up;
599 599
   int route_method;
600 600
 #endif
601
+
602
+  bool use_peer_id;
603
+  uint32_t peer_id;
601 604
 };
602 605
 
603 606
 #define streq(x, y) (!strcmp((x), (y)))
... ...
@@ -633,6 +636,7 @@ struct options
633 633
 #define OPT_P_SOCKBUF         (1<<25)
634 634
 #define OPT_P_SOCKFLAGS       (1<<26)
635 635
 #define OPT_P_CONNECTION      (1<<27)
636
+#define OPT_P_PEER_ID         (1<<28)
636 637
 
637 638
 #define OPT_P_DEFAULT   (~(OPT_P_INSTANCE|OPT_P_PULL_MODE))
638 639
 
... ...
@@ -305,6 +305,19 @@ send_push_reply (struct context *c)
305 305
   if (multi_push)
306 306
     buf_printf (&buf, ",push-continuation 1");
307 307
 
308
+  /* Send peer-id if client supports it */
309
+  if (c->c2.tls_multi->peer_info)
310
+    {
311
+      const char* proto_str = strstr(c->c2.tls_multi->peer_info, "IV_PROTO=");
312
+      if (proto_str)
313
+	{
314
+	  int proto = 0;
315
+	  int r = sscanf(proto_str, "IV_PROTO=%d", &proto);
316
+	  if ((r == 1) && (proto >= 2))
317
+	    buf_printf(&buf, ",peer-id %d", c->c2.tls_multi->peer_id);
318
+	}
319
+  }
320
+
308 321
   if (BLEN (&buf) > sizeof(cmd)-1)
309 322
     {
310 323
       const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
... ...
@@ -624,6 +624,8 @@ packet_opcode_name (int op)
624 624
       return "P_ACK_V1";
625 625
     case P_DATA_V1:
626 626
       return "P_DATA_V1";
627
+    case P_DATA_V2:
628
+      return "P_DATA_V2";
627 629
     default:
628 630
       return "P_???";
629 631
     }
... ...
@@ -1053,6 +1055,9 @@ tls_multi_init (struct tls_options *tls_options)
1053 1053
   ret->key_scan[1] = &ret->session[TM_ACTIVE].key[KS_LAME_DUCK];
1054 1054
   ret->key_scan[2] = &ret->session[TM_LAME_DUCK].key[KS_LAME_DUCK];
1055 1055
 
1056
+  /* By default not use P_DATA_V2 */
1057
+  ret->use_peer_id = false;
1058
+
1056 1059
   return ret;
1057 1060
 }
1058 1061
 
... ...
@@ -1826,6 +1831,9 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
1826 1826
       buf_printf (&out, "IV_PLAT=win\n");
1827 1827
 #endif
1828 1828
 
1829
+      /* support for P_DATA_V2 */
1830
+      buf_printf(&out, "IV_PROTO=2\n");
1831
+
1829 1832
       /* push compression status */
1830 1833
 #ifdef USE_COMP
1831 1834
       comp_generate_peer_info_string(&session->opt->comp_options, &out);
... ...
@@ -2765,7 +2773,8 @@ bool
2765 2765
 tls_pre_decrypt (struct tls_multi *multi,
2766 2766
 		 const struct link_socket_actual *from,
2767 2767
 		 struct buffer *buf,
2768
-		 struct crypto_options *opt)
2768
+		 struct crypto_options *opt,
2769
+		 bool floated)
2769 2770
 {
2770 2771
   struct gc_arena gc = gc_new ();
2771 2772
   bool ret = false;
... ...
@@ -2783,8 +2792,9 @@ tls_pre_decrypt (struct tls_multi *multi,
2783 2783
 	key_id = c & P_KEY_ID_MASK;
2784 2784
       }
2785 2785
 
2786
-      if (op == P_DATA_V1)
2787
-	{			/* data channel packet */
2786
+      if ((op == P_DATA_V1) || (op == P_DATA_V2))
2787
+	{
2788
+	  /* data channel packet */
2788 2789
 	  for (i = 0; i < KEY_SCAN_SIZE; ++i)
2789 2790
 	    {
2790 2791
 	      struct key_state *ks = multi->key_scan[i];
... ...
@@ -2808,7 +2818,7 @@ tls_pre_decrypt (struct tls_multi *multi,
2808 2808
 #ifdef ENABLE_DEF_AUTH
2809 2809
 		  && !ks->auth_deferred
2810 2810
 #endif
2811
-		  && link_socket_actual_match (from, &ks->remote_addr))
2811
+		  && (floated || link_socket_actual_match (from, &ks->remote_addr)))
2812 2812
 		{
2813 2813
 		  /* return appropriate data channel decrypt key in opt */
2814 2814
 		  opt->key_ctx_bi = &ks->key;
... ...
@@ -2816,7 +2826,19 @@ tls_pre_decrypt (struct tls_multi *multi,
2816 2816
 		  opt->pid_persist = NULL;
2817 2817
 		  opt->flags &= multi->opt.crypto_flags_and;
2818 2818
 		  opt->flags |= multi->opt.crypto_flags_or;
2819
+
2819 2820
 		  ASSERT (buf_advance (buf, 1));
2821
+		  if (op == P_DATA_V2)
2822
+		    {
2823
+		      if (buf->len < 4)
2824
+			{
2825
+			  msg (D_TLS_ERRORS, "Protocol error: received P_DATA_V2 from %s but length is < 4",
2826
+				print_link_socket_actual (from, &gc));
2827
+			  goto error;
2828
+			}
2829
+		      ASSERT (buf_advance (buf, 3));
2830
+		    }
2831
+
2820 2832
 		  ++ks->n_packets;
2821 2833
 		  ks->n_bytes += buf->len;
2822 2834
 		  dmsg (D_TLS_KEYSELECT,
... ...
@@ -3381,14 +3403,24 @@ tls_post_encrypt (struct tls_multi *multi, struct buffer *buf)
3381 3381
 {
3382 3382
   struct key_state *ks;
3383 3383
   uint8_t *op;
3384
+  uint32_t peer;
3384 3385
 
3385 3386
   ks = multi->save_ks;
3386 3387
   multi->save_ks = NULL;
3387 3388
   if (buf->len > 0)
3388 3389
     {
3389 3390
       ASSERT (ks);
3390
-      ASSERT (op = buf_prepend (buf, 1));
3391
-      *op = (P_DATA_V1 << P_OPCODE_SHIFT) | ks->key_id;
3391
+
3392
+      if (!multi->opt.server && multi->use_peer_id)
3393
+	{
3394
+	  peer = htonl(((P_DATA_V2 << P_OPCODE_SHIFT) | ks->key_id) << 24 | (multi->peer_id & 0xFFFFFF));
3395
+	  ASSERT (buf_write_prepend (buf, &peer, 4));
3396
+	}
3397
+      else
3398
+	{
3399
+	  ASSERT (op = buf_prepend (buf, 1));
3400
+	  *op = (P_DATA_V1 << P_OPCODE_SHIFT) | ks->key_id;
3401
+	}
3392 3402
       ++ks->n_packets;
3393 3403
       ks->n_bytes += buf->len;
3394 3404
     }
... ...
@@ -3461,6 +3493,34 @@ tls_rec_payload (struct tls_multi *multi,
3461 3461
   return ret;
3462 3462
 }
3463 3463
 
3464
+void
3465
+tls_update_remote_addr (struct tls_multi *multi, const struct link_socket_actual *addr)
3466
+{
3467
+  struct gc_arena gc = gc_new ();
3468
+  int i, j;
3469
+
3470
+  for (i = 0; i < TM_SIZE; ++i)
3471
+    {
3472
+      struct tls_session *session = &multi->session[i];
3473
+
3474
+      for (j = 0; j < KS_SIZE; ++j)
3475
+	{
3476
+	  struct key_state *ks = &session->key[j];
3477
+
3478
+	  if (!link_socket_actual_defined(&ks->remote_addr) ||
3479
+		link_socket_actual_match (addr, &ks->remote_addr))
3480
+	    continue;
3481
+
3482
+	  dmsg (D_TLS_KEYSELECT, "TLS: tls_update_remote_addr from IP=%s to IP=%s",
3483
+	       print_link_socket_actual (&ks->remote_addr, &gc),
3484
+	       print_link_socket_actual (addr, &gc));
3485
+
3486
+	  ks->remote_addr = *addr;
3487
+	}
3488
+    }
3489
+  gc_free (&gc);
3490
+}
3491
+
3464 3492
 /*
3465 3493
  * Dump a human-readable rendition of an openvpn packet
3466 3494
  * into a garbage collectable string which is returned.
... ...
@@ -3495,7 +3555,7 @@ protocol_dump (struct buffer *buffer, unsigned int flags, struct gc_arena *gc)
3495 3495
   key_id = c & P_KEY_ID_MASK;
3496 3496
   buf_printf (&out, "%s kid=%d", packet_opcode_name (op), key_id);
3497 3497
 
3498
-  if (op == P_DATA_V1)
3498
+  if ((op == P_DATA_V1) || (op == P_DATA_V2))
3499 3499
     goto print_data;
3500 3500
 
3501 3501
   /*
... ...
@@ -60,6 +60,7 @@
60 60
 #define P_CONTROL_V1                   4     /* control channel packet (usually TLS ciphertext) */
61 61
 #define P_ACK_V1                       5     /* acknowledgement for packets received */
62 62
 #define P_DATA_V1                      6     /* data channel packet */
63
+#define P_DATA_V2                      9     /* data channel packet with peer-id */
63 64
 
64 65
 /* indicates key_method >= 2 */
65 66
 #define P_CONTROL_HARD_RESET_CLIENT_V2 7     /* initial key from client, forget previous state */
... ...
@@ -67,7 +68,7 @@
67 67
 
68 68
 /* define the range of legal opcodes */
69 69
 #define P_FIRST_OPCODE                 1
70
-#define P_LAST_OPCODE                  8
70
+#define P_LAST_OPCODE                  9
71 71
 
72 72
 /* Should we aggregate TLS
73 73
  * acknowledgements, and tack them onto
... ...
@@ -305,7 +306,8 @@ int tls_multi_process (struct tls_multi *multi,
305 305
 bool tls_pre_decrypt (struct tls_multi *multi,
306 306
 		      const struct link_socket_actual *from,
307 307
 		      struct buffer *buf,
308
-		      struct crypto_options *opt);
308
+		      struct crypto_options *opt,
309
+		      bool floated);
309 310
 
310 311
 
311 312
 /**************************************************************************/
... ...
@@ -430,6 +432,15 @@ bool tls_send_payload (struct tls_multi *multi,
430 430
 bool tls_rec_payload (struct tls_multi *multi,
431 431
 		      struct buffer *buf);
432 432
 
433
+/**
434
+ * Updates remote address in TLS sessions.
435
+ *
436
+ * @param multi - Tunnel to update
437
+ * @param addr - new address
438
+ */
439
+void tls_update_remote_addr (struct tls_multi *multi,
440
+			     const struct link_socket_actual *addr);
441
+
433 442
 #ifdef MANAGEMENT_DEF_AUTH
434 443
 static inline char *
435 444
 tls_get_peer_info(const struct tls_multi *multi)
... ...
@@ -497,6 +497,10 @@ struct tls_multi
497 497
   char *peer_info;
498 498
 #endif
499 499
 
500
+  /* For P_DATA_V2 */
501
+  uint32_t peer_id;
502
+  bool use_peer_id;
503
+
500 504
   /*
501 505
    * Our session objects.
502 506
    */