Skip to content

Commit

Permalink
Inline stream management into sasl2/bind2
Browse files Browse the repository at this point in the history
  • Loading branch information
singpolyma committed Dec 7, 2023
1 parent 5994385 commit 07a4259
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 9 deletions.
1 change: 1 addition & 0 deletions packages/client/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function client(options = {}) {
streamFeatures,
entity,
middleware,
sasl2,
});
const resourceBinding = _resourceBinding(
{ iqCaller, streamFeatures },
Expand Down
1 change: 1 addition & 0 deletions packages/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function client(options = {}) {
streamFeatures,
entity,
middleware,
sasl2,
});
const resourceBinding = _resourceBinding(
{ iqCaller, streamFeatures },
Expand Down
4 changes: 3 additions & 1 deletion packages/stream-features/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module.exports = function route() {
return next();

const prevent = await next();
if (!prevent && entity.jid) entity._status("online", entity.jid);
if (!prevent && entity.jid && entity.status !== "online") {
entity._status("online", entity.jid);
}
};
};
64 changes: 56 additions & 8 deletions packages/stream-management/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module.exports = function streamManagement({
streamFeatures,
entity,
middleware,
sasl2,
}) {
let address = null;

Expand Down Expand Up @@ -88,24 +89,30 @@ module.exports = function streamManagement({
// https://xmpp.org/extensions/xep-0198.html#enable
// For client-to-server connections, the client MUST NOT attempt to enable stream management until after it has completed Resource Binding unless it is resuming a previous session

const resumeSuccess = () => {
sm.enabled = true;
if (address) entity.jid = address;
entity.status = "online";
};

const resumeFailed = () => {
sm.id = "";
sm.enabled = false;
sm.outbound = 0;
};

streamFeatures.use("sm", NS, async (context, next) => {
// Resuming
if (sm.id) {
try {
await resume(entity, sm.inbound, sm.id);
sm.enabled = true;
entity.jid = address;
entity.status = "online";
resumeSuccess(await resume(entity, sm.inbound, sm.id));
return true;
// If resumption fails, continue with session establishment
// eslint-disable-next-line no-unused-vars
} catch {
sm.id = "";
sm.enabled = false;
sm.outbound = 0;
resumeFailed();
}
}

// Enabling

// Resource binding first
Expand All @@ -129,5 +136,46 @@ module.exports = function streamManagement({
sm.inbound = 0;
});

sasl2?.inline("sm", NS, async (_, addInline) => {
if (sm.id) {
const success = await addInline(
xml("resume", { xmlns: NS, h: sm.inbound, previd: sm.id }),
);
const resumed = success.getChild("resumed", NS);
if (resumed) {
resumeSuccess(resumed);
} else {
resumeFailed();
}
}
});

sasl2?.bindInline(NS, async (addInline) => {
const success = await addInline(
xml("enable", {
xmlns: NS,
max: sm.preferredMaximum,
resume: sm.allowResume ? "true" : undefined,
}),
);
const bound = success.getChild("bound", "urn:xmpp:bind:0");
if (!bound) return; // Did a resume or something, don't need this

const enabled = bound?.getChild("enabled", NS);
if (enabled) {
if (sm.outbound_q.length > 0) {
throw "Stream Management assertion failure, queue should be empty after enable";
}
sm.outbound = 0;
sm.enabled = true;
sm.id = enabled.attrs.id;
sm.max = enabled.attrs.max;
} else {
sm.enabled = false;
}

sm.inbound = 0;
});

return sm;
};

0 comments on commit 07a4259

Please sign in to comment.