The reflector server can now handle newer clients

The reflector server now have a mechanism to handle clients using a newer
protocol version than the server supports. If a client upon connect
indicates a protocol version newer than what the server can handle it
will ask the client to downgrade its protocol version. It is up to the
client to choose wether it can handle the downgrade or not.
This commit is contained in:
Tobias Blomberg 2019-10-20 14:06:23 +02:00
parent 3bc78ecfde
commit a2fa7c6f4b
5 changed files with 104 additions and 39 deletions

View File

@ -357,24 +357,35 @@ void ReflectorClient::handleMsgProtoVer(std::istream& is)
MsgProtoVer msg;
if (!msg.unpack(is))
{
cout << "Client " << m_con->remoteHost() << ":" << m_con->remotePort()
<< " ERROR: Could not unpack MsgProtoVer\n";
std::cout << "Client " << m_con->remoteHost() << ":" << m_con->remotePort()
<< " ERROR: Could not unpack MsgProtoVer\n";
sendError("Illegal MsgProtoVer protocol message received");
return;
}
m_client_proto_ver.set(msg.majorVer(), msg.minorVer());
ProtoVerRange valid_proto_ver_range(
ProtoVer(MIN_MAJOR_VER, MIN_MINOR_VER),
ProtoVer(MsgProtoVer::MAJOR, MsgProtoVer::MINOR));
if (!valid_proto_ver_range.isWithinRange(m_client_proto_ver))
ProtoVer max_proto_ver(MsgProtoVer::MAJOR, MsgProtoVer::MINOR);
if (m_client_proto_ver > max_proto_ver)
{
cout << "Client " << m_con->remoteHost() << ":" << m_con->remotePort()
<< " Incompatible protocol version: "
<< msg.majorVer() << "." << msg.minorVer() << ". Should be "
<< MsgProtoVer::MAJOR << "." << MsgProtoVer::MINOR << "." << endl;
stringstream ss;
std::cout << "Client " << m_con->remoteHost() << ":" << m_con->remotePort()
<< " use protocol version "
<< msg.majorVer() << "." << msg.minorVer()
<< " which is newer than we can handle. Asking for downgrade to "
<< MsgProtoVer::MAJOR << "." << MsgProtoVer::MINOR << "."
<< std::endl;
sendMsg(MsgProtoVerDowngrade());
return;
}
else if (m_client_proto_ver < ProtoVer(MIN_MAJOR_VER, MIN_MINOR_VER))
{
std::cout << "Client " << m_con->remoteHost() << ":" << m_con->remotePort()
<< " is using protocol version "
<< msg.majorVer() << "." << msg.minorVer()
<< " which is too old. Must at least be version "
<< MIN_MAJOR_VER << "." << MIN_MINOR_VER << "." << std::endl;
std::ostringstream ss;
ss << "Unsupported protocol version " << msg.majorVer() << "."
<< msg.minorVer();
<< msg.minorVer() << ". Must be at least "
<< MIN_MAJOR_VER << "." << MIN_MINOR_VER << ".";
sendError(ss.str());
return;
}

View File

@ -224,32 +224,6 @@ class ReflectorUdpMsgBase : public ReflectorUdpMsg
/************************** Administrative Messages **************************/
/**
@brief Protocol version TCP network message
@author Tobias Blomberg / SM0SVX
@date 2017-02-12
This is the first message exchanged between the client and the server. It tells
the server what protocol version that the client supports. If the client use a
protocol version that the server does not support, the client is denied access.
*/
class MsgProtoVer : public ReflectorMsgBase<5>
{
public:
static const uint16_t MAJOR = 2;
static const uint16_t MINOR = 0;
MsgProtoVer(void) : m_major(MAJOR), m_minor(MINOR) {}
uint16_t majorVer(void) const { return m_major; }
uint16_t minorVer(void) const { return m_minor; }
ASYNC_MSG_MEMBERS(m_major, m_minor);
private:
uint16_t m_major;
uint16_t m_minor;
}; /* MsgProtoVer */
/**
@brief Heartbeat TCP network message
@author Tobias Blomberg / SM0SVX
@ -265,6 +239,65 @@ class MsgHeartbeat : public ReflectorMsgBase<1>
}; /* MsgHeartbeat */
/**
@brief Protocol version TCP network message
@author Tobias Blomberg / SM0SVX
@date 2017-02-12
This is the first message exchanged between the client and the server. It is
sent by the client to tell the server what protocol version that the client
supports. If the client use a protocol version that the server does not
support, the client is denied access. Alternatively, if the client protocol
version is larger than what the server supports, the server may send a
MsgProtoVerDowngrade message to ask the client to use an older version of the
protocol.
*/
class MsgProtoVer : public ReflectorMsgBase<5>
{
public:
static const uint16_t MAJOR = 2;
static const uint16_t MINOR = 0;
MsgProtoVer(void) : m_major(MAJOR), m_minor(MINOR) {}
MsgProtoVer(uint16_t major, uint16_t minor)
: m_major(major), m_minor(minor) {}
uint16_t majorVer(void) const { return m_major; }
uint16_t minorVer(void) const { return m_minor; }
ASYNC_MSG_MEMBERS(m_major, m_minor);
private:
uint16_t m_major;
uint16_t m_minor;
}; /* MsgProtoVer */
/**
@brief Protocol version downgrade request
@author Tobias Blomberg / SM0SVX
@date 2019-10-19
This message is sent by the reflector server to a client that announces a newer
protocol version than the server is able to support. The client should resend
the MsgProtoVer message set to a version number no larger than what the server
indicates in this message. The client must then use only protocol messages
compatible with the lower protocol version.
*/
class MsgProtoVerDowngrade : public ReflectorMsgBase<6>
{
public:
MsgProtoVerDowngrade(void)
: m_major(MsgProtoVer::MAJOR), m_minor(MsgProtoVer::MINOR) {}
uint16_t majorVer(void) const { return m_major; }
uint16_t minorVer(void) const { return m_minor; }
ASYNC_MSG_MEMBERS(m_major, m_minor);
private:
uint16_t m_major;
uint16_t m_minor;
}; /* MsgProtoVerDowngrade */
/**
@brief Authentication challenge TCP network message
@author Tobias Blomberg / SM0SVX

View File

@ -657,6 +657,9 @@ void ReflectorLogic::onFrameReceived(FramedTcpConnection *con,
case MsgError::TYPE:
handleMsgError(ss);
break;
case MsgProtoVerDowngrade::TYPE:
handleMsgProtoVerDowngrade(ss);
break;
case MsgAuthChallenge::TYPE:
handleMsgAuthChallenge(ss);
break;
@ -711,6 +714,23 @@ void ReflectorLogic::handleMsgError(std::istream& is)
} /* ReflectorLogic::handleMsgError */
void ReflectorLogic::handleMsgProtoVerDowngrade(std::istream& is)
{
MsgProtoVerDowngrade msg;
if (!msg.unpack(is))
{
cerr << "*** ERROR[" << name() << "]: Could not unpack MsgProtoVerDowngrade" << endl;
disconnect();
return;
}
cout << name() << ": Server too old and we cannot downgrade to protocol version "
<< msg.majorVer() << "." << msg.minorVer() << " from "
<< MsgProtoVer::MAJOR << "." << MsgProtoVer::MINOR
<< endl;
disconnect();
} /* ReflectorLogic::handleMsgProtoVerDowngrade */
void ReflectorLogic::handleMsgAuthChallenge(std::istream& is)
{
if (m_con_state != STATE_EXPECT_AUTH_CHALLENGE)

View File

@ -253,6 +253,7 @@ class ReflectorLogic : public LogicBase
void onFrameReceived(Async::FramedTcpConnection *con,
std::vector<uint8_t>& data);
void handleMsgError(std::istream& is);
void handleMsgProtoVerDowngrade(std::istream& is);
void handleMsgAuthChallenge(std::istream& is);
void handleMsgNodeList(std::istream& is);
void handleMsgNodeJoined(std::istream& is);

View File

@ -11,7 +11,7 @@ LIBECHOLIB=1.3.3
LIBASYNC=1.6.0.99.3-reflector_tg
# SvxLink versions
SVXLINK=1.7.99.10-reflector_tg
SVXLINK=1.7.99.11-reflector_tg
MODULE_HELP=1.0.0
MODULE_PARROT=1.1.1
MODULE_ECHO_LINK=1.5.0