3232
3333#include "memdbg.h"
3434#include "ssl_pkt.h"
35+ #include "sid_hash.h"
3536
3637#ifdef HAVE_SYS_INOTIFY_H
3738#include <sys/inotify.h>
@@ -166,7 +167,7 @@ do_pre_decrypt_check(struct multi_context *m, struct tls_pre_decrypt_state *stat
166167 }
167168 else
168169 {
169- msg (D_MULTI_DEBUG ,
170+ msg (D_MULTI_MEDIUM ,
170171 "Valid packet (%s) with HMAC challenge from peer (%s), "
171172 "accepting new connection." ,
172173 packet_opcode_name (op ), peer );
@@ -180,6 +181,7 @@ do_pre_decrypt_check(struct multi_context *m, struct tls_pre_decrypt_state *stat
180181 return false;
181182}
182183
184+
183185#if defined(__GNUC__ ) || defined(__clang__ )
184186#pragma GCC diagnostic push
185187#pragma GCC diagnostic ignored "-Wsign-compare"
@@ -235,6 +237,7 @@ handle_connection_attempt(struct multi_context *m,
235237 struct tls_session * session =
236238 & mi -> context .c2 .tls_multi -> session [TM_INITIAL ];
237239 session_skip_to_pre_start (session , & state , & m -> top .c2 .from );
240+ multi_hash_sid_add (m , & state .peer_session_id , mi );
238241 }
239242 }
240243 }
@@ -254,17 +257,43 @@ handle_connection_attempt(struct multi_context *m,
254257struct multi_instance *
255258multi_get_instance_udp_control (struct multi_context * m , struct link_socket * sock )
256259{
260+ struct hash * addr_hash = m -> hash ;
261+
262+ /* Copy buffer, to a tmp buffer, so that reading the sesison does not
263+ * modify the internal pointers */
264+ struct buffer tmp = m -> top .c2 .buf ;
265+
266+ /* op code */
267+ uint8_t op = (uint8_t )buf_read_u8 (& tmp );
268+
269+ struct session_id sid = { 0 };
270+ session_id_read (& sid , & tmp );
271+
272+ struct hash_element * he_sid = multi_hash_sid_lookup (m , & sid );
273+
274+ if (he_sid )
275+ {
276+ return he_sid -> value ;
277+ }
278+
279+ /* If we cannot find the session the only valid case where we assign
280+ * this to an existing session is the case when this is a soft reset.
281+ * In this case we fall back to the lookup via IP address */
282+ if (op != P_CONTROL_SOFT_RESET_V1 )
283+ {
284+ return NULL ;
285+ }
286+
257287 struct mroute_addr real = { 0 };
258- struct hash * hash = m -> hash ;
259288 real .proto = sock -> info .proto ;
260289
261- if (mroute_extract_openvpn_sockaddr (& real , & m -> top .c2 .from .dest , true) && m -> top . c2 . buf . len > 0 )
290+ if (mroute_extract_openvpn_sockaddr (& real , & m -> top .c2 .from .dest , true))
262291 {
263292 struct hash_element * he ;
264- const uint64_t hv = hash_value (hash , & real );
265- struct hash_bucket * bucket = hash_bucket (hash , hv );
293+ const uint64_t addr_hv = hash_value (addr_hash , & real );
294+ struct hash_bucket * bucket = hash_bucket (addr_hash , addr_hv );
266295
267- he = hash_lookup_fast (hash , bucket , & real , hv );
296+ he = hash_lookup_fast (addr_hash , bucket , & real , addr_hv );
268297 if (he )
269298 {
270299 return he -> value ;
@@ -357,6 +386,13 @@ multi_get_create_instance_udp(struct multi_context *m, bool *floated, struct lin
357386 }
358387 else
359388 {
389+ if (m -> top .c2 .buf .len < 9 )
390+ {
391+ /* control packets must be at least the opcode byte + session id
392+ * (8 byte) long, otherwise they are not valid packets */
393+ return NULL ;
394+ }
395+
360396 mi = multi_get_instance_udp_control (m , sock );
361397
362398 /* we have no existing multi instance for this connection, control
0 commit comments