D1995: sshpeer: document the handshake mechanism

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Thu Feb 1 23:37:42 UTC 2018


indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  The mechanism by which SSH peers establish connections with remotes
  is wonky and requires a bit of code archeology to understand. While
  it is already documented in `hg help internals.wireproto`, it helps
  to have documentation in the code as well.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1995

AFFECTED FILES
  mercurial/sshpeer.py

CHANGE DETAILS

diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py
--- a/mercurial/sshpeer.py
+++ b/mercurial/sshpeer.py
@@ -210,8 +210,24 @@
             hint = self.ui.config("ui", "ssherrorhint")
             self._abort(error.RepoError(msg, hint=hint))
 
+        # The purpose of the ``between`` command with a null range is to
+        # reliably get a specific response (``1\n\n`` - a 1 byte reply
+        # with value ``\n``) from *all* servers, possibly after "noise"
+        # emitted by the server (e.g. message of the day banners). The
+        # ``between`` command has existed for as long as the SSH peer has
+        # existed, which is how we know that we can rely on that command
+        # working. If we send the ``between`` command, we should see
+        # ``1\n\n`` in the response. If not, the remote isn't a valid
+        # Mercurial server.
+        #
+        # The ``hello`` command was added in Mercurial 0.9.1 as a mechanism for
+        # servers to advertise their capabilities. The client sends both
+        # ``hello`` and ``between`` to tease out old servers. If the server
+        # doesn't support ``hello``, it will send an empty reply (``0\n``) to
+        # that command. However, there will always be a reply to the ``between``
+        # command allowing us to differentiate between "noise" and command
+        # response.
         try:
-            # skip any noise generated by remote shell
             self._callstream("hello")
             r = self._callstream("between", pairs=("%s-%s" % ("0"*40, "0"*40)))
         except IOError:
@@ -234,6 +250,9 @@
         else:
             badresponse()
 
+        # Search for the ``hello`` response in reverse wire order. If there
+        # was e.g. an SSH banner that happened to emit ``capabilities:``, that
+        # should be before Mercurial's output.
         self._caps = set()
         for l in reversed(lines):
             if l.startswith("capabilities:"):



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list