#
# patch "ChangeLog"
# from [f3d65f60cc585499549c93f29ea1e8e79e41798d]
# to [7eced76606bfb456d0015e674b666ecc2b62f46d]
#
# patch "netcmd.cc"
# from [36e1f3cae4c4b0ac416d746d2895373068aa043a]
# to [a7231f09224add93dd959915476088cc3fa951ba]
#
# patch "netcmd.hh"
# from [ab57b4e82546eb7dd946605d4fb84363883e99d9]
# to [5626696805eab24ff5bd23f114a749b3aa78645a]
#
# patch "netsync.cc"
# from [db4dc72988745a0d40e7b90db4b02aceb1533697]
# to [7cf6b787b43c2ab13abd1d2343e915f84778eddb]
#
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,10 @@
+2005-06-04 Timothy Brownawell
+
+ * netcmd.{cc,hh}, netsync.cc: Move {read,write}_*_cmd_payload
+ to netcmd::{read,write}_*_cmd .
+ * netcmd.cc, netsync.cc: Compatibility infrastructure.
+ * netsync.cc: Interoperate with v4 servers.
+
2005-06-03 Timothy Brownawell
* automate.cc (print_some_output): Fix compiler warning.
--- netcmd.cc
+++ netcmd.cc
@@ -50,6 +50,9 @@
cmd_code(bye_cmd)
{}
+netcmd::netcmd(u8 _version) : version(_version), cmd_code(bye_cmd)
+{}
+
size_t netcmd::encoded_size()
{
string tmp;
@@ -66,39 +69,63 @@
}
void
-write_netcmd(netcmd const & in, string & out)
+netcmd::write(string & out) const
{
- out += static_cast(in.version);
- out += static_cast(in.cmd_code);
- insert_variable_length_string(in.payload, out);
- adler32 check(reinterpret_cast(in.payload.data()),
- in.payload.size());
+ out += static_cast(version);
+ out += static_cast(cmd_code);
+ insert_variable_length_string(payload, out);
+ adler32 check(reinterpret_cast(payload.data()), payload.size());
insert_datum_lsb(check.sum(), out);
}
+
+// last should be zero (doesn't mean we're compatible with version 0).
+// The nonzero elements are the historical netsync/netcmd versions we can
+// interoperate with. For interoperating with newer versions, assume
+// compatibility and let the remote host make the call.
+static u8 const compatible_versions[] = {4, 0};
+
+bool is_compatible(u8 version)
+{
+ for(u8 const *x=compatible_versions; *x; ++x)
+ {
+ if(*x == version)
+ return true;
+ }
+ return false;
+}
bool
-read_netcmd(string & inbuf, netcmd & out)
+netcmd::read(string & inbuf)
{
size_t pos = 0;
if (inbuf.size() < constants::netcmd_minsz)
return false;
- out.version = extract_datum_lsb(inbuf, pos, "netcmd protocol number");
- int v = constants::netcmd_current_protocol_version;
- if (out.version != constants::netcmd_current_protocol_version)
- throw bad_decode(F("protocol version mismatch: wanted '%d' got '%d'")
- % widen(v)
- % widen(out.version));
+ u8 ver = extract_datum_lsb(inbuf, pos, "netcmd protocol number");
+ int v = version;
u8 cmd_byte = extract_datum_lsb(inbuf, pos, "netcmd code");
switch (cmd_byte)
{
- case static_cast(error_cmd):
- case static_cast(bye_cmd):
+ // hello may be newer than expected, or one we're compatible with
case static_cast(hello_cmd):
+ if (ver < version && !is_compatible(ver))
+ throw bad_decode(F("protocol version mismatch: wanted '%d' got '%d'")
+ % widen(v)
+ % widen(ver));
+ break;
+ // these may be older compatible versions
case static_cast(anonymous_cmd):
case static_cast(auth_cmd):
+ if (ver != version && (ver > version || !is_compatible(ver)))
+ throw bad_decode(F("protocol version mismatch: wanted '%d' got '%d'")
+ % widen(v)
+ % widen(ver));
+ break;
+ // these must match exactly what's expected
+ case static_cast(error_cmd):
+ case static_cast(bye_cmd):
case static_cast(confirm_cmd):
case static_cast(refine_cmd):
case static_cast(done_cmd):
@@ -107,11 +134,16 @@
case static_cast(data_cmd):
case static_cast(delta_cmd):
case static_cast(nonexistant_cmd):
- out.cmd_code = static_cast(cmd_byte);
+ if (ver != version)
+ throw bad_decode(F("protocol version mismatch: wanted '%d' got '%d'")
+ % widen(v)
+ % widen(ver));
break;
default:
throw bad_decode(F("unknown netcmd code 0x%x") % widen(cmd_byte));
}
+ cmd_code = static_cast(cmd_byte);
+ version = ver;
// check to see if we have even enough bytes for a complete uleb128
size_t payload_len = 0;
@@ -133,16 +165,16 @@
// Do this ourselves, so we can swap the strings instead of copying.
require_bytes(inbuf, pos, payload_len, "netcmd payload");
inbuf.erase(0, pos);
- out.payload=inbuf.substr(payload_len);
+ payload=inbuf.substr(payload_len);
inbuf.erase(payload_len, inbuf.npos);
- inbuf.swap(out.payload);
+ inbuf.swap(payload);
pos=0;
// they might have given us bogus data
u32 checksum = extract_datum_lsb(inbuf, pos, "netcmd checksum");
inbuf.erase(0, pos);
- adler32 check(reinterpret_cast(out.payload.data()),
- out.payload.size());
+ adler32 check(reinterpret_cast(payload.data()),
+ payload.size());
if (checksum != check.sum())
throw bad_decode(F("bad checksum 0x%x vs. 0x%x") % checksum % check.sum());
@@ -154,357 +186,369 @@
////////////////////////////////////////////
void
-read_error_cmd_payload(std::string const & in,
- std::string & errmsg)
+netcmd::read_error_cmd(std::string & errmsg) const
{
size_t pos = 0;
// syntax is:
- extract_variable_length_string(in, errmsg, pos, "error netcmd, message");
- assert_end_of_buffer(in, pos, "error netcmd payload");
+ extract_variable_length_string(payload, errmsg, pos, "error netcmd, message");
+ assert_end_of_buffer(payload, pos, "error netcmd payload");
}
void
-write_error_cmd_payload(std::string const & errmsg,
- std::string & out)
+netcmd::write_error_cmd(std::string const & errmsg)
{
- insert_variable_length_string(errmsg, out);
+ cmd_code = error_cmd;
+ payload.clear();
+ insert_variable_length_string(errmsg, payload);
}
void
-read_hello_cmd_payload(string const & in,
- rsa_keypair_id & server_keyname,
+netcmd::read_hello_cmd(rsa_keypair_id & server_keyname,
rsa_pub_key & server_key,
- id & nonce)
+ id & nonce) const
{
size_t pos = 0;
// syntax is:
string skn_str, sk_str;
- extract_variable_length_string(in, skn_str, pos, "hello netcmd, server key name");
+ extract_variable_length_string(payload, skn_str, pos,
+ "hello netcmd, server key name");
server_keyname = rsa_keypair_id(skn_str);
- extract_variable_length_string(in, sk_str, pos, "hello netcmd, server key");
+ extract_variable_length_string(payload, sk_str, pos,
+ "hello netcmd, server key");
server_key = rsa_pub_key(sk_str);
- nonce = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ nonce = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"hello netcmd, nonce"));
- assert_end_of_buffer(in, pos, "hello netcmd payload");
+ assert_end_of_buffer(payload, pos, "hello netcmd payload");
}
void
-write_hello_cmd_payload(rsa_keypair_id const & server_keyname,
+netcmd::write_hello_cmd(rsa_keypair_id const & server_keyname,
rsa_pub_key const & server_key,
- id const & nonce,
- string & out)
+ id const & nonce)
{
+ cmd_code = hello_cmd;
+ payload.clear();
I(nonce().size() == constants::merkle_hash_length_in_bytes);
- insert_variable_length_string(server_keyname(), out);
- insert_variable_length_string(server_key(), out);
- out += nonce();
+ insert_variable_length_string(server_keyname(), payload);
+ insert_variable_length_string(server_key(), payload);
+ payload += nonce();
}
void
-read_anonymous_cmd_payload(std::string const & in,
- protocol_role & role,
+netcmd::read_anonymous_cmd(protocol_role & role,
std::string & pattern,
- id & nonce2)
+ id & nonce2) const
{
size_t pos = 0;
// syntax is:
- u8 role_byte = extract_datum_lsb(in, pos, "anonymous netcmd, role");
+ u8 role_byte = extract_datum_lsb(payload, pos, "anonymous netcmd, role");
if (role_byte != static_cast(source_role)
&& role_byte != static_cast(sink_role)
&& role_byte != static_cast(source_and_sink_role))
throw bad_decode(F("unknown role specifier %d") % widen(role_byte));
role = static_cast(role_byte);
- extract_variable_length_string(in, pattern, pos, "anonymous netcmd, pattern");
- nonce2 = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ extract_variable_length_string(payload, pattern, pos,
+ "anonymous netcmd, pattern");
+ nonce2 = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"anonymous netcmd, nonce2"));
- assert_end_of_buffer(in, pos, "anonymous netcmd payload");
+ assert_end_of_buffer(payload, pos, "anonymous netcmd payload");
}
void
-write_anonymous_cmd_payload(protocol_role role,
+netcmd::write_anonymous_cmd(protocol_role role,
std::string const & pattern,
- id const & nonce2,
- std::string & out)
+ id const & nonce2)
{
+ cmd_code = anonymous_cmd;
I(nonce2().size() == constants::merkle_hash_length_in_bytes);
- out += static_cast(role);
- insert_variable_length_string(pattern, out);
- out += nonce2();
+ payload = static_cast(role);
+ insert_variable_length_string(pattern, payload);
+ payload += nonce2();
}
void
-read_auth_cmd_payload(string const & in,
- protocol_role & role,
+netcmd::read_auth_cmd(protocol_role & role,
string & pattern,
id & client,
id & nonce1,
id & nonce2,
- string & signature)
+ string & signature) const
{
size_t pos = 0;
// syntax is:
//
//
- u8 role_byte = extract_datum_lsb(in, pos, "auth netcmd, role");
+ u8 role_byte = extract_datum_lsb(payload, pos, "auth netcmd, role");
if (role_byte != static_cast(source_role)
&& role_byte != static_cast(sink_role)
&& role_byte != static_cast(source_and_sink_role))
throw bad_decode(F("unknown role specifier %d") % widen(role_byte));
role = static_cast(role_byte);
- extract_variable_length_string(in, pattern, pos, "auth netcmd, pattern");
- client = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ extract_variable_length_string(payload, pattern, pos, "auth netcmd, pattern");
+ client = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"auth netcmd, client identifier"));
- nonce1 = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ nonce1 = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"auth netcmd, nonce1"));
- nonce2 = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ nonce2 = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"auth netcmd, nonce2"));
- extract_variable_length_string(in, signature, pos, "auth netcmd, signature");
- assert_end_of_buffer(in, pos, "auth netcmd payload");
+ extract_variable_length_string(payload, signature, pos,
+ "auth netcmd, signature");
+ assert_end_of_buffer(payload, pos, "auth netcmd payload");
}
void
-write_auth_cmd_payload(protocol_role role,
+netcmd::write_auth_cmd(protocol_role role,
string const & pattern,
id const & client,
id const & nonce1,
id const & nonce2,
- string const & signature,
- string & out)
+ string const & signature)
{
+ cmd_code = auth_cmd;
I(client().size() == constants::merkle_hash_length_in_bytes);
I(nonce1().size() == constants::merkle_hash_length_in_bytes);
I(nonce2().size() == constants::merkle_hash_length_in_bytes);
- out += static_cast(role);
- insert_variable_length_string(pattern, out);
- out += client();
- out += nonce1();
- out += nonce2();
- insert_variable_length_string(signature, out);
+ payload = static_cast(role);
+ insert_variable_length_string(pattern, payload);
+ payload += client();
+ payload += nonce1();
+ payload += nonce2();
+ insert_variable_length_string(signature, payload);
}
void
-read_confirm_cmd_payload(string const & in,
- string & signature)
+netcmd::read_confirm_cmd(string & signature) const
{
size_t pos = 0;
// syntax is:
- extract_variable_length_string(in, signature, pos, "confirm netcmd, signature");
- assert_end_of_buffer(in, pos, "confirm netcmd payload");
+ extract_variable_length_string(payload, signature, pos,
+ "confirm netcmd, signature");
+ assert_end_of_buffer(payload, pos, "confirm netcmd payload");
}
void
-write_confirm_cmd_payload(string const & signature,
- string & out)
+netcmd::write_confirm_cmd(string const & signature)
{
- insert_variable_length_string(signature, out);
+ cmd_code = confirm_cmd;
+ payload.clear();
+ insert_variable_length_string(signature, payload);
}
void
-read_refine_cmd_payload(string const & in, merkle_node & node)
+netcmd::read_refine_cmd(merkle_node & node) const
{
// syntax is:
- read_node(in, node);
+ read_node(payload, node);
}
void
-write_refine_cmd_payload(merkle_node const & node, string & out)
+netcmd::write_refine_cmd(merkle_node const & node)
{
- write_node(node, out);
+ cmd_code = refine_cmd;
+ payload.clear();
+ write_node(node, payload);
}
void
-read_done_cmd_payload(string const & in,
- size_t & level,
- netcmd_item_type & type)
+netcmd::read_done_cmd(size_t & level, netcmd_item_type & type) const
{
size_t pos = 0;
// syntax is:
- level = extract_datum_uleb128(in, pos, "done netcmd, level number");
- type = read_netcmd_item_type(in, pos, "done netcmd, item type");
- assert_end_of_buffer(in, pos, "done netcmd payload");
+ level = extract_datum_uleb128(payload, pos,
+ "done netcmd, level number");
+ type = read_netcmd_item_type(payload, pos, "done netcmd, item type");
+ assert_end_of_buffer(payload, pos, "done netcmd payload");
}
void
-write_done_cmd_payload(size_t level,
- netcmd_item_type type,
- string & out)
+netcmd::write_done_cmd(size_t level,
+ netcmd_item_type type)
{
- insert_datum_uleb128(level, out);
- out += static_cast(type);
+ cmd_code = done_cmd;
+ payload.clear();
+ insert_datum_uleb128(level, payload);
+ payload += static_cast(type);
}
void
-read_send_data_cmd_payload(string const & in,
- netcmd_item_type & type,
- id & item)
+netcmd::read_send_data_cmd(netcmd_item_type & type, id & item) const
{
size_t pos = 0;
// syntax is:
- type = read_netcmd_item_type(in, pos, "send_data netcmd, item type");
- item = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ type = read_netcmd_item_type(payload, pos, "send_data netcmd, item type");
+ item = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"send_data netcmd, item identifier"));
- assert_end_of_buffer(in, pos, "send_data netcmd payload");
+ assert_end_of_buffer(payload, pos, "send_data netcmd payload");
}
void
-write_send_data_cmd_payload(netcmd_item_type type,
- id const & item,
- string & out)
+netcmd::write_send_data_cmd(netcmd_item_type type, id const & item)
{
+ cmd_code = send_data_cmd;
I(item().size() == constants::merkle_hash_length_in_bytes);
- out += static_cast(type);
- out += item();
+ payload = static_cast(type);
+ payload += item();
}
void
-read_send_delta_cmd_payload(string const & in,
- netcmd_item_type & type,
+netcmd::read_send_delta_cmd(netcmd_item_type & type,
id & base,
- id & ident)
+ id & ident) const
{
size_t pos = 0;
// syntax is:
- type = read_netcmd_item_type(in, pos, "send_delta netcmd, item type");
- base = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ type = read_netcmd_item_type(payload, pos, "send_delta netcmd, item type");
+ base = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"send_delta netcmd, base item identifier"));
- ident = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ ident = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"send_delta netcmd, ident item identifier"));
- assert_end_of_buffer(in, pos, "send_delta netcmd payload");
+ assert_end_of_buffer(payload, pos, "send_delta netcmd payload");
}
void
-write_send_delta_cmd_payload(netcmd_item_type type,
+netcmd::write_send_delta_cmd(netcmd_item_type type,
id const & base,
- id const & ident,
- string & out)
+ id const & ident)
{
+ cmd_code = send_delta_cmd;
I(base().size() == constants::merkle_hash_length_in_bytes);
I(ident().size() == constants::merkle_hash_length_in_bytes);
- out += static_cast(type);
- out += base();
- out += ident();
+ payload = static_cast(type);
+ payload += base();
+ payload += ident();
}
void
-read_data_cmd_payload(string const & in,
- netcmd_item_type & type,
- id & item,
- string & dat)
+netcmd::read_data_cmd(netcmd_item_type & type,
+ id & item, string & dat) const
{
size_t pos = 0;
// syntax is:
//
- type = read_netcmd_item_type(in, pos, "data netcmd, item type");
- item = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ type = read_netcmd_item_type(payload, pos, "data netcmd, item type");
+ item = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"data netcmd, item identifier"));
dat.clear();
- u8 compressed_p = extract_datum_lsb(in, pos, "data netcmd, compression flag");
- extract_variable_length_string(in, dat, pos, "data netcmd, data payload");
+ u8 compressed_p = extract_datum_lsb(payload, pos,
+ "data netcmd, compression flag");
+ extract_variable_length_string(payload, dat, pos,
+ "data netcmd, data payload");
if (compressed_p == 1)
dat = xform(dat);
- assert_end_of_buffer(in, pos, "data netcmd payload");
+ assert_end_of_buffer(payload, pos, "data netcmd payload");
}
void
-write_data_cmd_payload(netcmd_item_type type,
+netcmd::write_data_cmd(netcmd_item_type type,
id const & item,
- string const & dat,
- string & out)
+ string const & dat)
{
+ cmd_code = data_cmd;
I(item().size() == constants::merkle_hash_length_in_bytes);
- out += static_cast(type);
- out += item();
+ payload = static_cast(type);
+ payload += item();
if (dat.size() > constants::netcmd_minimum_bytes_to_bother_with_gzip)
{
string tmp;
tmp = xform(dat);
- out += static_cast(1); // compressed flag
- insert_variable_length_string(tmp, out);
+ payload += static_cast(1); // compressed flag
+ insert_variable_length_string(tmp, payload);
}
else
{
- out += static_cast(0); // compressed flag
- insert_variable_length_string(dat, out);
+ payload += static_cast(0); // compressed flag
+ insert_variable_length_string(dat, payload);
}
}
void
-read_delta_cmd_payload(string const & in,
- netcmd_item_type & type,
- id & base, id & ident, delta & del)
+netcmd::read_delta_cmd(netcmd_item_type & type,
+ id & base, id & ident, delta & del) const
{
size_t pos = 0;
// syntax is:
//
- type = read_netcmd_item_type(in, pos, "delta netcmd, item type");
- base = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ type = read_netcmd_item_type(payload, pos, "delta netcmd, item type");
+ base = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"delta netcmd, base identifier"));
- ident = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ ident = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"delta netcmd, ident identifier"));
- u8 compressed_p = extract_datum_lsb(in, pos, "delta netcmd, compression flag");
+ u8 compressed_p = extract_datum_lsb(payload, pos,
+ "delta netcmd, compression flag");
string tmp;
- extract_variable_length_string(in, tmp, pos, "delta netcmd, delta payload");
+ extract_variable_length_string(payload, tmp, pos,
+ "delta netcmd, delta payload");
if (compressed_p == 1)
tmp = xform(tmp);
del = delta(tmp);
- assert_end_of_buffer(in, pos, "delta netcmd payload");
+ assert_end_of_buffer(payload, pos, "delta netcmd payload");
}
void
-write_delta_cmd_payload(netcmd_item_type & type,
+netcmd::write_delta_cmd(netcmd_item_type & type,
id const & base, id const & ident,
- delta const & del, string & out)
+ delta const & del)
{
+ cmd_code = delta_cmd;
I(base().size() == constants::merkle_hash_length_in_bytes);
I(ident().size() == constants::merkle_hash_length_in_bytes);
- out += static_cast(type);
- out += base();
- out += ident();
+ payload = static_cast(type);
+ payload += base();
+ payload += ident();
string tmp = del();
if (tmp.size() > constants::netcmd_minimum_bytes_to_bother_with_gzip)
{
- out += static_cast(1); // compressed flag
+ payload += static_cast(1); // compressed flag
tmp = xform(tmp);
}
else
{
- out += static_cast(0); // compressed flag
+ payload += static_cast(0); // compressed flag
}
I(tmp.size() <= constants::netcmd_payload_limit);
- insert_variable_length_string(tmp, out);
+ insert_variable_length_string(tmp, payload);
}
void
-read_nonexistant_cmd_payload(string const & in,
- netcmd_item_type & type,
- id & item)
+netcmd::read_nonexistant_cmd(netcmd_item_type & type, id & item) const
{
size_t pos = 0;
// syntax is:
- type = read_netcmd_item_type(in, pos, "nonexistant netcmd, item type");
- item = id(extract_substring(in, pos, constants::merkle_hash_length_in_bytes,
+ type = read_netcmd_item_type(payload, pos, "nonexistant netcmd, item type");
+ item = id(extract_substring(payload, pos,
+ constants::merkle_hash_length_in_bytes,
"nonexistant netcmd, item identifier"));
- assert_end_of_buffer(in, pos, "nonexistant netcmd payload");
+ assert_end_of_buffer(payload, pos, "nonexistant netcmd payload");
}
void
-write_nonexistant_cmd_payload(netcmd_item_type type,
- id const & item,
- string & out)
+netcmd::write_nonexistant_cmd(netcmd_item_type type, id const & item)
{
+ cmd_code = nonexistant_cmd;
I(item().size() == constants::merkle_hash_length_in_bytes);
- out += static_cast(type);
- out += item();
+ payload = static_cast(type);
+ payload += item();
}
@@ -527,11 +571,10 @@
netcmd out_cmd, in_cmd;
string out_errmsg("your shoelaces are untied"), in_errmsg;
string buf;
- out_cmd.cmd_code = error_cmd;
- write_error_cmd_payload(out_errmsg, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_error_cmd_payload(in_cmd.payload, in_errmsg);
+ out_cmd.write_error_cmd(out_errmsg);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_error_cmd(in_errmsg);
BOOST_CHECK(in_cmd == out_cmd);
BOOST_CHECK(in_errmsg == out_errmsg);
L(F("errmsg_cmd test done, buffer was %d bytes\n") % buf.size());
@@ -542,9 +585,8 @@
L(F("checking i/o round trip on bye_cmd\n"));
netcmd out_cmd, in_cmd;
string buf;
- out_cmd.cmd_code = bye_cmd;
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
BOOST_CHECK(in_cmd == out_cmd);
L(F("bye_cmd test done, buffer was %d bytes\n") % buf.size());
}
@@ -557,11 +599,10 @@
rsa_keypair_id out_server_keyname("address@hidden"), in_server_keyname;
rsa_pub_key out_server_key("9387938749238792874"), in_server_key;
id out_nonce(raw_sha1("nonce it up")), in_nonce;
- out_cmd.cmd_code = hello_cmd;
- write_hello_cmd_payload(out_server_keyname, out_server_key, out_nonce, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_hello_cmd_payload(in_cmd.payload, in_server_keyname, in_server_key, in_nonce);
+ out_cmd.write_hello_cmd(out_server_keyname, out_server_key, out_nonce);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_hello_cmd(in_server_keyname, in_server_key, in_nonce);
BOOST_CHECK(in_cmd == out_cmd);
BOOST_CHECK(in_server_keyname == out_server_keyname);
BOOST_CHECK(in_server_key == out_server_key);
@@ -578,11 +619,10 @@
id out_nonce2(raw_sha1("nonce start my heart")), in_nonce2;
string out_pattern("radishes galore!"), in_pattern;
- out_cmd.cmd_code = anonymous_cmd;
- write_anonymous_cmd_payload(out_role, out_pattern, out_nonce2, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_anonymous_cmd_payload(in_cmd.payload, in_role, in_pattern, in_nonce2);
+ out_cmd.write_anonymous_cmd(out_role, out_pattern, out_nonce2);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_anonymous_cmd(in_role, in_pattern, in_nonce2);
BOOST_CHECK(in_cmd == out_cmd);
BOOST_CHECK(in_nonce2 == out_nonce2);
BOOST_CHECK(in_role == out_role);
@@ -601,13 +641,12 @@
string out_signature(raw_sha1("burble") + raw_sha1("gorby")), out_pattern("radishes galore!"),
in_signature, in_pattern;
- out_cmd.cmd_code = auth_cmd;
- write_auth_cmd_payload(out_role, out_pattern, out_client, out_nonce1,
- out_nonce2, out_signature, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_auth_cmd_payload(in_cmd.payload, in_role, in_pattern, in_client,
- in_nonce1, in_nonce2, in_signature);
+ out_cmd.write_auth_cmd(out_role, out_pattern, out_client, out_nonce1,
+ out_nonce2, out_signature);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_auth_cmd(in_role, in_pattern, in_client,
+ in_nonce1, in_nonce2, in_signature);
BOOST_CHECK(in_cmd == out_cmd);
BOOST_CHECK(in_client == out_client);
BOOST_CHECK(in_nonce1 == out_nonce1);
@@ -624,11 +663,10 @@
string buf;
string out_signature(raw_sha1("egg") + raw_sha1("tomago")), in_signature;
- out_cmd.cmd_code = confirm_cmd;
- write_confirm_cmd_payload(out_signature, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_confirm_cmd_payload(in_cmd.payload, in_signature);
+ out_cmd.write_confirm_cmd(out_signature);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_confirm_cmd(in_signature);
BOOST_CHECK(in_cmd == out_cmd);
BOOST_CHECK(in_signature == out_signature);
L(F("confirm_cmd test done, buffer was %d bytes\n") % buf.size());
@@ -650,11 +688,10 @@
out_node.set_slot_state(8, dead_leaf_state);
out_node.set_slot_state(15, subtree_state);
- out_cmd.cmd_code = refine_cmd;
- write_refine_cmd_payload(out_node, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_refine_cmd_payload(in_cmd.payload, in_node);
+ out_cmd.write_refine_cmd(out_node);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_refine_cmd(in_node);
BOOST_CHECK(in_cmd == out_cmd);
BOOST_CHECK(in_node == out_node);
L(F("refine_cmd test done, buffer was %d bytes\n") % buf.size());
@@ -668,11 +705,10 @@
netcmd_item_type out_type(key_item), in_type(manifest_item);
string buf;
- out_cmd.cmd_code = done_cmd;
- write_done_cmd_payload(out_level, out_type, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_done_cmd_payload(in_cmd.payload, in_level, in_type);
+ out_cmd.write_done_cmd(out_level, out_type);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_done_cmd(in_level, in_type);
BOOST_CHECK(in_level == out_level);
BOOST_CHECK(in_type == out_type);
L(F("done_cmd test done, buffer was %d bytes\n") % buf.size());
@@ -686,11 +722,10 @@
id out_id(raw_sha1("avocado is the yummiest")), in_id;
string buf;
- out_cmd.cmd_code = send_data_cmd;
- write_send_data_cmd_payload(out_type, out_id, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_send_data_cmd_payload(in_cmd.payload, in_type, in_id);
+ out_cmd.write_send_data_cmd(out_type, out_id);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_send_data_cmd(in_type, in_id);
BOOST_CHECK(in_type == out_type);
BOOST_CHECK(in_id == out_id);
L(F("send_data_cmd test done, buffer was %d bytes\n") % buf.size());
@@ -705,11 +740,10 @@
id out_base(raw_sha1("always check the exit locations")), in_base;
string buf;
- out_cmd.cmd_code = send_delta_cmd;
- write_send_delta_cmd_payload(out_type, out_head, out_base, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_send_delta_cmd_payload(in_cmd.payload, in_type, in_head, in_base);
+ out_cmd.write_send_delta_cmd(out_type, out_head, out_base);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_send_delta_cmd(in_type, in_head, in_base);
BOOST_CHECK(in_type == out_type);
BOOST_CHECK(in_head == out_head);
BOOST_CHECK(in_base == out_base);
@@ -724,11 +758,10 @@
id out_id(raw_sha1("tuna is not yummy")), in_id;
string out_dat("thank you for flying northwest"), in_dat;
string buf;
- out_cmd.cmd_code = data_cmd;
- write_data_cmd_payload(out_type, out_id, out_dat, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_data_cmd_payload(in_cmd.payload, in_type, in_id, in_dat);
+ out_cmd.write_data_cmd(out_type, out_id, out_dat);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_data_cmd(in_type, in_id, in_dat);
BOOST_CHECK(in_id == out_id);
BOOST_CHECK(in_dat == out_dat);
L(F("data_cmd test done, buffer was %d bytes\n") % buf.size());
@@ -744,11 +777,10 @@
delta out_delta("goodness, this is not an xdelta"), in_delta;
string buf;
- out_cmd.cmd_code = delta_cmd;
- write_delta_cmd_payload(out_type, out_head, out_base, out_delta, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_delta_cmd_payload(in_cmd.payload, in_type, in_head, in_base, in_delta);
+ out_cmd.write_delta_cmd(out_type, out_head, out_base, out_delta);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_delta_cmd(in_type, in_head, in_base, in_delta);
BOOST_CHECK(in_type == out_type);
BOOST_CHECK(in_head == out_head);
BOOST_CHECK(in_base == out_base);
@@ -764,11 +796,10 @@
id out_id(raw_sha1("avocado is the yummiest")), in_id;
string buf;
- out_cmd.cmd_code = nonexistant_cmd;
- write_send_data_cmd_payload(out_type, out_id, out_cmd.payload);
- write_netcmd(out_cmd, buf);
- BOOST_CHECK(read_netcmd(buf, in_cmd));
- read_send_data_cmd_payload(in_cmd.payload, in_type, in_id);
+ out_cmd.write_nonexistant_cmd(out_type, out_id);
+ out_cmd.write(buf);
+ BOOST_CHECK(in_cmd.read(buf));
+ in_cmd.read_nonexistant_cmd(in_type, in_id);
BOOST_CHECK(in_type == out_type);
BOOST_CHECK(in_id == out_id);
L(F("nonexistant_cmd test done, buffer was %d bytes\n") % buf.size());
--- netcmd.hh
+++ netcmd.hh
@@ -46,110 +46,99 @@
}
netcmd_code;
-struct netcmd
+class netcmd
{
+private:
u8 version;
netcmd_code cmd_code;
std::string payload;
+public:
netcmd();
+ netcmd(u8 _version);
+ netcmd_code get_cmd_code() const {return cmd_code;}
+ u8 get_version() const {return version;}
size_t encoded_size();
bool operator==(netcmd const & other) const;
-};
-// basic cmd i/o (including checksums)
-void write_netcmd(netcmd const & in, std::string & out);
-bool read_netcmd(std::string & inbuf, netcmd & out);
-// i/o functions for each type of command payload
-void read_error_cmd_payload(std::string const & in,
- std::string & errmsg);
-void write_error_cmd_payload(std::string const & errmsg,
- std::string & out);
+ // basic cmd i/o (including checksums)
+ void write(std::string & out) const;
+ bool read(std::string & inbuf);
-void read_hello_cmd_payload(std::string const & in,
- rsa_keypair_id & server_keyname,
- rsa_pub_key & server_key,
- id & nonce);
-void write_hello_cmd_payload(rsa_keypair_id const & server_keyname,
- rsa_pub_key const & server_key,
- id const & nonce,
- std::string & out);
+ // i/o functions for each type of command payload
+ void read_error_cmd(std::string & errmsg) const;
+ void write_error_cmd(std::string const & errmsg);
-void read_anonymous_cmd_payload(std::string const & in,
- protocol_role & role,
- std::string & pattern,
- id & nonce2);
-void write_anonymous_cmd_payload(protocol_role role,
- std::string const & pattern,
- id const & nonce2,
- std::string & out);
+//void read_bye_cmd() {}
+ void write_bye_cmd() {cmd_code = bye_cmd;}
-void read_auth_cmd_payload(std::string const & in,
- protocol_role & role,
- std::string & pattern,
- id & client,
- id & nonce1,
- id & nonce2,
- std::string & signature);
-void write_auth_cmd_payload(protocol_role role,
- std::string const & pattern,
- id const & client,
- id const & nonce1,
- id const & nonce2,
- std::string const & signature,
- std::string & out);
+ void read_hello_cmd(rsa_keypair_id & server_keyname,
+ rsa_pub_key & server_key,
+ id & nonce) const;
+ void write_hello_cmd(rsa_keypair_id const & server_keyname,
+ rsa_pub_key const & server_key,
+ id const & nonce);
-void read_confirm_cmd_payload(std::string const & in,
- std::string & signature);
-void write_confirm_cmd_payload(std::string const & signature,
- std::string & out);
+ void read_anonymous_cmd(protocol_role & role,
+ std::string & pattern,
+ id & nonce2) const;
+ void write_anonymous_cmd(protocol_role role,
+ std::string const & pattern,
+ id const & nonce2);
-void read_refine_cmd_payload(std::string const & in, merkle_node & node);
-void write_refine_cmd_payload(merkle_node const & node, std::string & out);
+ void read_auth_cmd(protocol_role & role,
+ std::string & pattern,
+ id & client,
+ id & nonce1,
+ id & nonce2,
+ std::string & signature) const;
+ void write_auth_cmd(protocol_role role,
+ std::string const & pattern,
+ id const & client,
+ id const & nonce1,
+ id const & nonce2,
+ std::string const & signature);
-void read_done_cmd_payload(std::string const & in, size_t & level, netcmd_item_type & type);
-void write_done_cmd_payload(size_t level, netcmd_item_type type, std::string & out);
+ void read_confirm_cmd(std::string & signature) const;
+ void write_confirm_cmd(std::string const & signature);
-void read_send_data_cmd_payload(std::string const & in,
- netcmd_item_type & type,
- id & item);
-void write_send_data_cmd_payload(netcmd_item_type type,
- id const & item,
- std::string & out);
+ void read_refine_cmd(merkle_node & node) const;
+ void write_refine_cmd(merkle_node const & node);
-void read_send_delta_cmd_payload(std::string const & in,
- netcmd_item_type & type,
- id & base,
- id & ident);
-void write_send_delta_cmd_payload(netcmd_item_type type,
- id const & base,
- id const & ident,
- std::string & out);
+ void read_done_cmd(size_t & level, netcmd_item_type & type) const;
+ void write_done_cmd(size_t level, netcmd_item_type type);
-void read_data_cmd_payload(std::string const & in,
- netcmd_item_type & type,
- id & item,
- std::string & dat);
-void write_data_cmd_payload(netcmd_item_type type,
- id const & item,
- std::string const & dat,
- std::string & out);
+ void read_send_data_cmd(netcmd_item_type & type,
+ id & item) const;
+ void write_send_data_cmd(netcmd_item_type type,
+ id const & item);
-void read_delta_cmd_payload(std::string const & in,
- netcmd_item_type & type,
- id & base, id & ident,
- delta & del);
-void write_delta_cmd_payload(netcmd_item_type & type,
- id const & base, id const & ident,
- delta const & del,
- std::string & out);
+ void read_send_delta_cmd(netcmd_item_type & type,
+ id & base,
+ id & ident) const;
+ void write_send_delta_cmd(netcmd_item_type type,
+ id const & base,
+ id const & ident);
-void read_nonexistant_cmd_payload(std::string const & in,
- netcmd_item_type & type,
- id & item);
-void write_nonexistant_cmd_payload(netcmd_item_type type,
- id const & item,
- std::string & out);
+ void read_data_cmd(netcmd_item_type & type,
+ id & item,
+ std::string & dat) const;
+ void write_data_cmd(netcmd_item_type type,
+ id const & item,
+ std::string const & dat);
+ void read_delta_cmd(netcmd_item_type & type,
+ id & base, id & ident,
+ delta & del) const;
+ void write_delta_cmd(netcmd_item_type & type,
+ id const & base, id const & ident,
+ delta const & del);
+ void read_nonexistant_cmd(netcmd_item_type & type,
+ id & item) const;
+ void write_nonexistant_cmd(netcmd_item_type type,
+ id const & item);
+
+};
+
#endif // __NETCMD_HH__
--- netsync.cc
+++ netsync.cc
@@ -221,6 +221,7 @@
string outbuf;
netcmd cmd;
+ u8 protocol_version;
bool armed;
bool arm();
@@ -242,8 +243,7 @@
vector written_keys;
vector written_certs;
- map< std::pair,
- boost::shared_ptr > merkle_tables;
+ map > merkle_tables;
map done_refinements;
map > > requested_items;
@@ -276,6 +276,8 @@
id mk_nonce();
void mark_recent_io();
+ void setup_client_tickers();
+
bool done_all_refinements();
bool cert_refinement_done();
bool all_requested_revisions_received();
@@ -375,18 +377,15 @@
id const & item);
bool merkle_node_exists(netcmd_item_type type,
- utf8 const & pattern,
size_t level,
prefix const & pref);
void load_merkle_node(netcmd_item_type type,
- utf8 const & pattern,
size_t level,
prefix const & pref,
merkle_ptr & node);
void rebuild_merkle_trees(app_state & app,
- utf8 const & pattern,
set const & branches);
bool dispatch_payload(netcmd const & cmd);
@@ -433,6 +432,7 @@
str(sock, to),
inbuf(""),
outbuf(""),
+ protocol_version(constants::netcmd_current_protocol_version),
armed(false),
pattern(""),
remote_peer_key_hash(""),
@@ -576,6 +576,30 @@
last_io_time = ::time(NULL);
}
+void
+session::setup_client_tickers()
+{
+ byte_in_ticker.reset(new ticker("bytes in", ">", 1024, true));
+ byte_out_ticker.reset(new ticker("bytes out", "<", 1024, true));
+ if (role == sink_role)
+ {
+ revision_checked_ticker.reset(new ticker("revs written", "w", 1));
+ cert_in_ticker.reset(new ticker("certs in", "c", 3));
+ revision_in_ticker.reset(new ticker("revs in", "r", 1));
+ }
+ else if (role == source_role)
+ {
+ cert_out_ticker.reset(new ticker("certs out", "C", 3));
+ revision_out_ticker.reset(new ticker("revs out", "R", 1));
+ }
+ else
+ {
+ I(role == source_and_sink_role);
+ revision_checked_ticker.reset(new ticker("revs written", "w", 1));
+ revision_in_ticker.reset(new ticker("revs in", "r", 1));
+ revision_out_ticker.reset(new ticker("revs out", "R", 1));
+ }
+}
bool
session::done_all_refinements()
@@ -701,7 +725,7 @@
session::write_netcmd_and_try_flush(netcmd const & cmd)
{
if (!encountered_error)
- write_netcmd(cmd, outbuf);
+ cmd.write(outbuf);
else
L(F("dropping outgoing netcmd (because we're in error unwind mode)\n"));
// FIXME: this helps keep the protocol pipeline full but it seems to
@@ -1260,7 +1284,8 @@
{
I(!outbuf.empty());
Netxx::signed_size_type count = str.write(outbuf.data(),
- std::min(outbuf.size(), constants::bufsz));
+ std::min(outbuf.size(),
+ constants::bufsz));
if(count > 0)
{
outbuf.erase(0, count);
@@ -1287,8 +1312,8 @@
session::queue_bye_cmd()
{
L(F("queueing 'bye' command\n"));
- netcmd cmd;
- cmd.cmd_code = bye_cmd;
+ netcmd cmd(protocol_version);
+ cmd.write_bye_cmd();
write_netcmd_and_try_flush(cmd);
this->sent_goodbye = true;
}
@@ -1297,9 +1322,8 @@
session::queue_error_cmd(string const & errmsg)
{
L(F("queueing 'error' command\n"));
- netcmd cmd;
- cmd.cmd_code = error_cmd;
- write_error_cmd_payload(errmsg, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_error_cmd(errmsg);
write_netcmd_and_try_flush(cmd);
this->sent_goodbye = true;
}
@@ -1311,9 +1335,8 @@
string typestr;
netcmd_item_type_to_string(type, typestr);
L(F("queueing 'done' command for %s level %s\n") % typestr % level);
- netcmd cmd;
- cmd.cmd_code = done_cmd;
- write_done_cmd_payload(level, type, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_done_cmd(level, type);
write_netcmd_and_try_flush(cmd);
}
@@ -1321,8 +1344,7 @@
session::queue_hello_cmd(id const & server,
id const & nonce)
{
- netcmd cmd;
- cmd.cmd_code = hello_cmd;
+ netcmd cmd(protocol_version);
hexenc server_encoded;
encode_hexenc(server, server_encoded);
@@ -1332,7 +1354,7 @@
app.db.get_pubkey(server_encoded, key_name, pub_encoded);
decode_base64(pub_encoded, pub);
- write_hello_cmd_payload(key_name, pub, nonce, cmd.payload);
+ cmd.write_hello_cmd(key_name, pub, nonce);
write_netcmd_and_try_flush(cmd);
}
@@ -1341,9 +1363,8 @@
string const & pattern,
id const & nonce2)
{
- netcmd cmd;
- cmd.cmd_code = anonymous_cmd;
- write_anonymous_cmd_payload(role, pattern, nonce2, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_anonymous_cmd(role, pattern, nonce2);
write_netcmd_and_try_flush(cmd);
}
@@ -1355,20 +1376,16 @@
id const & nonce2,
string const & signature)
{
- netcmd cmd;
- cmd.cmd_code = auth_cmd;
- write_auth_cmd_payload(role, pattern, client,
- nonce1, nonce2, signature,
- cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_auth_cmd(role, pattern, client, nonce1, nonce2, signature);
write_netcmd_and_try_flush(cmd);
}
void
session::queue_confirm_cmd(string const & signature)
{
- netcmd cmd;
- cmd.cmd_code = confirm_cmd;
- write_confirm_cmd_payload(signature, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_confirm_cmd(signature);
write_netcmd_and_try_flush(cmd);
}
@@ -1381,9 +1398,8 @@
netcmd_item_type_to_string(node.type, typestr);
L(F("queueing request for refinement of %s node '%s', level %d\n")
% typestr % hpref % static_cast(node.level));
- netcmd cmd;
- cmd.cmd_code = refine_cmd;
- write_refine_cmd_payload(node, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_refine_cmd(node);
write_netcmd_and_try_flush(cmd);
}
@@ -1412,9 +1428,8 @@
L(F("queueing request for data of %s item '%s'\n")
% typestr % hid);
- netcmd cmd;
- cmd.cmd_code = send_data_cmd;
- write_send_data_cmd_payload(type, item, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_send_data_cmd(type, item);
write_netcmd_and_try_flush(cmd);
note_item_requested(type, item);
}
@@ -1449,9 +1464,8 @@
L(F("queueing request for contents of %s delta '%s' -> '%s'\n")
% typestr % base_hid % ident_hid);
- netcmd cmd;
- cmd.cmd_code = send_delta_cmd;
- write_send_delta_cmd_payload(type, base, ident, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_send_delta_cmd(type, base, ident);
write_netcmd_and_try_flush(cmd);
note_item_requested(type, ident);
}
@@ -1475,9 +1489,8 @@
L(F("queueing %d bytes of data for %s item '%s'\n")
% dat.size() % typestr % hid);
- netcmd cmd;
- cmd.cmd_code = data_cmd;
- write_data_cmd_payload(type, item, dat, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_data_cmd(type, item, dat);
write_netcmd_and_try_flush(cmd);
note_item_sent(type, item);
}
@@ -1506,9 +1519,8 @@
L(F("queueing %s delta '%s' -> '%s'\n")
% typestr % base_hid % ident_hid);
- netcmd cmd;
- cmd.cmd_code = delta_cmd;
- write_delta_cmd_payload(type, base, ident, del, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_delta_cmd(type, base, ident, del);
write_netcmd_and_try_flush(cmd);
note_item_sent(type, ident);
}
@@ -1530,9 +1542,8 @@
L(F("queueing note of nonexistance of %s item '%s'\n")
% typestr % hid);
- netcmd cmd;
- cmd.cmd_code = nonexistant_cmd;
- write_nonexistant_cmd_payload(type, item, cmd.payload);
+ netcmd cmd(protocol_version);
+ cmd.write_nonexistant_cmd(type, item);
write_netcmd_and_try_flush(cmd);
}
@@ -1600,6 +1611,39 @@
return true;
}
+void
+get_branches(app_state & app, vector & names)
+{
+ vector< revision > certs;
+ app.db.get_revision_certs(branch_cert_name, certs);
+ for (size_t i = 0; i < certs.size(); ++i)
+ {
+ cert_value name;
+ decode_base64(idx(certs, i).inner().value, name);
+ names.push_back(name());
+ }
+ sort(names.begin(), names.end());
+ names.erase(std::unique(names.begin(), names.end()), names.end());
+ if(!names.size())
+ W(F("No branches found."));
+}
+
+utf8
+convert_pattern(utf8 & pat)
+{
+ string x=pat();
+ string pattern="";
+ string e=".|*?+()[]{}^$\\";
+ for(string::const_iterator i=x.begin(); i!=x.end(); i++)
+ {
+ if(e.find(*i) != e.npos)
+ pattern+='\\';
+ pattern+=*i;
+ }
+ return utf8(pattern+".*");
+}
+
+
static const var_domain known_servers_domain = var_domain("known-servers");
bool
@@ -1662,7 +1706,24 @@
decode_hexenc(their_key_hash, their_key_hash_decoded);
this->remote_peer_key_hash = their_key_hash_decoded;
}
-
+
+ vector branchnames;
+ set ok_branches;
+ get_branches(app, branchnames);
+ utf8 pat(pattern);
+ if(protocol_version == 4)
+ pat=convert_pattern(pattern);
+ boost::regex reg(pat());
+ for(vector::const_iterator i=branchnames.begin();
+ i!=branchnames.end(); i++)
+ {
+ if(boost::regex_match(*i, reg))
+ ok_branches.insert(utf8(*i));
+ }
+ rebuild_merkle_trees(app, ok_branches);
+
+ setup_client_tickers();
+
if (app.signing_key() != "")
{
// get our public key for its hash identifier
@@ -1703,23 +1764,6 @@
return false;
}
-void
-get_branches(app_state & app, vector & names)
-{
- vector< revision > certs;
- app.db.get_revision_certs(branch_cert_name, certs);
- for (size_t i = 0; i < certs.size(); ++i)
- {
- cert_value name;
- decode_base64(idx(certs, i).inner().value, name);
- names.push_back(name());
- }
- sort(names.begin(), names.end());
- names.erase(std::unique(names.begin(), names.end()), names.end());
- if(!names.size())
- W(F("No branches found."));
-}
-
bool
session::process_anonymous_cmd(protocol_role role,
string const & pattern,
@@ -1792,7 +1836,7 @@
P(F("allowed anonymous read permission for '%s'\n") % pattern);
- rebuild_merkle_trees(app, pattern, ok_branches);
+ rebuild_merkle_trees(app, ok_branches);
// get our private key and sign back
L(F("anonymous read permitted, signing back nonce\n"));
@@ -1936,7 +1980,7 @@
P(F("allowed '%s' write permission for '%s'\n") % their_id % pattern);
}
- rebuild_merkle_trees(app, pattern, ok_branches);
+ rebuild_merkle_trees(app, ok_branches);
// save their identity
this->remote_peer_key_hash = client;
@@ -2011,15 +2055,15 @@
this->authenticated = true;
merkle_ptr root;
- load_merkle_node(epoch_item, this->pattern, 0, get_root_prefix().val, root);
+ load_merkle_node(epoch_item, 0, get_root_prefix().val, root);
queue_refine_cmd(*root);
queue_done_cmd(0, epoch_item);
- load_merkle_node(key_item, this->pattern, 0, get_root_prefix().val, root);
+ load_merkle_node(key_item, 0, get_root_prefix().val, root);
queue_refine_cmd(*root);
queue_done_cmd(0, key_item);
- load_merkle_node(cert_item, this->pattern, 0, get_root_prefix().val, root);
+ load_merkle_node(cert_item, 0, get_root_prefix().val, root);
queue_refine_cmd(*root);
queue_done_cmd(0, cert_item);
return true;
@@ -2176,8 +2220,7 @@
L(F("received 'refine' netcmd on %s node '%s', level %d\n")
% typestr % hpref % lev);
- if (!merkle_node_exists(their_node.type, this->pattern,
- their_node.level, pref))
+ if (!merkle_node_exists(their_node.type, their_node.level, pref))
{
L(F("no corresponding %s merkle node for prefix '%s', level %d\n")
% typestr % hpref % lev);
@@ -2237,8 +2280,7 @@
L(F("found corresponding %s merkle node for prefix '%s', level %d\n")
% typestr % hpref % lev);
merkle_ptr our_node;
- load_merkle_node(their_node.type, this->pattern,
- their_node.level, pref, our_node);
+ load_merkle_node(their_node.type, their_node.level, pref, our_node);
for (size_t slot = 0; slot < constants::merkle_num_slots; ++slot)
{
switch (their_node.get_slot_state(slot))
@@ -2284,8 +2326,8 @@
our_node->extended_raw_prefix(slot, subprefix);
merkle_ptr our_subtree;
I(our_node->type == their_node.type);
- load_merkle_node(their_node.type, this->pattern,
- our_node->level + 1, subprefix, our_subtree);
+ load_merkle_node(their_node.type, our_node->level + 1,
+ subprefix, our_subtree);
I(our_node->type == our_subtree->type);
queue_refine_cmd(*our_subtree);
}
@@ -2384,8 +2426,8 @@
prefix subprefix;
our_node->extended_raw_prefix(slot, subprefix);
merkle_ptr our_subtree;
- load_merkle_node(our_node->type, this->pattern,
- our_node->level + 1, subprefix, our_subtree);
+ load_merkle_node(our_node->type, our_node->level + 1,
+ subprefix, our_subtree);
queue_refine_cmd(*our_subtree);
}
break;
@@ -2444,8 +2486,8 @@
prefix subprefix;
our_node->extended_raw_prefix(slot, subprefix);
merkle_ptr our_subtree;
- load_merkle_node(our_node->type, this->pattern,
- our_node->level + 1, subprefix, our_subtree);
+ load_merkle_node(our_node->type, our_node->level + 1,
+ subprefix, our_subtree);
queue_refine_cmd(*our_subtree);
}
break;
@@ -2533,8 +2575,8 @@
prefix subprefix;
our_node->extended_raw_prefix(slot, subprefix);
merkle_ptr our_subtree;
- load_merkle_node(our_node->type, this->pattern,
- our_node->level + 1, subprefix, our_subtree);
+ load_merkle_node(our_node->type, our_node->level + 1,
+ subprefix, our_subtree);
queue_refine_cmd(*our_subtree);
}
}
@@ -2876,13 +2918,11 @@
bool
session::merkle_node_exists(netcmd_item_type type,
- utf8 const & pattern,
size_t level,
prefix const & pref)
{
- map< std::pair,
- boost::shared_ptr >::const_iterator i =
- merkle_tables.find(std::make_pair(pattern,type));
+ map >::const_iterator i =
+ merkle_tables.find(type);
I(i != merkle_tables.end());
merkle_table::const_iterator j = i->second->find(std::make_pair(pref, level));
@@ -2891,15 +2931,13 @@
void
session::load_merkle_node(netcmd_item_type type,
- utf8 const & pattern,
size_t level,
prefix const & pref,
merkle_ptr & node)
{
- map< std::pair,
- boost::shared_ptr >::const_iterator i =
- merkle_tables.find(std::make_pair(pattern,type));
-
+ map >::const_iterator i =
+ merkle_tables.find(type);
+
I(i != merkle_tables.end());
merkle_table::const_iterator j = i->second->find(std::make_pair(pref, level));
I(j != i->second->end());
@@ -2911,7 +2949,7 @@
session::dispatch_payload(netcmd const & cmd)
{
- switch (cmd.cmd_code)
+ switch (cmd.get_cmd_code())
{
case bye_cmd:
@@ -2921,7 +2959,7 @@
case error_cmd:
{
string errmsg;
- read_error_cmd_payload(cmd.payload, errmsg);
+ cmd.read_error_cmd(errmsg);
return process_error_cmd(errmsg);
}
break;
@@ -2933,7 +2971,9 @@
rsa_keypair_id server_keyname;
rsa_pub_key server_key;
id nonce;
- read_hello_cmd_payload(cmd.payload, server_keyname, server_key, nonce);
+ cmd.read_hello_cmd(server_keyname, server_key, nonce);
+ if(cmd.get_version() < protocol_version)
+ protocol_version = cmd.get_version();
return process_hello_cmd(server_keyname, server_key, nonce);
}
break;
@@ -2948,7 +2988,9 @@
protocol_role role;
string pattern;
id nonce2;
- read_anonymous_cmd_payload(cmd.payload, role, pattern, nonce2);
+ cmd.read_anonymous_cmd(role, pattern, nonce2);
+ if(cmd.get_version() < protocol_version)
+ protocol_version = cmd.get_version();
return process_anonymous_cmd(role, pattern, nonce2);
}
break;
@@ -2960,8 +3002,11 @@
protocol_role role;
string pattern, signature;
id client, nonce1, nonce2;
- read_auth_cmd_payload(cmd.payload, role, pattern, client, nonce1, nonce2, signature);
- return process_auth_cmd(role, pattern, client, nonce1, nonce2, signature);
+ cmd.read_auth_cmd(role, pattern, client, nonce1, nonce2, signature);
+ if(cmd.get_version() < protocol_version)
+ protocol_version = cmd.get_version();
+ return process_auth_cmd(role, pattern, client,
+ nonce1, nonce2, signature);
}
break;
@@ -2970,7 +3015,7 @@
require(voice == client_voice, "confirm netcmd received in client voice");
{
string signature;
- read_confirm_cmd_payload(cmd.payload, signature);
+ cmd.read_confirm_cmd(signature);
return process_confirm_cmd(signature);
}
break;
@@ -2979,7 +3024,7 @@
require(authenticated, "refine netcmd received when authenticated");
{
merkle_node node;
- read_refine_cmd_payload(cmd.payload, node);
+ cmd.read_refine_cmd(node);
map< netcmd_item_type, done_marker>::iterator i = done_refinements.find(node.type);
require(i != done_refinements.end(), "refinement netcmd refers to valid type");
require(i->second.tree_is_done == false, "refinement netcmd received when tree is live");
@@ -2993,7 +3038,7 @@
{
size_t level;
netcmd_item_type type;
- read_done_cmd_payload(cmd.payload, level, type);
+ cmd.read_done_cmd(level, type);
return process_done_cmd(level, type);
}
break;
@@ -3006,7 +3051,7 @@
{
netcmd_item_type type;
id item;
- read_send_data_cmd_payload(cmd.payload, type, item);
+ cmd.read_send_data_cmd(type, item);
return process_send_data_cmd(type, item);
}
break;
@@ -3019,7 +3064,7 @@
{
netcmd_item_type type;
id base, ident;
- read_send_delta_cmd_payload(cmd.payload, type, base, ident);
+ cmd.read_send_delta_cmd(type, base, ident);
return process_send_delta_cmd(type, base, ident);
}
@@ -3032,7 +3077,7 @@
netcmd_item_type type;
id item;
string dat;
- read_data_cmd_payload(cmd.payload, type, item, dat);
+ cmd.read_data_cmd(type, item, dat);
return process_data_cmd(type, item, dat);
}
break;
@@ -3046,7 +3091,7 @@
netcmd_item_type type;
id base, ident;
delta del;
- read_delta_cmd_payload(cmd.payload, type, base, ident, del);
+ cmd.read_delta_cmd(type, base, ident, del);
return process_delta_cmd(type, base, ident, del);
}
break;
@@ -3059,7 +3104,7 @@
{
netcmd_item_type type;
id item;
- read_nonexistant_cmd_payload(cmd.payload, type, item);
+ cmd.read_nonexistant_cmd(type, item);
return process_nonexistant_cmd(type, item);
}
break;
@@ -3093,7 +3138,7 @@
{
if (!armed)
{
- if (read_netcmd(inbuf, cmd))
+ if (cmd.read(inbuf))
{
// inbuf.erase(0, cmd.encoded_size());
armed = true;
@@ -3144,39 +3189,6 @@
Netxx::Stream server(address().c_str(), default_port, timeout);
session sess(role, client_voice, patterns, app,
address(), server.get_socketfd(), timeout);
-
- vector branchnames;
- set ok_branches;
- get_branches(app, branchnames);
- boost::regex reg(idx(patterns, 0)());
- for(vector::const_iterator i=branchnames.begin();
- i!=branchnames.end(); i++)
- {
- if(boost::regex_match(*i, reg))
- ok_branches.insert(utf8(*i));
- }
- sess.rebuild_merkle_trees(app, idx(patterns, 0)(), ok_branches);
-
- sess.byte_in_ticker.reset(new ticker("bytes in", ">", 1024, true));
- sess.byte_out_ticker.reset(new ticker("bytes out", "<", 1024, true));
- if (role == sink_role)
- {
- sess.revision_checked_ticker.reset(new ticker("revs written", "w", 1));
- sess.cert_in_ticker.reset(new ticker("certs in", "c", 3));
- sess.revision_in_ticker.reset(new ticker("revs in", "r", 1));
- }
- else if (role == source_role)
- {
- sess.cert_out_ticker.reset(new ticker("certs out", "C", 3));
- sess.revision_out_ticker.reset(new ticker("revs out", "R", 1));
- }
- else
- {
- I(role == source_and_sink_role);
- sess.revision_checked_ticker.reset(new ticker("revs written", "w", 1));
- sess.revision_in_ticker.reset(new ticker("revs in", "r", 1));
- sess.revision_out_ticker.reset(new ticker("revs out", "R", 1));
- }
while (true)
{
@@ -3532,7 +3544,6 @@
static boost::shared_ptr
make_root_node(session & sess,
- utf8 const & pat,
netcmd_item_type ty)
{
boost::shared_ptr tab =
@@ -3543,7 +3554,7 @@
tab->insert(std::make_pair(std::make_pair(get_root_prefix().val, 0), tmp));
- sess.merkle_tables[std::make_pair(pat, ty)] = tab;
+ sess.merkle_tables[ty] = tab;
return tab;
}
@@ -3577,17 +3588,16 @@
void
session::rebuild_merkle_trees(app_state & app,
- utf8 const & pattern,
set const & branchnames)
{
- P(F("rebuilding merkle trees for pattern %s\n") % pattern);
+ P(F("rebuilding merkle trees ...\n"));
for(set::const_iterator i=branchnames.begin();
i!=branchnames.end(); ++i)
P(F("including branch %s") % *i);
- boost::shared_ptr ctab = make_root_node(*this, pattern, cert_item);
- boost::shared_ptr ktab = make_root_node(*this, pattern, key_item);
- boost::shared_ptr etab = make_root_node(*this, pattern, epoch_item);
+ boost::shared_ptr ctab = make_root_node(*this, cert_item);
+ boost::shared_ptr ktab = make_root_node(*this, key_item);
+ boost::shared_ptr etab = make_root_node(*this, epoch_item);
ticker certs_ticker("certs", "c", 256);
ticker keys_ticker("keys", "k", 1);