Subject: Re: [hybi] [Editorial Errata Reported] RFC6455 (3473)

From: Martin Thomson <[email-masked]>
Date: Fri, 1 Feb 2013 23:27:33 +0900

Is this "host and port" or "IP and port" ?  That too is unclear.  If
I'm sharding a.example.com and b.example.com and they are served on
the same VIP, is the expectation that wss://a.example.com/ and
wss://b.example.com/ can't have concurrent connection attempts?

On 1 February 2013 16:38, RFC Errata System <[email-masked]> wrote:
>
> The following errata report has been submitted for RFC6455,
> "The WebSocket Protocol".
>
> --------------------------------------
> You may review the report below and at:
> http://www.rfc-editor.org/errata_search.php?rfc=6455&eid=3473
>
> --------------------------------------
> Type: Editorial
> Reported by: Adam Rice <[email-masked]>
>
> Section: 4.1
>
> Original Text
> -------------
>    2.  If the client already has a WebSocket connection to the remote
>        host (IP address) identified by /host/ and port /port/ pair, even
>        if the remote host is known by another name, the client MUST wait
>        until that connection has been established or for that connection
>        to have failed.  There MUST be no more than one connection in a
>        CONNECTING state.  If multiple connections to the same IP address
>        are attempted simultaneously, the client MUST serialize them so
>        that there is no more than one connection at a time running
>        through the following steps.
>
> Corrected Text
> --------------
>    2.  If the client already has a WebSocket connection to the remote
>        host (IP address) identified by /host/ and port /port/ pair, even
>        if the remote host is known by another name, the client MUST wait
>        until that connection has been established or for that connection
>        to have failed.  There MUST be no more than one connection in a
>        CONNECTING state.  If multiple connections to the same /host/ and
>        /port/ pair are attempted simultaneously, the client MUST serialize
>        them so that there is no more than one connection at a time running
>        through the following steps.
>
> Notes
> -----
> The original wording makes it ambiguous whether distinct ports on the same host are considered distinct for throttling purposes. The first sentence implies that the throttling should be applied per (host,port) pair, whereas the final sentence implies it is only based on IP address.
>
> Implementations of both interpretations appear to exist in the wild.
>
> I propose disambiguating in favour of the (host,port) interpretation, because the host-only interpretation allows for a potential denial-of-service attack targeted against hosts which drop packets to unused ports.
>
> For example, an attacker from a different origin can create several hundred WebSockets to "wss://google.com:81/". Each one will attempt to connect in serial, and take tens of seconds to time out.
>
> If the user then attempts to use an application which legitimately uses a WebSocket to "wss://google.com:443/", then due to the throttling to google.com it will not be able to connect until all of the attacker's connections have timed out.
>
> The user will perceive that the legitimate application is malfunctioning, since there is no visible sign that they are being attacked. From the server end, the attack is only apparent in the firewall logs. The actual rate of SYN packets dropped will be small and unlikely to trigger an alert.
>
> On the other hand, with the (host,port) interpretation, connections to google.com:81 do not block connections to google.com:443, and this attack is completely ineffective.
>
> Instructions:
> -------------
> This errata is currently posted as "Reported". If necessary, please
> use "Reply All" to discuss whether it should be verified or
> rejected. When a decision is reached, the verifying party (IESG)
> can log in to change the status and edit the report, if necessary.
>
> --------------------------------------
> RFC6455 (draft-ietf-hybi-thewebsocketprotocol-17)
> --------------------------------------
> Title               : The WebSocket Protocol
> Publication Date    : December 2011
> Author(s)           : I. Fette, A. Melnikov
> Category            : PROPOSED STANDARD
> Source              : BiDirectional or Server-Initiated HTTP
> Area                : Applications
> Stream              : IETF
> Verifying Party     : IESG
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi

---

From: Takeshi Yoshino <[email-masked]>
Date: Mon, 4 Feb 2013 15:49:45 +0900

FYI:

The text (without /port/) was introduced by Ian Hickson on this release
(April 2009).
http://tools.ietf.org/rfcdiff?url2=draft-hixie-thewebsocketprotocol-11.txt
MUST was added to the sentence by bulk addition of MUSTs/SHOULDs on this
release. Even before this was specified as MUST indirectly by the
introduction text for this algorithm.
http://tools.ietf.org/rfcdiff?url2=draft-ietf-hybi-thewebsocketprotocol-04.txt

/port/ was added on this release. I couldn't find discussion led to this
change on the list.
http://tools.ietf.org/rfcdiff?url2=draft-ietf-hybi-thewebsocketprotocol-07.txt

> Is this "host and port" or "IP and port" ?  That too is unclear.  If

Yes... /host/ in the spec is not always IP address. According to hixie-11,
it was intended to mean IP and he added the text "even if the remote host
is known by another name" (I'm not saying everybody in HyBi later agreed
with the text interpreting it that way).

> wss://b.example.com/ can't have concurrent connection attempts?

I think we should do so (no concurrent connection to a.example.com and
b.example.com). Throttling based on domain name / port pair might make
sense if a.example.com and b.example.com has different backends as you said
and the LB having the VIP has much more processing power than backends. But
as anybody can have A record pointing to the IP address (x.x.x.x) of
a.example.com, an attacker can prepare a.attacker.com, b.attacker.com, ...
pointing to x.x.x.x and feed a script connecting to ws://a.attacker.com,
... to bypass the throttling (domain name based).

---

From: Adam Rice <[email-masked]>
Date: Mon, 4 Feb 2013 17:20:29 +0900

> wss://b.example.com/ can't have concurrent connection attempts?

I was assuming that in the first sentence the text "connection to the
remote host (IP address) ... even if the remote host is known by another
name" made the interpretation of "IP address" unambiguous.

But section 4.1 says that /host/ is defined in section 3, and section 3
 actually defines /host/ as "host = <host, defined in [RFC3986],
Section 3.2.2 <http://tools.ietf.org/html/rfc3986#section-3.2.2>>", ie. the
host portion of the URI.

So now I don't know.

---

From: Martin Thomson <[email-masked]>
Date: Tue, 5 Feb 2013 08:00:27 -0500

That is approximately where my reasoning lead. I think that the *safe*
option is to have one connection per name.
On Feb 4, 2013 3:20 AM, "Adam Rice" <[email-masked]> wrote:

> Section 3.2.2 <http://tools.ietf.org/html/rfc3986#section-3.2.2>>", ie.
> the host portion of the URI.
>
> So now I don't know.
>

---

From: Salvatore Loreto <[email-masked]>
Date: Thu, 14 Feb 2013 09:45:48 +0200

the original idea was to serialize the tentative to connect to the same 
IP address (especially in
the case several /host/ names share the same IP address);
IMO it becomes clear if you read the second paragraph of the bullet #2 
and the NOTE.

        If the client cannot determine the IP address of the remote host
        (for example, because all communication is being done through a
        proxy server that performs DNS queries itself), then the client
        MUST assume for the purposes of this step that each host name
        refers to a distinct remote host, and instead the client SHOULD
        limit the total number of simultaneous pending connections to a
        reasonably low number (e.g., the client might allow simultaneous
        pending connections to a.example.com and b.example.com, but if
        thirty simultaneous connections to a single host are requested,
        that may not be allowed).  For example, in a web browser context,
        the client needs to consider the number of tabs the user has open
        in setting a limit to the number of simultaneous pending
        connections.

        NOTE: This makes it harder for a script to perform a denial-of-
        service attack by just opening a large number of WebSocket
        connections to a remote host.  A server can further reduce the
        load on itself when attacked by pausing before closing the
        connection, as that will reduce the rate at which the client
        reconnects.

-- 
Salvatore Loreto, PhD
www.sloreto.com

On 2/5/13 3:00 PM, Martin Thomson wrote:
> On Feb 4, 2013 3:20 AM, "Adam Rice" <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>     On 1 February 2013 23:27, Martin Thomson <[email-masked]
>     <mailto:[email-masked]>> wrote:
>
>         I'm sharding a.example.com <http://a.example.com> and
>         b.example.com <http://b.example.com> and they are served on
>         the same VIP, is the expectation that wss://a.example.com/
>         <http://a.example.com/> and
>         wss://b.example.com/ <http://b.example.com/> can't have
>         concurrent connection attempts?
>
>
>     I was assuming that in the first sentence the text "connection to
>     the remote host (IP address) ... even if the remote host is known
>     by another name" made the interpretation of "IP address" unambiguous.
>
>     But section 4.1 says that /host/ is defined in section 3, and
>     section 3  actually defines /host/ as "host = <host, defined in
>     [RFC3986], Section 3.2.2
>     <http://tools.ietf.org/html/rfc3986#section-3.2.2>>", ie. the host
>     portion of the URI.
>
>     So now I don't know.
>
>
>

---

From: Salvatore Loreto <[email-masked]>
Date: Thu, 14 Feb 2013 10:19:25 +0200

to be clear, I am sympathetic with the need to better clarify the text 
and serialize
on both |host| and |port| but with the meaning of IP and |port|

-- 
Salvatore Loreto, PhD
www.sloreto.com

On 2/14/13 9:45 AM, Salvatore Loreto wrote:
> the original idea was to serialize the tentative to connect to the 
> same IP address (especially in
>> That is approximately where my reasoning lead. I think that the 
>> *safe* option is to have one connection per name.
>>
>>     On 1 February 2013 23:27, Martin Thomson
>>     <[email-masked] <mailto:[email-masked]>> wrote:
>>
>>     <http://tools.ietf.org/html/rfc3986#section-3.2.2>>", ie. the
>>     host portion of the URI.
>>
>>     So now I don't know.
>>
>>
>>

---

From: Barry Leiba <[email-masked]>
Date: Thu, 14 Feb 2013 10:56:59 -0500

On Feb 4, 2013 3:20 AM, "Adam Rice" <[email-masked]> wrote:
> actually defines /host/ as "host = <host, defined in [RFC3986], Section
> 3.2.2>", ie. the host portion of the URI.
>
> So now I don't know.

> option is to have one connection per name.

On Thu, Feb 14, 2013 at 2:45 AM, Salvatore Loreto
<[email-masked]> wrote:
> the original idea was to serialize the tentative to connect to the same IP
> address (especially in the case several /host/ names share the same IP
> address); IMO it becomes clear if you read the second paragraph of the
> bullet #2 and the NOTE.

OK... so how do you folks propose that your ADs resolve this errata report?

The options are as follows:

1. It's just wrong, and we should mark it "Rejected".  (This doesn't
seem like where you're going.)

2. It's absolutely correct as it is, and we should mark it "Verified".
 (It doesn't seem like it's this either.)

3. It's essentially correct, but needs some editing.  You can provide
the edits and we can edit it and then mark it "Verified".

4. It's true that there's a problem, but the resolution is beyond the
scope of an erratum.  We can either leave it as it is or edit it (to
tweak the proposed resolution and/or to explain the difficulty in
resolving it), and then mark it "Held for Document Update".

Barry, Applications AD

---

From: Barry Leiba <[email-masked]>
Date: Thu, 14 Feb 2013 11:46:51 -0500

Comment relayed (with permission) from someone who isn't subscribed to the list:

---------- Forwarded message ----------
From: Joakim Erdfelt <[email-masked]>
Date: Thu, Feb 14, 2013 at 11:31 AM
Subject: Re: [hybi] [Editorial Errata Reported] RFC6455 (3473)
To: Barry Leiba <[email-masked]>

Sorry, i don't have access to the ietf mailing list.

Speaking as a developer of the websocket implementation on the Java /
Eclipse Jetty side ...

This section is really just for Web Browsers to implement, not a
general purpose requirement for the protocol for all use cases and
implementations.

Some scenarios ...

Web Socket Proxies.

many websocket users -> websocket proxy -> destination server

In this scenario, if the questioned part of the RFC is enforced, then
a websocket proxy cannot exist. as the websocket proxy itself would be
in violation.

Also, the requirements of the pending websocket mux extension makes
the language of this section in RFC6455 interesting.
Is this requirement placed on the desire to connect to the destination
websocket server (you can call this the logical connection), or the
physical connection?

Mux also makes the above proxy scenario fun to noodle out.

--
Joakim Erdfelt <[email-masked]>
webtide.com
Developer advice, services and support
from the Jetty & CometD experts
eclipse.org/jetty - cometd.org

---

From: Adam Rice <[email-masked]>
Date: Fri, 15 Feb 2013 19:35:26 +0900

> resolving it), and then mark it "Held for Document Update".

I would like to take option 3. I would like to propose the following text
to clarify the intent of RFC6455 while preserving the meaning:

   2.  If the client already has a WebSocket connection to the same IP
       address and port pair, even if the remote host is known by another
       name, the client MUST wait until that connection has been established
       or for that connection to have failed.  There MUST be no more than
       one connection in a CONNECTING state.  If multiple connections to the
       same IP address and port pair are attempted simultaneously, the
       client MUST serialize them so that there is no more than one
       connection at a time running through the following steps.

The following paragraph already indicates what must be done in the case
where the IP address cannot be determined, so this change should not create
any difficulties in the case where the connection is tunnelled via an
HTTP(S) or SOCKS5 proxy.

I think the issue that this section creates problems for WebSocket proxies
and non-browser clients cannot be handled without changing the meaning of
the text, and so I would like to deal with that separately.

Thank you,
Adam Rice

---

From: Salvatore Loreto <[email-masked]>
Date: Fri, 15 Feb 2013 12:54:32 +0200

I agree with Adam on option 3
and also on the fact that we should not (and we are not allowed to)
change the meaning of the current text

Salvatore

-- 
Salvatore Loreto, PhD
www.sloreto.com

On 2/15/13 12:35 PM, Adam Rice wrote:
> On 15 February 2013 00:56, Barry Leiba <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>
> I would like to take option 3. I would like to propose the following 
> text to clarify the intent of RFC6455 while preserving the meaning:
>
> The following paragraph already indicates what must be done in the 
> case where the IP address cannot be determined, so this change should 
> not create any difficulties in the case where the connection 
> is tunnelled via an HTTP(S) or SOCKS5 proxy.
>
> I think the issue that this section creates problems for WebSocket 
> proxies and non-browser clients cannot be handled without changing the 
> meaning of the text, and so I would like to deal with that separately.
>
> Thank you,
> Adam Rice
>
>

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Fri, 15 Feb 2013 02:56:27 -0800

Agree. The original intent of the text was to serialize connections to an
<IP Address, Port> pair. Apologies for the unclear text.

On Fri, Feb 15, 2013 at 2:54 AM, Salvatore Loreto <
[email-masked]> wrote:

> Salvatore Loreto, PhDwww.sloreto.com
>
>

---

From: Barry Leiba <[email-masked]>
Date: Fri, 15 Feb 2013 09:32:57 -0500

> I would like to take option 3. I would like to propose the following text to
> clarify the intent of RFC6455 while preserving the meaning:
>

Great; Salvatore and Ian agree with this.  I'm happy to hear more
agreement or objections; if I don't hear objections in the next couple
of days, I'll go with this.

Barry

---

From: Simone Bordet <[email-masked]>
Date: Fri, 15 Feb 2013 18:56:15 +0100

Hi,

> the text, and so I would like to deal with that separately.

You have my +1 in advance for this :)
Let us know if something is needed to get this separate change going
(not familiar with IETF procedures).

-- 
Simone Bordet
----
http://cometd.org
http://webtide.com
http://intalio.com
Developer advice, training, services and support
from the Jetty & CometD experts.
Intalio, the modern way to build business applications.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 15 Feb 2013 11:56:17 -0800

Thanks Adam, this works nicely.

For extra clarity on the key 'MUST' sentence:
OLD:
There MUST be no more than
       one connection in a CONNECTING state.
NEW:
There MUST be no more than
       one connection in the CONNECTING state for any IP and port.

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 16 Feb 2013 08:26:04 +0100

Hi,

>        one connection in the CONNECTING state for any IP and port.

Fine by me as well.

Regards,
Willy