Let the session own its bind state, written by bound() alone
Mirror / push (push) Successful in 7s
Test / lint (pull_request) Successful in 26s
Test / test (18) (pull_request) Successful in 32s
Test / test (20) (pull_request) Successful in 40s
Test / test (22) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 37s
Test / test (26) (pull_request) Successful in 38s
Mirror / push (push) Successful in 7s
Test / lint (pull_request) Successful in 26s
Test / test (18) (pull_request) Successful in 32s
Test / test (20) (pull_request) Successful in 40s
Test / test (22) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 37s
Test / test (26) (pull_request) Successful in 38s
This commit is contained in:
+2
-8
@@ -8,7 +8,7 @@ export type { BindType };
|
||||
|
||||
import { ReconnectLoop } from './reconnect-loop.ts';
|
||||
import { Session } from './session.ts';
|
||||
import { checkSessionOptions, undeclaredInterfaceVersion } from './session-options.ts';
|
||||
import { checkSessionOptions } from './session-options.ts';
|
||||
import { connect as netConnect } from 'node:net';
|
||||
import { connect as tlsConnect } from 'node:tls';
|
||||
import { defaultInterfaceVersion } from './defs/constants.ts';
|
||||
@@ -174,13 +174,7 @@ async function bind(session: Session, options: ClientOptions): Promise<VoidResul
|
||||
return { err: new Error(`Remote host refused login: ${sent.pduObj.cmdStatus ?? 'unknown'}`) };
|
||||
}
|
||||
|
||||
const declared = sent.pduObj.tlvs.sc_interface_version?.tagValue;
|
||||
|
||||
session.boundAs = bindType;
|
||||
session.loggedIn = true;
|
||||
session.peerInterfaceVersion = typeof declared === 'number'
|
||||
? declared
|
||||
: undeclaredInterfaceVersion;
|
||||
session.bound(bindType, sent.pduObj.tlvs.sc_interface_version?.tagValue);
|
||||
session.log.info('client - bound', { bindType, systemId });
|
||||
|
||||
return {};
|
||||
|
||||
+17
-17
@@ -1,12 +1,12 @@
|
||||
import type { CloseOptions, OnRequest } from './session-options.ts';
|
||||
import type { BindType, CloseOptions, OnRequest } from './session-options.ts';
|
||||
import type { PduObject, TlvInputs } from './pdu.ts';
|
||||
import type { Result, VoidResult } from './result.ts';
|
||||
import type { Server as NetServer, Socket } from 'node:net';
|
||||
import type { Server as TlsServer, TlsOptions } from 'node:tls';
|
||||
import type { SmppLog } from './log.ts';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import { Session, bindCommands, defaultSystemId } from './session.ts';
|
||||
import { bindTypeFromCommand, checkSessionOptions, undeclaredInterfaceVersion } from './session-options.ts';
|
||||
import { Session, defaultSystemId } from './session.ts';
|
||||
import { bindTypeFromCommand, checkSessionOptions } from './session-options.ts';
|
||||
import { createServer as createNetServer } from 'node:net';
|
||||
import { createServer as createTlsServer } from 'node:tls';
|
||||
import { defaultInterfaceVersion } from './defs/constants.ts';
|
||||
@@ -173,21 +173,21 @@ function bindRespTlvs(session: Session, options: ServerOptions): TlvInputs | und
|
||||
async function acceptBind(
|
||||
session: Session,
|
||||
pduObj: PduObject,
|
||||
bindType: BindType,
|
||||
options: ServerOptions,
|
||||
identity: Record<string, string>,
|
||||
): Promise<void> {
|
||||
const declared = pduObj.params.interface_version;
|
||||
|
||||
session.boundAs = bindTypeFromCommand(pduObj.cmdName);
|
||||
session.loggedIn = true;
|
||||
session.peerInterfaceVersion = typeof declared === 'number'
|
||||
? declared
|
||||
: undeclaredInterfaceVersion;
|
||||
session.bound(bindType, pduObj.params.interface_version);
|
||||
|
||||
await session.sendReturn(pduObj, 'ESME_ROK', identity, bindRespTlvs(session, options));
|
||||
}
|
||||
|
||||
async function onBind(session: Session, pduObj: PduObject, options: ServerOptions): Promise<void> {
|
||||
async function onBind(
|
||||
session: Session,
|
||||
pduObj: PduObject,
|
||||
bindType: BindType,
|
||||
options: ServerOptions,
|
||||
): Promise<void> {
|
||||
const identity = { system_id: options.systemId ?? defaults.systemId };
|
||||
const systemId = paramText(pduObj.params.system_id);
|
||||
|
||||
@@ -198,7 +198,7 @@ async function onBind(session: Session, pduObj: PduObject, options: ServerOption
|
||||
return;
|
||||
}
|
||||
|
||||
await acceptBind(session, pduObj, options, identity);
|
||||
await acceptBind(session, pduObj, bindType, options, identity);
|
||||
session.log.verbose('server - bound', { systemId });
|
||||
}
|
||||
|
||||
@@ -211,16 +211,16 @@ async function handleRequest(
|
||||
pduObj: PduObject,
|
||||
options: ServerOptions,
|
||||
): Promise<boolean> {
|
||||
const isBind = bindCommands.includes(pduObj.cmdName);
|
||||
const bindType = bindTypeFromCommand(pduObj.cmdName);
|
||||
|
||||
if (session.loggedIn) {
|
||||
if (isBind || !options.onRequest) return false;
|
||||
if (session.boundAs !== undefined) {
|
||||
if (bindType || !options.onRequest) return false;
|
||||
|
||||
return options.onRequest(session, pduObj);
|
||||
}
|
||||
|
||||
if (isBind) {
|
||||
await onBind(session, pduObj, options);
|
||||
if (bindType) {
|
||||
await onBind(session, pduObj, bindType, options);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+22
-10
@@ -19,7 +19,7 @@ import { ReconnectLoop } from './reconnect-loop.ts';
|
||||
import { leftOf } from './idle-waiters.ts';
|
||||
import { errorFrom } from './error-from.ts';
|
||||
import { optionalParamsMinVersion } from './defs/constants.ts';
|
||||
import { bindCarries, bindCommands, defaultSystemId, defaults } from './session-options.ts';
|
||||
import { bindCarries, bindCommands, defaultSystemId, defaults, undeclaredInterfaceVersion } from './session-options.ts';
|
||||
import { isResp, objToPdu, pduReturn } from './pdu.ts';
|
||||
import { refusalAnswer } from './pdu-refusal.ts';
|
||||
import { guardedLog } from './log.ts';
|
||||
@@ -54,15 +54,12 @@ export class Session extends EventEmitter<SessionEvents> {
|
||||
|
||||
readonly log: SmppLog;
|
||||
|
||||
/** The role the ESME bound with, whichever end of the link this is. Undefined before any bind. */
|
||||
boundAs: BindType | undefined = undefined;
|
||||
/** Which end of the link this is. `server()` sets it; a hand-wired SMSC must set it too. */
|
||||
linkEnd: LinkEnd = 'esme';
|
||||
loggedIn = false;
|
||||
/** What the peer declared when binding: 0x00 if it declared none, undefined before any bind. */
|
||||
peerInterfaceVersion: number | undefined = undefined;
|
||||
userData: unknown = undefined;
|
||||
|
||||
private bind: { as: BindType; peerVersion: number } | undefined = undefined;
|
||||
|
||||
private readonly concatReference = new ConcatReference();
|
||||
private readonly dlrMerger: DlrMerger;
|
||||
private readonly incoming: IncomingRequests;
|
||||
@@ -154,6 +151,23 @@ export class Session extends EventEmitter<SessionEvents> {
|
||||
return this.transport.sock;
|
||||
}
|
||||
|
||||
/** The role the ESME bound with, whichever end of the link this is. Undefined before any bind. */
|
||||
get boundAs(): BindType | undefined {
|
||||
return this.bind?.as;
|
||||
}
|
||||
|
||||
/** What the peer declared when binding: 0x00 if it declared none, undefined before any bind. */
|
||||
get peerInterfaceVersion(): number | undefined {
|
||||
return this.bind?.peerVersion;
|
||||
}
|
||||
|
||||
/** Records a bind this link accepted or had accepted, until the next one. A version that is not a number is none. */
|
||||
bound(bindType: BindType, declaredVersion: unknown): void {
|
||||
const peerVersion = typeof declaredVersion === 'number' ? declaredVersion : undeclaredInterfaceVersion;
|
||||
|
||||
this.bind = { as: bindType, peerVersion };
|
||||
}
|
||||
|
||||
/** Whether this session's bind direction carries a command. Consulted by the library's senders. */
|
||||
bindAllows(cmdName: string): boolean {
|
||||
return bindCarries(this.boundAs, cmdName, this.linkEnd);
|
||||
@@ -171,15 +185,13 @@ export class Session extends EventEmitter<SessionEvents> {
|
||||
}
|
||||
|
||||
/** Answers a request the peer sent us. Responses are never waited on. */
|
||||
async sendReturn(
|
||||
sendReturn(
|
||||
pdu: PduObject,
|
||||
status: ErrorName = 'ESME_ROK',
|
||||
params: Record<string, ParamValue> = {},
|
||||
tlvs?: TlvInputs,
|
||||
): Promise<VoidResult> {
|
||||
return Promise.resolve(
|
||||
this.answer(pduReturn(pdu, status, params, tlvs), pdu.cmdName, pdu.seqNr),
|
||||
);
|
||||
return Promise.resolve(this.answer(pduReturn(pdu, status, params, tlvs), pdu.cmdName, pdu.seqNr));
|
||||
}
|
||||
|
||||
private answer(built: Result<{ buffer: Buffer }>, cmdName: string, seqNr: number): VoidResult {
|
||||
|
||||
Reference in New Issue
Block a user