Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close sessions which originSet is fully covered by other sessions and reuse those #17

Closed
szmarczak opened this issue Jul 19, 2019 · 15 comments · Fixed by #21
Closed

Close sessions which originSet is fully covered by other sessions and reuse those #17

szmarczak opened this issue Jul 19, 2019 · 15 comments · Fixed by #21
Assignees
Labels
agent enhancement New feature or request help wanted Extra attention is needed
Milestone

Comments

@szmarczak
Copy link
Owner

See https://nodejs.org/api/http2.html#http2_event_origin

@szmarczak szmarczak added the question Further information is requested label Jul 19, 2019
@pietermees
Copy link

More details on when connection coalescing is allowed can be found in the RFC: https://tools.ietf.org/html/draft-ietf-httpbis-origin-frame-06#section-2.4

@szmarczak
Copy link
Owner Author

Specifically, such clients [...] SHOULD use the connection for all requests to
origins in the Origin Set for which the connection is authoritative,
unless there are operational reasons for opening a new connection.
...
Because ORIGIN can change the set of origins a connection is used for
over time, it is possible that a client might have more than one
viable connection to an origin open at any time. When this occurs,
clients SHOULD NOT emit new requests on any connection whose Origin
Set is a proper subset of another connection's Origin Set, and SHOULD
close it once all outstanding requests are satisfied.

So as I understand it if I got two connections:

  • connection A with an authority of A and B
  • connection B with an authority of B

And I want to make a request to B I should use connection B instead no matter what?

@pietermees
Copy link

I think it's saying the opposite: you should use connection A and close connection B as soon as it finishes processing all outstanding requests, so you can keep 1 connection alive for both origins?

@szmarczak
Copy link
Owner Author

clients SHOULD NOT emit new requests on any connection whose Origin
Set is a proper subset of another connection's Origin Set, and SHOULD
close it once all outstanding requests are satisfied.

Connection A contains the authority of B, which is a proper subset of connection B. OTOH, it says

whose Origin Set is a proper subset of another connection's Origin Set

Does it refer to the whole Origin Set or just a part of it?

@szmarczak
Copy link
Owner Author

From https://httpwg.org/specs/rfc7540.html

An origin server might offer a certificate with multiple subjectAltName attributes or names with wildcards, one of which is valid for the authority in the URI. For example, a certificate with a subjectAltName of *.example.com might permit the use of the same connection for requests to URIs starting with https://a.example.com/ and https://b.example.com/.

In some deployments, reusing a connection for multiple origins can result in requests being directed to the wrong origin server. For example, TLS termination might be performed by a middlebox that uses the TLS Server Name Indication (SNI) [TLS-EXT] extension to select an origin server. This means that it is possible for clients to send confidential information to servers that might not be the intended target for the request, even though the server is otherwise authoritative.

@szmarczak szmarczak pinned this issue Jul 28, 2019
@pietermees
Copy link

@szmarczak could you clarify what you find confusing the origin set RFC language? I think it clearly states that if you have a connection that is authoritative for a set of origins that are already fully covered by another connection, you should close the former. This makes sense as the more valuable connection is the one with the larger encompassing set?

Regarding RFC7540, I think it simply states that in some scenarios connection reuse can end up sending data to the wrong server. That happens because SNI happens at connect time when you were trying to reach origin A, but now you’re reusing the same connection for origin B. The spec resolves this potential issue by having the server send a 421 error and allowing the client to retry the request on another connection (for example one explicitly established to origin B).

In summary:

  1. A connection originally established for origin A can be reused for origin B if that connection is also authoritative for B
  2. Authoritative is determined by
    • DNS resolving to the same IP:port for http
    • (DNS resolving to the same IP:port OR having an ORIGIN frame that indicates authority) AND having TLS subjectAltName authority
  3. If one connection’s authority is a subset of another’s, you can close the former
  4. If connection reuse ends up sending a request to the wrong server, that server should respond with a 421 and you are allowed to retry on another connection.

@pietermees
Copy link

https://tools.ietf.org/html/draft-ietf-httpbis-origin-frame-06 further clarifies that ORIGIN helps address two issues:

  1. Preventing 421 responses and when they do happen how to manipulate the connection’s origin set to prevent further issues.
  2. Relax the need for DNS resolving to the same IP before you can reuse a connection. Note that this involves its own security considerations which are outlined in section 4 of the ORIGIN draft RFC

@szmarczak
Copy link
Owner Author

I don't understand the meaning of proper in:

clients SHOULD NOT emit new requests on any connection whose Origin
Set is a proper subset of another connection's Origin Set

What's considered a proper subset? In my example server B holds the primary authority of B. Server A provides two valid authorities: A and B.

Does it refer to the primary authority? IOW:

First, you want to exchange some data with B. So you connect to server B, which holds the primary authority of B. Then, you connet to server A and it has two valid authorities: A (note: A is not owned by B, they're two different parties) and B. What should you do? What's the proper Origin Set?

@pietermees
Copy link

pietermees commented Jul 28, 2019 via email

@szmarczak
Copy link
Owner Author

Ah, my bad. Thanks for the explaination! Sorry, I didn't know that these are math keywords. I'm not native English :P Again, great thanks. You've been right from the beginning. I'll try to make a PR ASAP.

@pietermees
Copy link

pietermees commented Jul 28, 2019 via email

@szmarczak szmarczak unpinned this issue Jul 28, 2019
@szmarczak szmarczak added agent enhancement New feature or request and removed question Further information is requested labels Jul 29, 2019
@szmarczak szmarczak changed the title When to reuse sessions with many origins? Close sessions which originSet is fully covered by other sessions Jul 29, 2019
@szmarczak szmarczak added the help wanted Extra attention is needed label Jul 29, 2019
@szmarczak szmarczak changed the title Close sessions which originSet is fully covered by other sessions Close sessions which originSet is fully covered by other sessions and reuse sessions with many origins Jul 30, 2019
@szmarczak szmarczak changed the title Close sessions which originSet is fully covered by other sessions and reuse sessions with many origins Close sessions which originSet is fully covered by other sessions and reuse them Jul 30, 2019
@szmarczak
Copy link
Owner Author

@pietermees I understand the part above. So if I got this:

  • connection A with an authority of A and C,
  • connection B with an authority of B and C,

and I want to make a request to C, it doesn't matter whether I choose A or B? (I can't create a C connection because it would violate the RFC)

@szmarczak szmarczak self-assigned this Jul 30, 2019
@szmarczak szmarczak changed the title Close sessions which originSet is fully covered by other sessions and reuse them Close sessions which originSet is fully covered by other sessions and reuse those Jul 30, 2019
@pietermees
Copy link

@szmarczak correct, that's my understanding as well!
You'd be free to pick either one. A good path in this case might be to use the connection that was most recently used for a request? That would direct traffic to the most active connection and allow an unused one to potentially get closed due to being unused at some later point?

@szmarczak
Copy link
Owner Author

@pietermees You may want to see #21 (there are two todos left). I haven't made the tests yet.

@szmarczak
Copy link
Owner Author

Finished that todos. I just need to add some RFC comments so it's easier to understand the code and make the tests.

@szmarczak szmarczak added this to the v1.0.0-beta.1 milestone Aug 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agent enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
2 participants