Skip to content

Commit ee2fa47

Browse files
tegefaulkesCMCDragonkai
authored andcommitted
feat: handling connections draining before closing socket
* Related #9 [ci skip]
1 parent 2346e8c commit ee2fa47

File tree

4 files changed

+255
-18
lines changed

4 files changed

+255
-18
lines changed

src/QUICClient.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class QUICClient extends EventTarget {
9191
const {
9292
p: errorP,
9393
rejectP: rejectErrorP
94-
} = utils.promise();
94+
} = utils.promise<never>();
9595
const handleQUICSocketError = (e: events.QUICSocketErrorEvent) => {
9696
rejectErrorP(e.detail);
9797
};
@@ -174,10 +174,24 @@ class QUICClient extends EventTarget {
174174
try {
175175
await Promise.race([connection.establishedP, errorP]);
176176
} catch (e) {
177+
logger.error(e.toString());
178+
// console.error(e);
179+
logger.debug(`Is shared?: ${isSocketShared}`);
180+
// Waiting for connection to destroy
181+
const destroyedProm = utils.promise<void>();
182+
connection.addEventListener('destroy', ()=> {
183+
destroyedProm.resolveP();
184+
},
185+
{
186+
once: true,
187+
},
188+
)
189+
await destroyedProm.p;
177190
if (!isSocketShared) {
178191
// Stop our own socket
179192
await socket.stop();
180193
}
194+
// Wrapping error to contain both stack traces
181195
throw e;
182196
}
183197

src/QUICConnection.ts

+16-8
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class QUICConnection extends EventTarget {
251251
}
252252

253253
/**
254-
* This provides the ability to destroy with a specific error
254+
* This provides the ability to destroy with a specific error. This will wait for the connection to fully drain.
255255
*/
256256
public async destroy(
257257
{
@@ -289,7 +289,7 @@ class QUICConnection extends EventTarget {
289289
}
290290
}
291291
// If it is not closed, it could still be draining
292-
if (!this.conn.isClosed()) {
292+
if (this.conn.isDraining()) {
293293
// The `recv`, `send`, `timeout`, and `on_timeout` should continue to be called
294294
const { p: closeP, resolveP: resolveCloseP } = utils.promise();
295295
this.resolveCloseP = resolveCloseP;
@@ -300,6 +300,11 @@ class QUICConnection extends EventTarget {
300300
}
301301
this.connectionMap.delete(this.connectionId);
302302
this.dispatchEvent(new events.QUICConnectionDestroyEvent());
303+
// Clean up timeout
304+
if (this.timer != null) {
305+
clearTimeout(this.timer);
306+
delete this.timer;
307+
}
303308
this.logger.info(`Destroyed ${this.constructor.name}`);
304309
}
305310

@@ -339,6 +344,9 @@ class QUICConnection extends EventTarget {
339344
this.logger.debug(`Did a recv ${data.byteLength}`);
340345
this.conn.recv(data, recvInfo);
341346
} catch (e) {
347+
this.logger.error(e.toString());
348+
// console.error(e);
349+
// console.log(this.conn.isClosed());
342350
// Depending on the exception, the `this.conn.recv`
343351
// may have automatically started closing the connection
344352
this.dispatchEvent(
@@ -427,13 +435,12 @@ class QUICConnection extends EventTarget {
427435

428436
try {
429437
if (this.conn.isClosed()) {
430-
431-
432438
if (this.resolveCloseP != null) this.resolveCloseP();
433439
return;
434-
} else if (this.conn.isDraining()) {
435-
return;
436440
}
441+
// else if (this.conn.isDraining()) {
442+
// return;
443+
// }
437444
const sendBuffer = new Uint8Array(quiche.MAX_DATAGRAM_SIZE);
438445
let sendLength: number;
439446
let sendInfo: SendInfo;
@@ -481,7 +488,7 @@ class QUICConnection extends EventTarget {
481488
sendInfo.to.host
482489
);
483490
} catch (e) {
484-
console.error(e);
491+
this.logger.error(e.toString())
485492
this.dispatchEvent(new events.QUICConnectionErrorEvent({ detail: e }));
486493
return;
487494
}
@@ -491,11 +498,12 @@ class QUICConnection extends EventTarget {
491498
this.logger.debug('SEND FINALLY');
492499

493500
this.setTimeout();
501+
this.logger.debug(`connection is closed?: ${this.conn.isClosed()}`)
502+
this.logger.debug(`connection is draining?: ${this.conn.isDraining()}`)
494503
if (
495504
this[status] !== 'destroying' &&
496505
(this.conn.isClosed() || this.conn.isDraining())
497506
) {
498-
499507
this.logger.debug('CALLING DESTROY');
500508

501509
await this.destroy();

src/config.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type TlsConfig = {
1515

1616
type QUICConfig = {
1717
tlsConfig: TlsConfig | undefined;
18+
verifyFromPemFile: string | undefined;
1819
supportedPrivateKeyAlgos: string | undefined;
1920
verifyPeer: boolean;
2021
logKeys: string | undefined;
@@ -34,9 +35,10 @@ type QUICConfig = {
3435

3536
const clientDefault: QUICConfig = {
3637
tlsConfig: undefined,
38+
verifyFromPemFile: undefined,
3739
supportedPrivateKeyAlgos: supportedPrivateKeyAlgosDefault,
3840
logKeys: undefined,
39-
verifyPeer: false,
41+
verifyPeer: true,
4042
grease: true,
4143
maxIdleTimeout: 5000,
4244
maxRecvUdpPayloadSize: quiche.MAX_DATAGRAM_SIZE,
@@ -59,6 +61,7 @@ const clientDefault: QUICConfig = {
5961

6062
const serverDefault: QUICConfig = {
6163
tlsConfig: undefined,
64+
verifyFromPemFile: undefined,
6265
supportedPrivateKeyAlgos: supportedPrivateKeyAlgosDefault,
6366
logKeys: undefined,
6467
verifyPeer: false,
@@ -102,6 +105,9 @@ function buildQuicheConfig(config: QUICConfig): QuicheConfig {
102105
quicheConfig.loadPrivKeyFromPemFile(config.tlsConfig.privKeyFromPemFile);
103106
}
104107
}
108+
if (config.verifyFromPemFile != null) {
109+
quicheConfig.loadVerifyLocationsFromFile(config.verifyFromPemFile);
110+
}
105111
if (config.logKeys != null) {
106112
quicheConfig.logKeys();
107113
}

0 commit comments

Comments
 (0)