14 #include "bytestreamhandler.h"
15 #include "socks5bytestreammanager.h"
16 #include "socks5bytestreamserver.h"
17 #include "socks5bytestream.h"
18 #include "clientbase.h"
21 #include "connectionbase.h"
31 static const char* s5bModeValues[] =
38 return s5bModeValues[mode];
41 SOCKS5BytestreamManager::Query::Query()
46 SOCKS5BytestreamManager::Query::Query(
const std::string& sid, S5BMode mode,
47 const StreamHostList& hosts )
48 : StanzaExtension(
ExtS5BQuery ), m_sid( sid ), m_mode( mode ), m_hosts( hosts ), m_type( TypeSH )
52 SOCKS5BytestreamManager::Query::Query(
const JID& jid,
const std::string& sid,
bool activate )
53 : StanzaExtension(
ExtS5BQuery ), m_sid( sid ), m_jid( jid ), m_type( activate ? TypeA : TypeSHU )
57 SOCKS5BytestreamManager::Query::Query(
const Tag* tag )
60 if( !tag || tag->name() !=
"query" || tag->xmlns() != XMLNS_BYTESTREAMS
64 m_sid = tag->findAttribute(
"sid" );
65 m_mode =
static_cast<S5BMode
>( util::deflookup( tag->findAttribute(
"mode" ), s5bModeValues, S5BTCP ) );
67 const TagList& l = tag->children();
68 TagList::const_iterator it = l.begin();
69 for( ; it != l.end(); ++it )
71 if( (*it)->name() ==
"streamhost" && (*it)->hasAttribute(
"jid" )
72 && (*it)->hasAttribute(
"host" ) && (*it)->hasAttribute(
"port" ) )
76 sh.jid = (*it)->findAttribute(
"jid" );
77 sh.host = (*it)->findAttribute(
"host" );
78 sh.port = atoi( (*it)->findAttribute(
"port" ).c_str() );
79 m_hosts.push_back( sh );
81 else if( (*it)->name() ==
"streamhost-used" )
84 m_jid = (*it)->findAttribute(
"jid" );
86 else if( (*it)->name() ==
"activate" )
89 m_jid = (*it)->cdata();
94 SOCKS5BytestreamManager::Query::~Query()
98 const std::string& SOCKS5BytestreamManager::Query::filterString()
const
100 static const std::string filter =
"/iq/query[@xmlns='" +
XMLNS_BYTESTREAMS +
"']";
104 Tag* SOCKS5BytestreamManager::Query::tag()
const
106 if( m_type == TypeInvalid )
109 Tag* t =
new Tag(
"query" );
110 t->setXmlns( XMLNS_BYTESTREAMS );
111 t->addAttribute(
"sid", m_sid );
116 t->addAttribute(
"mode", util::deflookup( m_mode, s5bModeValues,
"tcp" ) );
117 StreamHostList::const_iterator it = m_hosts.begin();
118 for( ; it != m_hosts.end(); ++it )
120 Tag* s =
new Tag( t,
"streamhost" );
121 s->addAttribute(
"jid", (*it).jid.full() );
122 s->addAttribute(
"host", (*it).host );
123 s->addAttribute(
"port", (*it).port );
129 Tag* s =
new Tag( t,
"streamhost-used" );
130 s->addAttribute(
"jid", m_jid.full() );
135 Tag* c =
new Tag( t,
"activate" );
136 c->setCData( m_jid.full() );
149 : m_parent( parent ), m_socks5BytestreamHandler( s5bh ), m_server( 0 )
175 m_hosts.push_back( sh );
179 const std::string& sid,
185 "No parent (ClientBase) set, cannot request bytestream." );
189 if( m_hosts.empty() )
192 "No stream hosts set, cannot request bytestream." );
196 const std::string& msid = sid.empty() ? m_parent->
getID() : sid;
197 const std::string&
id = m_parent->
getID();
212 m_server->registerHash( sha.
hex() );
216 asi.sHosts = m_hosts;
219 asi.to = from ? from : m_parent->
jid();
220 asi.incoming =
false;
221 m_asyncTrackMap[msid] = asi;
223 m_trackMap[id] = msid;
224 m_parent->
send( iq,
this, S5BOpenStream );
229 void SOCKS5BytestreamManager::acknowledgeStreamHost(
bool success,
const JID& jid,
230 const std::string& sid )
232 AsyncTrackMap::const_iterator it = m_asyncTrackMap.find( sid );
233 if( it == m_asyncTrackMap.end() || !m_parent )
236 const AsyncS5BItem& item = (*it).second;
251 m_parent->
send( *iq );
257 const std::string&
id = m_parent->
getID();
261 m_trackMap[id] = sid;
262 m_parent->
send( *iq,
this, S5BActivateStream );
272 if( !q || !m_socks5BytestreamHandler
273 || m_trackMap.find( iq.
id() ) != m_trackMap.end() )
280 const std::string& sid = q->sid();
282 if( sid.empty() || q->mode() ==
S5BUDP )
288 asi.sHosts = q->hosts();
290 asi.from = iq.
from();
293 m_asyncTrackMap[sid] = asi;
307 const StreamHost* SOCKS5BytestreamManager::findProxy(
const JID& from,
const std::string& hostjid,
308 const std::string& sid )
310 AsyncTrackMap::const_iterator it = m_asyncTrackMap.find( sid );
311 if( it == m_asyncTrackMap.end() )
314 if( (*it).second.from == from )
316 StreamHostList::const_iterator it2 = (*it).second.sHosts.begin();
317 for( ; it2 != (*it).second.sHosts.end(); ++it2 )
319 if( (*it2).jid == hostjid )
329 bool SOCKS5BytestreamManager::haveStream(
const JID& from )
331 S5BMap::const_iterator it = m_s5bMap.begin();
332 for( ; it != m_s5bMap.end(); ++it )
334 if( (*it).second && (*it).second->target() == from )
342 AsyncTrackMap::iterator it = m_asyncTrackMap.find( sid );
343 if( it == m_asyncTrackMap.end() || !m_socks5BytestreamHandler )
348 (*it).second.from, (*it).second.to, sid );
356 AsyncTrackMap::iterator it = m_asyncTrackMap.find( sid );
357 if( it != m_asyncTrackMap.end() )
360 m_asyncTrackMap.erase( it );
365 const std::string&
id,
387 m_parent->
send( iq );
392 StringMap::iterator it = m_trackMap.find( iq.
id() );
393 if( it == m_trackMap.end() )
405 if( q && m_socks5BytestreamHandler )
407 const std::string& proxy = q->jid().full();
408 const StreamHost* sh = findProxy( iq.
from(), proxy, (*it).second );
412 bool selfProxy = ( proxy == m_parent->
jid().
full() && m_server );
416 sha.
feed( (*it).second );
432 m_s5bMap[(*it).second] = s5b;
448 case S5BActivateStream:
454 S5BMap::const_iterator it5 = m_s5bMap.find( (*it).second );
455 if( it5 != m_s5bMap.end() )
456 (*it5).second->activate();
470 m_trackMap.erase( it );
475 S5BMap::iterator it = m_s5bMap.find( s5b->
sid() );
476 if( it != m_s5bMap.end() )
479 m_s5bMap.erase( it );
A virtual interface that allows to receive new incoming Bytestream requests from remote entities.
virtual void handleIncomingBytestream(Bytestream *bs)=0
virtual void handleBytestreamError(const IQ &iq, const std::string &sid)=0
virtual void handleOutgoingBytestream(Bytestream *bs)=0
virtual void handleIncomingBytestreamRequest(const std::string &sid, const JID &from)=0
const std::string & sid() const
This is the common base class for a Jabber/XMPP Client and a Jabber Component.
const std::string getID()
void removeIqHandler(IqHandler *ih, int exttype)
void removeIDHandler(IqHandler *ih)
void registerIqHandler(IqHandler *ih, int exttype)
ConnectionBase * connectionImpl() const
void registerStanzaExtension(StanzaExtension *ext)
virtual ConnectionBase * newInstance() const =0
A stanza error abstraction implemented as a StanzaExtension.
An abstraction of an IQ stanza.
const std::string & full() const
void warn(LogArea area, const std::string &message) const
An implementation of SHA1.
void feed(const unsigned char *data, unsigned length)
virtual ~SOCKS5BytestreamManager()
virtual void handleIqID(const IQ &iq, int context)
virtual bool handleIq(const IQ &iq)
void addStreamHost(const JID &jid, const std::string &host, int port)
void rejectSOCKS5Bytestream(const std::string &sid, StanzaError reason=StanzaErrorNotAcceptable)
bool requestSOCKS5Bytestream(const JID &to, S5BMode mode, const std::string &sid=EmptyString, const JID &from=JID())
bool dispose(SOCKS5Bytestream *s5b)
void acceptSOCKS5Bytestream(const std::string &sid)
An implementation of a single SOCKS5 Bytestream (XEP-0065).
void setStreamHosts(const StreamHostList &hosts)
void addExtension(const StanzaExtension *se)
void setFrom(const JID &from)
const std::string & id() const
const StanzaExtension * findExtension(int type) const
void clearMap(std::map< Key, T * > &M)
The namespace for the gloox library.
std::list< Tag * > TagList
const std::string EmptyString
@ StanzaErrorItemNotFound
@ StanzaErrorFeatureNotImplemented
@ StanzaErrorNotAcceptable
std::list< StreamHost > StreamHostList
const std::string XMLNS_BYTESTREAMS