From f9e36014aef296a4ad661738c4ae791eb3d930db Mon Sep 17 00:00:00 2001 From: Shane Bryldt Date: Mon, 23 Oct 2017 08:17:27 -0600 Subject: [PATCH] FS-10739: [libblade] Fixed disconnecting downstream sessions when upstream session is disconnected, without disconnecting loopback which always remains available --- libs/libblade/src/blade_session.c | 7 ++++--- libs/libblade/src/blade_sessionmgr.c | 19 +++++++++++++------ libs/libblade/test/testcon.cfg | 4 ++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libs/libblade/src/blade_session.c b/libs/libblade/src/blade_session.c index d3dd6be117..0e50b90f64 100644 --- a/libs/libblade/src/blade_session.c +++ b/libs/libblade/src/blade_session.c @@ -180,6 +180,9 @@ KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs) ks_assert(bs); + // make sure this is done first to remove the upstream session before it is attempted to be used for sending route updates + blade_sessionmgr_session_remove(blade_handle_sessionmgr_get(bs->handle), bs); + // if this is an upstream session there will be no routes, so this is harmless to always run regardless ks_hash_read_lock(bs->routes); for (it = ks_hash_first(bs->routes, KS_UNLOCKED); it; it = ks_hash_next(&it)) { @@ -192,9 +195,6 @@ KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs) } ks_hash_read_unlock(bs->routes); - // this will also clear the local id, and master id in the handle if this is the upstream session - blade_sessionmgr_session_remove(blade_handle_sessionmgr_get(bs->handle), bs); - while (ks_q_trypop(bs->sending, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json); while (ks_q_trypop(bs->receiving, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json); @@ -586,6 +586,7 @@ KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, ks_ blade_rpc_request_create(&brpcreq, bs->handle, ks_pool_get(bs->handle), bs->id, json, callback, data); ks_assert(brpcreq); + // @todo update to get default ttl from configuration if (ttl <= 0) ttl = 10; blade_rpc_request_ttl_set(brpcreq, ttl); diff --git a/libs/libblade/src/blade_sessionmgr.c b/libs/libblade/src/blade_sessionmgr.c index 6faa01e5eb..359bf8b3e2 100644 --- a/libs/libblade/src/blade_sessionmgr.c +++ b/libs/libblade/src/blade_sessionmgr.c @@ -246,15 +246,22 @@ KS_DECLARE(ks_status_t) blade_sessionmgr_session_remove(blade_sessionmgr_t *bsmg routemgr = blade_handle_routemgr_get(bsmgr->handle); if (blade_session_upstream(bs)) { + bsmgr->upstream = NULL; blade_routemgr_local_set(routemgr, NULL); blade_routemgr_master_set(routemgr, NULL); - // @todo this is the upstream session that has actually terminated, any downstream connections should also be terminated - // properly, such that the downstream clients will not attempt to reconnect with the same session id, but will instead - // reestablish new sessions and likewise terminate downstream sessions - // @todo this also reflects that downstream connections should not be accepted in the transport implementation until an - // upstream connection has been established, unless it is the master node which has no upstream session, plumbing to - // support this does not yet exist + ks_hash_read_lock(bsmgr->sessions); + for (ks_hash_iterator_t *it = ks_hash_first(bsmgr->sessions, KS_UNLOCKED); it; it = ks_hash_next(&it)) { + void *key = NULL; + blade_session_t *value = NULL; + + ks_hash_this(it, (const void **)&key, NULL, (void **)&value); + + if (blade_session_loopback(value)) continue; + + blade_session_hangup(value); + } + ks_hash_read_unlock(bsmgr->sessions); } blade_session_write_unlock(bs); diff --git a/libs/libblade/test/testcon.cfg b/libs/libblade/test/testcon.cfg index 011c06deb1..63f6102ba4 100644 --- a/libs/libblade/test/testcon.cfg +++ b/libs/libblade/test/testcon.cfg @@ -18,8 +18,8 @@ blade: ssl: { key = "./ca/intermediate/private/controller@freeswitch-downstream.key.pem"; - cert = "./ca/intermediate/cert/controller@freeswitch-downstream.cert.pem"; - chain = "./ca/intermediate/cert/ca-chain.cert.pem"; + cert = "./ca/intermediate/certs/controller@freeswitch-downstream.cert.pem"; + chain = "./ca/intermediate/certs/ca-chain.cert.pem"; }; }; };