[IMPROVE][Federation] Add support for _tcp and protocol DNS entries (#17818)

pull/16332/head^2
Alan Sikora 5 years ago committed by GitHub
parent bcf26aaf89
commit 02645e4f61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 49
      app/federation/server/lib/dns.js
  2. 2
      app/federation/server/lib/http.js

@ -29,15 +29,20 @@ export function registerWithHub(peerDomain, url, publicKey) {
export function searchHub(peerDomain) {
try {
logger.dns.debug(`searchHub: peerDomain=${ peerDomain }`);
// If there is no DNS entry for that, get from the Hub
const { data: { peer } } = federationRequest('GET', `${ hubUrl }/api/v1/peers?search=${ peerDomain }`);
if (!peer) {
logger.dns.debug(`searchHub: could not find peerDomain=${ peerDomain }`);
throw federationErrors.peerCouldNotBeRegisteredWithHub('dns.registerWithHub');
}
const { url, public_key: publicKey } = peer;
logger.dns.debug(`searchHub: found peerDomain=${ peerDomain } url=${ url }`);
return {
url,
peerDomain,
@ -55,13 +60,14 @@ export function search(peerDomain) {
throw federationErrors.disabled('dns.search');
}
logger.dns.debug(`search: ${ peerDomain }`);
logger.dns.debug(`search: peerDomain=${ peerDomain }`);
let srvEntries = [];
let protocol = '';
// Search by HTTPS first
try {
logger.dns.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._https.${ peerDomain }`);
srvEntries = dnsResolveSRV(`_rocketchat._https.${ peerDomain }`);
protocol = 'https';
} catch (err) {
@ -71,6 +77,7 @@ export function search(peerDomain) {
// If there is not entry, try with http
if (!srvEntries.length) {
try {
logger.dns.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._http.${ peerDomain }`);
srvEntries = dnsResolveSRV(`_rocketchat._http.${ peerDomain }`);
protocol = 'http';
} catch (err) {
@ -78,24 +85,56 @@ export function search(peerDomain) {
}
}
// If there is not entry, try with tcp
if (!srvEntries.length) {
try {
logger.dns.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._tcp.${ peerDomain }`);
srvEntries = dnsResolveSRV(`_rocketchat._tcp.${ peerDomain }`);
protocol = 'https'; // https is the default
// Then, also try to get the protocol
logger.dns.debug(`search: peerDomain=${ peerDomain } txt=rocketchat-tcp-protocol.${ peerDomain }`);
protocol = dnsResolveTXT(`rocketchat-tcp-protocol.${ peerDomain }`);
protocol = protocol[0].join('');
if (protocol !== 'http' && protocol !== 'https') {
protocol = null;
}
} catch (err) {
// if there is an error while getting the _tcp entry, it means the config is not there
// but if there is an error looking for the `_rocketchat_tcp_protocol` entry, it means we should use https
}
}
const [srvEntry] = srvEntries;
// If there is no entry, throw error
if (!srvEntry) {
if (!srvEntry || !protocol) {
logger.dns.debug(`search: could not find valid SRV entry peerDomain=${ peerDomain } srvEntry=${ JSON.stringify(srvEntry) } protocol=${ protocol }`);
return searchHub(peerDomain);
}
let publicKey = null;
// Get the public key from the TXT record
const publicKeyTxtRecords = dnsResolveTXT(`rocketchat-public-key.${ peerDomain }`);
try {
logger.dns.debug(`search: peerDomain=${ peerDomain } txt=rocketchat-public-key.${ peerDomain }`);
const publicKeyTxtRecords = dnsResolveTXT(`rocketchat-public-key.${ peerDomain }`);
// Join the TXT record, that might be split
const publicKey = publicKeyTxtRecords[0].join('');
// Join the TXT record, that might be split
publicKey = publicKeyTxtRecords[0].join('');
} catch (err) {
// Ignore errors when looking for DNS entries
}
// If there is no entry, throw error
if (!publicKey) {
logger.dns.debug(`search: could not find TXT entry for peerDomain=${ peerDomain } - SRV entry found`);
return searchHub(peerDomain);
}
logger.dns.debug(`search: found peerDomain=${ peerDomain } srvEntry=${ srvEntry.name }:${ srvEntry.port } protocol=${ protocol }`);
return {
url: `${ protocol }://${ srvEntry.name }:${ srvEntry.port }`,
peerDomain,

@ -37,6 +37,8 @@ export function federationRequestToPeer(method, peerDomain, uri, body, options =
let result;
try {
logger.http.debug(() => `federationRequestToPeer => url=${ baseUrl }${ uri }`);
result = federationRequest(method, `${ baseUrl }${ uri }`, body, options.headers || {}, peerKey);
} catch (err) {
logger.http.error(`${ ignoreErrors ? '[IGNORED] ' : '' }Error ${ err }`);

Loading…
Cancel
Save