Skip to content

Commit

Permalink
quic: allow multiple independent .connect() calls
Browse files Browse the repository at this point in the history
Explicitly allow calling `.connect()` multiple times to generate
separate client sessions on the same socket. This requires making
`kMaybeBind` call its callback even if the socket is already bound.

PR-URL: nodejs#176
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
addaleax authored and juanarbol committed Dec 17, 2019
1 parent 081afca commit 652ceb7
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 20 deletions.
4 changes: 3 additions & 1 deletion doc/api/quic.md
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,9 @@ added: REPLACEME
be `'udp4'`, indicating UDP over IPv4, or `'udp6'`, indicating UDP over
IPv6. Defaults to `'udp4'`.

Create a new `QuicClientSession`.
Create a new `QuicClientSession`. This function can be called multiple times
to create sessions associated with different endpoints on the same
client endpoint.

### quicsocket.destroy([error])
<!-- YAML
Expand Down
33 changes: 15 additions & 18 deletions lib/internal/quic/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -741,15 +741,18 @@ class QuicSocket extends EventEmitter {
}

// Bind the UDP socket on demand, only if it hasn't already been bound.
// Function is a non-op if the socket is already bound
// Function is a non-op if the socket is already bound or in the process of
// being bound, and will call the callback once the socket is ready.
[kMaybeBind](callback = () => {}) {
if (this.#state !== kSocketUnbound) {
if (this.bound)
return process.nextTick(callback);
else
return this.on('ready', callback);
}
// This socket will be in a pending state until it is bound. Once bound,
// the this[kReady]() method will be called, switching the state to
// kSocketBound and notifying the associated sessions
// TODO(@jasnell): If the socket is already bound, the callback should
// be invoked with an error.
if (this.#state !== kSocketUnbound)
return;
// kSocketBound and notifying the associated sessions.
this.#state = kSocketPending;
this.#lookup(this.#address, afterLookup.bind(this, callback));
}
Expand Down Expand Up @@ -930,18 +933,12 @@ class QuicSocket extends EventEmitter {
if (typeof callback === 'function')
session.on('ready', callback);

const afterBind =
connectAfterBind.bind(
this,
session,
this.#lookup,
address,
getSocketType(type));
if (this.#state === kSocketBound) {
afterBind();
} else {
this[kMaybeBind](afterBind);
}
this[kMaybeBind](connectAfterBind.bind(
this,
session,
this.#lookup,
address,
getSocketType(type)));

return session;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const { once } = require('events');
}
});

let done = 0;
for (const server of servers) {
const req = client.connect({
address: 'localhost',
Expand All @@ -60,7 +61,7 @@ const { once } = require('events');

const [ stream ] = await once(req, 'stream');
stream.resume();
await once(stream, 'end');
await(stream, 'end');

server.close();
req.close();
Expand Down

0 comments on commit 652ceb7

Please sign in to comment.