git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Shawn Pearce <spearce@spearce.org>
To: Duy Nguyen <pclouds@gmail.com>
Cc: Junio C Hamano <gitster@pobox.com>,
	Stefan Beller <sbeller@google.com>,
	Git Mailing List <git@vger.kernel.org>
Subject: Re: [RFC/PATCH 0/3] protocol v2
Date: Wed, 4 Mar 2015 11:10:21 -0800	[thread overview]
Message-ID: <CAJo=hJupr=07+r6z5s9RiT_v2LYtdioiVS=yNfMag+mKfH9FhA@mail.gmail.com> (raw)
In-Reply-To: <CACsJy8B=MN412dZYYc=NwpXHVz=Pxv+8wWMT7JNurVgqKrWn8A@mail.gmail.com>

On Wed, Mar 4, 2015 at 4:05 AM, Duy Nguyen <pclouds@gmail.com> wrote:
> On Wed, Mar 4, 2015 at 11:27 AM, Shawn Pearce <spearce@spearce.org> wrote:
>> Let me go on a different tangent a bit from the current protocol.
>>
>> http://www.grpc.io/ was recently released and is built on the HTTP/2
>> standard. It uses protobuf as a proven extensibility mechanism.
>> Including a full C based grpc stack just to speak the Git wire
>> protocol is quite likely overkill, but I think the embedding of a
>> proven extensible format inside of a bi-directional framed streaming
>> system like HTTP/2 offers some good guidance.
>
> I'll take this as "learn from grpc, not just reuse grpc"

Correct, that was what I was trying to say and I just wrote it poorly.

HTTP 1.x, HTTP/2 and protobuf have proven themselves to be fairly open
to extension and working well in the wild for transports. There is
useful guidance there that we should draw from to try and leave doors
open for the future.

HTTP/2, protobuf and grpc are fairly complex. I consider any one of
them too complicated for Git specific use. However HTTP/2 is probably
the future of HTTP stacks so we may see it show up in libcurl or
something as popular as libcurl in another 10 years. Hg had some
reasonably sane ideas about building the wire protocol to work well on
HTTP 1.x upfront rather than Git tacking it on much later.

>> Network protocol parsing is hard. Especially in languages like C where
>> buffer overflows are possible. Or where a client could trivially DoS a
>> server by sending a packet of size uint_max and the server naively
>> trying to malloc() that buffer. Defining the network protocol in an
>> IDL like protobuf 3 and being machine generated from stable well
>> maintained code has its advantages.
>
> I'm still studying the spec, so I can't comment if using IDL/protobuf3
> is a good idea yet.
>
> But I think at least we can avoid DoS by changing the pkt-line (again)
> a bit: the length 0xffff means that actual length is 0xfffe and the
> next pkt-line is part of this pkt-line. Higher level (upload-pack or
> fetch-pack, for example) must set an upper limit for packet_read() so
> it won't try to concatenate pkt-lines forever.

pkt-line is a reasonably simple and efficient framing system. A 64 KiB
pkt-line frame only costs ~0.0061% overhead; ~0.0076% overhead if you
are a pack stream in a side-band-64k channel. That is probably more
efficient than HTTP/2 or SSL framing.

I see no reason to attempt to try and reduce that overhead further. 64
KiB frame size is enough for anyone to move data efficiently with
these headers. In practice you are going to wrap that up into SSH or
SSL/TLS and those overheads are so much higher it doesn't matter we
have a tiny loss here.

I think a mistake in the wire protocol was making the pkt-line length
human readable hex, but the sideband channel binary. _If_ we redo the
framing the only change I would make is making the side band readable.
Thus far we have only used 0, 1, 2 for sideband channels. These could
easily be moved into human readable channel ids:

  'd':  currently sideband 0; this is the application data, aka the pack data
  'p':  currently sideband 1; this is the progress stream for stderr
  'e':  currently sideband 2; there was an error, data in this packet
is the message text, and the connection will shutdown after the
packet.

And then leave all other sideband values undefined and reserved for
future use, just like they are all open today.

I am not convinced framing changes are necessary. I would fine with
leaving the sideband streams as 0,1,2... but if we want a text based
protocol for ease of debugging we should be text based across the
board and try very hard to avoid these binary values in the framing,
or ever needing to use a magical NUL byte in the middle of a packet to
find a gap in older parsers for newer data.


If you want to build a larger stream like ref advertisement inside a
pkt-line framing without using a pkt-line per ref record, you should
follow the approach used by pack data streams where it uses the 5 byte
side-band pkt-line framing and a side-band channel is allocated for
that data. Application code can then run a side-band demux to yank out
the inner stream and parse it.

It may be simpler to restrict ref names to be smaller than 64k in
length so you have room for framing and hash value to be transferred
inside of a single pkt-line, then use the pkt-line framing to do the
transfer.

Today's upload-pack ref advertisment has ~25% overhead. Most of that
is in the duplicated tag name for the peeled refs/tags/v1.0^{} lines.
If you drop those names (but keep the pkt-line and SHA-1), its only
about 8% overhead above the packed-refs file.

I think optimization efforts for ref advertisement need to focus on
reducing the number of refs sent back and forth, not shrinking the
individual records down smaller.


Earlier in this thread Junio raised a point that the flush-pkt is
confusing because it has way too many purposes. I agree. IIRC we have
0001-0003 as invalid pkt-line headers that could be used for special
markers in the stream.

For example we could use 0000 flush-pkt as "end of section" and define
0001 as "i am done speaking and now wait for you to reply".

I think we need to keep 0004 as "empty packet" in case we ever get
ourselves into a position where it makes sense to pass an empty string
from one end of the connection to another.


Running pkt-line inside of side-band-64k is... weird to read. IIRC we
only do that in the smart HTTP protocol to the remote-curl helper, and
this is where Junio's remarks about flush-pkt being confusing come
from. If we rewrote the protocol to have that explicit 0001 "i am done
talking" marker the helper wouldn't need the double framing to
understand how to break up the originally bidirectional packet stream
into a sequence of bursts sent on unidirectional HTTP 1.x.

  reply	other threads:[~2015-03-04 19:10 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-24  3:12 [RFC/PATCH 0/3] protocol v2 Stefan Beller
2015-02-24  3:12 ` [PATCH 1/3] Document protocol capabilities extension Stefan Beller
2015-02-24  3:12 ` [PATCH 2/3] receive-pack: add advertisement of different protocol options Stefan Beller
2015-02-24  3:12 ` [PATCH 3/3] receive-pack: enable protocol v2 Stefan Beller
2015-02-24  4:02 ` [RFC/PATCH 0/3] " Duy Nguyen
2015-02-24  5:40   ` Stefan Beller
2015-02-24  6:15   ` Junio C Hamano
2015-02-24 23:37     ` Stefan Beller
2015-02-25 12:44       ` Duy Nguyen
2015-02-25 18:04         ` Junio C Hamano
2015-02-26  7:31           ` Stefan Beller
2015-02-26 10:15             ` Duy Nguyen
2015-02-26 20:08               ` Stefan Beller
     [not found]                 ` <CACsJy8DOS_999ZgW7TqsH-dkrUFpjZf0TFQeFUt9s0bNhHY0Bw@mail.gmail.com>
2015-02-27 22:20                   ` Stefan Beller
2015-02-26 20:13               ` Junio C Hamano
2015-02-27  1:26                 ` Stefan Beller
2015-02-27  2:15                   ` Stefan Beller
2015-02-27 23:05                 ` Junio C Hamano
2015-02-27 23:44                   ` Stefan Beller
2015-02-28  0:33                     ` Junio C Hamano
2015-02-28  0:46                       ` Stefan Beller
2015-02-28  1:01                         ` [RFC/PATCH 0/5] protocol v2 for upload-pack Stefan Beller
2015-02-28  1:01                           ` [RFC/PATCH 1/5] upload-pack: only accept capabilities on the first "want" line Stefan Beller
2015-02-28  1:01                           ` [RFC/PATCH 2/5] upload-pack: support out of band client capability requests Stefan Beller
2015-02-28  7:47                             ` Kyle J. McKay
2015-02-28 11:22                               ` Duy Nguyen
2015-02-28 22:36                                 ` Kyle J. McKay
2015-03-01  0:11                                   ` Duy Nguyen
2015-02-28 11:36                             ` Duy Nguyen
2015-02-28  1:01                           ` [RFC/PATCH 3/5] connect.c: connect to a remote service with some flags Stefan Beller
2015-02-28 11:11                             ` Torsten Bögershausen
2015-03-01  3:22                             ` Junio C Hamano
2015-02-28  1:01                           ` [RFC/PATCH 4/5] daemon.c: accept extra service arguments Stefan Beller
2015-03-01  3:39                             ` Junio C Hamano
2015-02-28  1:01                           ` [RFC/PATCH 5/5] WIP/Document the http protocol change Stefan Beller
2015-02-28 12:26                             ` Duy Nguyen
2015-03-01  9:11                           ` [RFC/PATCH 0/5] protocol v2 for upload-pack Johannes Sixt
2015-03-02  2:58                             ` Junio C Hamano
2015-03-02  3:47                         ` [RFC/PATCH 0/3] protocol v2 Junio C Hamano
2015-03-02  9:21                           ` Duy Nguyen
2015-03-02  9:24                             ` Duy Nguyen
2015-03-03 10:33                             ` Duy Nguyen
2015-03-03 17:13                               ` Junio C Hamano
2015-03-03 19:47                                 ` Junio C Hamano
2015-03-04  1:54                                 ` Duy Nguyen
2015-03-04  4:27                                   ` Shawn Pearce
2015-03-04 12:05                                     ` Duy Nguyen
2015-03-04 19:10                                       ` Shawn Pearce [this message]
2015-03-05  1:03                                         ` Stefan Beller
2015-03-05 16:03                                           ` Stefan Beller
2015-03-24 17:42                                 ` Stefan Beller
2015-03-24 18:00                                   ` Junio C Hamano
2015-03-06 23:38                             ` [PATCH] protocol upload-pack-v2 Stefan Beller
2015-03-06 23:40                               ` Stefan Beller
2015-03-06 23:55                               ` Duy Nguyen
2015-03-07  0:00                               ` Duy Nguyen
2015-03-07  0:28                               ` Junio C Hamano
2015-03-07  4:28                                 ` Stefan Beller
2015-03-07  5:21                                   ` Duy Nguyen
2015-03-08 20:36                                   ` Junio C Hamano
2015-03-31 19:58                                     ` Junio C Hamano
2015-04-02 12:37                                       ` Duy Nguyen
2015-04-02 14:45                                         ` Junio C Hamano
2015-04-02 22:18                                       ` Martin Fick
2015-04-02 22:58                                         ` Junio C Hamano
2015-04-02 23:00                                         ` Stefan Beller
2015-04-02 23:14                                           ` Stefan Beller
2015-03-10  1:38                               ` Duy Nguyen
2015-03-10 19:36                                 ` Kyle J. McKay
2015-02-28  0:07                   ` [RFC/PATCH 0/3] protocol v2 Duy Nguyen
2015-02-28  0:26                     ` Junio C Hamano
2015-03-01  8:41     ` Junio C Hamano
2015-03-01 11:32       ` Duy Nguyen
2015-03-01 19:56         ` Stefan Beller
2015-03-02  1:05           ` David Lang
2015-03-01 23:06         ` Junio C Hamano
2015-03-02  1:09           ` David Lang
2015-03-02  3:10             ` Junio C Hamano
2015-03-01 23:06       ` Philip Oakley
2015-03-02  9:32         ` Duy Nguyen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJo=hJupr=07+r6z5s9RiT_v2LYtdioiVS=yNfMag+mKfH9FhA@mail.gmail.com' \
    --to=spearce@spearce.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=pclouds@gmail.com \
    --cc=sbeller@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).