glooxd  0.3-svn
router.cpp
1 /*
2  Copyright (c) 2008-2009 by Jakob Schroeter <js@camaya.net>
3  This file is part of the glooxd library. http://camaya.net/glooxd
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 #include "configmanager.h"
15 #include "c2s.h"
16 #include "glooxd.h"
17 #include "router.h"
18 
19 #include <gloox/error.h>
20 #include <gloox/gloox.h>
21 #include <gloox/iq.h>
22 #include <gloox/logsink.h>
23 #include <gloox/message.h>
24 #include <gloox/presence.h>
25 #include <gloox/taghandler.h>
26 #include <gloox/util.h>
27 
28 #include <cstdio>
29 
30 namespace glooxd
31 {
32 
33  Router::Router( ConfigManager& cm, const gloox::LogSink& logInstance, bool threading )
34  : m_cm( cm ), m_logInstance( logInstance ), m_threading( threading )
35  {
36  m_cm.registerConfigHandler( this );
37  }
38 
40  {
41  gloox::util::clearList( m_queue );
42  }
43 
44  void Router::run()
45  {
46  if( !m_threading && !m_queue.size() )
47  return;
48 
49  do
50  {
51  m_queueSemaphore.wait();
52  gloox::Tag* t = m_queue.front();
53  m_queueMutex.lock();
54  m_queue.pop_front();
55  m_queueMutex.unlock();
56  handleTag( t );
57  } while( m_threading );
58  }
59 
61  {
62  m_threading = false;
63  m_queueMutex.lock();
64  m_queue.push_back( 0 );
65  m_queueMutex.unlock();
66  }
67 
68  void Router::registerDomain( TagHandler* th, const std::string& domain, bool node )
69  {
70  if( node )
71  {
72  m_logInstance.dbg( static_cast<gloox::LogArea>( LogAreaRouter ),
73  "Registered target for " + domain + ", for user traffic" );
74  gloox::util::MutexGuard mg(m_userRoutingMutex );
75  m_userRouting.insert( std::make_pair( domain, th ) );
76  }
77  else
78  {
79  m_logInstance.dbg( static_cast<gloox::LogArea>( LogAreaRouter ),
80  "Registered target for " + domain + ", for domain traffic" );
81  gloox::util::MutexGuard mg(m_domainRoutingMutex );
82  m_domainRouting.insert( std::make_pair( domain, th ) );
83  }
84  }
85 
86  bool Router::isLocal( const std::string& /*domain*/ )
87  {
88  // FIXME check with DomainManager!
89  return true;
90  }
91 
92  void Router::removeDomain( TagHandler* /*th*/, const std::string& domain, bool node )
93  {
94  if( node )
95  {
96  gloox::util::MutexGuard mg(m_userRoutingMutex );
97  RoutingTable::iterator it = m_userRouting.find( domain );
98  if( it !=m_userRouting.end() )
99  {
100  m_userRouting.erase( it );
101  m_logInstance.dbg( static_cast<gloox::LogArea>( LogAreaRouter ),
102  "Removed target for " + domain + ", for user traffic" );
103  }
104  }
105  else
106  {
107  gloox::util::MutexGuard mg(m_domainRoutingMutex );
108  RoutingTable::iterator it = m_domainRouting.find( domain );
109  if( it != m_domainRouting.end() )
110  {
111  m_domainRouting.erase( it );
112  m_logInstance.dbg( static_cast<gloox::LogArea>( LogAreaRouter ),
113  "Removed target for " + domain + ", for domain traffic" );
114  }
115  }
116  }
117 
118  void Router::handleIncomingTag( gloox::Tag* tag )
119  {
120  if( !tag )
121  return;
122 
123  m_queueMutex.lock();
124  m_queue.push_back( tag );
125  m_queueMutex.unlock();
126  m_queueSemaphore.post();
127  }
128 
129  void Router::handleTag( gloox::Tag* tag )
130  {
131  if( !tag )
132  return;
133 
134 #ifdef DEBUG
135  printf( "!!!!!Router::handleTag(): %s\n", tag->xml().c_str() );
136 #endif
137  const gloox::JID to( tag->findAttribute( "to" ) );
138 
139  if( !to )
140  routeBySender( tag );
141  else if( isLocal( to.server() ) )
142  routeByReceipient( tag );
143  else
144  {
145  gloox::Tag* t = returnError( tag, gloox::StanzaErrorRemoteServerNotFound );
146  handleIncomingTag( t );
147  delete tag;
148  }
149  }
150 
151  void Router::routeBySender( gloox::Tag* tag )
152  {
153  if( !tag )
154  return;
155 #ifdef DEBUG
156  printf( "!!!!!Router::routeBySender(): %s\n", tag->xml().c_str() );
157 #endif
158 
159  const gloox::JID from( tag->findAttribute( "from" ) );
160 
161  gloox::util::MutexGuard mg( m_domainRoutingMutex );
162  RoutingTable::const_iterator it = m_domainRouting.find( from.server() );
163  if( it == m_domainRouting.end() )
164  {
165  delete tag;
166  return;
167  }
168 
169 #ifdef DEBUG
170  printf( "!!!!!found domain destination by 'from'\n" );
171 #endif
172  (*it).second->handleIncomingTag( tag );
173  }
174 
175  void Router::routeByReceipient( gloox::Tag* tag )
176  {
177  if( !tag )
178  return;
179 
180 #ifdef DEBUG
181  printf( "!!!!!Router::routeByReceipient(): %s\n", tag->xml().c_str() );
182 #endif
183  const gloox::JID to( tag->findAttribute( "to" ) );
184 // const std::string& name = tag->name();
185 
186  if( to.username().empty() || to.resource().empty() )
187  {
188  gloox::util::MutexGuard mg( m_domainRoutingMutex );
189  RoutingTable::const_iterator it = m_domainRouting.find( to.server() );
190  if( it != m_domainRouting.end() )
191  {
192 #ifdef DEBUG
193  printf( "!!!!!found domain destination by 'to'\n" );
194 #endif
195  (*it).second->handleIncomingTag( tag );
196  return;
197  }
198  }
199  else
200  {
201  gloox::util::MutexGuard mg( m_userRoutingMutex );
202  RoutingTable::const_iterator it = m_userRouting.find( to.server() );
203  if( it != m_userRouting.end() )
204  {
205 #ifdef DEBUG
206  printf( "!!!!!found user destination by 'to'\n" );
207 #endif
208  (*it).second->handleOutgoingTag( tag );
209  return;
210  }
211  }
212 
213  gloox::Tag* t = returnError( tag, gloox::StanzaErrorRemoteServerNotFound );
214  handleIncomingTag( t );
215  delete tag;
216  }
217 
218 }