WIP: Leave alert_notification and outbind unanswered #19
@@ -32,6 +32,8 @@
|
|||||||
a caller that reads only `smsIds` meets a failure it has not met before. A whole number in an
|
a caller that reads only `smsIds` meets a failure it has not met before. A whole number in an
|
||||||
address or an id still spells its digits, so `message_id: 123` is unchanged. The integer fields
|
address or an id still spells its digits, so `message_id: 123` is unchanged. The integer fields
|
||||||
name a refused `NaN` too, where the refusal used to read `null`.
|
name a refused `NaN` too, where the refusal used to read `null`.
|
||||||
|
- An inbound `alert_notification` or `outbind` is logged and left unanswered, as SMPP 3.4 gives
|
||||||
|
neither a response. Each used to raise a `sessionError`.
|
||||||
|
|
||||||
## 0.5.0
|
## 0.5.0
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { createSms } from './sms.ts';
|
|||||||
import { dlrFromPdu } from './dlr.ts';
|
import { dlrFromPdu } from './dlr.ts';
|
||||||
import { paramText } from './defs/types.ts';
|
import { paramText } from './defs/types.ts';
|
||||||
import { respIdParams, segmentId } from './sms-id.ts';
|
import { respIdParams, segmentId } from './sms-id.ts';
|
||||||
|
import { respNameFor } from './defs/commands.ts';
|
||||||
|
|
||||||
/** SMPP 3.4 lists ESME_RMSGQFUL under submit_sm_resp only; 4.6.2's retryable code is another. */
|
/** SMPP 3.4 lists ESME_RMSGQFUL under submit_sm_resp only; 4.6.2's retryable code is another. */
|
||||||
export function refusedSegmentStatus(
|
export function refusedSegmentStatus(
|
||||||
@@ -171,6 +172,12 @@ export class IncomingRequests {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!respNameFor(pduObj.cmdName)) {
|
||||||
|
this.log.info('session - ignoring a command that takes no response', { cmdName: pduObj.cmdName });
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.log.info('session - no handler for command', { cmdName: pduObj.cmdName });
|
this.log.info('session - no handler for command', { cmdName: pduObj.cmdName });
|
||||||
await this.session.sendReturn(pduObj, 'ESME_RINVCMDID');
|
await this.session.sendReturn(pduObj, 'ESME_RINVCMDID');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1792,6 +1792,26 @@ describe('a PDU the codec cannot read', () => {
|
|||||||
assert.ok((await raceWithin(2000, failed)) instanceof Error, 'one sessionError per refused PDU');
|
assert.ok((await raceWithin(2000, failed)) instanceof Error, 'one sessionError per refused PDU');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('answers neither alert_notification nor outbind, which have no response', async t => {
|
||||||
|
const { peer, session } = await bound(t);
|
||||||
|
let failures = 0;
|
||||||
|
|
||||||
|
session.on('sessionError', () => { failures++; });
|
||||||
|
peer.writeRaw(pduBytes({
|
||||||
|
cmdName: 'alert_notification',
|
||||||
|
params: { esme_addr: '46701234567', source_addr: '46709876543' },
|
||||||
|
seqNr: 3,
|
||||||
|
}));
|
||||||
|
peer.writeRaw(pduBytes({ cmdName: 'outbind', params: { password: 'pw', system_id: 'smsc' }, seqNr: 4 }));
|
||||||
|
peer.writeRaw(pduBytes({ cmdName: 'enquire_link', seqNr: 5 }));
|
||||||
|
|
||||||
|
const answered = await answerTo(peer);
|
||||||
|
|
||||||
|
assert.equal(answered.cmdName, 'enquire_link_resp');
|
||||||
|
assert.equal(answered.seqNr, 5);
|
||||||
|
assert.equal(failures, 0);
|
||||||
|
});
|
||||||
|
|
||||||
test('answers a deliver_sm with a truncated TLV stream with ESME_RINVTLVSTREAM', async t => {
|
test('answers a deliver_sm with a truncated TLV stream with ESME_RINVTLVSTREAM', async t => {
|
||||||
const { peer, session } = await bound(t);
|
const { peer, session } = await bound(t);
|
||||||
let reports = 0;
|
let reports = 0;
|
||||||
|
|||||||
@@ -200,12 +200,6 @@ and is also what the panel ranked hardest — two methods, one answer.
|
|||||||
caller never wrote." A goal is the maintainer's, so nothing edits README until that is
|
caller never wrote." A goal is the maintainer's, so nothing edits README until that is
|
||||||
answered. From the prose pass of #18.
|
answered. From the prose pass of #18.
|
||||||
|
|
||||||
- [ ] **Answer `alert_notification` and `outbind` by not answering them.** Both are response-less in
|
|
||||||
SMPP 3.4, both fall through `route()`'s default into `unhandled()`, which calls
|
|
||||||
`sendReturn(pduObj, 'ESME_RINVCMDID')`; `pduReturn()` then finds no response command, and the
|
|
||||||
failure reaches the application as `sessionError` on every occurrence. `alert_notification`
|
|
||||||
appears nowhere in `src/` but `defs/commands.ts`. One case arm each: log and return.
|
|
||||||
|
|
||||||
- [ ] **Range-check `maxOctets` with its five siblings.** `limitsOf()` in `session-options.ts`
|
- [ ] **Range-check `maxOctets` with its five siblings.** `limitsOf()` in `session-options.ts`
|
||||||
covers `idleTimeout`, `maxOutstanding`, `maxReassembly`, `reassemblyTimeout`, `responseTimeout`
|
covers `idleTimeout`, `maxOutstanding`, `maxReassembly`, `reassemblyTimeout`, `responseTimeout`
|
||||||
and `shutdownTimeout`; `maxOctets` is documented, consumed by `Reassembler`, and absent from
|
and `shutdownTimeout`; `maxOctets` is documented, consumed by `Reassembler`, and absent from
|
||||||
|
|||||||
Reference in New Issue
Block a user