68 lines
2.4 KiB
TypeScript
68 lines
2.4 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test, { after, describe } from 'node:test';
|
|
import type { Session } from '../src/session.ts';
|
|
import { server } from '../src/server.ts';
|
|
|
|
const SMPP_PORT = Number(process.env.SMPP_PORT ?? '2775');
|
|
|
|
function delay(ms: number): Promise<void> {
|
|
return new Promise(resolve => { setTimeout(resolve, ms); });
|
|
}
|
|
|
|
async function waitFor<T>(get: () => T | undefined, budget = 8000): Promise<T | undefined> {
|
|
const deadline = Date.now() + budget;
|
|
let value = get();
|
|
|
|
while (value === undefined && Date.now() < deadline) {
|
|
await delay(20);
|
|
value = get();
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
const { err, server: smpp } = await server({ authenticate: () => true, idleTimeout: 40_000, port: SMPP_PORT });
|
|
|
|
assert.equal(err, undefined);
|
|
assert.ok(smpp);
|
|
|
|
after(async () => {
|
|
await smpp.close();
|
|
});
|
|
|
|
// smppload 2.5.3 (built at interop-tests/peers/smppload, its issue #8 rebar3/BEAM friction worked
|
|
// around with a current rebar3 release) is otherwise blocked: every bind_transceiver it puts on the
|
|
// wire is two octets short of what its own command_length declares, corrupting command_length and
|
|
// command_id both - findings/07-load.md carries the tshark capture. S6 and S8, both scoped to this
|
|
// peer in PLAN.md, could not run; dumbclient.test.ts carries the load and window scenarios instead.
|
|
describe('smppload (blocked)', () => {
|
|
test('the corrupted bind_transceiver is refused as an unframeable stream, not left to hang', async () => {
|
|
let session: Session | undefined;
|
|
let sessionErr: Error | undefined;
|
|
let closed = false;
|
|
|
|
smpp.on('session', incoming => {
|
|
session = incoming;
|
|
incoming.on('sessionError', sessionError => { sessionErr = sessionError; });
|
|
incoming.on('close', () => { closed = true; });
|
|
});
|
|
|
|
const bound = await waitFor(() => session, 20_000);
|
|
|
|
assert.ok(bound, 'smppload never opened a TCP connection to node:2775');
|
|
|
|
const refusal = await waitFor(() => sessionErr, 10_000);
|
|
|
|
assert.ok(refusal);
|
|
// maxPduLength (pdu-refusal.ts) is 1MiB; the corrupted command_length (0x2a shifted into the
|
|
// high bytes) reads as roughly 2.75M, so this is the "unreadable stream" teardown, not the
|
|
// "one bad PDU, link stays up" path - see AGENTS.md, "A stream this library cannot frame...".
|
|
assert.match(refusal.message, /Refusing a cmd_length of \d+/);
|
|
|
|
await waitFor(() => (closed ? true : undefined), 5000);
|
|
assert.equal(closed, true);
|
|
assert.ok(bound);
|
|
assert.equal(bound.loggedIn, false);
|
|
});
|
|
});
|