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