Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef __XMPP_CHANNEL_H__ 6 : #define __XMPP_CHANNEL_H__ 7 : 8 : #include <atomic> 9 : #include <boost/asio/ip/tcp.hpp> 10 : #include <boost/scoped_ptr.hpp> 11 : #include <tbb/spin_mutex.h> 12 : 13 : #include "base/timer.h" 14 : #include "base/lifetime.h" 15 : #include "base/address.h" 16 : #include "xmpp/xmpp_channel_mux.h" 17 : #include "xmpp/xmpp_state_machine.h" 18 : #include "xmpp/xmpp_session.h" 19 : 20 : class LifetimeActor; 21 : class ShowXmppConnection; 22 : class TcpServer; 23 : class TcpSession; 24 : class XmppChannelConfig; 25 : class XmppClient; 26 : class XmppConnectionEndpoint; 27 : class XmppServer; 28 : class XmppSession; 29 : 30 : class XmppConnection { 31 : public: 32 : struct ProtoStats { 33 23198 : ProtoStats() { 34 23198 : open = 0; 35 23198 : close = 0; 36 23198 : keepalive = 0; 37 23198 : update = 0; 38 23198 : } 39 208 : void swap(ProtoStats& other) { 40 416 : open.store(other.open.exchange(open)); 41 416 : close.store(other.close.exchange(close)); 42 416 : keepalive.store(other.keepalive.exchange(keepalive)); 43 416 : update.store(other.update.exchange(update)); 44 208 : } 45 : std::atomic<uint32_t> open; 46 : std::atomic<uint32_t> close; 47 : std::atomic<uint32_t> keepalive; 48 : std::atomic<uint32_t> update; 49 : }; 50 : 51 : struct ErrorStats { 52 11599 : ErrorStats() { 53 11599 : connect_error = 0; 54 11599 : session_close = 0; 55 11599 : open_fail = 0; 56 11599 : stream_feature_fail = 0; 57 11599 : handshake_fail = 0; 58 11599 : } 59 104 : void swap(ErrorStats& other) { 60 208 : connect_error.store(other.connect_error.exchange(connect_error)); 61 208 : session_close.store(other.session_close.exchange(session_close)); 62 208 : open_fail.store(other.open_fail.exchange(open_fail)); 63 208 : stream_feature_fail.store(other.stream_feature_fail.exchange(stream_feature_fail)); 64 208 : handshake_fail.store(other.handshake_fail.exchange(handshake_fail)); 65 104 : } 66 : std::atomic<uint32_t> connect_error; 67 : std::atomic<uint32_t> session_close; 68 : std::atomic<uint32_t> open_fail; 69 : std::atomic<uint32_t> stream_feature_fail; 70 : std::atomic<uint32_t> handshake_fail; 71 : }; 72 : 73 : XmppConnection(TcpServer *server, const XmppChannelConfig *config); 74 : virtual ~XmppConnection(); 75 : 76 : void SetConfig(const XmppChannelConfig *); 77 : 78 : // Invoked from XmppServer when a session is accepted. 79 : virtual bool AcceptSession(XmppSession *session); 80 : virtual void ReceiveMsg(XmppSession *session, const std::string &); 81 : 82 : virtual boost::asio::ip::tcp::endpoint endpoint() const; 83 : virtual boost::asio::ip::tcp::endpoint local_endpoint() const; 84 : std::string endpoint_string() const; 85 : std::string local_endpoint_string() const; 86 73020 : TcpServer *server() { return server_; } 87 : XmppSession *CreateSession(); 88 83857 : int GetTaskInstance() const { return GetTaskInstance(is_client_); } 89 : 90 : const std::string &ToUVEKey() const; 91 : const std::string &ToString() const; 92 : const std::string &FromString() const; 93 : void SetAdminDown(bool toggle); 94 : bool Send(const uint8_t *data, size_t size, 95 : const std::string *msg_str = NULL); 96 : 97 : // Xmpp connection messages 98 : virtual bool SendOpen(XmppSession *session); 99 : virtual bool SendOpenConfirm(XmppSession *session); 100 : virtual bool SendStreamFeatureRequest(XmppSession *session); 101 : virtual bool SendStartTls(XmppSession *session); 102 : virtual bool SendProceedTls(XmppSession *session); 103 : 104 : void SendKeepAlive(); 105 : void SendClose(XmppSession *session); 106 : 107 : // Ssl Handshake callback response 108 : void ProcessSslHandShakeResponse(SslSessionPtr session, 109 : const boost::system::error_code& error); 110 : 111 : // PubSub Messages 112 : int ProcessXmppIqMessage(const XmppStanza::XmppMessage *); 113 : 114 : // chat messages 115 : int ProcessXmppChatMessage(const XmppStanza::XmppChatMessage *); 116 : 117 : void StartKeepAliveTimer(); 118 : void StopKeepAliveTimer(); 119 : void UpdateKeepAliveTimer(uint8_t time_out); 120 : 121 : void set_session(XmppSession *session); 122 : void clear_session(); 123 : void SetTo(const std::string &); 124 : 125 : const XmppSession *session() const; 126 : XmppSession *session(); 127 : 128 4267350 : bool logUVE() const { return !is_client_ && log_uve_; } 129 37561 : bool IsClient() const { return is_client_; } 130 : virtual void ManagedDelete() = 0; 131 : virtual void RetryDelete() = 0; 132 : virtual LifetimeActor *deleter() = 0; 133 : virtual const LifetimeActor *deleter() const = 0; 134 : virtual LifetimeManager *lifetime_manager() = 0; 135 : xmsm::XmState GetStateMcState() const; 136 : xmsm::XmOpenConfirmState GetStateMcOpenConfirmState() const; 137 : 138 25446 : bool IsActiveChannel() const { 139 25446 : return state_machine_->IsActiveChannel(); 140 : } 141 119593 : XmppChannelMux *ChannelMux() {return mux_.get(); } 142 1 : void SetChannelMux(XmppChannelMux *channel_mux) { mux_.reset(channel_mux); } 143 : 144 11537 : void Initialize() { state_machine_->Initialize(); } 145 2624 : void Clear() { state_machine_->Clear(); } 146 3768 : void SetAdminState(bool down) { state_machine_->SetAdminState(down); } 147 : 148 : void Shutdown(); 149 : bool MayDelete() const; 150 : bool IsDeleted() const; 151 : 152 151 : std::string &GetComputeHostName() { return to_; } 153 : std::string &GetControllerHostName() { return from_; } 154 : 155 : std::string &GetFrom() { return from_; } 156 3995025 : std::string &GetTo() { return to_; } 157 : 158 : virtual void set_close_reason(const std::string &reason) = 0; 159 : virtual void increment_flap_count() = 0; 160 : virtual uint32_t flap_count() const = 0; 161 : virtual const std::string last_flap_at() const = 0; 162 : 163 : virtual void WriteReady(); 164 : 165 : friend class XmppStateMachineTest; 166 : 167 487 : int GetConfiguredHoldTime() const { 168 487 : return state_machine_->GetConfiguredHoldTime(); 169 : } 170 : 171 974 : int GetNegotiatedHoldTime() const { 172 974 : return state_machine_->hold_time(); 173 : } 174 : 175 1046 : std::string StateName() const { 176 1046 : return state_machine_->StateName(); 177 : } 178 : 179 559 : std::string LastStateName() const { 180 559 : return state_machine_->LastStateName(); 181 : } 182 : 183 559 : std::string LastStateChangeAt() const { 184 559 : return state_machine_->LastStateChangeAt(); 185 : } 186 : 187 559 : std::string LastEvent() const { 188 559 : return state_machine_->last_event(); 189 : } 190 : 191 554 : uint32_t tx_open() const { 192 554 : return stats_[1].open; 193 : } 194 554 : uint32_t tx_keepalive() const { 195 554 : return stats_[1].keepalive; 196 : } 197 554 : uint32_t tx_close() const { 198 554 : return stats_[1].close; 199 : } 200 554 : uint32_t tx_update() const { 201 554 : return stats_[1].update; 202 : } 203 : 204 554 : uint32_t rx_open() const { 205 554 : return stats_[0].open; 206 : } 207 554 : uint32_t rx_keepalive() const { 208 554 : return stats_[0].keepalive; 209 : } 210 554 : uint32_t rx_close() const { 211 554 : return stats_[0].close; 212 : } 213 554 : uint32_t rx_update() const { 214 554 : return stats_[0].update; 215 : } 216 : 217 : void LogMsg(std::string msg); 218 1177490 : bool disable_read() const { return disable_read_; } 219 0 : void set_disable_read(bool disable_read) { disable_read_ = disable_read; } 220 : XmppStateMachine *state_machine(); 221 : const XmppStateMachine *state_machine() const; 222 : 223 : void set_state_machine(XmppStateMachine *state_machine) { 224 : state_machine_.reset(state_machine); 225 : } 226 : 227 104 : void SwapXmppStateMachine(XmppConnection *other) { 228 104 : state_machine_.swap(other->state_machine_); 229 104 : } 230 72 : uint8_t dscp_value() const { return dscp_value_; } 231 : int SetDscpValue(uint8_t value); 232 : 233 : void inc_connect_error(); 234 : void inc_session_close(); 235 : void inc_open_fail(); 236 : void inc_stream_feature_fail(); 237 : void inc_handshake_failure(); 238 : size_t get_connect_error(); 239 : size_t get_session_close(); 240 : size_t get_open_fail(); 241 : size_t get_stream_feature_fail(); 242 : size_t get_handshake_failure(); 243 : size_t get_sm_connect_attempts(); 244 : size_t get_sm_keepalive_count(); 245 : 246 : static const char *kAuthTypeNil; 247 : static const char *kAuthTypeTls; 248 : std::string GetXmppAuthenticationType() const; 249 : void SwapContents(XmppConnection *other); 250 4355447 : boost::asio::ip::tcp::endpoint &endpoint() { return endpoint_; } 251 1436 : const Timer *keepalive_timer() const { return keepalive_timer_; } 252 : 253 : protected: 254 : TcpServer *server_; 255 : XmppSession *session_; 256 : const XmppChannelMux *channel_mux() const; 257 : 258 : private: 259 : bool KeepAliveTimerExpired(); 260 : void KeepaliveTimerErrorHanlder(std::string error_name, 261 : std::string error_message); 262 : XmppStanza::XmppMessage *XmppDecode(const std::string &msg); 263 : void LogKeepAliveSend(); 264 : int GetTaskInstance(bool is_client) const; 265 : void IncProtoStats(unsigned int type); 266 : 267 : boost::asio::ip::tcp::endpoint endpoint_; 268 : boost::asio::ip::tcp::endpoint local_endpoint_; 269 : const XmppChannelConfig *config_; 270 : 271 : // Protection for session_ and keepalive_timer_ 272 : tbb::spin_mutex spin_mutex_; 273 : Timer *keepalive_timer_; 274 : 275 : bool is_client_; 276 : bool log_uve_; 277 : bool admin_down_; 278 : bool disable_read_; 279 : std::string from_; // bare jid 280 : std::string to_; 281 : bool auth_enabled_; 282 : uint8_t dscp_value_; 283 : std::string xmlns_; 284 : mutable std::string uve_key_str_; 285 : 286 : boost::scoped_ptr<XmppStateMachine> state_machine_; 287 : boost::scoped_ptr<XmppChannelMux> mux_; 288 : std::unique_ptr<XmppStanza::XmppMessage> last_msg_; 289 : 290 : ProtoStats stats_[2]; 291 : ErrorStats error_stats_; 292 : 293 : DISALLOW_COPY_AND_ASSIGN(XmppConnection); 294 : }; 295 : 296 : class XmppServerConnection : public XmppConnection { 297 : public: 298 : XmppServerConnection(XmppServer *server, const XmppChannelConfig *config); 299 : virtual ~XmppServerConnection(); 300 : 301 : virtual void ManagedDelete(); 302 : virtual void RetryDelete(); 303 : virtual LifetimeActor *deleter(); 304 : virtual const LifetimeActor *deleter() const; 305 : virtual LifetimeManager *lifetime_manager(); 306 : XmppServer *server(); 307 : 308 : virtual void set_close_reason(const std::string &reason); 309 : virtual uint32_t flap_count() const; 310 : virtual void increment_flap_count(); 311 : virtual const std::string last_flap_at() const; 312 : 313 6541 : bool duplicate() const { return duplicate_; } 314 0 : void set_duplicate() { duplicate_ = true; } 315 : 316 19209 : bool on_work_queue() const { return on_work_queue_; } 317 6541 : void set_on_work_queue() { on_work_queue_ = true; } 318 6541 : void clear_on_work_queue() { on_work_queue_ = false; } 319 : 320 25512 : XmppConnectionEndpoint *conn_endpoint() { return conn_endpoint_; } 321 12406 : void set_conn_endpoint(XmppConnectionEndpoint *conn_endpoint) { 322 12406 : conn_endpoint_ = conn_endpoint; 323 12406 : } 324 : void FillShowInfo(ShowXmppConnection *show_connection) const; 325 : 326 : private: 327 : class DeleteActor; 328 : 329 : bool duplicate_; 330 : bool on_work_queue_; 331 : XmppConnectionEndpoint *conn_endpoint_; 332 : boost::scoped_ptr<DeleteActor> deleter_; 333 : LifetimeRef<XmppServerConnection> server_delete_ref_; 334 : }; 335 : 336 : class XmppClientConnection : public XmppConnection { 337 : public: 338 : XmppClientConnection(XmppClient *server, const XmppChannelConfig *config); 339 : virtual ~XmppClientConnection(); 340 : 341 : virtual void ManagedDelete(); 342 : virtual void RetryDelete(); 343 : virtual LifetimeActor *deleter(); 344 : virtual const LifetimeActor *deleter() const; 345 : virtual LifetimeManager *lifetime_manager(); 346 : XmppClient *server(); 347 : 348 : virtual void set_close_reason(const std::string &reason); 349 : virtual uint32_t flap_count() const; 350 : virtual void increment_flap_count(); 351 : virtual const std::string last_flap_at() const; 352 : 353 : private: 354 : class DeleteActor; 355 : 356 : std::string close_reason_; 357 : uint32_t flap_count_; 358 : uint64_t last_flap_; 359 : boost::scoped_ptr<DeleteActor> deleter_; 360 : LifetimeRef<XmppClientConnection> server_delete_ref_; 361 : }; 362 : 363 : class XmppConnectionEndpoint { 364 : public: 365 : XmppConnectionEndpoint(const std::string &client); 366 : 367 : void set_close_reason(const std::string &close_reason); 368 : uint32_t flap_count() const; 369 : void increment_flap_count(); 370 : uint64_t last_flap() const; 371 : const std::string last_flap_at() const; 372 : XmppConnection *connection(); 373 : const XmppConnection *connection() const; 374 : void set_connection(XmppConnection *connection); 375 : void reset_connection(); 376 : 377 : private: 378 : std::string client_; 379 : std::string close_reason_; 380 : uint32_t flap_count_; 381 : uint64_t last_flap_; 382 : XmppConnection *connection_; 383 : }; 384 : 385 : #endif // __XMPP_CHANNEL_H__