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