# # # patch "constants.hh" # from [adc7ef399cc939ee0b1ec47b97510f7ebdcaf2fd] # to [66134f17373632d6b83ae6cd293b319ed2219c8c] # # patch "netcmd.cc" # from [303dbc50dc5e0ab9e0eb381d1faad7fbab1c592c] # to [db8fdc942bab5c77a2335b0663baf8df116f62e0] # # patch "netsync.cc" # from [11a86d0793f450923d9f6e3eaedf696e4d6bfe20] # to [2eeffe750a843e30a2c13e4621f6f62f0ebb0096] # ============================================================ --- constants.hh adc7ef399cc939ee0b1ec47b97510f7ebdcaf2fd +++ constants.hh 66134f17373632d6b83ae6cd293b319ed2219c8c @@ -130,6 +130,9 @@ namespace constants // the current netcmd/netsync protocol version u8 const netcmd_current_protocol_version = 7; + // the oldest netcmd/netsync protocol version that we're compatible with + u8 const netcmd_minimum_protocol_version = 6; + // minimum size of any netcmd on the wire std::size_t const netcmd_minsz = (1 // version + 1 // cmd code ============================================================ --- netcmd.cc 303dbc50dc5e0ab9e0eb381d1faad7fbab1c592c +++ netcmd.cc db8fdc942bab5c77a2335b0663baf8df116f62e0 @@ -46,7 +46,7 @@ read_netcmd_item_type(string const & in, } } -netcmd::netcmd() : version(constants::netcmd_current_protocol_version), +netcmd::netcmd() : version(0), cmd_code(error_cmd) {} @@ -112,12 +112,15 @@ netcmd::read(string_queue & inbuf, chain default: // if the versions don't match, we will throw the more descriptive // error immediately after this switch. - if (extracted_ver == version) + if (extracted_ver <= constants::netcmd_current_protocol_version && + extracted_ver >= constants::netcmd_minimum_protocol_version) throw bad_decode(F("unknown netcmd code 0x%x") % widen(cmd_byte)); } // Ignore the version on usher_cmd packets. - if (extracted_ver != version && cmd_code != usher_cmd) + if (extracted_ver <= constants::netcmd_current_protocol_version && + extracted_ver >= constants::netcmd_minimum_protocol_version && + cmd_code != usher_cmd) throw bad_decode(F("protocol version mismatch: wanted '%d' got '%d'\n" "%s") % widen(version) ============================================================ --- netsync.cc 11a86d0793f450923d9f6e3eaedf696e4d6bfe20 +++ netsync.cc 2eeffe750a843e30a2c13e4621f6f62f0ebb0096 @@ -156,7 +156,31 @@ // drop the TCP stream at any point, if too much data is received or too // much idle time passes; no commitments or transactions are made. // +// Version Negotiation +// ------------------- // +// Before the exchange begin, the client may receive one or more +// "usher " packets, any number sent by "usher" proxies and +// one sent by more recent servers. It ignores the protocol version +// field on these packets, but replys with a "usher_reply " +// packet containing its own maximum supported protocol version. +// +// Older server begin by sending a "hello" packet (see below) that contains +// their only supported protocol version. New servers first send a "usher" +// packet and use the response to determine the client's maximum protocol +// version, and then use the lesser of that or their own maximum version +// in the "hello" packet and all later packets. +// +// When the client receive the "hello" packet it uses that version as the +// protocol version for all remaining packets. +// +// If the "usher_reply" packet indicates a version that's older than the +// minimum version supported by the server, the server sends an error packet +// and closes the connection. +// +// If the "hello" packet indicates a version not supported by the client, +// it sends an error packet and closes the connection. +// // Authentication and setup // ------------------------ //