Completed support for web relay with multiple DNS names.

Ylian Saint-Hilaire committed Jul 10, 2022 at 11:32 UTC 5eca4eecee1580817ff9ff73a463cda4381ae560
1 file changed +75 -30
webserver.js
+75 -30
@@ -6612,42 +6612,87 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6612 const port = parseInt(req.query.p);
6613 const appid = parseInt(req.query.appid);
6614
6615 - // Check to see if we already have a multi-relay session that matches exactly this device and port for this user
6616 - // TODO: Check that we have an exact session on any of the relay DNS names
6617 - const xrelaySessionId = req.session.userid + '/' + req.session.x + '/' + req.hostname;
6618 - const xrelaySession = webRelaySessions[xrelaySessionId];
6619 - if ((xrelaySession != null) && (xrelaySession.domain.id == domain.id) && (xrelaySession.userid == userid) && (xrelaySession.nodeid == nodeid) && (xrelaySession.addr == addr) && (xrelaySession.port == port) && (xrelaySession.appid == appid)) {
6620 - // We found an exact match, we are all setup already, redirect to root
6621 - res.redirect('/');
6622 - return;
6623 - }
6615 + try {
6616
6625 - // TODO: Check if there is a free relay DNS name we can use
6617 + // Check that we have an exact session on any of the relay DNS names
6618 + var xrelaySessionId, xrelaySession, freeRelayHost, oldestRelayTime, oldestRelayHost;
6619 + for (var hostIndex in obj.args.relaydns) {
6620 + const host = obj.args.relaydns[hostIndex];
6621 + xrelaySessionId = req.session.userid + '/' + req.session.x + '/' + host;
6622 + xrelaySession = webRelaySessions[xrelaySessionId];
6623 + if (xrelaySession == null) {
6624 + // We found an unused hostname, save this as it could be useful.
6625 + if (freeRelayHost == null) { freeRelayHost = host; }
6626 + } else {
6627 + // Check if we already have a relay session that matches exactly what we want
6628 + if ((xrelaySession.domain.id == domain.id) && (xrelaySession.userid == userid) && (xrelaySession.nodeid == nodeid) && (xrelaySession.addr == addr) && (xrelaySession.port == port) && (xrelaySession.appid == appid)) {
6629 + // We found an exact match, we are all setup already, redirect to root of that DNS name
6630 + if (host == req.hostname) {
6631 + // Request was made on the same host, redirect to root.
6632 + res.redirect('/');
6633 + } else {
6634 + // Request was made to a different host
6635 + const httpport = ((args.aliasport != null) ? args.aliasport : args.port);
6636 + res.redirect('https://' + host + ((httpport != 443) ? (':' + httpport) : '') + '/');
6637 + }
6638 + return;
6639 + }
6640
6627 - // There is a relay session, but it's not correct, close it.
6628 - // TODO: Do this on the session that got the olders request
6629 - if (xrelaySession != null) {
6630 - xrelaySession.close();
6631 - delete webRelaySessions[xrelaySessionId];
6632 - }
6641 + // Keep a record of the oldest web relay session, this could be useful.
6642 + if (oldestRelayHost == null) {
6643 + // Oldest host not set yet, set it
6644 + oldestRelayHost = host;
6645 + oldestRelayTime = xrelaySession.lastOperation;
6646 + } else {
6647 + // Check if this host is older then oldest so far
6648 + if (oldestRelayTime > xrelaySession.lastOperation) {
6649 + oldestRelayHost = host;
6650 + oldestRelayTime = xrelaySession.lastOperation;
6651 + }
6652 + }
6653 + }
6654 + }
6655
6634 - // Create a web relay session
6635 - const relaySession = require('./apprelays.js').CreateWebRelaySession(obj, db, req, args, domain, userid, nodeid, addr, port, appid, xrelaySessionId);
6636 - relaySession.onclose = function (sessionId) {
6637 - // Remove the relay session
6638 - delete webRelaySessions[sessionId];
6639 - // If there are not more relay sessions, clear the cleanup timer
6640 - if ((Object.keys(webRelaySessions).length == 0) && (obj.cleanupTimer != null)) { clearInterval(webRelayCleanupTimer); obj.cleanupTimer = null; }
6641 - }
6656 + // Check if there is a free relay DNS name we can use
6657 + var selectedHost = null;
6658 + if (freeRelayHost != null) {
6659 + // There is a free one, use it.
6660 + selectedHost = freeRelayHost;
6661 + xrelaySessionId = req.session.userid + '/' + req.session.x + '/' + selectedHost;
6662 + } else {
6663 + // No free ones, close the oldest one
6664 + selectedHost = oldestRelayHost;
6665 + xrelaySessionId = req.session.userid + '/' + req.session.x + '/' + selectedHost;
6666 + xrelaySession = webRelaySessions[xrelaySessionId];
6667 + xrelaySession.close();
6668 + delete webRelaySessions[xrelaySessionId];
6669 + }
6670
6643 - // Set the multi-tunnel session
6644 - webRelaySessions[xrelaySessionId] = relaySession;
6671 + // Create a web relay session
6672 + const relaySession = require('./apprelays.js').CreateWebRelaySession(obj, db, req, args, domain, userid, nodeid, addr, port, appid, xrelaySessionId);
6673 + relaySession.onclose = function (sessionId) {
6674 + // Remove the relay session
6675 + delete webRelaySessions[sessionId];
6676 + // If there are not more relay sessions, clear the cleanup timer
6677 + if ((Object.keys(webRelaySessions).length == 0) && (obj.cleanupTimer != null)) { clearInterval(webRelayCleanupTimer); obj.cleanupTimer = null; }
6678 + }
6679 +
6680 + // Set the multi-tunnel session
6681 + webRelaySessions[xrelaySessionId] = relaySession;
6682 +
6683 + // Setup the cleanup timer if needed
6684 + if (obj.cleanupTimer == null) { webRelayCleanupTimer = setInterval(checkWebRelaySessionsTimeout, 10000); }
6685
6646 - // Setup the cleanup timer if needed
6647 - if (obj.cleanupTimer == null) { webRelayCleanupTimer = setInterval(checkWebRelaySessionsTimeout, 10000); }
6686 + if (selectedHost == req.hostname) {
6687 + // Request was made on the same host, redirect to root.
6688 + res.redirect('/');
6689 + } else {
6690 + // Request was made to a different host
6691 + const httpport = ((args.aliasport != null) ? args.aliasport : args.port);
6692 + res.redirect('https://' + selectedHost + ((httpport != 443) ? (':' + httpport) : '') + '/');
6693 + }
6694
6649 - // Redirect to root
6650 - res.redirect('/');
6695 + } catch (ex) { console.log(ex); }
6696 });
6697
6698 // Handle all incoming requests as web relays