11import type { X509Certificate } from '@peculiar/x509' ;
22import type { Host , ServerCryptoOps } from '@/types' ;
3- import type QUICConnection from '@/QUICConnection' ;
43import type { ClientCryptoOps } from '@/types' ;
54import Logger , { LogLevel , StreamHandler , formatting } from '@matrixai/logger' ;
65import QUICServer from '@/QUICServer' ;
6+ import QUICClient from '@/QUICClient' ;
77import * as utils from '@/utils' ;
8- import { promise } from '@/utils' ;
98import * as events from '@/events' ;
10- import QUICClient from '@/QUICClient' ;
119import * as errors from '@/errors' ;
1210import * as testsUtils from './utils' ;
1311
@@ -307,146 +305,8 @@ describe(QUICServer.name, () => {
307305 await quicServer . stop ( ) ;
308306 } ) ;
309307 } ) ;
310- // TODO: what is this? re-enable?
311- // Describe.only('connection bootstrap', () => {
312- // // Test without peer verification
313- // test.only('', async () => {
314- // const quicServer = new QUICServer({
315- // crypto: {
316- // key,
317- // ops: serverCryptoOps,
318- // },
319- // config: {
320- // key: keyPairECDSAPEM.privateKey,
321- // cert: certECDSAPEM,
322- // verifyPeer: false,
323- // },
324- // logger: logger.getChild('QUICServer'),
325- // });
326- // await quicServer.start({
327- // host: '127.0.0.1',
328- // });
329- //
330- // const scidBuffer = new ArrayBuffer(quiche.MAX_CONN_ID_LEN);
331- // await clientCrypto.randomBytes(scidBuffer);
332- // const scid = new QUICConnectionId(scidBuffer);
333- //
334- // // Verify peer
335- // // Note that you cannot send to IPv4 from dual stack socket
336- // // It must be sent as IPv4 mapped IPv6
337- //
338- // const socket = new QUICSocket({
339- // logger: logger.getChild(QUICSocket.name),
340- // });
341- // await socket.start({
342- // host: '127.0.0.1',
343- // });
344- //
345- // // ???
346- // const clientConfig: QUICConfig = {
347- // ...clientDefault,
348- // verifyPeer: false,
349- // };
350- //
351- // // This creates a connection state
352- // // We now need to trigger it
353- // const connection = await QUICConnection.createQUICConnection({
354- // type: 'client',
355- // scid,
356- // socket,
357- // remoteInfo: {
358- // host: quicServer.host,
359- // port: quicServer.port,
360- // },
361- // config: clientConfig,
362- // logger: logger.getChild(QUICConnection.name),
363- // });
364- //
365- // connection.addEventListener('error', (e) => {
366- // console.log('error', e);
367- // });
368- //
369- // // Trigger the connection
370- // await connection.send();
371- //
372- // // Wait till it is established
373- // console.log('BEFORE ESTABLISHED P');
374- // await connection.establishedP;
375- // console.log('AFTER ESTABLISHED P');
376- //
377- // // You must destroy the connection
378- // console.log('DESTROY CONNECTION');
379- // await connection.stop();
380- // console.log('DESTROYED CONNECTION');
381- //
382- // console.log('STOP SOCKET');
383- // await socket.stop();
384- // console.time('STOPPED SOCKET');
385- // await quicServer.stop();
386- // console.timeEnd('STOPPED SOCKET');
387- // });
388- // });
389- // Test('bootstrapping a new connection', async () => {
390- // const quicServer = new QUICServer({
391- // crypto,
392- // config: {
393- // key: keyPairEd25519PEM.privateKey,
394- // cert: certEd25519PEM,
395- // },
396- // logger: logger.getChild('QUICServer'),
397- // });
398- // await quicServer.start();
399- //
400- // const scidBuffer = new ArrayBuffer(quiche.MAX_CONN_ID_LEN);
401- // await crypto.ops.randomBytes(scidBuffer);
402- // const scid = new QUICConnectionId(scidBuffer);
403- //
404- // const socket = new QUICSocket({
405- // crypto,
406- // resolveHostname: utils.resolveHostname,
407- // logger: logger.getChild(QUICSocket.name),
408- // });
409- // await socket.start();
410- //
411- // // Const config = buildQuicheConfig({
412- // // ...clientDefault
413- // // });
414- // // Here we want to VERIFY the peer
415- // // If we use the same certificate
416- // // then it should be consider as if it is trusted!
417- //
418- // const quicConfig: QUICConfig = {
419- // ...clientDefault,
420- // verifyPeer: true,
421- // };
422- //
423- // const connection = await QUICConnection.connectQUICConnection({
424- // scid,
425- // socket,
426- //
427- // remoteInfo: {
428- // host: utils.resolvesZeroIP(quicServer.host),
429- // port: quicServer.port,
430- // },
431- //
432- // config: quicConfig,
433- // });
434- //
435- // await socket.stop();
436- // await quicServer.stop();
437- //
438- // // We can run with several rsa keypairs and certificates
439- // });
440- // describe('updating configuration', () => {
441- // // We want to test changing the configuration over time
442- // });
443- // Test hole punching, there's an initiation function
444- // We can make it start doing this, but technically it's the socket's duty to do this
445- // not just the server side
446- test ( 'socket stopping first triggers client destruction' , async ( ) => {
308+ test ( 'stopping server socket should result in server error and client timeout' , async ( ) => {
447309 const tlsConfigServer = await testsUtils . generateTLSConfig ( 'RSA' ) ;
448-
449- const connectionEventProm = promise < QUICConnection > ( ) ;
450310 const server = new QUICServer ( {
451311 crypto : {
452312 key,
@@ -461,98 +321,51 @@ describe(QUICServer.name, () => {
461321 } ,
462322 } ) ;
463323 socketCleanMethods . extractSocket ( server ) ;
324+ const { p : quicServerErrorP , rejectP : rejectQuicServerErrorP } =
325+ utils . promise < Error > ( ) ;
464326 server . addEventListener (
465- events . EventQUICServerConnection . name ,
466- ( e : events . EventQUICServerConnection ) =>
467- connectionEventProm . resolveP ( e . detail ) ,
327+ events . EventQUICServerError . name ,
328+ ( e : events . EventQUICServerError ) => {
329+ rejectQuicServerErrorP ( e . detail ) ;
330+ } ,
468331 ) ;
469332 await server . start ( {
470333 host : '127.0.0.1' ,
471334 } ) ;
472335 const clientCryptoOps : ClientCryptoOps = {
473336 randomBytes : testsUtils . randomBytes ,
474337 } ;
475- // If the server is slow to respond then this will time out.
476- // Then main cause of this was the server not processing the initial packet
477- // that creates the `QUICConnection`, as a result, the whole creation waited
478- // an extra 1 second for the client to retry the initial packet.
479338 const client = await QUICClient . createQUICClient ( {
480339 host : '127.0.0.1' ,
481340 port : server . port ,
482341 localHost : '127.0.0.1' ,
483342 crypto : {
484343 ops : clientCryptoOps ,
485344 } ,
486- logger : logger . getChild ( QUICClient . name ) ,
487345 config : {
488346 verifyPeer : false ,
347+ maxIdleTimeout : 200 ,
489348 } ,
349+ logger : logger . getChild ( QUICClient . name ) ,
490350 } ) ;
491- socketCleanMethods . extractSocket ( client ) ;
492-
493- // Handling client connection error event
494- const clientConnectionErrorProm = promise < never > ( ) ;
495- client . connection . addEventListener (
496- events . EventQUICConnectionError . name ,
497- ( evt : events . EventQUICConnectionError ) =>
498- clientConnectionErrorProm . rejectP ( evt . detail ) ,
499- { once : true } ,
500- ) ;
501-
502- const serverConnection = await connectionEventProm . p ;
503- // Handling server connection error event
504- const serverConnectionErrorProm = promise < never > ( ) ;
505- serverConnection . addEventListener (
506- events . EventQUICConnectionError . name ,
507- ( evt : events . EventQUICConnectionError ) =>
508- serverConnectionErrorProm . rejectP ( evt . detail ) ,
509- { once : true } ,
510- ) ;
511-
512- // Handling server connection stop event
513- const serverConnectionStoppedProm = promise < void > ( ) ;
514- client . connection . addEventListener (
515- events . EventQUICConnectionStopped . name ,
516- ( ) => serverConnectionStoppedProm . resolveP ( ) ,
517- { once : true } ,
518- ) ;
519-
520- // Handling server error event
521- const serverErrorProm = promise < never > ( ) ;
522- server . addEventListener (
523- events . EventQUICServerError . name ,
524- ( evt : events . EventQUICServerError ) => serverErrorProm . rejectP ( evt . detail ) ,
525- { once : true } ,
526- ) ;
527-
528- // Handling client destroy event
529- const serverStoppedProm = promise < void > ( ) ;
530- server . addEventListener (
531- events . EventQUICServerStopped . name ,
532- ( ) => serverStoppedProm . resolveP ( ) ,
533- { once : true } ,
534- ) ;
535-
536- // @ts -ignore: kidnap protected property
537- const serverSocket = server . socket ;
538- await serverSocket . stop ( { force : true } ) ;
539-
540- // Socket failure triggers server connection local failure
541- await expect ( serverConnectionErrorProm . p ) . rejects . toThrow (
542- errors . ErrorQUICConnectionLocal ,
351+ const { p : quicClientErrorP , rejectP : rejectQuicClientErrorP } =
352+ utils . promise < Error > ( ) ;
353+ client . addEventListener (
354+ events . EventQUICClientError . name ,
355+ ( e : events . EventQUICClientError ) => {
356+ rejectQuicClientErrorP ( e . detail ) ;
357+ } ,
543358 ) ;
544- await expect ( serverErrorProm . p ) . rejects . toThrow (
359+ socketCleanMethods . extractSocket ( client ) ;
360+ // Force stop the server socket
361+ // @ts -ignore: protected property
362+ await server . socket . stop ( { force : true } ) ;
363+ // Results in an error event on the server
364+ await expect ( quicServerErrorP ) . rejects . toThrowError (
545365 errors . ErrorQUICServerSocketNotRunning ,
546366 ) ;
547- await serverStoppedProm . p ;
548- await serverConnectionStoppedProm . p ;
549-
550- // Socket failure will not trigger any close frame since transport has failed so client connection will time out
551- await expect ( clientConnectionErrorProm . p ) . rejects . toThrow (
367+ await expect ( quicClientErrorP ) . rejects . toThrowError (
552368 errors . ErrorQUICConnectionIdleTimeout ,
553369 ) ;
554-
555- await client . destroy ( { force : true } ) ;
556- await server . stop ( { force : true } ) ;
557370 } ) ;
558371} ) ;
0 commit comments