plaisthos has uploaded this change for review. ( http://gerrit.openvpn.net/c/openvpn/+/1726?usp=email )
Change subject: Split multi_get_create_instance_udp into data and control parts ...................................................................... Split multi_get_create_instance_udp into data and control parts This currently leads to a bit of code duplication but this refactoring will make the follow up patches cleaner and better to understand when the control channel lookup will be changed to use session ids instead of IP addresses. Change-Id: I8e9923b51b77f184c7d49d697004cb02d2b5cfc3 Signed-off-by: Arne Schwabe <[email protected]> --- M src/openvpn/mudp.c 1 file changed, 88 insertions(+), 52 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/26/1726/1 diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index e8d8128..aa7defe 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -197,8 +197,7 @@ struct multi_instance * handle_connection_attempt(struct multi_context *m, struct link_socket *sock, - struct mroute_addr *real, - struct hash_bucket *bucket) + struct mroute_addr *real) { struct hash *hash = m->hash; struct tls_pre_decrypt_state state = { 0 }; @@ -229,7 +228,9 @@ if (mi) { const uint64_t hv = hash_value(hash, real); + struct hash_bucket *bucket = hash_bucket(hash, hv); hash_add_fast(hash, bucket, &mi->real, hv, mi); + mi->did_real_hash = true; multi_assign_peer_id(m, mi); @@ -278,6 +279,19 @@ return NULL; } +struct multi_instance * +multi_get_instance_udp_control(struct multi_context *m, struct link_socket *sock) +{ + struct mroute_addr real = { 0 }; + real.proto = sock->info.proto; + + if (mroute_extract_openvpn_sockaddr(&real, &m->top.c2.from.dest, true) && m->top.c2.buf.len > 0) + { + return multi_get_instance_real_udp_real(m, &real); + } + + return NULL; +} /** * Get a client instance based on real address. If @@ -285,72 +299,94 @@ * maintaining real address hash table atomicity. */ struct multi_instance * -multi_get_create_instance_udp(struct multi_context *m, bool *floated, struct link_socket *sock) +multi_get_instance_udp_data(struct multi_context *m, bool *floated, struct mroute_addr *real, struct link_socket *sock) { - struct gc_arena gc = gc_new(); - struct mroute_addr real = { 0 }; struct multi_instance *mi = NULL; - struct hash *hash = m->hash; - real.proto = sock->info.proto; - if (mroute_extract_openvpn_sockaddr(&real, &m->top.c2.from.dest, true) && m->top.c2.buf.len > 0) + uint8_t *ptr = BPTR(&m->top.c2.buf); + uint8_t op = ptr[0] >> P_OPCODE_SHIFT; + bool v2 = (op == P_DATA_V2) && (m->top.c2.buf.len >= (1 + 3)); + bool peer_id_disabled = false; + + /* make sure buffer has enough length to read opcode (1 byte) and peer-id (3 bytes) */ + if (v2) { - const uint64_t hv = hash_value(hash, &real); - struct hash_bucket *bucket = hash_bucket(hash, hv); - uint8_t *ptr = BPTR(&m->top.c2.buf); - uint8_t op = ptr[0] >> P_OPCODE_SHIFT; - bool v2 = (op == P_DATA_V2) && (m->top.c2.buf.len >= (1 + 3)); - bool peer_id_disabled = false; + uint32_t peer_id = ((uint32_t)ptr[1] << 16) | ((uint32_t)ptr[2] << 8) | ((uint32_t)ptr[3]); + peer_id_disabled = (peer_id == MAX_PEER_ID); - /* make sure buffer has enough length to read opcode (1 byte) and peer-id (3 bytes) */ - if (v2) + if (!peer_id_disabled && (peer_id < m->max_clients) && (m->instances[peer_id])) { - uint32_t peer_id = ((uint32_t)ptr[1] << 16) | ((uint32_t)ptr[2] << 8) | ((uint32_t)ptr[3]); - peer_id_disabled = (peer_id == MAX_PEER_ID); - - if (!peer_id_disabled && (peer_id < m->max_clients) && m->instances[peer_id]) + /* Floating on TCP will never be possible, so ensure we only process + * UDP clients */ + if (m->instances[peer_id]->context.c2.link_sockets[0]->info.proto + == sock->info.proto) { - /* Floating on TCP will never be possible, so ensure we only process - * UDP clients */ - if (m->instances[peer_id]->context.c2.link_sockets[0]->info.proto - == sock->info.proto) - { - mi = m->instances[peer_id]; - *floated = !link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from); + mi = m->instances[peer_id]; + *floated = !link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from); - if (*floated) - { - /* reset prefix, since here we are not sure peer is the one it claims to be - */ - ungenerate_prefix(mi); - msg(D_MULTI_MEDIUM, "Float requested for peer %" PRIu32 " to %s", peer_id, - mroute_addr_print(&real, &gc)); - } + if (*floated) + { + /* reset prefix, since here we are not sure peer is the one it claims to be + */ + ungenerate_prefix(mi); + struct gc_arena gc = gc_new(); + msg(D_MULTI_MEDIUM, "Float requested for peer %" PRIu32 " to %s", peer_id, + mroute_addr_print(real, &gc)); + gc_free(&gc); } + return mi; } } - if (!v2 || peer_id_disabled) - { - mi = multi_get_instance_real_udp_real(m, &real); - } + } + if (!v2 || peer_id_disabled) + { + return multi_get_instance_real_udp_real(m, real); + } + return NULL; +} - /* we have no existing multi instance for this connection */ - if (!mi) - { - mi = handle_connection_attempt(m, sock, &real, bucket); - } +struct multi_instance * +multi_get_create_instance_udp(struct multi_context *m, bool *floated, struct link_socket *sock) +{ + uint8_t *ptr = BPTR(&m->top.c2.buf); + uint8_t op = ptr[0] >> P_OPCODE_SHIFT; -#ifdef ENABLE_DEBUG - if (check_debug_level(D_MULTI_DEBUG)) - { - const char *status = mi ? "[ok]" : "[failed]"; + struct mroute_addr real = { 0 }; + real.proto = sock->info.proto; - dmsg(D_MULTI_DEBUG, "GET INST BY REAL: %s %s", mroute_addr_print(&real, &gc), status); - } -#endif + if (!mroute_extract_openvpn_sockaddr(&real, &m->top.c2.from.dest, true) || m->top.c2.buf.len == 0) + { + return NULL; } - gc_free(&gc); + struct multi_instance *mi = NULL; + if (op == P_DATA_V1 || op == P_DATA_V2) + { + mi = multi_get_instance_udp_data(m, floated, &real, sock); + } + else + { + mi = multi_get_instance_udp_control(m, sock); + + /* we have no existing multi instance for this connection, control + * packets can create a session. Data packets cannot */ + if (!mi) + { + mi = handle_connection_attempt(m, sock, &real); + } + } + +#ifdef ENABLE_DEBUG + if (check_debug_level(D_MULTI_DEBUG)) + { + struct gc_arena gc = gc_new(); + const char *status = mi ? "[ok]" : "[failed]"; + + dmsg(D_MULTI_DEBUG, "GET INST BY REAL/SID: %s %s", mroute_addr_print(&real, &gc), status); + gc_free(&gc); + } +#endif + ASSERT(!(mi && mi->halt)); return mi; } -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1726?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: newchange Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I8e9923b51b77f184c7d49d697004cb02d2b5cfc3 Gerrit-Change-Number: 1726 Gerrit-PatchSet: 1 Gerrit-Owner: plaisthos <[email protected]> Gerrit-CC: openvpn-devel <[email protected]>
_______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
