Change host direction if possible and re-negotiate the transport when receiving stream hosts from remote.
git-svn-id: http://yate.null.ro/svn/yate/trunk@5497 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
7d30311e6d
commit
e620049e17
|
@ -971,7 +971,7 @@ JGStreamHost* JGStreamHost::fromXml(XmlElement* xml)
|
|||
const char* jid = xml->attribute("jid");
|
||||
if (TelEngine::null(jid))
|
||||
return 0;
|
||||
return new JGStreamHost(jid,xml->attribute("host"),
|
||||
return new JGStreamHost(false,jid,xml->attribute("host"),
|
||||
String(xml->attribute("port")).toInteger(-1),xml->attribute("zeroconf"));
|
||||
}
|
||||
|
||||
|
|
|
@ -784,14 +784,15 @@ class JGStreamHost : public String
|
|||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param local Local stream host
|
||||
* @param jid Stream host jid (id)
|
||||
* @param addr Stream host address
|
||||
* @param port Stream host port
|
||||
* @param zeroConf Optional zero conf definition (override address/port)
|
||||
*/
|
||||
JGStreamHost(const char* jid, const char* addr, int port, const char* zeroConf = 0)
|
||||
JGStreamHost(bool local, const char* jid, const char* addr, int port, const char* zeroConf = 0)
|
||||
: String(jid),
|
||||
m_address(addr), m_port(port), m_zeroConf(zeroConf)
|
||||
m_local(local), m_address(addr), m_port(port), m_zeroConf(zeroConf)
|
||||
{}
|
||||
|
||||
/**
|
||||
|
@ -800,7 +801,7 @@ public:
|
|||
*/
|
||||
inline JGStreamHost(const JGStreamHost& src)
|
||||
: String(src),
|
||||
m_address(src.m_address), m_port(src.m_port),
|
||||
m_local(src.m_local), m_address(src.m_address), m_port(src.m_port),
|
||||
m_zeroConf(src.m_zeroConf)
|
||||
{}
|
||||
|
||||
|
@ -834,6 +835,7 @@ public:
|
|||
*/
|
||||
static XmlElement* buildRsp(const char* jid);
|
||||
|
||||
bool m_local;
|
||||
String m_address;
|
||||
int m_port;
|
||||
String m_zeroConf;
|
||||
|
|
|
@ -227,6 +227,9 @@ protected:
|
|||
void processActionTransportInfo(JGEvent* event);
|
||||
// Handle answer (session accept) events for non file transfer
|
||||
void processActionAccept(JGEvent* ev);
|
||||
// Handle stream hosts events
|
||||
// Return false if the session was terminated
|
||||
bool processStreamHosts(JGEvent* ev);
|
||||
// Update a received candidate. Return true if changed
|
||||
bool updateCandidate(unsigned int component, JGSessionContent& local,
|
||||
JGSessionContent& recv);
|
||||
|
@ -286,9 +289,13 @@ protected:
|
|||
// If host dir succeeds, still return false, but don't terminate transfer
|
||||
bool setupSocksFileTransfer(bool start);
|
||||
// Change host sender. Return false on failure
|
||||
bool changeFTHostDir();
|
||||
bool changeFTHostDir(bool resetState = true);
|
||||
// Drop file transfer data. Remove the first host in list
|
||||
void dropFT(bool removeFirst);
|
||||
// Drop file transfer hosts
|
||||
void dropFTHosts(bool local, const char* reason = 0);
|
||||
// Drop file transfer host
|
||||
void dropFTHost(JGStreamHost* sh, ObjList* remove, const char* reason = 0);
|
||||
// Get the RTP direction param from a content
|
||||
// FIXME: ignore content senders for early media ?
|
||||
inline const char* rtpDir(const JGSessionContent& c) {
|
||||
|
@ -1880,38 +1887,7 @@ bool YJGConnection::handleEvent(JGEvent* event)
|
|||
event->confirmElement(XMPPError::Request);
|
||||
break;
|
||||
case JGSession::ActStreamHost:
|
||||
if (m_ftStatus != FTNone) {
|
||||
// Check if allowed
|
||||
if (m_ftHostDirection != FTHostRemote) {
|
||||
event->confirmElement(XMPPError::Request);
|
||||
break;
|
||||
}
|
||||
// Check if we already received it
|
||||
if (m_ftStatus != FTIdle) {
|
||||
event->confirmElement(XMPPError::Request);
|
||||
break;
|
||||
}
|
||||
event->setConfirmed();
|
||||
// Remember stanza id
|
||||
m_ftStanzaId = event->id();
|
||||
// Copy hosts from event
|
||||
ListIterator iter(event->m_streamHosts);
|
||||
for (GenObject* o = 0; 0 != (o = iter.get());) {
|
||||
event->m_streamHosts.remove(o,false);
|
||||
m_streamHosts.append(o);
|
||||
}
|
||||
if (!setupSocksFileTransfer(false)) {
|
||||
if (m_ftStanzaId) {
|
||||
m_session->sendStreamHostUsed("",m_ftStanzaId);
|
||||
m_ftStanzaId = "";
|
||||
}
|
||||
if (!setupSocksFileTransfer(false))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
event->confirmElement(XMPPError::Request);
|
||||
break;
|
||||
return processStreamHosts(event);
|
||||
default:
|
||||
Debug(this,DebugNote,
|
||||
"Received unexpected Jingle event (%p) with action=%s [%p]",
|
||||
|
@ -2235,6 +2211,53 @@ void YJGConnection::processActionAccept(JGEvent* event)
|
|||
Engine::enqueue(message("call.answered",false,true));
|
||||
}
|
||||
|
||||
// Handle stream hosts events
|
||||
// Return false if the session was terminated
|
||||
bool YJGConnection::processStreamHosts(JGEvent* ev)
|
||||
{
|
||||
if (!ev)
|
||||
return true;
|
||||
if (m_ftStatus == FTNone) {
|
||||
ev->confirmElement(XMPPError::Request);
|
||||
return true;
|
||||
}
|
||||
// Check if allowed
|
||||
if (m_ftHostDirection != FTHostRemote) {
|
||||
// Check if we can change direction
|
||||
if (!changeFTHostDir(false)) {
|
||||
ev->confirmElement(XMPPError::Request);
|
||||
return true;
|
||||
}
|
||||
// Drop current FT host
|
||||
dropFT(true);
|
||||
// Remove local hosts
|
||||
dropFTHosts(true,"received remote host(s)");
|
||||
m_ftStatus = FTIdle;
|
||||
}
|
||||
// Check if we already received it
|
||||
if (m_ftStatus != FTIdle) {
|
||||
ev->confirmElement(XMPPError::Request);
|
||||
return true;
|
||||
}
|
||||
ev->setConfirmed();
|
||||
// Remember stanza id
|
||||
m_ftStanzaId = ev->id();
|
||||
// Copy hosts from event
|
||||
ObjList* o = ev->m_streamHosts.skipNull();
|
||||
while (o) {
|
||||
m_streamHosts.append(o->get());
|
||||
o->remove(false);
|
||||
o = o->skipNull();
|
||||
}
|
||||
if (setupSocksFileTransfer(false))
|
||||
return true;
|
||||
if (m_ftStanzaId) {
|
||||
m_session->sendStreamHostUsed("",m_ftStanzaId);
|
||||
m_ftStanzaId = "";
|
||||
}
|
||||
return setupSocksFileTransfer(false);
|
||||
}
|
||||
|
||||
// Update a received candidate. Return true if changed
|
||||
bool YJGConnection::updateCandidate(unsigned int component, JGSessionContent& local,
|
||||
JGSessionContent& recv)
|
||||
|
@ -3076,14 +3099,15 @@ bool YJGConnection::setupSocksFileTransfer(bool start)
|
|||
if (Engine::dispatch(m)) {
|
||||
const char* addr = m.getValue("address");
|
||||
int port = m.getIntValue("port");
|
||||
m_ftNotifier = m.getValue("notifier");
|
||||
if (!null(addr) && port > 0) {
|
||||
m_ftNotifier = m.getValue("notifier");
|
||||
m_streamHosts.append(new JGStreamHost(m_local,addr,port));
|
||||
m_streamHosts.append(new JGStreamHost(true,m_local,addr,port));
|
||||
m_ftStatus = FTWaitEstablish;
|
||||
// Send our stream host
|
||||
m_session->sendStreamHosts(m_streamHosts,&m_ftStanzaId);
|
||||
break;
|
||||
}
|
||||
dropFT(true);
|
||||
}
|
||||
error = "chan.socks failed";
|
||||
}
|
||||
|
@ -3095,10 +3119,7 @@ bool YJGConnection::setupSocksFileTransfer(bool start)
|
|||
// Remove the first stream host if status is idle: it failed
|
||||
if (m_ftStatus != FTIdle) {
|
||||
dropFT(false);
|
||||
JGStreamHost* sh = static_cast<JGStreamHost*>(o->get());
|
||||
Debug(this,DebugNote,"Removing failed streamhost '%s:%d' [%p]",
|
||||
sh->m_address.c_str(),sh->m_port,this);
|
||||
o->remove();
|
||||
dropFTHost(0,o,"failed");
|
||||
o = m_streamHosts.skipNull();
|
||||
}
|
||||
|
||||
|
@ -3116,9 +3137,7 @@ bool YJGConnection::setupSocksFileTransfer(bool start)
|
|||
m_ftNotifier = m.getValue("notifier");
|
||||
break;
|
||||
}
|
||||
Debug(this,DebugNote,"Removing failed streamhost '%s:%d' [%p]",
|
||||
sh->m_address.c_str(),sh->m_port,this);
|
||||
o->remove();
|
||||
dropFTHost(sh,o,"failed");
|
||||
o = m_streamHosts.skipNull();
|
||||
}
|
||||
if (o)
|
||||
|
@ -3153,19 +3172,45 @@ void YJGConnection::dropFT(bool removeFirst)
|
|||
if (removeFirst) {
|
||||
// Remove first entry in hosts
|
||||
ObjList* o = m_streamHosts.skipNull();
|
||||
if (o) {
|
||||
JGStreamHost* sh = static_cast<JGStreamHost*>(o->get());
|
||||
Debug(this,DebugAll,"Removing streamhost '%s:%d' [%p]",
|
||||
sh->m_address.c_str(),sh->m_port,this);
|
||||
o->remove();
|
||||
}
|
||||
if (o)
|
||||
dropFTHost(0,o);
|
||||
}
|
||||
m_ftNotifier.clear();
|
||||
clearEndpoint("data");
|
||||
}
|
||||
|
||||
// Drop file transfer hosts
|
||||
void YJGConnection::dropFTHosts(bool local, const char* reason)
|
||||
{
|
||||
for (ObjList* o = m_streamHosts.skipNull(); o;) {
|
||||
JGStreamHost* sh = static_cast<JGStreamHost*>(o->get());
|
||||
if (sh->m_local != local)
|
||||
o = o->skipNext();
|
||||
else {
|
||||
dropFTHost(sh,o,reason);
|
||||
o = o->skipNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Drop file transfer host
|
||||
void YJGConnection::dropFTHost(JGStreamHost* sh, ObjList* remove, const char* reason)
|
||||
{
|
||||
if (!sh && remove)
|
||||
sh = static_cast<JGStreamHost*>(remove->get());
|
||||
if (!sh)
|
||||
return;
|
||||
Debug(this,DebugAll,"Removing %s streamhost '%s:%d' reason='%s' [%p]",
|
||||
sh->m_local ? "local" : "remote",sh->m_address.c_str(),sh->m_port,
|
||||
TelEngine::c_safe(reason),this);
|
||||
if (remove)
|
||||
remove->remove();
|
||||
else
|
||||
TelEngine::destruct(sh);
|
||||
}
|
||||
|
||||
// Change host sender. Return false on failure
|
||||
bool YJGConnection::changeFTHostDir()
|
||||
bool YJGConnection::changeFTHostDir(bool resetState)
|
||||
{
|
||||
// Outgoing: we've sent hosts, allow remote to sent hosts
|
||||
// Incoming: remote sent hosts, allow us to send hosts
|
||||
|
@ -3176,6 +3221,8 @@ bool YJGConnection::changeFTHostDir()
|
|||
fromLocal ? "local" : "remote",this);
|
||||
return true;
|
||||
}
|
||||
if (!resetState)
|
||||
return false;
|
||||
if (m_ftHostDirection != FTHostNone)
|
||||
Debug(this,DebugNote,"No more hosts available [%p]",this);
|
||||
m_ftHostDirection = FTHostNone;
|
||||
|
@ -3956,7 +4003,7 @@ void YJGDriver::initialize()
|
|||
const char* ftAddr = sect->getValue("socks_proxy_ip");
|
||||
int ftPort = sect->getIntValue("socks_proxy_port",-1);
|
||||
if (!(null(ftAddr) || ftPort < 1))
|
||||
m_ftProxy = new JGStreamHost(ftJid,ftAddr,ftPort);
|
||||
m_ftProxy = new JGStreamHost(true,ftJid,ftAddr,ftPort);
|
||||
else
|
||||
Debug(this,DebugNote,
|
||||
"Invalid addr/port (%s:%s) for default file transfer proxy",
|
||||
|
|
Loading…
Reference in New Issue