diff --git a/ProxyChannel.cxx b/ProxyChannel.cxx index d4c3762a..36554098 100644 --- a/ProxyChannel.cxx +++ b/ProxyChannel.cxx @@ -5759,8 +5759,8 @@ void CallSignalSocket::OnSetup(SignalingMsg * msg) } #endif - // TODO: on a multi-homed server, the SCI may get the wrong source address and the call fails - RasSrv->SendRas(sci_ras, m_call->GetCalledParty()->GetRasAddress(), NULL, m_call->GetCalledParty()->GetH235Authenticators()); + // on a multi-homed server, the SCI may get the wrong source address and the call fails + RasSrv->SendRas(sci_ras, m_call->GetCalledParty()->GetRasAddress(), m_call->GetCalledParty()->GetRasServerIP(), m_call->GetCalledParty()->GetH235Authenticators()); // store Setup m_call->StoreSetup(msg); diff --git a/RasSrv.cxx b/RasSrv.cxx index 9a9df913..a13604b2 100644 --- a/RasSrv.cxx +++ b/RasSrv.cxx @@ -1154,9 +1154,16 @@ GkInterface *RasServer::SelectInterface(const Address & addr) { if (interfaces.empty()) return NULL; - ifiterator iter = find_if(interfaces.begin(), interfaces.end(), bind2nd(mem_fun(&GkInterface::IsReachable), &addr)); - if (iter != interfaces.end()) + // prefer the interface that actually has the IP bound to it + ifiterator iter = find_if(interfaces.begin(), interfaces.end(), bind2nd(mem_fun(&GkInterface::IsBoundTo), &addr)); + if (iter != interfaces.end()) { return *iter; + } + // otherwise use an interface that can reach the IP + iter = find_if(interfaces.begin(), interfaces.end(), bind2nd(mem_fun(&GkInterface::IsReachable), &addr)); + if (iter != interfaces.end()) { + return *iter; + } else return SelectDefaultInterface(addr.GetVersion()); } @@ -1229,6 +1236,16 @@ bool RasServer::SendRas(H225_RasMessage & rasobj, const Address & addr, WORD pt, return listener->SendRas(rasobj, addr, pt, auth); } +bool RasServer::SendRas(H225_RasMessage & rasobj, const H225_TransportAddress & dest, const Address & local, GkH235Authenticators * auth) +{ + PIPSocket::Address addr; + WORD pt; + if (GetIPAndPortFromTransportAddr(dest, addr, pt)) + return SendRas(rasobj, addr, pt, local, auth); + PTRACE(1, "RAS\tInvalid address when trying to send " << rasobj.GetTagName()); + return false; +} + bool RasServer::SendRIP(H225_RequestSeqNum seqNum, unsigned ripDelay, const Address & addr, WORD port, GkH235Authenticators * auth) { H225_RasMessage ras_msg; @@ -2014,9 +2031,7 @@ bool RegistrationRequestPDU::Process() WORD port = 0; if (!GetIPAndPortFromTransportAddr(request.m_rasAddress[i], addr, port) || !addr.IsValid() || port == 0) { - PTRACE(5, "RAS\tRemoving RAS address " - << AsString(request.m_rasAddress[i]) << " from RRQ" - ); + PTRACE(5, "RAS\tRemoving RAS address " << AsString(request.m_rasAddress[i]) << " from RRQ"); request.m_rasAddress.RemoveAt(i--); } } @@ -2629,6 +2644,7 @@ bool RegistrationRequestPDU::Process() PTRACE(3, "RAS\tRRQ rejected by unknown reason from " << rx_addr); return BuildRRJ(H225_RegistrationRejectReason::e_undefinedReason); } + ep->SetRasServerIP(m_msg->m_localAddr); // remember which of our IPs the endpoint has sent the RRQ to (need for H.460.18 SCI) #ifdef HAS_H46017 if (usesH46017) { diff --git a/RasSrv.h b/RasSrv.h index 17b7fb09..f54650af 100644 --- a/RasSrv.h +++ b/RasSrv.h @@ -107,6 +107,7 @@ class RasServer : public Singleton, public SocketsReader { bool SendRas(H225_RasMessage &, const Address &, WORD, RasListener * = NULL, GkH235Authenticators * auth = NULL); bool SendRas(H225_RasMessage &, const H225_TransportAddress &, RasListener * = NULL, GkH235Authenticators * auth = NULL); bool SendRas(H225_RasMessage &, const Address &, WORD, const Address &, GkH235Authenticators * auth); + bool SendRas(H225_RasMessage & rasobj, const H225_TransportAddress & dest, const Address & local, GkH235Authenticators * auth); bool SendRIP(H225_RequestSeqNum seqNum, unsigned ripDelay, const Address & addr, WORD port, GkH235Authenticators * auth); bool IsRedirected(unsigned = 0) const; diff --git a/RasTbl.h b/RasTbl.h index bca742e5..e205f361 100644 --- a/RasTbl.h +++ b/RasTbl.h @@ -116,6 +116,8 @@ class EndpointRec H225_TransportAddress GetRasAddress() const; H225_TransportAddress GetCallSignalAddress() const; PIPSocket::Address GetIP() const; + // for multi-homed servers: the IP that the endpoint sent his RAS messages to (needed for H.460.18 SCI) + PIPSocket::Address GetRasServerIP() const { return m_rasServerIP; } H225_EndpointIdentifier GetEndpointIdentifier() const; H225_ArrayOf_AliasAddress GetAliases() const; H225_EndpointType GetEndpointType() const; @@ -131,6 +133,7 @@ class EndpointRec virtual void SetRasAddress(const H225_TransportAddress &); virtual void SetCallSignalAddress(const H225_TransportAddress &); + virtual void SetRasServerIP(const PIPSocket::Address & ip) { m_rasServerIP = ip; } virtual void SetTimeToLive(int); virtual bool SetAliases(const H225_ArrayOf_AliasAddress &, PBoolean = false); virtual bool RemoveAliases(const H225_ArrayOf_AliasAddress &); @@ -372,6 +375,7 @@ class EndpointRec H225_TransportAddress m_rasAddress; H225_TransportAddress m_callSignalAddress; + PIPSocket::Address m_rasServerIP; H225_EndpointIdentifier m_endpointIdentifier; H225_ArrayOf_AliasAddress m_terminalAliases; H225_EndpointType *m_terminalType; diff --git a/changes.txt b/changes.txt index 4d7a9ad3..10821cc5 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,6 @@ Changes from 5.2 to 5.3 ======================= +- BUGFIX(ProxyChannel.cxx) fix H.460.18 on multi-homed servers (SCI comes from the correct IP now) - new switch to disable SNMP traps [SNMP] EnableTraps=0 - BUGFIX(ProxyChannel.cxx) don't throw SNMP trap on H.245 connection errors (causes crash under load with Net-SNMP) - BUGFIX(snmp.cxx) shutdown GnuGk when SNMP agent can't be started diff --git a/docs/known_bugs.txt b/docs/known_bugs.txt index 57bfa8d2..e3cfc6c7 100644 --- a/docs/known_bugs.txt +++ b/docs/known_bugs.txt @@ -1,6 +1,4 @@ Known bugs: -* on a multi-homed H.460.18 server, the SCI announcing an incoming call may come from - the wrong source IP (workaround: Set Home= and use no more than 1 IPv4 and 1 IPv6) * call failover and call rerouting fail when the new call destination is using H.460.18 * H.245 sockets are bound to all interfaces (0.0.0.0), Home config option is ignored which may cause problems on multihomed hosts (virtual servers)