Log the dropped request, and scope the receipt sentence to a reconnect

This commit is contained in:
2026-09-01 20:53:58 +02:00
parent e6250ef44e
commit 471923a7b6
3 changed files with 14 additions and 5 deletions
+5 -3
View File
@@ -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. 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 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 on: `sms.sendResp()` on a message whose link dropped writes nothing and returns an `err`. Where a
`sms.sendDlr()` still goes out, since a receipt is a request of its own, correlated by the id it names. 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 `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. 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` - **`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. 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: - **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()`. 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 - **`checkuserpass` is now `authenticate`**, takes `{ password, session, systemId, systemType }` and
returns `false` or `{ userData }`. returns `false` or `{ userData }`.
+5 -1
View File
@@ -68,7 +68,11 @@ export class IncomingRequests {
if (this.onRequest && await this.onRequest(this.session, pduObj)) return; 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. // 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)) { if (!this.session.bindAllows(pduObj.cmdName)) {
this.log.info('session - command the peer\'s bind direction does not carry', { this.log.info('session - command the peer\'s bind direction does not carry', {
+4 -1
View File
@@ -603,7 +603,6 @@ describe('reconnect', () => {
// A response is dispatched before `incomingPduObj`, so only the raw event sees one arrive. // A response is dispatched before `incomingPduObj`, so only the raw event sees one arrive.
peerOf(smpp).on('incomingPdu', () => { taken++; }); 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 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/); assert.match((await held.sendResp()).err?.message ?? '', /link this message arrived on is gone/);
@@ -635,6 +634,10 @@ describe('reconnect', () => {
await handled; await handled;
assert.equal(messages, 0); 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 => { test('does not reconnect after an explicit close', async t => {