OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
xmpp_server.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_server.h"
6 
7 #include <boost/foreach.hpp>
8 #include <boost/tuple/tuple.hpp>
9 
10 #include "base/task_annotations.h"
11 #include "xmpp/xmpp_connection.h"
12 #include "xmpp/xmpp_factory.h"
13 #include "xmpp/xmpp_lifetime.h"
14 #include "xmpp/xmpp_log.h"
15 #include "xmpp/xmpp_sandesh.h"
16 #include "xmpp/xmpp_session.h"
17 
18 #include "sandesh/request_pipeline.h"
19 #include "sandesh/common/vns_types.h"
20 #include "sandesh/common/vns_constants.h"
21 #include "sandesh/xmpp_server_types.h"
22 #include "sandesh/xmpp_trace_sandesh_types.h"
23 #include "sandesh/xmpp_client_server_sandesh_types.h"
24 
25 using namespace std;
26 using namespace boost::asio;
27 using boost::tie;
28 
29 #define DEFAULT_XMPP_HOLD_TIME 90
31 public:
33  : LifetimeActor(server->lifetime_manager()), server_(server) {
34  }
35  virtual bool MayDelete() const {
36  CHECK_CONCURRENCY("bgp::Config");
37  return server_->MayDelete();
38  }
39  virtual void Shutdown() {
40  CHECK_CONCURRENCY("bgp::Config");
41  server_->SessionShutdown();
42  }
43  virtual void Destroy() {
44  CHECK_CONCURRENCY("bgp::Config");
45  server_->Terminate();
46  }
47 
48 private:
50 };
51 
52 
53 XmppServer::XmppServer(EventManager *evm, const string &server_addr,
54  const XmppChannelConfig *config)
56  evm, ssl::context::sslv23_server, config->auth_enabled, true),
57  max_connections_(0),
58  lifetime_manager_(XmppStaticObjectFactory::Create<XmppLifetimeManager>(
59  TaskScheduler::GetInstance()->GetTaskId("bgp::Config"))),
60  deleter_(new DeleteActor(this)),
61  server_addr_(server_addr),
62  log_uve_(false),
63  auth_enabled_(config->auth_enabled),
64  tcp_hold_time_(config->tcp_hold_time),
65  gr_helper_disable_(config->gr_helper_disable),
66  dscp_value_(0),
67  connection_queue_(TaskScheduler::GetInstance()->GetTaskId("bgp::Config"),
68  0, boost::bind(&XmppServer::DequeueConnection, this, _1)) {
69 
70  if (config->auth_enabled) {
71 
72  // Get SSL context from base class and update
73  boost::asio::ssl::context *ctx = context();
74  boost::system::error_code ec;
75 
76  // set mode
77  ctx->set_options(ssl::context::default_workarounds |
78  ssl::context::no_sslv3 | ssl::context::no_sslv2, ec);
79  if (ec.value() != 0) {
80  LOG(ERROR, "Error : " << ec.message() << ", setting ssl options");
81  exit(EINVAL);
82  }
83 
84  // CA certificate, used to verify if the peer certificate
85  // is signed by a trusted CA
86  std::string ca_cert_filename = config->path_to_ca_cert;
87  if (!ca_cert_filename.empty()) {
88 
89  // Verify peer has CA signed certificate
90  ctx->set_verify_mode(boost::asio::ssl::verify_peer, ec);
91  if (ec.value() != 0) {
92  LOG(ERROR, "Error : " << ec.message()
93  << ", while setting ssl verification mode");
94  exit(EINVAL);
95  }
96 
97  ctx->load_verify_file(config->path_to_ca_cert, ec);
98  if (ec.value() != 0) {
99  LOG(ERROR, "Error : " << ec.message()
100  << ", while using cacert file : "
101  << config->path_to_ca_cert);
102  exit(EINVAL);
103  }
104  }
105 
106  // server certificate
107  ctx->use_certificate_file(config->path_to_server_cert,
108  boost::asio::ssl::context::pem, ec);
109  if (ec.value() != 0) {
110  LOG(ERROR, "Error : " << ec.message()
111  << ", while using server cert file : "
112  << config->path_to_server_cert);
113  exit(EINVAL);
114  }
115 
116  // server private key
117  ctx->use_private_key_file(config->path_to_server_priv_key,
118  boost::asio::ssl::context::pem, ec);
119  if (ec.value() != 0) {
120  LOG(ERROR, "Error : " << ec.message()
121  << ", while using privkey file : "
122  << config->path_to_server_priv_key);
123  exit(EINVAL);
124  }
125  }
126 }
127 
129 public:
130  explicit XmppConfigUpdater(XmppServer *server,
131  BgpConfigManager *config_manager) :
132  server_(server) {
135  this, _1, _2);
137  this, _1, _2);
138  config_manager->RegisterObservers(obs);
139  }
140 
141  const BgpGlobalSystemConfig &config() const { return config_; }
142 
143  void ProcessProtocolConfig(const BgpProtocolConfig *protocol_config,
145 
146  if (server_->subcluster_name() != protocol_config->subcluster_name()) {
147  server_->set_subcluster_name(protocol_config->subcluster_name());
148  server_->ClearAllConnections();
149  }
150  }
151 
154  // Clear peers only if GR is or was enabled.
155  bool clear_peers = config_.gr_enable() || system->gr_enable();
156  bool update_peers = false;
157  config_.set_gr_enable(system->gr_enable());
158  config_.set_gr_time(system->gr_time());
159  config_.set_llgr_time(system->llgr_time());
160  config_.set_end_of_rib_timeout(system->end_of_rib_timeout());
161  config_.set_gr_xmpp_helper(system->gr_xmpp_helper());
162 
163  // Process any change in xmpp-hold-time
164  if (config_.fc_enabled() != system->fc_enabled() ||
165  config_.xmpp_hold_time() != system->xmpp_hold_time()) {
166  config_.set_xmpp_hold_time(system->xmpp_hold_time());
167  config_.set_fc_enabled(system->fc_enabled());
168  // if fc_enabled is not set, use default hold time
169  if (!system->fc_enabled())
170  config_.set_xmpp_hold_time(DEFAULT_XMPP_HOLD_TIME);
171  update_peers = true;
172  }
173 
174  // Process any change in rd-cluster-seed knob
175  if (config_.rd_cluster_seed() != system->rd_cluster_seed()) {
176  config_.set_rd_cluster_seed(system->rd_cluster_seed());
177  clear_peers = true;
178  }
179 
180  if (clear_peers)
181  server_->ClearAllConnections();
182  else if (update_peers)
183  server_->UpdateAllConnections(config_.xmpp_hold_time());
184  }
185 
186  const string subcluster_name() const { return server_->subcluster_name(); }
187  void set_subcluster_name(const string& name) {
188  server_->set_subcluster_name(name);
189  }
190 
191  uint8_t xmpp_hold_time() const { return config_.xmpp_hold_time(); }
192  void set_xmpp_hold_time(int hold_time) {
193  config_.set_xmpp_hold_time(hold_time);
194  }
195 
196 private:
199 };
200 
201 XmppServer::XmppServer(EventManager *evm, const string &server_addr)
202  : XmppConnectionManager(evm, ssl::context::sslv23_server, false, false),
203  max_connections_(0),
205  TaskScheduler::GetInstance()->GetTaskId("bgp::Config"))),
206  deleter_(new DeleteActor(this)),
207  server_addr_(server_addr),
208  log_uve_(false),
209  auth_enabled_(false),
210  tcp_hold_time_(XmppChannelConfig::kTcpHoldTime),
211  gr_helper_disable_(false),
212  xmpp_config_updater_(NULL),
213  dscp_value_(0),
214  connection_queue_(TaskScheduler::GetInstance()->GetTaskId("bgp::Config"),
215  0, boost::bind(&XmppServer::DequeueConnection, this, _1)) {
216 }
217 
218 
220  : XmppConnectionManager(evm, ssl::context::sslv23_server, false, false),
221  max_connections_(0),
222  lifetime_manager_(new LifetimeManager(
223  TaskScheduler::GetInstance()->GetTaskId("bgp::Config"))),
224  deleter_(new DeleteActor(this)),
225  log_uve_(false),
226  auth_enabled_(false),
227  tcp_hold_time_(XmppChannelConfig::kTcpHoldTime),
228  gr_helper_disable_(false),
229  dscp_value_(0),
230  connection_queue_(TaskScheduler::GetInstance()->GetTaskId("bgp::Config"),
231  0, boost::bind(&XmppServer::DequeueConnection, this, _1)) {
232 }
233 
235  xmpp_config_updater_.reset(new XmppConfigUpdater(this, config_manager));
236 }
237 
239  // Check if GR is disabled..
240  if (!xmpp_config_updater_ || !xmpp_config_updater_->config().gr_enable())
241  return 0;
242  return xmpp_config_updater_->config().gr_time();
243 }
244 
246  // Check if GR is disabled..
247  if (!xmpp_config_updater_ || !xmpp_config_updater_->config().gr_enable())
248  return 0;
249  return xmpp_config_updater_->config().llgr_time();
250 }
251 
254  return xmpp_config_updater_->config().end_of_rib_timeout();
256 }
257 
260  xmpp_config_updater_->config().end_of_rib_timeout();
262 }
263 
265  // Check if disabled in .conf file.
266  if (gr_helper_disable_)
267  return false;
268 
269  // Check from configuration.
271  return false;
272 
273  // Check if GR is disabled..
274  if (!xmpp_config_updater_->config().gr_enable())
275  return false;
276 
277  return xmpp_config_updater_->config().gr_xmpp_helper();
278 }
279 
281 
282  // If the server is deleted, do not do graceful restart
283  if (deleter()->IsDeleted())
284  return false;
285 
286  // Check if GR helper mode is disabled.
287  if (!IsGRHelperModeEnabled())
288  return false;
289 
290  // Enable GR if either gr-time or llgr-time is configured.
291  return (xmpp_config_updater_->config().gr_time() ||
292  xmpp_config_updater_->config().llgr_time());
293 }
294 
298 }
299 
300 bool XmppServer::Initialize(short port) {
301  log_uve_ = false;
302  return TcpServer::Initialize(port);
303 }
304 
305 bool XmppServer::Initialize(short port, bool logUVE) {
306  log_uve_ = logUVE;
307  return TcpServer::Initialize(port);
308 }
309 
310 bool XmppServer::Initialize(short port, bool logUVE, const IpAddress& ip) {
311  log_uve_ = logUVE;
312  return TcpServer::Initialize(port, ip);
313 }
314 
315 //
316 // Can be removed after Shutdown is renamed to ManagedDelete.
317 //
320 }
321 
322 //
323 // Return true if it's possible to delete the XmppServer.
324 //
325 // No need to check the connection WorkQueue since XmppServerConnections on it
326 // are dependents of the XmppServer.
327 //
328 bool XmppServer::MayDelete() const {
329  return (GetSessionQueueSize() == 0);
330 }
331 
332 //
333 // Trigger deletion of the XmppServer.
334 //
335 // A mutex is used to ensure that we do not create new XmppServerConnections
336 // after this point. Note that this routine and AcceptSession may be called
337 // concurrently from 2 different threads in tests.
338 //
340  tbb::mutex::scoped_lock lock(deletion_mutex_);
341  deleter_->Delete();
342 }
343 
344 //
345 // Called when the XmppServer delete actor is being destroyed.
346 //
348  ClearSessions();
350 }
351 
353  return deleter_.get();
354 }
355 
357  return deleter_.get();
358 }
359 
361  return lifetime_manager_.get();
362 }
363 
366  SOL_SOCKET, SO_REUSEADDR> reuse_addr_t;
368  Socket *socket = session->socket();
369 
370  boost::system::error_code err;
371  socket->open(ip::tcp::v4(), err);
372  if (err) {
373  XMPP_WARNING(ServerOpenFail, err.message());
374  }
375 
376  socket->set_option(reuse_addr_t(true), err);
377  if (err) {
378  XMPP_WARNING(SetSockOptFail, "", XMPP_PEER_DIR_OUT, err.message());
379  }
380 
381  socket->bind(LocalEndpoint(), err);
382  if (err) {
383  XMPP_WARNING(ServerBindFailure, err.message());
384  }
385 
386  XmppSession *xmpps = static_cast<XmppSession *>(session);
387  err = xmpps->EnableTcpKeepalive(tcp_hold_time_);
388  if (err) {
389  XMPP_WARNING(ServerKeepAliveFailure, session->ToUVEKey(),
390  XMPP_PEER_DIR_OUT, err.message());
391  }
392 
393  return session;
394 }
395 
397  return connection_event_map_.size();
398 }
399 
401  tbb::reader_writer_lock::scoped_lock_read lock(connection_map_mutex_);
402  return connection_map_.size();
403 }
404 
406  return ConnectionMapSize() + deleted_connection_set_.size();
407 }
408 
410  tbb::reader_writer_lock::scoped_lock_read lock(connection_map_mutex_);
411  ConnectionMap::iterator loc = connection_map_.find(remote_endpoint);
412  if (loc != connection_map_.end()) {
413  return loc->second;
414  }
415  return NULL;
416 }
417 
418 XmppServerConnection *XmppServer::FindConnection(const string &address) {
419  tbb::reader_writer_lock::scoped_lock_read lock(connection_map_mutex_);
420  for (auto& value : connection_map_) {
421  if (value.second->ToString() == address)
422  return value.second;
423  }
424  return NULL;
425 }
426 
427 bool XmppServer::ClearConnection(const string &hostname) {
428  tbb::reader_writer_lock::scoped_lock_read lock(connection_map_mutex_);
429  for (auto& value : connection_map_) {
430  if (value.second->GetComputeHostName() == hostname) {
431  value.second->Clear();
432  return true;
433  }
434  }
435  return false;
436 }
437 
438 void XmppServer::UpdateAllConnections(uint8_t time_out) {
439  tbb::reader_writer_lock::scoped_lock_read lock(connection_map_mutex_);
440  for (auto& value : connection_map_) {
441  value.second->UpdateKeepAliveTimer(time_out);
442  }
443 }
444 
446  tbb::reader_writer_lock::scoped_lock_read lock(connection_map_mutex_);
447  for (auto& value : connection_map_) {
448  value.second->Clear();
449  }
450 }
451 
453  ConnectionEventCb cb) {
454  connection_event_map_.insert(make_pair(id, cb));
455 }
456 
458  ConnectionEventCbMap::iterator it = connection_event_map_.find(id);
459  if (it != connection_event_map_.end())
460  connection_event_map_.erase(it);
461 }
462 
464  xmps::PeerState state) {
465  ConnectionEventCbMap::iterator iter = connection_event_map_.begin();
466  for (; iter != connection_event_map_.end(); ++iter) {
467  ConnectionEventCb cb = iter->second;
468  cb(mux, state);
469  }
470 }
471 
473  SslSession *session = new XmppSession(this, socket);
474  boost::system::error_code err;
475  XmppSession *xmpp_session = static_cast<XmppSession *>(session);
476  err = xmpp_session->EnableTcpKeepalive(tcp_hold_time_);
477  if (err) {
478  XMPP_WARNING(ServerKeepAliveFailure, xmpp_session->ToUVEKey(),
479  XMPP_PEER_DIR_OUT, err.message());
480  }
481  return session;
482 }
483 
484 //
485 // Accept newly formed passive tcp session by creating necessary xmpp data
486 // structures. We do so to make sure that if there is any error reported
487 // over this tcp session, it can still be correctly handled, even though
488 // the allocated xmpp data structures are not fully processed yet.
489 //
491  tbb::mutex::scoped_lock lock(deletion_mutex_);
492  if (deleter_->IsDeleted())
493  return false;
494 
495  XmppSession *session = dynamic_cast<XmppSession *>(tcp_session);
496  XmppServerConnection *connection = CreateConnection(session);
497 
498  if (xmpp_config_updater_) {
499  connection->state_machine()->set_hold_time(
500  xmpp_config_updater_->xmpp_hold_time());
501  }
502  // Register event handler.
503  tcp_session->set_observer(boost::bind(&XmppStateMachine::OnSessionEvent,
504  connection->state_machine(), _1, _2));
505 
506  // set async_read_ready as false
507  session->set_read_on_connect(false);
508  connection->set_session(session);
509  connection->state_machine()->set_session(session);
510  connection->set_on_work_queue();
511  connection_queue_.Enqueue(connection);
512  return true;
513 }
514 
515 //
516 // Remove the given XmppServerConnection from the ConnectionMap.
517 //
519  CHECK_CONCURRENCY("bgp::Config");
520 
521  assert(connection->IsDeleted());
522  Endpoint endpoint = connection->endpoint();
523  tbb::reader_writer_lock::scoped_lock lock(connection_map_mutex_);
524  ConnectionMap::iterator loc = connection_map_.find(endpoint);
525  assert(loc != connection_map_.end() && loc->second == connection);
526  connection_map_.erase(loc);
527 }
528 
530  XmppConnection *connection1, XmppConnection *connection2) {
531  tbb::reader_writer_lock::scoped_lock lock(connection_map_mutex_);
532  ConnectionMap::iterator loc1 =
533  connection_map_.find(connection1->endpoint());
534  assert(loc1 != connection_map_.end());
535  ConnectionMap::iterator loc2 =
536  connection_map_.find(connection2->endpoint());
537  assert(loc2 != connection_map_.end());
538  swap(loc1->second, loc2->second);
539  swap(loc1->second->endpoint(), loc2->second->endpoint());
540 }
541 
542 //
543 // Insert the given XmppServerConnection into the ConnectionMap.
544 //
546  CHECK_CONCURRENCY("bgp::Config");
547 
548  assert(!connection->IsDeleted());
549  connection->Initialize();
550  Endpoint endpoint = connection->endpoint();
551  ConnectionMap::iterator loc;
552  bool result;
553  tbb::reader_writer_lock::scoped_lock lock(connection_map_mutex_);
554  tie(loc, result) = connection_map_.insert(make_pair(endpoint, connection));
555  assert(result);
556  max_connections_ = max(max_connections_, connection_map_.size());
557 }
558 
559 //
560 // Create XmppConnnection and its associated data structures. This API is
561 // only used to allocate data structures and initialize necessary fields.
562 // The data structures are not populated to any maps in the XmppServer at
563 // this point. However, the newly created XmppServerConnection does add
564 // itself as a dependent of the XmppServer via LifetimeManager linkage.
565 //
567  XmppServerConnection *connection;
568 
569  XmppChannelConfig cfg(false);
570  cfg.endpoint = session->remote_endpoint();
571  cfg.local_endpoint = session->local_endpoint();
572  cfg.FromAddr = server_addr_;
573  cfg.logUVE = log_uve_;
575  cfg.dscp_value = dscp_value_;
576 
577  XMPP_DEBUG(XmppCreateConnection, session->ToUVEKey(), XMPP_PEER_DIR_OUT,
578  session->ToString());
579  connection = XmppStaticObjectFactory::Create<XmppServerConnection>
580  (this, static_cast<const XmppChannelConfig*>(&cfg));
581 
582  return connection;
583 }
584 
585 void XmppServer::SetDscpValue(uint8_t value) {
586  tbb::reader_writer_lock::scoped_lock_read lock(connection_map_mutex_);
587  dscp_value_ = value;
588  for (auto& value : connection_map_) {
589  XmppServerConnection *connection = value.second;
590  connection->SetDscpValue(dscp_value_);
591  }
592 }
593 //
594 // Handler for XmppServerConnections that are dequeued from the WorkQueue.
595 //
596 // Since the XmppServerConnections on the WorkQueue are dependents of the
597 // XmppServer, we are guaranteed that the XmppServer won't get destroyed
598 // before the connection WorkQueue is drained.
599 //
601  CHECK_CONCURRENCY("bgp::Config");
602  connection->clear_on_work_queue();
603 
604  // This happens if the XmppServer got deleted while the XmppConnnection
605  // was on the WorkQueue.
606  if (connection->IsDeleted()) {
607  connection->RetryDelete();
608  return true;
609  }
610 
611  XmppSession *session = connection->session();
612  connection->clear_session();
613  Endpoint remote_endpoint = session->remote_endpoint();
614  XmppServerConnection *old_connection = FindConnection(remote_endpoint);
615 
616  // Close as duplicate if we have a connection from the same Endpoint.
617  // Otherwise go ahead and insert into the ConnectionMap. We may find
618  // it has a conflicting Endpoint name and decide to terminate it when
619  // we process the Open message.
620  if (old_connection) {
621  XMPP_DEBUG(XmppCreateConnection, session->ToUVEKey(), XMPP_PEER_DIR_IN,
622  "Close duplicate connection " + session->ToString());
623  // Remove reference to the session from StateMachine directly. We don't
624  // go through the entire normal cleanup pipeline for cleaning these
625  // duplicate connections.
626  assert(connection->state_machine()->session());
627  assert(connection->state_machine()->session() == session);
628  connection->state_machine()->RemoveSession();
629  DeleteSession(session);
630  connection->set_duplicate();
631  connection->ManagedDelete();
632  InsertDeletedConnection(connection);
633  } else {
634  InsertConnection(connection);
635  connection->AcceptSession(session);
636  }
637 
638  return true;
639 }
640 
642  return connection_queue_.Length();
643 }
644 
646  connection_queue_.set_disable(disabled);
647 }
648 
649 //
650 // Connection is marked deleted, add it to the ConnectionSet.
651 //
653  CHECK_CONCURRENCY("bgp::Config");
654 
655  assert(connection->IsDeleted());
656  ConnectionSet::iterator it;
657  bool result;
658  tie(it, result) = deleted_connection_set_.insert(connection);
659  assert(result);
660 }
661 
662 //
663 // Connection is being destroyed, remove it from the ConnectionSet.
664 //
666  CHECK_CONCURRENCY("bgp::Config");
667 
668  assert(connection->IsDeleted());
669  ConnectionSet::iterator it = deleted_connection_set_.find(connection);
670  assert(it != deleted_connection_set_.end());
671  deleted_connection_set_.erase(it);
672  ReleaseConnectionEndpoint(connection);
673 }
674 
676  const string &endpoint_name) {
677  tbb::mutex::scoped_lock lock(endpoint_map_mutex_);
678  ConnectionEndpointMap::const_iterator loc =
679  connection_endpoint_map_.find(endpoint_name);
680  return (loc != connection_endpoint_map_.end() ? loc->second : NULL);
681 }
682 
684  XmppServerConnection *connection, bool &created) {
685  created = false;
686  if (!connection)
687  return NULL;
688 
689  tbb::mutex::scoped_lock lock(endpoint_map_mutex_);
690 
691  ConnectionEndpointMap::const_iterator loc =
692  connection_endpoint_map_.find(connection->ToString());
693  XmppConnectionEndpoint *conn_endpoint;
694 
695  if (loc != connection_endpoint_map_.end()) {
696  conn_endpoint = loc->second;
697  if (!conn_endpoint->connection()) {
698  created = true;
699  conn_endpoint->set_connection(connection);
700  connection->set_conn_endpoint(conn_endpoint);
701  }
702  return conn_endpoint;
703  }
704 
705  created = true;
706  conn_endpoint = new XmppConnectionEndpoint(connection->ToString());
707  bool result;
708  tie(loc, result) = connection_endpoint_map_.insert(
709  make_pair(connection->ToString(), conn_endpoint));
710  assert(result);
711  conn_endpoint->set_connection(connection);
712  connection->set_conn_endpoint(conn_endpoint);
713  return conn_endpoint;
714 }
715 
716 //
717 // Remove association of the given XmppConnectionEndpoint with XmppConnection.
718 // This method is provided just to make things symmetrical - the caller could
719 // simply have called XmppConnectionEndpoint::reset_connection directly.
720 //
722  tbb::mutex::scoped_lock lock(endpoint_map_mutex_);
723 
724  if (!connection->conn_endpoint())
725  return;
726  assert(connection->conn_endpoint()->connection() == connection);
727  connection->conn_endpoint()->reset_connection();
728  connection->set_conn_endpoint(NULL);
729 }
730 
732  vector<ShowXmppConnection> *show_connection_list) const {
733  tbb::reader_writer_lock::scoped_lock_read lock(connection_map_mutex_);
734  for (const auto& value : connection_map_) {
735  const XmppServerConnection *connection = value.second;
736  ShowXmppConnection show_connection;
737  connection->FillShowInfo(&show_connection);
738  show_connection_list->push_back(show_connection);
739  }
740  for (const auto& connection : deleted_connection_set_) {
741  ShowXmppConnection show_connection;
742  connection->FillShowInfo(&show_connection);
743  show_connection_list->push_back(show_connection);
744  }
745 }
746 
747 void XmppServer::FillShowServer(ShowXmppServerResp *resp) const {
748  SocketIOStats peer_socket_stats;
749  GetRxSocketStats(&peer_socket_stats);
750  resp->set_rx_socket_stats(peer_socket_stats);
751  GetTxSocketStats(&peer_socket_stats);
752  resp->set_tx_socket_stats(peer_socket_stats);
753  resp->set_current_connections(ConnectionMapSize());
754  resp->set_max_connections(max_connections_);
755 }
756 
758 public:
759  static bool CallbackS1(const Sandesh *sr,
760  const RequestPipeline::PipeSpec ps, int stage, int instNum,
762  const ShowXmppConnectionReq *req =
763  static_cast<const ShowXmppConnectionReq *>(ps.snhRequest_.get());
764  XmppSandeshContext *xsc =
765  dynamic_cast<XmppSandeshContext *>(req->module_context("XMPP"));
766 
767  ShowXmppConnectionResp *resp = new ShowXmppConnectionResp;
768  vector<ShowXmppConnection> connections;
769  if (xsc)
770  xsc->xmpp_server->FillShowConnections(&connections);
771  resp->set_connections(connections);
772  resp->set_context(req->context());
773  resp->Response();
774  return true;
775  }
776 };
777 
778 void ShowXmppConnectionReq::HandleRequest() const {
779  RequestPipeline::PipeSpec ps(this);
780 
781  // Request pipeline has single stage to collect connection info and
782  // respond to the request.
785  s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
787  s1.instances_.push_back(0);
788  ps.stages_.push_back(s1);
789  RequestPipeline rp(ps);
790 }
791 
793 public:
794  static bool CallbackS1(const Sandesh *sr,
795  const RequestPipeline::PipeSpec ps, int stage, int instNum,
797 
798  const ClearXmppConnectionReq *req =
799  static_cast<const ClearXmppConnectionReq *>(ps.snhRequest_.get());
800  XmppSandeshContext *xsc =
801  dynamic_cast<XmppSandeshContext *>(req->module_context("XMPP"));
802 
803  ClearXmppConnectionResp *resp = new ClearXmppConnectionResp;
804  if (!xsc || !xsc->test_mode) {
805  resp->set_success(false);
806  } else if (req->get_hostname_or_all() != "all") {
807  if (xsc->xmpp_server->ClearConnection(req->get_hostname_or_all())) {
808  resp->set_success(true);
809  } else {
810  resp->set_success(false);
811  }
812  } else {
813  if (xsc->xmpp_server->ConnectionCount()) {
815  resp->set_success(true);
816  } else {
817  resp->set_success(false);
818  }
819  }
820 
821  resp->set_context(req->context());
822  resp->Response();
823  return true;
824  }
825 };
826 
827 void ClearXmppConnectionReq::HandleRequest() const {
828 
829  // config task is used to create and delete connection objects.
830  // hence use the same task to find the connection
832  s1.taskId_ = TaskScheduler::GetInstance()->GetTaskId("bgp::Config");
833  s1.instances_.push_back(0);
835 
836  RequestPipeline::PipeSpec ps(this);
837  ps.stages_.push_back(s1);
838  RequestPipeline rp(ps);
839 }
840 
842 public:
843  static bool CallbackS1(const Sandesh *sr,
844  const RequestPipeline::PipeSpec ps, int stage, int instNum,
846  const ShowXmppServerReq *req =
847  static_cast<const ShowXmppServerReq *>(ps.snhRequest_.get());
848  XmppSandeshContext *xsc =
849  dynamic_cast<XmppSandeshContext *>(req->module_context("XMPP"));
850 
851  ShowXmppServerResp *resp = new ShowXmppServerResp;
852  if (xsc)
853  xsc->xmpp_server->FillShowServer(resp);
854  resp->set_context(req->context());
855  resp->Response();
856  return true;
857  }
858 };
859 
860 void ShowXmppServerReq::HandleRequest() const {
861  RequestPipeline::PipeSpec ps(this);
864  s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
866  s1.instances_.push_back(0);
867  ps.stages_.push_back(s1);
868  RequestPipeline rp(ps);
869 }
XmppConnectionEndpoint * LocateConnectionEndpoint(XmppServerConnection *connection, bool &created)
Definition: xmpp_server.cc:683
boost::asio::ip::tcp::endpoint endpoint
Definition: xmpp_config.h:24
bool auth_enabled_
Definition: xmpp_server.h:145
std::string server_addr_
Definition: xmpp_server.h:143
BgpGlobalSystemConfigObserver system
Definition: bgp_config.h:749
std::vector< int > instances_
void set_read_on_connect(bool read)
Definition: tcp_session.h:151
void UnRegisterConnectionEvent(xmps::PeerId)
Definition: xmpp_server.cc:457
LifetimeManager * lifetime_manager()
Definition: xmpp_server.cc:360
uint32_t GetEndOfRibSendTime() const
Definition: xmpp_server.cc:258
Endpoint local_endpoint() const
Definition: tcp_session.cc:205
virtual void DeleteSession(TcpSession *session)
Definition: tcp_server.cc:197
void FillShowConnections(std::vector< ShowXmppConnection > *show_connection_list) const
Definition: xmpp_server.cc:731
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
void FillShowServer(ShowXmppServerResp *resp) const
Definition: xmpp_server.cc:747
virtual bool AcceptSession(XmppSession *session)
void ProcessGlobalSystemConfig(const BgpGlobalSystemConfig *system, BgpConfigManager::EventType event)
Definition: xmpp_server.cc:152
void Shutdown(bool delete_entries=true)
Definition: queue_task.h:152
virtual void InsertDeletedConnection(XmppServerConnection *connection)
Definition: xmpp_server.cc:652
virtual void Destroy()
Definition: xmpp_server.cc:43
boost::asio::ip::tcp::socket Socket
Definition: tcp_server.h:31
tbb::reader_writer_lock connection_map_mutex_
Definition: xmpp_server.h:112
ConnectionEventCbMap connection_event_map_
Definition: xmpp_server.h:142
void set_hold_time(int hold_time)
bool log_uve_
Definition: xmpp_server.h:144
boost::asio::ip::tcp::endpoint local_endpoint
Definition: xmpp_config.h:25
bool MayDelete() const
Definition: xmpp_server.cc:328
virtual bool Initialize(short port)
Definition: xmpp_server.cc:300
virtual boost::asio::ip::tcp::endpoint endpoint() const
virtual bool IsPeerCloseGraceful() const
Definition: xmpp_server.cc:280
boost::function< void(XmppChannelMux *, xmps::PeerState)> ConnectionEventCb
Definition: xmpp_server.h:42
XmppConnectionEndpoint * conn_endpoint()
DeleteActor(XmppServer *server)
Definition: xmpp_server.cc:32
virtual std::string ToString() const
Definition: tcp_session.h:83
#define XMPP_PEER_DIR_IN
Definition: xmpp_log.h:15
const BgpGlobalSystemConfig & config() const
Definition: xmpp_server.cc:141
boost::asio::ip::address IpAddress
Definition: address.h:13
void RegisterObservers(const Observers &obs)
Definition: bgp_config.h:772
uint16_t rd_cluster_seed() const
Definition: bgp_config.h:661
virtual TcpSession * CreateSession()
Definition: tcp_server.cc:188
boost::asio::ip::tcp::endpoint Endpoint
Definition: xmpp_server.h:34
void GetTxSocketStats(SocketIOStats *socket_stats) const
Definition: tcp_server.cc:643
virtual void ManagedDelete()
void set_conn_endpoint(XmppConnectionEndpoint *conn_endpoint)
boost::asio::ssl::context * context()
Definition: ssl_server.cc:41
#define XMPP_PEER_DIR_OUT
Definition: xmpp_log.h:14
static bool CallbackS1(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
Definition: xmpp_server.cc:843
boost::system::error_code EnableTcpKeepalive(int tcp_hold_time)
virtual LifetimeActor * deleter()
Definition: xmpp_server.cc:352
void SetDscpValue(uint8_t value)
Definition: xmpp_server.cc:585
BgpProtocolObserver protocol
Definition: bgp_config.h:745
void GetRxSocketStats(SocketIOStats *socket_stats) const
Definition: tcp_server.cc:639
static const int kEndOfRibTime
Definition: bgp_config.h:607
uint32_t GetEndOfRibReceiveTime() const
Definition: xmpp_server.cc:252
bool ClearConnection(const std::string &hostname)
Definition: xmpp_server.cc:427
unsigned int boolean
Definition: mcast_common.h:11
int GetTaskId(const std::string &name)
Definition: task.cc:856
virtual void RetryDelete()
void Shutdown()
Definition: xmpp_server.cc:339
Endpoint LocalEndpoint() const
Definition: tcp_server.cc:306
void set_subcluster_name(const string &name)
Definition: xmpp_server.cc:187
int tcp_hold_time_
Definition: xmpp_server.h:146
bool DequeueConnection(XmppServerConnection *connection)
Definition: xmpp_server.cc:600
std::string path_to_ca_cert
Definition: xmpp_config.h:30
void Terminate()
Definition: xmpp_server.cc:347
void set_observer(EventObserver observer)
Definition: tcp_session.cc:218
ConnectionEndpointMap connection_endpoint_map_
Definition: xmpp_server.h:136
bool gr_xmpp_helper() const
Definition: bgp_config.h:633
virtual SslSession * AllocSession(SslSocket *socket)
Definition: xmpp_server.cc:472
std::string FromAddr
Definition: xmpp_config.h:21
XmppConnection * connection()
XmppConfigUpdater(XmppServer *server, BgpConfigManager *config_manager)
Definition: xmpp_server.cc:130
uint16_t gr_time() const
Definition: bgp_config.h:623
void UpdateAllConnections(uint8_t time_out)
Definition: xmpp_server.cc:438
bool IsDeleted() const
void NotifyConnectionEvent(XmppChannelMux *, xmps::PeerState)
Definition: xmpp_server.cc:463
virtual XmppServerConnection * CreateConnection(XmppSession *session)
Definition: xmpp_server.cc:566
boost::scoped_ptr< DeleteActor > deleter_
Definition: xmpp_server.h:140
virtual ~XmppServer()
Definition: xmpp_server.cc:295
size_t Length() const
Definition: queue_task.h:356
bool fc_enabled() const
Definition: bgp_config.h:639
static TaskScheduler * GetInstance()
Definition: task.cc:547
void ProcessProtocolConfig(const BgpProtocolConfig *protocol_config, BgpConfigManager::EventType event)
Definition: xmpp_server.cc:143
boost::asio::ssl::stream< boost::asio::ip::tcp::socket > SslSocket
Definition: ssl_server.h:16
virtual bool AcceptSession(TcpSession *session)
Definition: xmpp_server.cc:490
static bool CallbackS1(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
Definition: xmpp_server.cc:794
tbb::mutex endpoint_map_mutex_
Definition: xmpp_server.h:135
void STLDeleteElements(Container *container)
Definition: util.h:114
#define CHECK_CONCURRENCY(...)
virtual void InsertConnection(XmppServerConnection *connection)
Definition: xmpp_server.cc:545
ConnectionSet deleted_connection_set_
Definition: xmpp_server.h:132
int SetDscpValue(uint8_t value)
virtual void RemoveDeletedConnection(XmppServerConnection *connection)
Definition: xmpp_server.cc:665
void ClearAllConnections()
Definition: xmpp_server.cc:445
virtual bool MayDelete() const
Definition: xmpp_server.cc:35
std::string path_to_server_cert
Definition: xmpp_config.h:28
uint16_t end_of_rib_timeout() const
Definition: bgp_config.h:629
XmppServer * server_
Definition: xmpp_server.cc:197
void ReleaseConnectionEndpoint(XmppServerConnection *connection)
Definition: xmpp_server.cc:721
size_t max_connections_
Definition: xmpp_server.h:133
void set_xmpp_hold_time(int hold_time)
Definition: xmpp_server.cc:192
size_t ConnectionMapSize() const
Definition: xmpp_server.cc:400
boost::scoped_ptr< LifetimeManager > lifetime_manager_
Definition: xmpp_server.h:139
void set_connection(XmppConnection *connection)
BgpGlobalSystemConfig config_
Definition: xmpp_server.cc:198
virtual void RemoveConnection(XmppServerConnection *connection)
Definition: xmpp_server.cc:518
const std::string & ToString() const
const string subcluster_name() const
Definition: xmpp_server.cc:186
void set_disable(bool disabled)
Definition: queue_task.h:319
virtual void Shutdown()
Definition: xmpp_server.cc:39
ConnectionMap connection_map_
Definition: xmpp_server.h:114
void set_session(XmppSession *session)
WorkQueue< XmppServerConnection * > connection_queue_
Definition: xmpp_server.h:151
uint8_t xmpp_hold_time() const
Definition: bgp_config.h:655
const std::string & ToUVEKey() const
Definition: tcp_session.h:178
uint8_t dscp_value
Definition: xmpp_config.h:34
XmppServer * xmpp_server
Definition: xmpp_sandesh.h:16
void set_session(TcpSession *session)
uint16_t GetGracefulRestartTime() const
Definition: xmpp_server.cc:238
uint32_t GetLongLivedGracefulRestartTime() const
Definition: xmpp_server.cc:245
#define XMPP_DEBUG(obj,...)
Definition: xmpp_log.h:59
Endpoint remote_endpoint() const
Definition: tcp_session.h:135
void SessionShutdown()
Definition: xmpp_server.cc:318
void SwapXmppConnectionMapEntries(XmppConnection *connection1, XmppConnection *connection2)
Definition: xmpp_server.cc:529
#define LOG(_Level, _Msg)
Definition: logging.h:33
boost::shared_ptr< const SandeshRequest > snhRequest_
virtual bool Initialize(unsigned short port)
Definition: tcp_server.cc:59
static bool CallbackS1(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
Definition: xmpp_server.cc:759
void ClearSessions()
Definition: tcp_server.cc:159
size_t GetConnectionQueueSize() const
Definition: xmpp_server.cc:641
bool gr_helper_disable_
Definition: xmpp_server.h:147
XmppServer(EventManager *evm, const std::string &server_addr, const XmppChannelConfig *config)
size_t ConnectionCount() const
Definition: xmpp_server.cc:405
XmppSession * session()
void FillShowInfo(ShowXmppConnection *show_connection) const
XmppConnectionEndpoint * FindConnectionEndpoint(const std::string &endpoint_name)
Definition: xmpp_server.cc:675
tbb::mutex deletion_mutex_
Definition: xmpp_server.h:138
virtual void OnSessionEvent(TcpSession *session, TcpSession::Event event)
XmppStateMachine * state_machine()
void SetConnectionQueueDisable(bool disabled)
Definition: xmpp_server.cc:645
virtual Socket * socket() const
Definition: tcp_session.h:86
const XmppSession * session() const
size_t ConnectionEventCount() const
Definition: xmpp_server.cc:396
bool Enqueue(QueueEntryT entry)
Definition: queue_task.h:248
uint32_t llgr_time() const
Definition: bgp_config.h:625
uint8_t dscp_value_
Definition: xmpp_server.h:149
boost::scoped_ptr< XmppConfigUpdater > xmpp_config_updater_
Definition: xmpp_server.h:148
bool IsGRHelperModeEnabled() const
Definition: xmpp_server.cc:264
bool gr_enable() const
Definition: bgp_config.h:635
void RegisterConnectionEvent(xmps::PeerId, ConnectionEventCb)
Definition: xmpp_server.cc:452
#define DEFAULT_XMPP_HOLD_TIME
Definition: xmpp_server.cc:29
const std::string & subcluster_name() const
Definition: bgp_config.h:555
std::string path_to_server_priv_key
Definition: xmpp_config.h:29
static EventManager evm
#define XMPP_WARNING(obj,...)
Definition: xmpp_log.h:35
void CreateConfigUpdater(BgpConfigManager *config_manager)
Definition: xmpp_server.cc:234
friend class DeleteActor
Definition: xmpp_server.h:119
uint8_t xmpp_hold_time() const
Definition: xmpp_server.cc:191
virtual XmppServerConnection * FindConnection(Endpoint remote_endpoint)
Definition: xmpp_server.cc:409
virtual TcpSession * CreateSession()
Definition: xmpp_server.cc:364