Skip to content

Latest commit

 

History

History
65 lines (42 loc) · 3.78 KB

L114-node-server-connection-injection.md

File metadata and controls

65 lines (42 loc) · 3.78 KB

L114: Node Server Connection Injection

Abstract

Add a new method createConnectionInjector to the Server class to allow existing TCP connections or TCP connection-like objects to be injected into the server. These connections would have the TLS handshake conducted according to the credentials provided in the call to that method, and then method handlers and interceptors for the server would apply as usual.

Background

As a part of the design gRFC A29: xDS-Based Security for gRPC Clients and Servers, a single server can apply different security configurations to different incoming connections on the same port depending on properties of those connections. This is not possible with the existing Node gRPC Server implementation, because the Node HTTP2 server listens on a port and automatically performs the TLS handshake for every incoming connection.

In addition, this functionality has been requested in grpc/grpc-node#2317.

Related Proposals:

Proposal

We will add a new method createConnectionInjector(credentials: ServerCredentials): ConnectionInjector to the Server class. The ConnectionInjector class has the following API:

interface ConnectionInjector {
  injectConnection(connection: stream.Duplex): void;
  drain(graceTimeMs: number): void;
  destroy(): void;
}

The injectConnection method accepts any duplex byte stream object, represented as the built in stream.Duplex class. The built in APIs represent TCP connections with the net.Socket class, which is a subclass of stream.Duplex. The server will perform the TLS handshake with the specified credentials and then handle the connection just like any other connection that comes in on a listening port.

The drain method gracefully closes all open connections injected in to this ConnectionInjector, similar to the Server#drain method defined in gRFC L111.

The destroy method shuts down the ConnectionInjector and gracefully closes all open connections injected into it, similar to the Server#unbind method defined in gRFC L109.

Rationale

drain method

The xDS Server needs to be able to drain existing connections after receiving an update to the Listener resource. A drain method on the ConnectionInjector provides a simple way to do that and it matches an existing Server method.

destroy method

A connection injector does not own any listening TCP ports, so it generally does not represent resources that need to be released. However, gRFC A29 introduces new credentials types that are more resource-intensive, so it is useful to be able to release references to those.

Alternatives considered

Opaque handle usable in existing APIs

An alternative design is for createConnectionInjector to return an opaque object (Handle) that can be passed as an argument to the drain and unbind methods, in addition to another new Server method injectConnection(handle: Handle, connection: stream.Duplex). This is functionally equivalent to the proposed design, but I think it's cleaner to have that functionality in an object.

Implementation

I (murgatroid99) will implement this in parallel with the design review.