Merge remote-tracking branch 'origin/typescript' into receipt-field-separators
This commit is contained in:
@@ -39,6 +39,7 @@ export class IncomingRequests {
|
||||
private readonly session: Session;
|
||||
private readonly smsIdFormat: SmsIdFormat;
|
||||
private readonly systemId: string;
|
||||
private linkGeneration = 0;
|
||||
|
||||
constructor(options: IncomingRequestsOptions) {
|
||||
this.dlrMerger = options.dlrMerger;
|
||||
@@ -62,8 +63,17 @@ export class IncomingRequests {
|
||||
}
|
||||
|
||||
async handle(pduObj: PduObject): Promise<void> {
|
||||
const generation = this.linkGeneration;
|
||||
|
||||
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) {
|
||||
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', {
|
||||
bindType: this.session.boundAs ?? '',
|
||||
@@ -96,6 +106,7 @@ export class IncomingRequests {
|
||||
|
||||
/** Drops the segments of every message that never became whole, and of every one still held. */
|
||||
clear(): void {
|
||||
this.linkGeneration++;
|
||||
this.held.clear();
|
||||
this.reassembler.clear();
|
||||
}
|
||||
@@ -163,6 +174,8 @@ export class IncomingRequests {
|
||||
|
||||
if (!first) return;
|
||||
|
||||
const generation = this.linkGeneration;
|
||||
|
||||
const sms = createSms({
|
||||
from: paramText(first.params.source_addr),
|
||||
message: decodeSegments(pduObjs),
|
||||
@@ -170,6 +183,7 @@ export class IncomingRequests {
|
||||
session: this.session,
|
||||
to: paramText(first.params.destination_addr),
|
||||
}, {
|
||||
lostLink: () => this.linkGeneration !== generation,
|
||||
// A turn later, so a listener sending its receipt straight after the response still holds.
|
||||
onAnswered: () => { setImmediate(() => { this.held.release(pduObjs); }); },
|
||||
// Past the refusal only while a drain is still waiting for this message; an ordinary send after.
|
||||
|
||||
+10
-2
@@ -38,7 +38,7 @@ export type Sms = {
|
||||
/** Answers every segment. Part of the protocol, not optional. Defaults to ESME_ROK. */
|
||||
sendResp: (options?: SendRespOptions) => Promise<VoidResult>;
|
||||
session: Session;
|
||||
/** The id answered to the peer: what sendResp() was given, or a generated UUID v7. */
|
||||
/** The id `sendResp()` was given, or a generated UUID v7. */
|
||||
readonly smsId: string;
|
||||
submitTime: Date;
|
||||
to: string;
|
||||
@@ -54,6 +54,7 @@ export type SmsInput = {
|
||||
|
||||
/** What the session's incoming side gives a message so it can be answered and accounted for. */
|
||||
export type SmsHandlers = {
|
||||
lostLink: () => boolean;
|
||||
onAnswered: () => void;
|
||||
send: (input: PduObjectInput) => Promise<Result<{ pduObj: PduObject }>>;
|
||||
};
|
||||
@@ -76,7 +77,8 @@ export function createSms(input: SmsInput, handlers: SmsHandlers): Sms {
|
||||
message: input.message,
|
||||
pduObjs: input.pduObjs,
|
||||
sendDlr: status => sendDlr(sms, handlers.send, status),
|
||||
sendResp: options => sendResp(sms, answered, options ?? {}).finally(handlers.onAnswered),
|
||||
sendResp: options => sendResp(sms, answered, options ?? {}, handlers.lostLink)
|
||||
.finally(handlers.onAnswered),
|
||||
session: input.session,
|
||||
get smsId(): string {
|
||||
return answered.smsId;
|
||||
@@ -92,6 +94,7 @@ async function sendResp(
|
||||
sms: Sms,
|
||||
answered: { smsId: string },
|
||||
options: SendRespOptions,
|
||||
lostLink: () => boolean,
|
||||
): Promise<VoidResult> {
|
||||
const total = sms.pduObjs.length;
|
||||
|
||||
@@ -105,6 +108,11 @@ async function sendResp(
|
||||
|
||||
if (options.smsId !== undefined) answered.smsId = options.smsId;
|
||||
|
||||
// A response carries the sequence number it was asked on, which the next link knows nothing about.
|
||||
if (lostLink()) {
|
||||
return { err: new Error('The link this message arrived on is gone, so nothing would correlate the response') };
|
||||
}
|
||||
|
||||
const results = await Promise.all(sms.pduObjs.map((pduObj, index) => sms.session.sendReturn(
|
||||
pduObj,
|
||||
options.status ?? 'ESME_ROK',
|
||||
|
||||
Reference in New Issue
Block a user