# # # patch "constants.cc" # from [8a0d55deed72eb4866e296ea6863f21c574943d6] # to [af905b1012513817bd7ed554c845359d0e564ceb] # # patch "constants.hh" # from [b9bc0cea940b4be75380a952b9988329af48f397] # to [158f3dd6dc17483af738d2cdcf1c726ab7909a3d] # # patch "netsync.cc" # from [60c6fcbaaa69c833a47724faec4bf182d867ef58] # to [fb9f8adbd6e53cb7b4375a830f8ffbaa18fe2424] # # patch "packet.cc" # from [f84b440b1088f7522e1776ea8d7be8a5002e6ea7] # to [bb02904c4ea7677e86a235c9984100d7d36705ac] # ============================================================ --- constants.cc 8a0d55deed72eb4866e296ea6863f21c574943d6 +++ constants.cc af905b1012513817bd7ed554c845359d0e564ceb @@ -9,64 +9,25 @@ // this file contains magic constants which you could, in theory, tweak. // probably best not to tweak them though. +// +// style notes: (1) scalar constants should be defined in constants.hh so +// their values are visible to the compiler; (2) do not use std::string or +// any other non-POD type for aggregate constants defined in this file, as +// this tends to cause unnecessary copying and unconditionally-executed +// initialization code for constants that don't get used always; (3) use +// "char const foo[]" instead of "char const * const foo" -- it's less +// typing and it saves an indirection. #include "constants.hh" -#include "numeric_vocab.hh" #include -using std::string; - namespace constants { - - // number of bits in an RSA key we use - size_t const keylen = 1024; - - // number of seconds in window, in which to consider CVS commits equivalent - // if they have otherwise compatible contents (author, changelog) - time_t const cvs_window = 60 * 5; - - // size of a line of database traffic logging, beyond which lines will be - // truncated. - size_t const db_log_line_sz = 70; - - size_t const default_terminal_width = 72; - - // size in bytes of the database xdelta version reconstruction cache. - // the value of 7 MB was determined as the optimal point after timing - // various values with a pull of the monotone repository - it could - // be tweaked further. - size_t const db_version_cache_sz = 7 * (1 << 20); - - // the value of 7 MB was determined by blindly copying the line above and - // not doing any testing at all - it could be tweaked further. - size_t const db_roster_cache_sz = 7 * (1 << 20); - - // this value is very much an estimate. the calculation is: - // -- 40 bytes content hash - // -- a path component, maybe 10 or 15 bytes - // -- 40 bytes birth revision - // -- 40 bytes name marking hash - // -- 40 bytes content marking hash - // -- plus internal pointers, etc., for strings, sets, shared_ptrs, heap - // overhead, ... - // -- plus any space taken for attrs - // so ~175 bytes for a file node, plus internal slop, plus attrs (another - // 60 bytes per attr, or so), minus 80 bytes for dir nodes. So this just - // picks a number that seems a reasonable amount over 175. - size_t const db_estimated_roster_node_sz = 210; - - unsigned long const db_max_delayed_file_bytes = 16 * 1024 * 1024; - - // size of a line of text in the log buffer, beyond which log lines will be - // truncated. - size_t const log_line_sz = 0x300; - // all the ASCII characters (bytes) which are legal in a sequence of // base64-encoded data. note that botan doesn't count \v or \f as // whitespace (unlike ) and so neither do we. - char const * const legal_packet_bytes = + char const legal_base64_bytes[] = // base64 data characters "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -75,17 +36,13 @@ namespace constants " \r\n\t" ; - string const regex_legal_packet_bytes("([a-zA-Z0-9+/= \r\n\t]+)"); - // all the ASCII characters (bytes) which are legal in a SHA1 hex id - char const * const legal_id_bytes = + char const legal_id_bytes[] = "0123456789abcdef" ; - string const regex_legal_id_bytes("([0-9a-f]{40})"); - // all the ASCII characters (bytes) which are legal in an ACE string - char const * const legal_ace_bytes = + char const legal_ace_bytes[] = // LDH characters "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -96,7 +53,7 @@ namespace constants ; // all the ASCII characters (bytes) which can occur in cert names - char const * const legal_cert_name_bytes = + char const legal_cert_name_bytes[] = // LDH characters "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -104,10 +61,8 @@ namespace constants "-" ; - string const regex_legal_cert_name_bytes("([-a-zA-Z0-9]+)"); - // all the ASCII characters (bytes) which can occur in key names - char const * const legal_key_name_bytes = + char const legal_key_name_bytes[] = // LDH characters "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -120,19 +75,18 @@ namespace constants "+_" ; - string const regex_legal_key_name_bytes("(address@hidden)"); - // merkle tree / netcmd / netsync related stuff + char const netsync_key_initializer[netsync_session_key_length_in_bytes] + = { 0 }; - size_t const merkle_fanout_bits = 4; + // attributes + char const encoding_attribute[] = "mtn:encoding"; + char const manual_merge_attribute[] = "mtn:manual_merge"; + char const binary_encoding[] = "binary"; + char const default_encoding[] = "default"; - // all other merkle constants are derived - size_t const merkle_hash_length_in_bits = merkle_hash_length_in_bytes * 8; - size_t const merkle_num_tree_levels = merkle_hash_length_in_bits / merkle_fanout_bits; - size_t const merkle_num_slots = 1 << merkle_fanout_bits; - size_t const merkle_bitmap_length_in_bits = merkle_num_slots * 2; - size_t const merkle_bitmap_length_in_bytes = merkle_bitmap_length_in_bits / 8; - + // consistency checks - inside the namespace so we don't have to sprinkle + // constants:: all over them. BOOST_STATIC_ASSERT(sizeof(char) == 1); BOOST_STATIC_ASSERT(CHAR_BIT == 8); BOOST_STATIC_ASSERT(merkle_num_tree_levels > 0); @@ -143,21 +97,6 @@ namespace constants BOOST_STATIC_ASSERT((merkle_hash_length_in_bits % merkle_fanout_bits) == 0); BOOST_STATIC_ASSERT(merkle_bitmap_length_in_bits > 0); BOOST_STATIC_ASSERT((merkle_bitmap_length_in_bits % 8) == 0); - - u8 const netcmd_current_protocol_version = 6; - - size_t const netcmd_minimum_bytes_to_bother_with_gzip = 0xfff; - - size_t const netsync_session_key_length_in_bytes = 20; // 160 bits - size_t const netsync_hmac_value_length_in_bytes = 20; // 160 bits - - netsync_session_key const netsync_key_initializer(string(netsync_session_key_length_in_bytes, 0)); - - // attributes - string const encoding_attribute("mtn:encoding"); - string const manual_merge_attribute("mtn:manual_merge"); - string const binary_encoding("binary"); - string const default_encoding("default"); } // Local Variables: ============================================================ --- constants.hh b9bc0cea940b4be75380a952b9988329af48f397 +++ constants.hh 158f3dd6dc17483af738d2cdcf1c726ab7909a3d @@ -10,160 +10,168 @@ // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. -#include -#include +#include +#include #include "numeric_vocab.hh" -#include "vocab.hh" namespace constants { - // this file contains magic constants which you could, in theory, tweak. // probably best not to tweak them though. + // all scalar constants are defined in this file so their values are + // visible to the compiler; aggregate constants are defined in + // constants.cc, which also has some static assertions to make sure + // everything is consistent. // number of bits in an RSA key we use - extern size_t const keylen; + std::size_t const keylen = 1024; // number of characters in a SHA1 id - static size_t const idlen = 40; + std::size_t const idlen = 40; // number of characters in an encoded epoch - static size_t const epochlen = idlen; + std::size_t const epochlen = idlen; // number of characters in a raw epoch - static size_t const epochlen_bytes = epochlen / 2; + std::size_t const epochlen_bytes = epochlen / 2; // number of seconds in window, in which to consider CVS commits equivalent // if they have otherwise compatible contents (author, changelog) - extern time_t const cvs_window; + std::time_t const cvs_window = 60 * 5; // number of bytes in a password buffer. further bytes will be dropped. - static size_t const maxpasswd = 0xfff; + std::size_t const maxpasswd = 0xfff; // number of bytes to use in buffers, for buffered i/o operations - static size_t const bufsz = 0x3ffff; + std::size_t const bufsz = 0x3ffff; // size of a line of database traffic logging, beyond which lines will be // truncated. - extern size_t const db_log_line_sz; + std::size_t const db_log_line_sz = 70; // maximum size in bytes of the database xdelta version reconstruction - // cache - extern size_t const db_version_cache_sz; + // cache. the value of 7 MB was determined as the optimal point after + // timing various values with a pull of the monotone repository - it could + // be tweaked further. + std::size_t const db_version_cache_sz = 7 * (1 << 20); // maximum size in bytes of the write-back roster cache - extern size_t const db_roster_cache_sz; + // the value of 7 MB was determined by blindly copying the line above and + // not doing any testing at all - it could be tweaked further. + std::size_t const db_roster_cache_sz = 7 * (1 << 20); // estimated number of bytes taken for a node_t and its corresponding // marking_t. used to estimate the current size of the write-back roster - // cache - extern size_t const db_estimated_roster_node_sz; + // cache. the calculation is: + // -- 40 bytes content hash + // -- a path component, maybe 10 or 15 bytes + // -- 40 bytes birth revision + // -- 40 bytes name marking hash + // -- 40 bytes content marking hash + // -- plus internal pointers, etc., for strings, sets, shared_ptrs, heap + // overhead, ... + // -- plus any space taken for attrs + // so ~175 bytes for a file node, plus internal slop, plus attrs (another + // 60 bytes per attr, or so), minus 80 bytes for dir nodes. So this just + // picks a number that seems a reasonable amount over 175. + std::size_t const db_estimated_roster_node_sz = 210; // maximum number of bytes to be consumed with the delayed write cache - extern unsigned long const db_max_delayed_file_bytes; + unsigned long const db_max_delayed_file_bytes = 16 * (1 << 20); // size of a line of text in the log buffer, beyond which log lines will be // truncated. - extern size_t const log_line_sz; + std::size_t const log_line_sz = 0x300; // assumed width of the terminal, when we can't query for it directly - extern size_t const default_terminal_width; + std::size_t const default_terminal_width = 72; - // all the ASCII characters (bytes) which are legal in a packet - extern char const * const legal_packet_bytes; + // all the ASCII characters (bytes) which are legal in a base64 blob + extern char const legal_base64_bytes[]; - // boost regex that matches the bytes in legal_packet_bytes - extern std::string const regex_legal_packet_bytes; - // all the ASCII characters (bytes) which are legal in an ACE string - extern char const * const legal_ace_bytes; + extern char const legal_ace_bytes[]; // all the ASCII characters (bytes) which are legal in a SHA1 hex id - extern char const * const legal_id_bytes; + extern char const legal_id_bytes[]; - // boost regex that matches the bytes in legal_id_bytes - extern std::string const regex_legal_id_bytes; - // all the ASCII characters (bytes) which can occur in cert names - extern char const * const legal_cert_name_bytes; + extern char const legal_cert_name_bytes[]; - // boost regex that matches the bytes in legal_cert_name_bytes - extern std::string const regex_legal_cert_name_bytes; - // all the ASCII characters (bytes) which can occur in key names - extern char const * const legal_key_name_bytes; + extern char const legal_key_name_bytes[]; - // boost regex that matches the bytes in legal_key_name_bytes - extern std::string const regex_legal_key_name_bytes; - // remaining constants are related to netsync protocol // number of bytes in the hash used in netsync - static size_t const merkle_hash_length_in_bytes = 20; + std::size_t const merkle_hash_length_in_bytes = 20; // number of bits of merkle prefix consumed by each level of tree - extern size_t const merkle_fanout_bits; + std::size_t const merkle_fanout_bits = 4; // derived from hash_length_in_bytes - extern size_t const merkle_hash_length_in_bits; + std::size_t const merkle_hash_length_in_bits + = merkle_hash_length_in_bytes * 8; // derived from fanout_bits - extern size_t const merkle_num_tree_levels; + std::size_t const merkle_num_tree_levels + = merkle_hash_length_in_bits / merkle_fanout_bits; // derived from fanout_bits - extern size_t const merkle_num_slots; + std::size_t const merkle_num_slots = 1 << merkle_fanout_bits; // derived from fanout_bits - extern size_t const merkle_bitmap_length_in_bits; + std::size_t const merkle_bitmap_length_in_bits = merkle_num_slots * 2; // derived from fanout_bits - extern size_t const merkle_bitmap_length_in_bytes; + std::size_t const merkle_bitmap_length_in_bytes + = merkle_bitmap_length_in_bits / 8; // the current netcmd/netsync protocol version - extern u8 const netcmd_current_protocol_version; + u8 const netcmd_current_protocol_version = 6; // minimum size of any netcmd on the wire - static size_t const netcmd_minsz = (1 // version - + 1 // cmd code - + 1); // smallest uleb possible + std::size_t const netcmd_minsz = (1 // version + + 1 // cmd code + + 1); // smallest uleb possible // largest command *payload* allowed in a netcmd // in practice, this sets the size of the largest compressed file - static size_t const netcmd_payload_limit = 2 << 27; + std::size_t const netcmd_payload_limit = 2 << 27; // maximum size of any netcmd on the wire, including payload - static size_t const netcmd_maxsz = netcmd_minsz + netcmd_payload_limit; + std::size_t const netcmd_maxsz = netcmd_minsz + netcmd_payload_limit; // netsync fragments larger than this are gzipped - extern size_t const netcmd_minimum_bytes_to_bother_with_gzip; + std::size_t const netcmd_minimum_bytes_to_bother_with_gzip = 0xfff; // TCP port to listen on / connect to when doing netsync - static size_t const netsync_default_port = 4691; + std::size_t const netsync_default_port = 4691; // maximum number of simultaneous clients on a server - static size_t const netsync_connection_limit = 1024; + std::size_t const netsync_connection_limit = 1024; // number of seconds a connection can be idle before it's dropped - static size_t const netsync_timeout_seconds = 21600; // 6 hours + std::size_t const netsync_timeout_seconds = 21600; // 6 hours // netsync HMAC key length - extern size_t const netsync_session_key_length_in_bytes; + std::size_t const netsync_session_key_length_in_bytes = 20; // netsync HMAC value length - extern size_t const netsync_hmac_value_length_in_bytes; + std::size_t const netsync_hmac_value_length_in_bytes = 20; // how long a sha1 digest should be - static size_t const sha1_digest_length = 20; // 160 bits + std::size_t const sha1_digest_length = 20; // 160 bits // netsync session key default initializer - extern netsync_session_key const netsync_key_initializer; + extern char const netsync_key_initializer[]; // attributes - extern std::string const encoding_attribute; - extern std::string const binary_encoding; - extern std::string const default_encoding; - extern std::string const manual_merge_attribute; + extern char const encoding_attribute[]; + extern char const binary_encoding[]; + extern char const default_encoding[]; + extern char const manual_merge_attribute[]; } // Local Variables: ============================================================ --- netsync.cc 60c6fcbaaa69c833a47724faec4bf182d867ef58 +++ netsync.cc fb9f8adbd6e53cb7b4375a830f8ffbaa18fe2424 @@ -507,8 +507,10 @@ session::session(protocol_role role, remote_peer_key_hash(""), remote_peer_key_name(""), session_key(constants::netsync_key_initializer), - read_hmac(constants::netsync_key_initializer, app.opts.use_transport_auth), - write_hmac(constants::netsync_key_initializer, app.opts.use_transport_auth), + read_hmac(netsync_session_key(constants::netsync_key_initializer), + app.opts.use_transport_auth), + write_hmac(netsync_session_key(constants::netsync_key_initializer), + app.opts.use_transport_auth), authenticated(false), last_io_time(::time(NULL)), byte_in_ticker(NULL), ============================================================ --- packet.cc f84b440b1088f7522e1776ea8d7be8a5002e6ea7 +++ packet.cc bb02904c4ea7677e86a235c9984100d7d36705ac @@ -326,29 +326,19 @@ feed_packet_consumer app_state & app; size_t & count; packet_consumer & cons; - string ident; - string key; - string certname; - string base; - string sp; feed_packet_consumer(size_t & count, packet_consumer & c, app_state & app_) - : app(app_), count(count), cons(c), - ident(constants::regex_legal_id_bytes), - key(constants::regex_legal_key_name_bytes), - certname(constants::regex_legal_cert_name_bytes), - base(constants::regex_legal_packet_bytes), - sp("[[:space:]]+") + : app(app_), count(count), cons(c) {} void validate_id(string const & id) const { - E(id.size() == 40 + E(id.size() == constants::idlen && id.find_first_not_of(constants::legal_id_bytes) == string::npos, F("malformed packet: invalid identifier")); } void validate_base64(string const & s) const { E(s.size() > 0 - && s.find_first_not_of(constants::legal_packet_bytes) == string::npos, + && s.find_first_not_of(constants::legal_base64_bytes) == string::npos, F("malformed packet: invalid base64 block")); } void validate_key(string const & k) const