From 5256f68dad555692a25c483a20c85d15e825ee37 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 10 Oct 2019 21:34:03 +0200 Subject: [PATCH] Fix an issue with routing between nodes, when flexisip nodes are behind a nat. The fix consists in forcing messages sent between nodes to use the internal transport. --- include/flexisip/agent.hh | 7 ++++++- include/flexisip/module.hh | 2 +- src/agent.cc | 7 +++++++ src/module-forward.cc | 25 +++++++++++++++++++++---- src/module.cc | 2 +- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/include/flexisip/agent.hh b/include/flexisip/agent.hh index 50e56361..a2b458d6 100644 --- a/include/flexisip/agent.hh +++ b/include/flexisip/agent.hh @@ -140,6 +140,9 @@ public: const url_t *getPreferredRouteUrl() const { return mPreferredRouteV4; } + tport_t *getInternalTport()const{ + return mInternalTport; + } /** * URI associated to this server specifically. */ @@ -206,6 +209,7 @@ private: void initializePreferredRoute(); void loadModules(); void startMdns(); + static int messageCallback(nta_agent_magic_t *context, nta_agent_t *agent, msg_t *msg, sip_t *sip); std::string mServerString; std::list mModules; @@ -241,7 +245,8 @@ private: std::unique_ptr mLogWriter; DomainRegistrationManager *mDrm; std::string mPassphrase; - static int messageCallback(nta_agent_magic_t *context, nta_agent_t *agent, msg_t *msg, sip_t *sip); + tport_t *mInternalTport = nullptr; + static constexpr const char* sInternalTransportIdent = "internal-transport"; bool mTerminating; bool mUseMaddr; #if ENABLE_MDNS diff --git a/include/flexisip/module.hh b/include/flexisip/module.hh index b9f3e88e..ad1ef6b3 100644 --- a/include/flexisip/module.hh +++ b/include/flexisip/module.hh @@ -273,7 +273,7 @@ public: // These methods do host comparison taking into account that each one of argument can be an ipv6 address enclosed in // brakets. static bool urlHostMatch(const char *host1, const char *host2); - static bool urlHostMatch(url_t *url, const char *host); + static bool urlHostMatch(const url_t *url, const char *host); // Returns the host taking into account that if it is an ipv6 address, then brakets are removed. static std::string getHost(const char *host); diff --git a/src/agent.cc b/src/agent.cc index 264bb5fd..6a4dbadc 100644 --- a/src/agent.cc +++ b/src/agent.cc @@ -382,12 +382,19 @@ void Agent::start(const string &transport_override, const string passphrase) { if (nta_agent_add_tport( mAgent, (const url_string_t *)mPreferredRouteV4, TPTAG_IDLE(tports_idle_timeout), TPTAG_TIMEOUT(incompleteIncomingMessageTimeout), + TPTAG_IDENT(sInternalTransportIdent), TPTAG_KEEPALIVE(keepAliveInterval), TPTAG_QUEUESIZE(queueSize), TPTAG_SDWN_ERROR(1), TAG_END() ) == -1) { char prefRouteV4[266]; url_e(prefRouteV4, sizeof(prefRouteV4), mPreferredRouteV4); LOGF("Could not enable internal transport %s: %s", prefRouteV4, strerror(errno)); } + tp_name_t tn = {0}; + tn.tpn_ident = (char*)sInternalTransportIdent; + mInternalTport = tport_by_name(nta_agent_tports(mAgent), &tn); + if (!mInternalTport){ + LOGF("Could not obtain pointer to internal tport. Bug somewhere."); + } } tport_t *primaries = tport_primaries(nta_agent_tports(mAgent)); diff --git a/src/module-forward.cc b/src/module-forward.cc index cedbd50f..8c912696 100644 --- a/src/module-forward.cc +++ b/src/module-forward.cc @@ -39,11 +39,11 @@ static char const *compute_branch(nta_agent_t *sa, msg_t *msg, sip_t const *sip, class ForwardModule : public Module, ModuleToolbox { public: ForwardModule(Agent *ag); + virtual ~ForwardModule(); virtual void onDeclare(GenericStruct *module_config); virtual void onLoad(const GenericStruct *root); virtual void onRequest(shared_ptr &ev); virtual void onResponse(shared_ptr &ev); - ~ForwardModule(); void sendRequest(shared_ptr &ev, url_t *dest); private: @@ -52,12 +52,14 @@ class ForwardModule : public Module, ModuleToolbox { url_t *getDestinationFromRoute(su_home_t *home, sip_t *sip); bool isLooping(shared_ptr &ev, const char *branch); unsigned int countVia(shared_ptr &ev); + bool isAClusterNode(const url_t *url); su_home_t mHome; sip_route_t *mOutRoute; - bool mRewriteReqUri; - bool mAddPath; string mDefaultTransport; std::list mParamsToRemove; + list mClusterNodes; + bool mRewriteReqUri; + bool mAddPath; static ModuleInfo sInfo; }; @@ -110,6 +112,19 @@ void ForwardModule::onLoad(const GenericStruct *mc) { * a gruu request uri is under control of this domain or not. */ mRouterModule = dynamic_cast(getAgent()->findModule("Router")); if (!mRouterModule) LOGA("Could not find router module."); + + const GenericStruct *clusterSection = GenericManager::get()->getRoot()->get("cluster"); + bool clusterEnabled = clusterSection->get("enabled")->read(); + if (clusterEnabled) { + mClusterNodes = clusterSection->get("nodes")->read(); + } +} + +bool ForwardModule::isAClusterNode(const url_t *url){ + for(const string& node : mClusterNodes){ + if (ModuleToolbox::urlHostMatch(url, node.c_str())) return true; + } + return false; } url_t *ForwardModule::overrideDest(shared_ptr &ev, url_t *dest) { @@ -296,7 +311,9 @@ void ForwardModule::sendRequest(shared_ptr &ev, url_t *dest) { tp_name_t name = {0, 0, 0, 0, 0, 0}; tport_t *tport = nullptr; if (ev->getOutgoingAgent() != nullptr) { - if ((tport = getAgent()->getDRM()->lookupTport(dest)) != nullptr){ + if (isAClusterNode(dest) && (tport = getAgent()->getInternalTport()) != NULL){ + LOGD("Using internal transport to route message to a node of the cluster."); + }else if ((tport = getAgent()->getDRM()->lookupTport(dest)) != nullptr){ LOGD("Found outgoing tport from domain registration manager."); } else if (tport_name_by_url(ms->getHome(), &name, reinterpret_cast(dest)) == 0) { // tport_by_name can only work for IPs diff --git a/src/module.cc b/src/module.cc index 94e23213..a136bd80 100644 --- a/src/module.cc +++ b/src/module.cc @@ -432,7 +432,7 @@ bool ModuleToolbox::urlHostMatch(const char *host1, const char *host2) { return strncasecmp(host1, host2, MAX(len1, len2)) == 0; } -bool ModuleToolbox::urlHostMatch(url_t *url, const char *host) { +bool ModuleToolbox::urlHostMatch(const url_t *url, const char *host) { return urlHostMatch(url->url_host, host); } -- 2.21.0