Re: [quicwg/base-drafts] Rewrite text about Version Negotiation (#1039)
Martin Thomson <notifications@github.com> Wed, 17 January 2018 04:37 UTC
Return-Path: <bounces+848413-a050-quic-issues=ietf.org@sgmail.github.com>
X-Original-To: quic-issues@ietfa.amsl.com
Delivered-To: quic-issues@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 780A112EC9F for <quic-issues@ietfa.amsl.com>; Tue, 16 Jan 2018 20:37:44 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.029
X-Spam-Level:
X-Spam-Status: No, score=-2.029 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=github.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2H-xHfoj0qvp for <quic-issues@ietfa.amsl.com>; Tue, 16 Jan 2018 20:37:42 -0800 (PST)
Received: from o1.sgmail.github.com (o1.sgmail.github.com [192.254.114.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id BEA9D1243F6 for <quic-issues@ietf.org>; Tue, 16 Jan 2018 20:37:41 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=github.com; h=from:reply-to:to:cc:in-reply-to:references:subject:mime-version:content-type:content-transfer-encoding:list-id:list-archive:list-post:list-unsubscribe; s=s20150108; bh=qM+crVpVU7IUHi1hwZXQDnqZaVM=; b=L25KCYqXIq6qutNI lO2URIp+Boxqyj0U3iDS7Pu/UIfdz9r1C7mdaGp1n/4fgNeMStAMAnXnoFStGCAk Beec7hDUpokhheWIw9mfrwUdflrrR9+PTtnvpKc4ShJaPZAisZD6CF72R5Mz25ZL F4/RtDJtO+VXSOY9nS7lPCxBX1E=
Received: by filter0469p1iad2.sendgrid.net with SMTP id filter0469p1iad2-29870-5A5ED314-C 2018-01-17 04:37:40.832434781 +0000 UTC
Received: from github-smtp2b-ext-cp1-prd.iad.github.net (github-smtp2b-ext-cp1-prd.iad.github.net [192.30.253.17]) by ismtpd0002p1iad1.sendgrid.net (SG) with ESMTP id gUbYC3C0Ttiwfq8aPSD4vw for <quic-issues@ietf.org>; Wed, 17 Jan 2018 04:37:40.715 +0000 (UTC)
Date: Wed, 17 Jan 2018 04:37:40 +0000
From: Martin Thomson <notifications@github.com>
Reply-To: quicwg/base-drafts <reply+0166e4ab39ef158dc893a877bce711480a4d32d257656d7f92cf000000011676951492a169ce1115d834@reply.github.com>
To: quicwg/base-drafts <base-drafts@noreply.github.com>
Cc: Subscribed <subscribed@noreply.github.com>
Message-ID: <quicwg/base-drafts/pull/1039/c358194841@github.com>
In-Reply-To: <quicwg/base-drafts/pull/1039@github.com>
References: <quicwg/base-drafts/pull/1039@github.com>
Subject: Re: [quicwg/base-drafts] Rewrite text about Version Negotiation (#1039)
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="--==_mimepart_5a5ed3148cf6d_3e853f928c34ef28138627"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: martinthomson
X-GitHub-Recipient: quic-issues
X-GitHub-Reason: subscribed
X-Auto-Response-Suppress: All
X-GitHub-Recipient-Address: quic-issues@ietf.org
X-SG-EID: l64QuQ2uJCcEyUykJbxN122A6QRmEpucztpreh3Pak2v4lw5bTDbcFlr6S+qlZ3xjYF8A+vafDsA66 J12TIuXW0bj3aQQyEuPizOnV722gfSM/ipuvZOyDyx/i+Xa4j5bChkVZL/6nT/aNX39+ZmV/MxSToU zJEqoNjmjzbhfuprXyx91NS17yhBD8JAThmwEENLr/T9JkT1xHpL7kUrCdZtwpGk77TD0HLTbF1EEF A=
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic-issues/M5fT3Il5jQ9e10tPL8HJt1UdHDs>
X-BeenThere: quic-issues@ietf.org
X-Mailman-Version: 2.1.22
List-Id: Notification list for GitHub issues related to the QUIC WG <quic-issues.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic-issues/>
List-Post: <mailto:quic-issues@ietf.org>
List-Help: <mailto:quic-issues-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 17 Jan 2018 04:37:44 -0000
I think that @mikkelfj is almost right here, but I think that there's a more general problem with your pseudo-c-code. I don't think that we need to proscribe a particular software architecture (we're not THAT far gone just yet), but the way that I think of approaching this problem is to start with what the software needs to do first. And for me the first step isn't to just process the packet, but to determine which connection it should be handled by. The code here mixes connection selection into the handing more than I'd like. I also see a few places where you assume that long header is synonymous with handshake, and that's not something we're assuming when writing these descriptions (it's true of the current set of types, but I don't think that we're prepared to commit to that just yet). I'd like to think that we could have a simple bit of logic there. Something like: ```python connection = lookup_by_connection_id(packet.connection_id) if connection is None: connection = lookup_by_tuple(packet.address) if connection is not None: connection.handle_packet(packet) return ``` After which you engage the logic for handling packets that don't belong to existing connections, which includes server-side version negotiation. This is what I ended up with when following that to its conclusion: ```python # Lookup by connection ID. A client that has just one connection might # implement this lookup simply by checking the connection ID against their one # connection. The connection ID might be None for short headers, but that's OK. # Note that the lookup needs to be able to return the same connection against # multiple connection IDs in order to support NEW_CONNECTION_ID. connection = lookup_by_connection_id(packet.connection_id) if connection is not None: connection.handle_packet(packet) return # The lookup by tuple is run in two steps. The first check works only when the # configuration allows the peer to omit the connection ID. In that case we # should only have one connection on each tuple. if config.allow_omit_connection_id: connections = lookup_by_tuple(packet.address) assert(len(connections) <= 1) if len(connections) == 1: connections[0].handle_packet(packet) return # Clients that are handshaking might receive a 1-RTT packet with a # server-selected connection ID if there is packet loss or reordering. Clients # that allow multiple connections on the same address tuple need to pass the # packet to all potential connections. The client packet handler is responsible # for buffering packets that it isn't ready for yet. if is_client: connections = lookup_by_tuple(packet.address) assert(config.allow_shared_tuple or len(connections) <= 1) for c in connections: if not c.handshake_done(): c.handle_packet(packet) return # The server might need to make a new connection now. # First check that the version is supported. (Note that we can assume that # short headers, which have a version of None, are unsupported on the basis that we # should have found a connection already for any of those. Only the client # needs to deal with short headers before version negotiation completes.) if not is_supported_version(packet.version): if packet.maybe_initial(): # True if long header and if size is plausible. send_version_negotiation(packet.address.src) return # drop it if packet.is_initial(): connection = make_connection() connection.version_negotiation_done = true connection.handle_packet(packet) return # Servers will want to be very careful here. if is_maybe_0rtt(packet): buffer_0rtt(packet) # Anything not handled by this point is junk and can be dropped. ``` Admittedly, this is a fair bit simpler without the buffering complicating things, but I think that we have to cover that possibility properly when we write text. Also, it could probably be factored more cleanly, but it turns out to be quite complicated once you add buffering. I was surprised to see that the addition of multiple connections on the same address tuple didn't complicate things that much if you accept that you want to buffer 1-RTT packets at the client. While that's likely only because of the structure I chose to use here, it's still something of a positive outcome, I guess. When the packet arrives at a connection, you run the version check first. The client has to do version negotiation. This is pretty simple: ```python if not this.version_negotiation_done: # This branch only applies to clients because the server always sets # version_negotiation_done to true before starting. assert(is_client) if packet.version == 0: this.version = pick_version(packet.versions) this.version_negotiation_done = true this.start_over() return false # packet will be discarded if packet.version == this.version: this.version_negotiation_done = true return true # This includes short headers, which we aren't ready for yet. return false if packet.version is not None and packet.version != this.version: return false # discard it return true # OK to process this packet ``` Noting that this doesn't handle the case where the client needs to buffer 1-RTT, so any potential buffering check needs to come before this is run. And then it's on to the standard processing, decryption and so forth. There's also a bunch of tail-end processing necessary, such as that needed to maintain the lookup tables, and that needs to be conditional on the success of the decryption, but that's an exercise for the reader. One thing that I think is important is that I barely pay attention to whether the packet is long or short in this logic. Though that determines whether or not we have a version field in the packet (and thus whether we consider the version supported), and similarly whether the connection ID might be absent, that effect is constrained to those places that check those fields. Otherwise the code doesn't care about packet format. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/quicwg/base-drafts/pull/1039#issuecomment-358194841
- [quicwg/base-drafts] Rewrite text about Version N… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… MikkelFJ
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… MikkelFJ
- Re: [quicwg/base-drafts] Rewrite text about Versi… ianswett
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… ianswett
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… MikkelFJ
- Re: [quicwg/base-drafts] Rewrite text about Versi… Mike Bishop
- Re: [quicwg/base-drafts] Rewrite text about Versi… MikkelFJ
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Nick Banks
- Re: [quicwg/base-drafts] Rewrite text about Versi… MikkelFJ
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… MikkelFJ
- Re: [quicwg/base-drafts] Rewrite text about Versi… MikkelFJ
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… Marten Seemann
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Mike Bishop
- Re: [quicwg/base-drafts] Rewrite text about Versi… Mike Bishop
- Re: [quicwg/base-drafts] Rewrite text about Versi… Mike Bishop
- Re: [quicwg/base-drafts] Rewrite text about Versi… Mike Bishop
- Re: [quicwg/base-drafts] Rewrite text about Versi… Kazuho Oku
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… martinduke
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson
- Re: [quicwg/base-drafts] Rewrite text about Versi… Martin Thomson