OpenSDN source code
xmpp_state_machine.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef __XMPP_STATE_MC__
6 #define __XMPP_STATE_MC__
7 
8 #include <mutex>
9 
10 #include <boost/asio.hpp>
11 #include <boost/statechart/state_machine.hpp>
12 
13 #include "base/queue_task.h"
14 #include "base/timer.h"
15 #include "io/ssl_session.h"
16 #include "xmpp/xmpp_proto.h"
17 
18 namespace sc = boost::statechart;
19 
20 namespace xmsm {
21  struct Idle;
22  struct Active;
23  struct Connect;
24  struct OpenSent;
25  struct OpenConfirm;
26  struct XmppStreamEstablished;
27 }
28 
29 namespace xmsm {
30  struct EvStart;
31  struct Idle;
32 
33 typedef enum {
34  IDLE = 0,
35  ACTIVE = 1,
36  CONNECT = 2,
37  OPENSENT = 3,
39  ESTABLISHED = 5
41 
42 typedef enum {
47 
48 
49 typedef enum {
53 
54 }
55 
56 class XmppConnection;
57 class XmppSession;
58 class TcpSession;
59 class XmppConnectionInfo;
60 
62  public sc::state_machine<XmppStateMachine, xmsm::Idle> {
63 public:
64  static const int kOpenTime = 15; // seconds
65  static const int kConnectInterval = 30; // seconds
66  static const int kHoldTime = 90; // seconds
67  static const int kMaxAttempts = 4;
68  static const int kJitter = 10; // percentage
69 
70  XmppStateMachine(XmppConnection *connection, bool active, bool auth_enabled = false, int config_hold_time = kHoldTime);
72 
73  void Initialize();
74  void Clear();
75  void SetAdminState(bool down);
76 
77  // State transitions
78  void OnStart(const xmsm::EvStart &event);
79 
80  virtual void StartConnectTimer(int seconds);
81  void CancelConnectTimer();
82  virtual void StartOpenTimer(int seconds);
83  void CancelOpenTimer();
84 
85  int GetConfiguredHoldTime() const;
86  virtual void StartHoldTimer();
87  void CancelHoldTimer();
88  void ResetSession();
89 
90  bool IsAuthEnabled() { return auth_enabled_; }
91 
92  void TimerErrorHandler(std::string name, std::string error);
93 
94  // Feed session events into the state machine.
95  virtual void OnSessionEvent(TcpSession *session, TcpSession::Event event);
96 
97  // Receive Passive Open.
99 
100  // Receive incoming message
103  const XmppStanza::XmppMessage *msg);
104 
105  // Receive incoming ssl events
106  //void OnEvent(XmppSession *session, xmsm::SslHandShakeResponse);
108 
109  //void OnSessionError(Error error);
110 
111  // transfer the ownership of the session to the connection.
112  void AssignSession();
113 
114  // Calculate Timer value for active to connect transition.
115  int GetConnectTime() const;
116 
118  handshake_cb_ = cb;
119  }
120 
122 
123  std::string StateName() const;
124  std::string LastStateName() const;
125  std::string LastStateChangeAt() const;
126  xmsm::XmState StateType() const;
128 
129  // getters and setters
132  connection_ = const_cast<XmppConnection *>(connection);
133  }
135  bool IsActiveChannel();
136  bool logUVE();
137  const char *ChannelType();
139  void clear_session();
141  XmppSession *session() { return session_; }
142  void RemoveSession() { session_ = NULL; }
143  void set_state(xmsm::XmState state);
147  return openconfirm_state_;
148  }
149 
152  int get_connect_attempts() const { return attempts_; }
153 
156  int get_keepalive_count() const { return keepalive_count_; }
157 
158  int hold_time() const { return hold_time_; }
159  virtual int hold_time_msecs() const { return hold_time_ * 1000; }
161 
162  void unconsumed_event(const sc::event_base &event);
163 
164  void SendConnectionInfo(const std::string &event,
165  const std::string &nextstate = "");
166 
167  void SendConnectionInfo(XmppConnectionInfo *info, const std::string &event,
168  const std::string &nextstate = "");
171 
172  void set_last_event(const std::string &event) {
173  std::scoped_lock lock(mutex_);
174  last_event_ = event;
176  }
177 
178  void update_last_event(const std::string &event);
179 
180  const std::string last_event() const {
181  std::scoped_lock lock(mutex_);
182  return last_event_;
183  }
184 
188  void AssertOnHoldTimeout();
189  bool HoldTimerExpired();
190  const Timer *hold_timer() const { return hold_timer_; }
191 
192 private:
193  friend class XmppStateMachineTest;
194 
195  bool ConnectTimerExpired();
196  bool OpenTimerExpired();
197  bool Enqueue(const sc::event_base &ev);
198  bool DequeueEvent(boost::intrusive_ptr<const sc::event_base> event);
199  void ProcessEvent(const sc::event_base &event);
201  const XmppStanza::XmppMessage *msg);
202 
212  uint32_t attempts_;
214  bool deleted_;
221  uint64_t state_since_;
222  std::string last_event_;
223  uint64_t last_event_at_;
225  mutable std::mutex mutex_;
226 
228 };
229 
230 #endif
Definition: timer.h:55
bool cancelled() const
Definition: timer.h:101
xmsm::XmOpenConfirmState get_openconfirm_state()
void update_last_event(const std::string &event)
xmsm::XmOpenConfirmState OpenConfirmStateType() const
void set_state(xmsm::XmState state)
void ProcessEvent(const sc::event_base &event)
void set_connection(const XmppConnection *connection)
xmsm::XmState get_state()
virtual void StartHoldTimer()
void SetAdminState(bool down)
XmppSession * session_
XmppStateMachine(XmppConnection *connection, bool active, bool auth_enabled=false, int config_hold_time=kHoldTime)
void DeleteSession(XmppSession *session)
std::string StateName() const
virtual void StartOpenTimer(int seconds)
static const int kConnectInterval
bool DequeueEvent(boost::intrusive_ptr< const sc::event_base > event)
void SendConnectionInfo(XmppConnectionInfo *info, const std::string &event, const std::string &nextstate="")
void OnStart(const xmsm::EvStart &event)
SslHandShakeCallbackHandler HandShakeCbHandler()
void ProcessStreamHeaderMessage(XmppSession *session, const XmppStanza::XmppMessage *msg)
xmsm::XmState StateType() const
void set_hold_time(int hold_time)
XmppConnection * connection()
const char * ChannelType()
WorkQueue< boost::intrusive_ptr< const sc::event_base > > work_queue_
void set_last_event(const std::string &event)
friend class XmppStateMachineTest
void TimerErrorHandler(std::string name, std::string error)
std::string LastStateName() const
bool PassiveOpen(XmppSession *session)
virtual void StartConnectTimer(int seconds)
void SwapXmppConnection(XmppStateMachine *other)
const Timer * hold_timer() const
XmppConnection * connection_
std::string LastStateChangeAt() const
void ProcessMessage(XmppSession *session, const XmppStanza::XmppMessage *msg)
xmsm::XmOpenConfirmState openconfirm_state_
void OnEvent(SslSession *session, xmsm::SslHandShakeResponse)
bool Enqueue(const sc::event_base &ev)
void OnMessage(XmppSession *session, const XmppStanza::XmppMessage *msg)
void set_session(TcpSession *session)
void SetHandShakeCbHandler(SslHandShakeCallbackHandler cb)
int get_keepalive_count() const
xmsm::XmState state_
XmppSession * session()
void set_openconfirm_state(xmsm::XmOpenConfirmState state)
DISALLOW_COPY_AND_ASSIGN(XmppStateMachine)
int GetConfiguredHoldTime() const
virtual int hold_time_msecs() const
void SendConnectionInfo(const std::string &event, const std::string &nextstate="")
int get_connect_attempts() const
const std::string last_event() const
xmsm::XmState last_state_
static const int kMaxAttempts
void ResurrectOldConnection(XmppConnection *connection, XmppSession *session)
static const int kHoldTime
static const int kOpenTime
static const int kJitter
virtual void OnSessionEvent(TcpSession *session, TcpSession::Event event)
void unconsumed_event(const sc::event_base &event)
SslHandShakeCallbackHandler handshake_cb_
@ EvTLSHANDSHAKE_SUCCESS
@ EvTLSHANDSHAKE_FAILURE
@ OPENCONFIRM_FEATURE_NEGOTIATION
@ OPENCONFIRM_FEATURE_SUCCESS
@ OPENCONFIRM_INIT
boost::function< void(SslSessionPtr, const boost::system::error_code &error)> SslHandShakeCallbackHandler
Definition: ssl_session.h:16
static uint64_t UTCTimestampUsec()
Definition: time_util.h:13