15 #include "configmanager.h"
17 #include "streambase.h"
18 #include "streamfeature.h"
21 #include <gloox/connectiontcpserver.h>
22 #include <gloox/connectionbase.h>
23 #include <gloox/jid.h>
24 #include <gloox/logsink.h>
25 #include <gloox/mutexguard.h>
26 #include <gloox/util.h>
29 #ifndef WIN32_LEAN_AND_MEAN
30 #define WIN32_LEAN_AND_MEAN
43 SM& _sm,
bool threading,
44 const gloox::JID& _name )
46 m_sm( _sm ), m_threading( threading ), m_strictXMPP( true ), m_running( true ),
47 m_supportRecipientUnavailable( true )
56 gloox::util::clearList( m_servers );
57 gloox::util::clearList( m_clients );
59 printf(
"m_obsoleteClients.size(): %d\n", m_obsoleteClients.size() );
60 gloox::util::clearList( m_features );
61 gloox::util::clearList( m_queue );
68 if( m_queueSemaphore.
trywait() )
70 gloox::Tag* t = m_queue.front();
73 m_queueMutex.unlock();
77 }
while( m_threading );
80 void C2S::handleShutdown()
83 gloox::util::ForEach( m_servers, &gloox::ConnectionTCPServer::disconnect );
84 m_serverMutex.unlock();
86 gloox::ConnectionError ce = gloox::ConnNoError;
87 gloox::StreamError se = gloox::StreamErrorSystemShutdown;
90 m_clientMutex.unlock();
95 m_queue.push_back( 0 );
96 m_queueMutex.unlock();
99 gloox::ConnectionError C2S::recv(
int timeout )
101 if( !m_clients.size() && !m_servers.size() )
104 ::Sleep( timeout / 1000 );
108 return gloox::ConnNoError;
112 m_serverMutex.lock();
113 ServerList::const_iterator its = m_servers.begin();
114 for( ; its != m_servers.end(); ++its )
115 (*its)->recv( timeout );
117 m_serverMutex.unlock();
121 m_clientMutex.lock();
122 StreamBaseList::const_iterator itc = m_clients.begin();
123 for( ; itc != m_clients.end(); ++itc )
125 (*itc)->recv( timeout );
130 m_obsoleteClientMutex.lock();
132 itc = m_obsoleteClients.begin();
133 for( ; itc != m_obsoleteClients.end(); ++itc )
134 m_clients.remove( (*itc) );
136 m_clientMutex.unlock();
139 gloox::util::clearList( m_obsoleteClients );
140 m_obsoleteClientMutex.unlock();
143 return gloox::ConnNoError;
146 gloox::ConnectionError C2S::receive()
148 gloox::ConnectionError ce = gloox::ConnNoError;
149 while( ce == gloox::ConnNoError )
155 bool C2S::handleC2SInterfaceAdded(
const std::string& interface,
161 ServerList::iterator it = m_servers.begin();
162 for( ; it != m_servers.end()
163 && ( (*it)->server() != gloox::EmptyString || (*it)->port() != port )
164 && ( (*it)->server() !=
interface || (*it)->port() != port ); ++it )
167 if( it == m_servers.end() )
170 gloox::ConnectionTCPServer* s =
new gloox::ConnectionTCPServer(
this,
m_logInstance, interface, port );
171 if( s->connect() != gloox::ConnNoError )
174 "Failed to listen on "
175 + ( interface.empty() ?
"*" : interface ) +
":"
176 + gloox::util::int2string( port ) );
183 "Listening on " + ( interface.empty() ?
"*" : interface ) +
":"
184 + gloox::util::int2string( port ) );
187 printf(
"handleC2SInterfaceAdded 1: locking\n" );
189 m_serverMutex.lock();
190 m_servers.push_back( s );
191 m_serverMutex.unlock();
193 printf(
"handleC2SInterfaceAdded 1: unlocked\n" );
200 "Already listening on " + ( interface.empty() ?
"*" : interface ) +
":"
201 + gloox::util::int2string( port ) );
204 if( m_servers.size() == 1 )
210 void C2S::handleDomainAdded(
const std::string& domain )
218 void C2S::handleDomainRemoved(
const std::string& domain )
223 m_router.removeDomain(
this, domain,
true );
226 bool C2S::handleC2SInterfaceRemoved(
const std::string& interface,
229 gloox::util::MutexGuard mg( m_serverMutex );
230 ServerList::iterator it = m_servers.begin();
231 for( ; it != m_servers.end(); ++it )
233 if( (*it)->server() ==
interface && (*it)->port() == port )
236 m_servers.erase( it );
237 if( !m_servers.size() )
247 void C2S::disconnect( StreamBase* client )
255 printf(
"making client obsolete: %s\n", client->jid().full().c_str() );
256 printf(
"disconnect: obsolete client locking\n" );
258 gloox::util::MutexGuard mg( m_obsoleteClientMutex );
260 printf(
"disconnect: obsolete client locked\n" );
262 m_obsoleteClients.push_back( client );
265 void C2S::handleIncomingConnection( gloox::ConnectionBase* ,
266 gloox::ConnectionBase* connection )
272 "Incoming connection from "
273 + connection->server() +
":"
274 + gloox::util::int2string( connection->port() ) );
277 client->setStrictXMPP( m_strictXMPP );
279 FeatureList::const_iterator it = m_features.begin();
280 for( ; it != m_features.end(); ++it )
282 StreamFeature* f = (*it)->newInstance();
283 f->setParent( client );
286 client->setFeatures( fl );
289 printf(
"handleIncomingConnection: client locking\n" );
291 gloox::util::MutexGuard mg( m_clientMutex );
293 printf(
"handleIncomingConnection: client locked\n" );
295 m_clients.push_back( client );
298 void C2S::handleIncomingTag( gloox::Tag* tag )
304 printf(
"C2S::handleIncomingTag()\n" );
305 printf(
"passing to router directly\n" );
310 void C2S::handleOutgoingTag( gloox::Tag* tag )
316 m_queue.push_back( tag );
317 m_queueMutex.unlock();
318 m_queueSemaphore.
post();
321 void C2S::handleTag( gloox::Tag* tag )
327 printf(
"C2S::handleTag()\n" );
330 const gloox::JID& to( tag->findAttribute(
"to" ) );
333 printf(
"handleTag: client locking\n" );
335 gloox::util::MutexGuard mg( m_clientMutex );
337 printf(
"handleTag: client locked\n" );
339 StreamBaseList::const_iterator it = m_clients.begin();
340 for( ; it != m_clients.end(); ++it )
342 if( (*it)->jid().full() == to.full() )
344 (*it)->handleOutgoingTag( tag );
347 else if( (*it)->id() == to.resource() )
349 (*it)->handleIncomingTag( tag );
355 "C2S::handleTag unable to route stanza: "
358 if( m_supportRecipientUnavailable )
365 if( tag->name() ==
"iq" )
369 const gloox::JID& from( tag->findAttribute(
"from" ) );
370 if( !from.full().empty() )
372 StreamBaseList::const_iterator it2 = m_clients.begin();
373 for( ; it2 != m_clients.end(); ++it2 )
375 if( (*it2)->jid().full() == from.full() )
377 gloox::Tag* t =
returnError( tag, gloox::StanzaErrorRecipientUnavailable, gloox::StanzaErrorTypeWait );
378 handleOutgoingTag( t );