OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
xmpp_client.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "xmpp/xmpp_client.h"
6 
7 #include <boost/foreach.hpp>
8 #include <boost/tuple/tuple.hpp>
9 
10 #include "base/task_annotations.h"
11 #include "xmpp/xmpp_factory.h"
12 #include "xmpp/xmpp_log.h"
13 #include "xmpp/xmpp_session.h"
14 
15 #include "sandesh/common/vns_types.h"
16 #include "sandesh/common/vns_constants.h"
17 #include "sandesh/xmpp_client_server_sandesh_types.h"
18 
19 using namespace std;
20 using namespace boost::asio;
21 using boost::tie;
22 
24 public:
26  : LifetimeActor(client->lifetime_manager()), client_(client) { }
27  virtual bool MayDelete() const {
28  CHECK_CONCURRENCY("bgp::Config");
29  return (client_->GetSessionQueueSize() == 0);
30  }
31  virtual void Shutdown() {
32  CHECK_CONCURRENCY("bgp::Config");
33  }
34  virtual void Destroy() {
35  CHECK_CONCURRENCY("bgp::Config");
36  }
37 
38 private:
40 };
41 
43  : XmppConnectionManager(evm, ssl::context::sslv23_client, false, false),
44  config_mgr_(new XmppConfigManager),
45  lifetime_manager_(new LifetimeManager(
46  TaskScheduler::GetInstance()->GetTaskId("bgp::Config"))),
47  deleter_(new DeleteActor(this)),
48  auth_enabled_(false),
49  tcp_hold_time_(XmppChannelConfig::kTcpHoldTime) {
50 }
51 
54  evm, ssl::context::sslv23_client, config->auth_enabled, true),
55  config_mgr_(new XmppConfigManager),
56  lifetime_manager_(new LifetimeManager(
57  TaskScheduler::GetInstance()->GetTaskId("bgp::Config"))),
58  deleter_(new DeleteActor(this)),
59  auth_enabled_(config->auth_enabled),
60  tcp_hold_time_(config->tcp_hold_time) {
61 
62  if (config->auth_enabled) {
63 
64  // Get SSL context from base class and update
65  boost::asio::ssl::context *ctx = context();
66  boost::system::error_code ec;
67 
68  //set mode
69  ctx->set_options(ssl::context::default_workarounds |
70  ssl::context::no_sslv3 | ssl::context::no_sslv2 | ssl::context::no_tlsv1, ec);
71  if (ec.value() != 0) {
72  LOG(ERROR, "Error : " << ec.message() << ", setting ssl options");
73  exit(EINVAL);
74  }
75 
76  // CA certificate, used to verify if the peer certificate
77  // is signed by a trusted CA
78  std::string ca_cert_filename = config->path_to_ca_cert;
79  if (!ca_cert_filename.empty()) {
80 
81  // Verify peer has CA signed certificate
82  ctx->set_verify_mode(boost::asio::ssl::verify_peer, ec);
83  if (ec.value() != 0) {
84  LOG(ERROR, "Error : " << ec.message()
85  << ", while setting ssl verification mode");
86  exit(EINVAL);
87  }
88 
89  ctx->load_verify_file(config->path_to_ca_cert, ec);
90  if (ec.value() != 0) {
91  LOG(ERROR, "Error : " << ec.message()
92  << ", while using cacert file : "
93  << config->path_to_ca_cert);
94  exit(EINVAL);
95  }
96  }
97 
98  // server certificate
99  ctx->use_certificate_chain_file(config->path_to_server_cert, ec);
100  if (ec.value() != 0) {
101  LOG(ERROR, "Error : " << ec.message() <<
102  ", while using server cert file : "
103  << config->path_to_server_cert);
104  exit(EINVAL);
105  }
106 
107  // server private key
108  ctx->use_private_key_file(config->path_to_server_priv_key,
109  boost::asio::ssl::context::pem, ec);
110  if (ec.value() != 0) {
111  LOG(ERROR, "Error : " << ec.message()
112  << ", while using privkey file : "
113  << config->path_to_server_priv_key);
114  exit(EINVAL);
115  }
116  }
117 }
118 
120 }
121 
122 bool XmppClient::Initialize(short port) {
123  TcpServer::Initialize(port);
124  return true;
125 }
126 
128  return deleter_.get();
129 }
130 
132  return lifetime_manager_.get();
133 }
134 
137  SOL_SOCKET, SO_REUSEADDR> reuse_addr_t;
138 
140  Socket *socket = session->socket();
141 
142  boost::system::error_code err;
143  socket->open(ip::tcp::v4(), err);
144  if (err) {
145  XMPP_WARNING(ClientOpenFail, session->ToUVEKey(), XMPP_PEER_DIR_OUT,
146  err.message());
147  DeleteSession(session);
148  return NULL;
149  }
150 
151  socket->set_option(reuse_addr_t(true), err);
152  if (err) {
153  XMPP_WARNING(SetSockOptFail, session->ToUVEKey(), XMPP_PEER_DIR_OUT,
154  err.message());
155  return session;
156  }
157 
158  err = session->SetSocketOptions();
159  if (err) {
160  DeleteSession(session);
161  assert(0);
162  }
163 
164  return session;
165 }
166 
169  deleter_->Delete();
170 }
171 
172 void
174  const XmppChannelConfig *current, const XmppChannelConfig *future) {
175  if (delta == XmppConfigManager::DF_ADD) {
176  XmppClientConnection *connection = CreateConnection(future);
177  connection->Initialize(); // trigger state-machine
178  }
179  if (delta == XmppConfigManager::DF_DELETE) {
180  ConnectionMap::iterator loc = connection_map_.find(current->endpoint);
181  if (loc != connection_map_.end()) {
182  loc->second->ManagedDelete();
183  }
184  }
185 }
186 
187 void
189  config_mgr_->SetFuture(cfg);
190  config_mgr_->PeerConfigDiff(
191  boost::bind(&XmppClient::ProcessConfigUpdate, this, _1, _2, _3));
192  config_mgr_->AcceptFuture();
193 }
194 
196  ConnectionEventCb cb) {
197  tbb::mutex::scoped_lock lock(connection_event_map_mutex_);
198  connection_event_map_.insert(make_pair(id, cb));
199 }
200 
202  tbb::mutex::scoped_lock lock(connection_event_map_mutex_);
203  ConnectionEventCbMap::iterator it = connection_event_map_.find(id);
204  if (it != connection_event_map_.end())
205  connection_event_map_.erase(it);
206 }
207 
209  xmps::PeerState state) {
210  tbb::mutex::scoped_lock lock(connection_event_map_mutex_);
211  ConnectionEventCbMap::iterator iter = connection_event_map_.begin();
212  for (; iter != connection_event_map_.end(); ++iter) {
213  ConnectionEventCb cb = iter->second;
214  cb(mux, state);
215  }
216 }
217 
219  return connection_event_map_.size();
220 }
221 
223  return connection_map_.size();
224 }
225 
227  SslSession *session = new XmppSession(this, socket);
228  return session;
229 }
230 
232  for (auto& value : connection_map_) {
233  if (value.second->ToString() == address)
234  return value.second;
235  }
236  return NULL;
237 }
238 
240  const XmppChannelConfig *config) {
241  XmppClientConnection *connection =
242  XmppStaticObjectFactory::Create<XmppClientConnection>(this, config);
243  Endpoint endpoint = connection->endpoint();
244  ConnectionMap::iterator loc;
245  bool result;
246  tie(loc, result) = connection_map_.insert(make_pair(endpoint, connection));
247  assert(result);
248 
249  return connection;
250 }
251 
253  assert(!connection->IsDeleted());
254  Endpoint endpoint = connection->endpoint();
255  ConnectionMap::iterator loc;
256  bool result;
257  tie(loc, result) = connection_map_.insert(make_pair(endpoint, connection));
258  assert(result);
259 }
260 
262  assert(connection->IsDeleted());
263  Endpoint endpoint = connection->endpoint();
264  ConnectionMap::iterator loc = connection_map_.find(endpoint);
265  assert(loc != connection_map_.end() && loc->second == connection);
266  connection_map_.erase(loc);
267 }
268 
269 XmppChannel *XmppClient::FindChannel(const string &address) {
270  XmppClientConnection *connection = FindConnection(address);
271  return (connection ? connection->ChannelMux() : NULL);
272 }
273 
274 int XmppClient::SetDscpValue(uint8_t value, const char *conn_id) {
275  XmppClientConnection *connection = FindConnection(conn_id);
276  if (connection) {
277  return connection->SetDscpValue(value);
278  }
279  return 0;
280 }
281 
282 void XmppClient::UpdateTimeOut(uint8_t time_out, const char *conn_id) {
283  XmppClientConnection *connection = FindConnection(conn_id);
284  if (connection) {
285  return connection->UpdateKeepAliveTimer(time_out);
286  }
287 }
288 
289 uint32_t XmppClient::XmppTimeOut(const char *conn_id) {
290  XmppClientConnection *connection = FindConnection(conn_id);
291  if (connection) {
292  return connection->state_machine()->hold_time();
293  }
294  return 0;
295 }
296 
boost::asio::ip::tcp::endpoint endpoint
Definition: xmpp_config.h:24
virtual SslSession * AllocSession(SslSocket *socket)
Definition: xmpp_client.cc:226
int SetDscpValue(uint8_t value, const char *conn_id)
Definition: xmpp_client.cc:274
LifetimeManager * lifetime_manager()
Definition: xmpp_client.cc:131
void InsertConnection(XmppClientConnection *connection)
Definition: xmpp_client.cc:252
boost::function< void(XmppChannelMux *, xmps::PeerState)> ConnectionEventCb
Definition: xmpp_client.h:33
XmppClientConnection * FindConnection(const std::string &address)
Definition: xmpp_client.cc:231
virtual void DeleteSession(TcpSession *session)
Definition: tcp_server.cc:197
virtual TcpSession * CreateSession()
Definition: xmpp_client.cc:135
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
boost::asio::ip::tcp::socket Socket
Definition: tcp_server.h:31
virtual boost::asio::ip::tcp::endpoint endpoint() const
void UpdateKeepAliveTimer(uint8_t time_out)
XmppClient(EventManager *evm)
Definition: xmpp_client.cc:42
boost::scoped_ptr< XmppConfigManager > config_mgr_
Definition: xmpp_client.h:77
virtual TcpSession * CreateSession()
Definition: tcp_server.cc:188
uint32_t XmppTimeOut(const char *conn_id)
Definition: xmpp_client.cc:289
boost::asio::ssl::context * context()
Definition: ssl_server.cc:41
#define XMPP_PEER_DIR_OUT
Definition: xmpp_log.h:14
XmppClientConnection * CreateConnection(const XmppChannelConfig *config)
Definition: xmpp_client.cc:239
unsigned int boolean
Definition: mcast_common.h:11
std::string path_to_ca_cert
Definition: xmpp_config.h:30
size_t ConnectionCount() const
Definition: xmpp_client.cc:222
bool IsDeleted() const
void ConfigUpdate(const XmppConfigData *cfg)
Definition: xmpp_client.cc:188
tbb::mutex connection_event_map_mutex_
Definition: xmpp_client.h:75
boost::asio::ssl::stream< boost::asio::ip::tcp::socket > SslSocket
Definition: ssl_server.h:16
void RemoveConnection(XmppClientConnection *connection)
Definition: xmpp_client.cc:261
void ProcessConfigUpdate(XmppConfigManager::DiffType delta, const XmppChannelConfig *current, const XmppChannelConfig *future)
Definition: xmpp_client.cc:173
#define CHECK_CONCURRENCY(...)
int SetDscpValue(uint8_t value)
virtual ~XmppClient()
Definition: xmpp_client.cc:119
void UnRegisterConnectionEvent(xmps::PeerId)
Definition: xmpp_client.cc:201
std::string path_to_server_cert
Definition: xmpp_config.h:28
ConnectionEventCbMap connection_event_map_
Definition: xmpp_client.h:74
int hold_time() const
ConnectionMap connection_map_
Definition: xmpp_client.h:73
XmppChannelMux * ChannelMux()
XmppChannel * FindChannel(const std::string &address)
Definition: xmpp_client.cc:269
boost::scoped_ptr< LifetimeManager > lifetime_manager_
Definition: xmpp_client.h:78
virtual void Shutdown()
Definition: xmpp_client.cc:31
boost::asio::ip::tcp::endpoint Endpoint
Definition: xmpp_client.h:24
virtual bool MayDelete() const
Definition: xmpp_client.cc:27
const std::string & ToUVEKey() const
Definition: tcp_session.h:178
size_t ConnectionEventCount() const
Definition: xmpp_client.cc:218
boost::scoped_ptr< DeleteActor > deleter_
Definition: xmpp_client.h:79
void RegisterConnectionEvent(xmps::PeerId, ConnectionEventCb)
Definition: xmpp_client.cc:195
#define LOG(_Level, _Msg)
Definition: logging.h:33
virtual bool Initialize(unsigned short port)
Definition: tcp_server.cc:59
void NotifyConnectionEvent(XmppChannelMux *, xmps::PeerState)
Definition: xmpp_client.cc:208
XmppStateMachine * state_machine()
virtual Socket * socket() const
Definition: tcp_session.h:86
virtual void Destroy()
Definition: xmpp_client.cc:34
void UpdateTimeOut(uint8_t time_out, const char *conn_id)
Definition: xmpp_client.cc:282
void Shutdown()
Definition: xmpp_client.cc:167
DeleteActor(XmppClient *client)
Definition: xmpp_client.cc:25
std::string path_to_server_priv_key
Definition: xmpp_config.h:29
virtual bool Initialize(short port)
Definition: xmpp_client.cc:122
virtual boost::system::error_code SetSocketOptions()
Definition: tcp_session.cc:868
virtual LifetimeActor * deleter()
Definition: xmpp_client.cc:127
static EventManager evm
#define XMPP_WARNING(obj,...)
Definition: xmpp_log.h:35