git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [RFC/WIP PATCH 11/11] Document protocol version 2

From
Stefan Beller <sbeller@google.com>
Date
Jun 1, 2015, 23:40 UTC
Message-ID
<CAGZ79kYD--dZ_V=_X_Eo31KYTKXt2njuf56XqRRdaTJeLhDjaQ@mail.gmail.com>
In-Reply-To
<CAGZ79kaRTLX7eBCOA=yQHVwcN-H-o_aZFfQ1gw7Nx-NC82pbag@mail.gmail.com>
On Mon, Jun 1, 2015 at 4:14 PM, Stefan Beller <sbeller@google.com> wrote:
Show 67 quoted lines
> On Fri, May 29, 2015 at 3:21 PM, Jeff King <peff@peff.net> wrote:
>> On Fri, May 29, 2015 at 02:52:14PM -0700, Junio C Hamano wrote:
>>
>>> > Currently we can do a = as part of the line after the first ref, such as
>>> >
>>> >     symref=HEAD:refs/heads/master agent=git/2:2.4.0
>>> >
>>> > so I thought we want to keep this.
>>>
>>> I do not understand that statement.
>>>
>>> Capability exchange in v2 is one packet per cap, so the above
>>> example would be expressed as:
>>>
>>>       symref=HEAD:refs/heads/master
>>>         agent=git/2:2.4.0
>>>
>>> right?  Your "keyvaluepair" is limited to [a-z0-9-_=]*, and neither
>>> of the above two can be expressed with that, which was why I said
>>> you need two different set of characters before and after "=".  Left
>>> hand side of "=" is tightly limited and that is OK.  Right hand side
>>> may contain characters like ':', '.' and '/', so your alphabet need
>>> to be more lenient, even in v1 (which I would imagine would be "any
>>> octet other than SP, LF and NUL").
>
> I think the recent issue with the push certificates shows that having arbitrary
> data after the = is a bad idea. So we need to be very cautious when to allow
> which data after the =.
>
> I'll try split up the patch.
>
>>
>> Yes. See git_user_agent_sanitized(), for example, which allows basically
>> any printable ASCII except for SP.
>>
>> I think the v2 capabilities do not even need to have that restriction.
>> It can allow arbitrary binary data, because it has an 8bit-clean framing
>> mechanism (pkt-lines). Of course, that means such capabilities cannot be
>> represented in a v1 conversation (whose framing mechanism involves SP
>> and NUL). But it's probably acceptable to introduce new capabilities
>> which are only available in a v2 conversation. Old clients that do not
>> understand v2 would not understand the capability either. It does
>> require new clients implementing the capability to _also_ implement v2
>> if they have not done so, but I do not mind pushing people in that
>> direction.
>>
>> The initial v2 client implementation should probably do a few cautionary
>> things, then:
>>
>>   1. Do _not_ fold the per-pkt capabilities into a v1 string; that loses
>>      the robust framing. I suggested string_list earlier, but probably
>>      we want a list of ptr/len pair, so that it can remain NUL-clean.
>>
>>   2. Avoid holding on to unknown packets longer than necessary. Some
>>      capability pkt-lines may be arbitrarily large (up to 64K). If we do
>>      not understand them during the v2 read of the capabilities, there
>>      is no point hanging on to them. It's not _wrong_ to do so, but just
>>      inefficient; if we know that clients will just throw away unknown
>>      packets, then we can later introduce new packets with large data,
>>      without worrying about wasting the client's resources.
>>
>>      I suspect it's not that big a deal either way, though. I have no
>>      plans for sending a bunch of large packets, and anyway network
>>      bandwidth is probably more precious than client memory.
>
> That's very sensible thoughts after rereading this email. The version
> I'll be sending out today will not follow those suggestions though. :(

Thinking about this further, maybe it is a good idea to restrict the capabilities advertising to alphabetical order?

The exchange would look like this:
server:
  for capability in list:
      pkt_write(capability)
  pkt_flush
client:
  do
    line = recv_pkt()
    parse_capability(line)
  while line != flush

with parse_capability checking if we know the capability and maybe setting some internal field if we know this capability.

Now if we assume the number of capabilities grows over time a lot (someone may "abuse" it for a cool feature, similar to the refs currently. Nobody thought about having so many refs in advance)

So how does parse_capability scale w.r.t the number of capabilities? If parse_capability is just a linear search then it is O(n) and with n capabilities the client faces an O(n^2) computation which is bad. So if we were to require alphabetic capabilities, you could internally keep track and the whole operation is O(n). I just wonder if this is premature optimization or some thought we need to think of.

To prevent this problem from popping up, it must be easier to introduce a new phase after the capabilities exchange than to just abuse the capabilities phase for whatever you plan on doing.

Thanks, Stefan

>
>>
>> -Peff
Previous: Stefan BellerNext: Jeff King
Message 52 of 61 in “Protocol version 2, again!”
  1. 00/11 Protocol version 2, again!Stefan Beller, May 26, 2015
  2. 01/11 upload-pack: make client capability parsing code a separate functionStefan Beller, May 26, 2015
  3. 02/11 upload-pack: only accept capabilities on the first "want" lineStefan Beller, May 26, 2015
  4. Junio C HamanoMay 26, 2015
  5. Stefan BellerMay 26, 2015
  6. 03/11 upload-pack: move capabilities out of send_refStefan Beller, May 26, 2015
  7. 04/11 upload-pack-2: Implement the version 2 of upload-packStefan Beller, May 26, 2015
  8. Eric SunshineMay 27, 2015
  9. Jeff KingMay 27, 2015
  10. Eric SunshineMay 27, 2015
  11. Jeff KingMay 27, 2015
  12. Stefan BellerMay 27, 2015
  13. Jeff KingMay 27, 2015
  14. Stefan BellerMay 27, 2015
  15. Jeff KingMay 27, 2015
  16. 05/11 transport: add infrastructure to support a protocol version numberStefan Beller, May 26, 2015
  17. Jeff KingMay 27, 2015
  18. Stefan BellerMay 27, 2015
  19. Jeff KingMay 27, 2015
  20. Junio C HamanoMay 27, 2015
  21. 06/11 remote.h: add get_remote_capabilities, request_capabilitiesStefan Beller, May 26, 2015
  22. Eric SunshineMay 27, 2015
  23. Jeff KingMay 27, 2015
  24. Eric SunshineMay 27, 2015
  25. Jeff KingMay 27, 2015
  26. Jeff KingMay 27, 2015
  27. Stefan BellerMay 29, 2015
  28. Jeff KingMay 29, 2015
  29. 07/11 fetch-pack: use the configured transport protocolStefan Beller, May 26, 2015
  30. Junio C HamanoMay 26, 2015
  31. Stefan BellerMay 26, 2015
  32. Jeff KingMay 27, 2015
  33. 08/11 transport: connect_setup appends protocol version numberStefan Beller, May 26, 2015
  34. Junio C HamanoMay 26, 2015
  35. Stefan BellerMay 26, 2015
  36. Junio C HamanoMay 27, 2015
  37. Jeff KingMay 27, 2015
  38. Eric SunshineMay 27, 2015
  39. Jeff KingMay 27, 2015
  40. 09/11 transport: get_refs_via_connect exchanges capabilities before refs.Stefan Beller, May 26, 2015
  41. Eric SunshineMay 27, 2015
  42. Jeff KingMay 27, 2015
  43. 10/11 t5544: add a test case for the new protocolStefan Beller, May 26, 2015
  44. Eric SunshineMay 27, 2015
  45. Jeff KingMay 27, 2015
  46. 11/11 Document protocol version 2Stefan Beller, May 26, 2015
  47. Junio C HamanoMay 29, 2015
  48. Stefan BellerMay 29, 2015
  49. Junio C HamanoMay 29, 2015
  50. Jeff KingMay 29, 2015
  51. Stefan BellerJun 1, 2015
  52. Stefan BellerJun 1, 2015
  53. Jeff KingJun 4, 2015
  54. Junio C HamanoJun 4, 2015
  55. Junio C HamanoJun 2, 2015
  56. Jeff KingMay 27, 2015
  57. Jeff KingMay 27, 2015
  58. Stefan BellerJun 1, 2015
  59. Duy NguyenJun 2, 2015
  60. Jeff KingJun 4, 2015
  61. Stefan BellerJun 4, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.