17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 12:09:19 +02:00

hardware protocol v2: make the hello handshake idempotent

A device which doesn't hear the welcome repeats its greeting. Minting a
fresh session for every repeat left both ends chasing each other's
session ids: the device eventually answered with the id it had been
given, the simulator had already moved on and rejected it as
INVALID_SESSION, the device restarted the handshake, and so on twice a
second for as long as the link was up.

The same greeting arriving on a session which has not been used yet is
now answered with the session it already has, and only a different
device, or one whose session had progressed, gets a new id. Repeated
greetings are counted as handshakes and shown in the debug panel, so the
condition which causes them stays visible instead of flooding the log.
This commit is contained in:
2026-09-17 15:01:58 +00:00
parent 63f322fa7b
commit 314595e8f0
3 changed files with 44 additions and 10 deletions

View File

@@ -1393,7 +1393,8 @@ debug_panel::update_section_hardware( std::vector<text_line> &Output ) {
+ " symbol " + std::to_string( protocol.unknown_symbols )
+ " handle " + std::to_string( protocol.unknown_handles )
+ " duplicates " + std::to_string( protocol.duplicate_commands )
+ " rate limited " + std::to_string( protocol.rate_limited );
+ " rate limited " + std::to_string( protocol.rate_limited )
+ " handshakes " + std::to_string( protocol.handshakes );
textline +=
"\nack " + std::to_string( protocol.acks )

View File

@@ -65,6 +65,8 @@ struct protocol_diagnostics
std::uint64_t acks = 0;
std::uint64_t nacks = 0;
std::uint64_t rate_limited = 0;
// powitania powtorzone przez urzadzenie, ktore nie uslyszalo WELCOME
std::uint64_t handshakes = 0;
std::uint64_t state_updates = 0;
std::uint64_t commands_executed = 0;
std::uint64_t controls_applied = 0;

View File

@@ -486,13 +486,29 @@ void protocol_session::handle_hello( decoded_packet const &Packet )
return;
}
// a fresh hello always starts a new session, invalidating whatever the previous one held
m_handles.clear();
m_handlelookup.clear();
m_subscriptions.clear();
m_controlsequence.clear();
m_transactions.clear();
m_transactionorder.clear();
// a hello retry has to be idempotent. a device which didn't hear the welcome repeats its
// greeting, and minting a fresh session for every repeat leaves both ends chasing each
// other's session ids: the device answers with the id it was given, the simulator has
// already moved on and rejects it, the device restarts the handshake, forever. the same
// greeting arriving on a session which hasn't been used yet is answered with that session
bool const rehandshake = (
( m_sessionid != 0 )
&& ( m_state == session_state::established )
&& ( true == m_handles.empty() )
&& ( name == m_devicename )
&& ( role == m_devicerole )
&& ( deviceid == m_deviceid ) );
if( false == rehandshake )
{
// a genuinely new session invalidates whatever the previous one held
m_handles.clear();
m_handlelookup.clear();
m_subscriptions.clear();
m_controlsequence.clear();
m_transactions.clear();
m_transactionorder.clear();
}
m_peermajor = major;
m_peerminor = minor;
@@ -506,7 +522,14 @@ void protocol_session::handle_hello( decoded_packet const &Packet )
auto const requested = ( framesize > 0 ? static_cast<std::size_t>( framesize ) : protocol_frame_size_default );
m_framesize = std::clamp<std::size_t>( std::min( requested, m_config.frame_size ), protocol_frame_size_min, protocol_frame_size_max );
m_sessionid = generate_session_id();
if( false == rehandshake )
{
m_sessionid = generate_session_id();
}
else
{
++m_diagnostics.handshakes;
}
m_state = session_state::established;
m_heartbeattimer = 0.0;
m_pingtimer = 0.0;
@@ -522,7 +545,15 @@ void protocol_session::handle_hello( decoded_packet const &Packet )
writer.write_string( Global.asVersion );
send( message_type::welcome, packetflag_response, writer );
WriteLog( "hardware: session " + std::to_string( m_sessionid ) + " established with '" + m_devicename + "' (" + m_devicerole + ")" );
if( false == rehandshake )
{
WriteLog( "hardware: session " + std::to_string( m_sessionid ) + " established with '" + m_devicename + "' (" + m_devicerole + ")" );
}
else if( true == debug_flags.log_messages )
{
// repeated greetings say the welcome isn't getting through; the panel counts them
WriteLog( "hardware: device '" + m_devicename + "' repeated its greeting, session " + std::to_string( m_sessionid ) + " kept" );
}
}
void protocol_session::handle_heartbeat( decoded_packet const &Packet )