diff --git a/README.md b/README.md index 5c10c48..48108aa 100644 --- a/README.md +++ b/README.md @@ -356,8 +356,9 @@ under it, the peer never answered in time, or you aborted it after it went out. where a drop ends the session and every send after it is refused. An answer cannot wait for a link that way, because it carries the sequence number the message arrived -on: `sms.sendResp()` on a message whose link dropped writes nothing and returns an `err`. Its -`sms.sendDlr()` still goes out, since a receipt is a request of its own, correlated by the id it names. +on: `sms.sendResp()` on a message whose link dropped writes nothing and returns an `err`. Where a +reconnect follows, its `sms.sendDlr()` still goes out on the new link, since a receipt is a request +of its own, correlated by the id it names. `responseTimeout` bounds the wait for a link and the wait for an answer separately, and a send also queues for a `maxOutstanding` slot, which nothing bounds — so it is not a deadline for the call. @@ -398,7 +399,8 @@ The spec tables are exported both individually (`cmds`, `consts`, `encodings`, ` - **`server()` resolves once, when it is listening**, and gives you a handle with `close()`, `port` and a `session` event. It no longer calls your callback once per incoming connection. - **The id a message is answered with goes to `sendResp({ smsId })`**, and `sms.smsId` is read-only: - it reports the id `sendResp()` was given, or the UUID v7 generated instead. Delete any `sms.smsId = …` line — assigning to it + it reports the id `sendResp()` was given, or the UUID v7 generated instead. Delete any + `sms.smsId = …` line — assigning to it throws a `TypeError`, since modules are always strict mode — and pass the id to `sendResp()`. - **`checkuserpass` is now `authenticate`**, takes `{ password, session, systemId, systemType }` and returns `false` or `{ userData }`. diff --git a/src/incoming-requests.ts b/src/incoming-requests.ts index 621ed9d..547015a 100644 --- a/src/incoming-requests.ts +++ b/src/incoming-requests.ts @@ -68,7 +68,11 @@ export class IncomingRequests { if (this.onRequest && await this.onRequest(this.session, pduObj)) return; // The link it arrived on went while the hook ran, so nothing we answer now correlates. - if (this.linkGeneration !== generation) return; + if (this.linkGeneration !== generation) { + this.log.info('session - dropping a request whose link went', { cmdName: pduObj.cmdName }); + + return; + } if (!this.session.bindAllows(pduObj.cmdName)) { this.log.info('session - command the peer\'s bind direction does not carry', { diff --git a/test/session-extras.test.ts b/test/session-extras.test.ts index 6a7ca54..1608de2 100644 --- a/test/session-extras.test.ts +++ b/test/session-extras.test.ts @@ -603,7 +603,6 @@ describe('reconnect', () => { // A response is dispatched before `incomingPduObj`, so only the raw event sees one arrive. peerOf(smpp).on('incomingPdu', () => { taken++; }); - // The answered one is out of the hold and the held one is not, so neither may reach the answer. assert.match((await answered.sendResp()).err?.message ?? '', /link this message arrived on is gone/); assert.match((await held.sendResp()).err?.message ?? '', /link this message arrived on is gone/); @@ -635,6 +634,10 @@ describe('reconnect', () => { await handled; assert.equal(messages, 0); + + await incoming.handle(submitPdu(2)); + + assert.equal(messages, 1, 'the harness delivers a message whose link stayed'); }); test('does not reconnect after an explicit close', async t => {