DDS  ver. 3.4
ServerChannelImpl.h
Go to the documentation of this file.
1 // Copyright 2014 GSI, Inc. All rights reserved.
2 //
3 //
4 //
5 
6 #ifndef DDS_ServerChannelImpl_h
7 #define DDS_ServerChannelImpl_h
8 
9 // DDS
10 #include "BaseChannelImpl.h"
11 #include "version.h"
12 
13 namespace dds
14 {
15  namespace protocol_api
16  {
17  template <class T>
18  class CServerChannelImpl : public CBaseChannelImpl<T>
19  {
20  protected:
21  CServerChannelImpl<T>(boost::asio::io_context& _service, const channelTypeVector_t _requiredChannelTypes)
22  : CBaseChannelImpl<T>(_service, 0)
23  , m_requiredChannelTypes(_requiredChannelTypes)
24  {
25  // Register handshake callback
26  this->template registerHandler<cmdHANDSHAKE>(
27  [this](const SSenderInfo& _sender, SCommandAttachmentImpl<cmdHANDSHAKE>::ptr_t _attachment) {
28  if (!processHandshake_channelTypeSupported(
29  static_cast<EChannelType>(_attachment->m_channelType), true, _sender.m_ID))
30  return;
31  if (!processHandshake_versionMatch(_attachment->m_version, true, _sender.m_ID))
32  return;
33  if (!processHandshake_sessionIDMatch(_attachment->m_sSID, true, _sender.m_ID))
34  return;
35 
36  this->m_protocolHeaderID = _sender.m_ID;
37  this->m_isHandshakeOK = true;
38  this->m_channelType = static_cast<EChannelType>(_attachment->m_channelType);
39 
40  // The following commands starts message processing which might have been queued before.
41  this->template pushMsg<cmdUNKNOWN>();
42 
43  // everything is OK, we can work with this agent
44  LOG(MiscCommon::info) << "[" << this->socket().remote_endpoint().address().to_string()
45  << "] has successfully connected.";
46 
47  this->template pushMsg<cmdREPLY_HANDSHAKE_OK>(_sender.m_ID);
48 
49  // notify all subscribers about the event
50  this->dispatchHandlers(EChannelEvents::OnHandshakeOK, _sender);
51  });
52 
53  // Register handshake callback
54  // this->template registerHandler<cmdLOBBY_MEMBER_HANDSHAKE>(
55  // [this](const SSenderInfo& _sender,
56  // SCommandAttachmentImpl<cmdLOBBY_MEMBER_HANDSHAKE>::ptr_t _attachment) {
57  // if (!processHandshake_channelTypeSupported(
58  // static_cast<EChannelType>(_attachment->m_channelType), false,
59  // _sender.m_ID))
60  // return;
61  // if (!processHandshake_versionMatch(_attachment->m_version, false,
62  // _sender.m_ID))
63  // return;
64  // if (!processHandshake_sessionIDMatch(_attachment->m_sSID, false,
65  // _sender.m_ID))
66  // return;
67  //
68  // // everything is OK, we can work with this agent
69  // LOG(MiscCommon::info)
70  // << "New lobby member [" << _sender.m_ID << "] has successfully
71  // connected.";
72  //
73  // SReplyCmd cmd =
74  // SReplyCmd("", (uint16_t)SReplyCmd::EStatusCode::OK, 0,
75  // (uint16_t)cmdLOBBY_MEMBER_HANDSHAKE);
76  // this->template pushMsg<cmdREPLY>(cmd, _sender.m_ID);
77  //
78  // // notify all subscribers about the event
79  // this->dispatchHandlers(EChannelEvents::OnLobbyMemberHandshakeOK, _sender);
80  // });
81  }
82 
84  {
85  }
86 
87  private:
88  bool processHandshake_channelTypeSupported(EChannelType _channelType, bool _lobbyLeader, uint64_t _senderID)
89  {
90  // Check that the client channel is actually supported
91  bool isSupportedChnl(false);
92  for (const auto& v : m_requiredChannelTypes)
93  {
94  isSupportedChnl = (_channelType == v);
95  if (isSupportedChnl)
96  break;
97  }
98 
99  if (!isSupportedChnl)
100  {
101  handshakeFailed("Unsupported channel type", _lobbyLeader, _senderID);
102  return false;
103  }
104  return true;
105  }
106 
107  bool processHandshake_versionMatch(uint16_t _version, bool _lobbyLeader, uint64_t _senderID)
108  {
109  // send shutdown if versions are incompatible
110  if (_version != DDS_PROTOCOL_VERSION)
111  {
112  std::stringstream ss;
113  ss << "Incompatible protocol version. Server: " << DDS_PROTOCOL_VERSION << " Client: " << _version;
114  handshakeFailed(ss.str(), _lobbyLeader, _senderID);
115  return false;
116  }
117  return true;
118  }
119 
120  bool processHandshake_sessionIDMatch(const std::string& _sessionID, bool _lobbyLeader, uint64_t _senderID)
121  {
122  // Check Session ID
123  if (this->m_sessionID.empty() || this->m_sessionID != _sessionID)
124  {
125  handshakeFailed("Incompatible Session ID", _lobbyLeader, _senderID);
126  return false;
127  }
128  return true;
129  }
130 
131  void handshakeFailed(const std::string& _reason, bool _lobbyLeader, uint64_t _senderID)
132  {
133  this->m_isHandshakeOK = false;
135  LOG(MiscCommon::warning) << _reason << "; Client: " << this->remoteEndIDString();
136 
137  this->template pushMsg<cmdREPLY_HANDSHAKE_ERR>(SSimpleMsgCmd(_reason, MiscCommon::fatal), _senderID);
138  // notify all subscribers about the event
139  this->dispatchHandlers(EChannelEvents::OnHandshakeFailed, SSenderInfo());
140  }
141 
142  private:
143  channelTypeVector_t m_requiredChannelTypes;
144  };
145  } // namespace protocol_api
146 } // namespace dds
147 
148 #endif
bool m_isHandshakeOK
Definition: BaseChannelImpl.h:988
Definition: def.h:151
Definition: BaseEventHandlersImpl.h:48
EChannelType
Definition: ProtocolDef.h:15
EChannelType m_channelType
Definition: BaseChannelImpl.h:989
std::shared_ptr< SEmptyCmd > ptr_t
Definition: CommandAttachmentImpl.h:64
std::string m_sessionID
Definition: BaseChannelImpl.h:990
#define LOG(severity)
Definition: Logger.h:56
Definition: AgentConnectionManager.h:13
std::string remoteEndIDString()
Definition: BaseChannelImpl.h:755
Definition: def.h:153
Definition: BaseChannelImpl.h:224
Definition: BaseChannelImpl.h:42
std::vector< EChannelType > channelTypeVector_t
Definition: ProtocolDef.h:21
boost::asio::ip::tcp::socket & socket()
Definition: BaseChannelImpl.h:326
uint64_t m_ID
Definition: BaseEventHandlersImpl.h:50
Definition: def.h:150