The unified diff between revisions [b976aa95..] and [5a03a08b..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch "ChangeLog"
#  from [8d3cbb0457a6d0781d5e80827ea8c62916264a5f]
#    to [c0b56d853e6bab768aecd1e4a355c103133be1fa]
#
# patch "netcmd.cc"
#  from [e04a41fed951a77dcef389e94cc26d04ae12220f]
#    to [3d925448e00e4f5a0e70f9ac977899fbf9312a1e]
#
# patch "netcmd.hh"
#  from [5626696805eab24ff5bd23f114a749b3aa78645a]
#    to [901532e162e97d3df8f89ccc1198203eef8ed8fe]
#
# patch "netsync.cc"
#  from [e1239ee221729406ac7a958d4f9f8740f774b127]
#    to [218fabbe4a06f50089a50833c72f9c1b4ed78a91]
#
============================================================
--- ChangeLog	8d3cbb0457a6d0781d5e80827ea8c62916264a5f
+++ ChangeLog	c0b56d853e6bab768aecd1e4a355c103133be1fa
@@ -1,3 +1,8 @@
+2005-06-16  Matt Johnston  <matt@ucc.asn.au>
+
+	* netcmd.{cc,hh}, netsync.cc: only read a single command packet
+	worth of data at a time, to avoid having to shuffle buffers about.
+
 2005-06-15  Matt Johnston  <matt@ucc.asn.au>

 	* monotone.texi: clarify some netsync parts of the tutorial
============================================================
--- netcmd.cc	e04a41fed951a77dcef389e94cc26d04ae12220f
+++ netcmd.cc	3d925448e00e4f5a0e70f9ac977899fbf9312a1e
@@ -47,10 +47,12 @@ netcmd::netcmd() : version(constants::ne
 }

 netcmd::netcmd() : version(constants::netcmd_current_protocol_version),
-                   cmd_code(bye_cmd)
+                   cmd_code(bye_cmd),
+                   payload_len(0), length_len(0)
 {}

-netcmd::netcmd(u8 _version) : version(_version), cmd_code(bye_cmd)
+netcmd::netcmd(u8 _version) : version(_version), cmd_code(bye_cmd),
+                   payload_len(0), length_len(0)
 {}

 size_t netcmd::encoded_size()
@@ -60,6 +62,17 @@ size_t netcmd::encoded_size()
   return 1 + 1 + tmp.size() + payload.size() + 4;
 }

+size_t netcmd::get_max_read()
+{
+  size_t ret = constants::netcmd_minsz + payload_len + length_len;
+  if (length_len > 0)
+    {
+      // netcmd_minsz already includes one byte for length_len
+      ret--;
+    }
+  return ret;
+}
+
 bool
 netcmd::operator==(netcmd const & other) const
 {
@@ -146,10 +159,11 @@ netcmd::read(string & inbuf)
   version = ver;

   // check to see if we have even enough bytes for a complete uleb128
-  size_t payload_len = 0;
+  size_t old_pos = pos;
   if (!try_extract_datum_uleb128<size_t>(inbuf, pos, "netcmd payload length",
       payload_len))
       return false;
+  length_len = pos - old_pos;

   // they might have given us a bogus size
   if (payload_len > constants::netcmd_payload_limit)
@@ -166,14 +180,18 @@ netcmd::read(string & inbuf)
   // Do this ourselves, so we can swap the strings instead of copying.
   require_bytes(inbuf, pos, payload_len, "netcmd payload");
   inbuf.erase(0, pos);
-  payload = inbuf.substr(payload_len);
-  inbuf.erase(payload_len, inbuf.npos);
+  pos = payload_len;
+  u32 checksum = extract_datum_lsb<u32>(inbuf, pos, "netcmd checksum");
+  inbuf.resize(payload_len);
   inbuf.swap(payload);
+
+  // we're done with inbuf
+  inbuf.clear();
   pos = 0;
+  payload_len = 0;
+  length_len = 0;

   // they might have given us bogus data
-  u32 checksum = extract_datum_lsb<u32>(inbuf, pos, "netcmd checksum");
-  inbuf.erase(0, pos);
   adler32 check(reinterpret_cast<u8 const *>(payload.data()),
                 payload.size());
   if (checksum != check.sum())
============================================================
--- netcmd.hh	5626696805eab24ff5bd23f114a749b3aa78645a
+++ netcmd.hh	901532e162e97d3df8f89ccc1198203eef8ed8fe
@@ -52,12 +52,15 @@ private:
   u8 version;
   netcmd_code cmd_code;
   std::string payload;
+  size_t payload_len;
+  size_t length_len;
 public:
   netcmd();
   netcmd(u8 _version);
   netcmd_code get_cmd_code() const {return cmd_code;}
   u8 get_version() const {return version;}
   size_t encoded_size();
+  size_t get_max_read();
   bool operator==(netcmd const & other) const;


============================================================
--- netsync.cc	e1239ee221729406ac7a958d4f9f8740f774b127
+++ netsync.cc	218fabbe4a06f50089a50833c72f9c1b4ed78a91
@@ -1264,7 +1264,11 @@ session::read_some()
 {
   I(inbuf.size() < constants::netcmd_maxsz);
   char tmp[constants::bufsz];
-  Netxx::signed_size_type count = str.read(tmp, sizeof(tmp));
+  size_t max_read = min(sizeof(tmp), cmd.get_max_read() - inbuf.size());
+  if (max_read == 0)
+    return true;
+
+  Netxx::signed_size_type count = str.read(tmp, max_read);
   if (count > 0)
     {
       L(F("read %d bytes from fd %d (peer %s)\n") % count % fd % peer_id);