0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd:Ⓜ️:fed::well_known: Simplify interface; add opts struct.

This commit is contained in:
Jason Volk 2020-10-14 06:59:30 -07:00
parent 543ff4d820
commit 888c62c156
6 changed files with 99 additions and 74 deletions

View file

@ -11,23 +11,6 @@
#pragma once
#define HAVE_IRCD_M_FED_H
/// Federation Interface
namespace ircd::m::fed
{
id::event::buf fetch_head(const id::room &room_id, const string_view &remote, const id::user &);
id::event::buf fetch_head(const id::room &room_id, const string_view &remote);
net::hostport matrix_service(net::hostport remote) noexcept;
string_view server(const mutable_buffer &out, const string_view &origin);
bool errant(const string_view &origin);
bool linked(const string_view &origin);
bool exists(const string_view &origin);
bool avail(const string_view &origin);
bool clear_error(const string_view &origin);
}
#include "well_known.h"
#include "request.h"
#include "version.h"
@ -50,6 +33,26 @@ namespace ircd::m::fed
#include "send.h"
#include "groups.h"
/// Federation Interface
namespace ircd::m::fed
{
// Utils
net::hostport matrix_service(net::hostport remote) noexcept;
string_view server(const mutable_buffer &out, const string_view &name, const well_known::opts & = {});
id::event::buf fetch_head(const id::room &room_id, const string_view &remote, const id::user &);
id::event::buf fetch_head(const id::room &room_id, const string_view &remote);
// Observers
bool errant(const string_view &server_name);
bool linked(const string_view &server_name);
bool exists(const string_view &server_name);
bool avail(const string_view &server_name);
// Control panel
bool clear_error(const string_view &server_name);
}
inline ircd::net::hostport
ircd::m::fed::matrix_service(net::hostport remote)
noexcept

View file

@ -52,6 +52,10 @@ struct ircd::m::fed::request::opts
/// this request.
const struct server::request::opts *sopts {nullptr};
/// Custom options to pass when resolving a server name with the well-known
/// system.
well_known::opts wkopts;
/// Whether dynamic content buffering for incoming data will be used.
/// if false, the user supplied buffer handles all data sent from the
/// remote server; this is faster, but if it runs out the request is

View file

@ -13,8 +13,9 @@
namespace ircd::m::fed::well_known
{
string_view fetch(const mutable_buffer &out, const string_view &origin);
string_view get(const mutable_buffer &out, const string_view &origin);
struct opts;
string_view get(const mutable_buffer &, const string_view &, const opts &);
extern conf::item<size_t> fetch_redirects;
extern conf::item<seconds> fetch_timeout;
@ -22,3 +23,18 @@ namespace ircd::m::fed::well_known
extern conf::item<seconds> cache_error;
extern conf::item<seconds> cache_default;
}
struct ircd::m::fed::well_known::opts
{
/// Whether to check the cache before making any request.
bool cache_check {true};
/// Allow expired cache results to be returned without making any refresh.
bool expired {false};
/// Allow a query to be made to a remote.
bool request {true};
/// Whether to cache the result of any request.
bool cache_result {true};
};

View file

@ -1491,7 +1491,7 @@ ircd::m::fed::request::request(const mutable_buffer &buf_,
// well-known this fails silently by just returning the input (likely).
const string_view &target
{
fed::server(buf_, opts.remote)
fed::server(buf_, opts.remote, opts.wkopts)
};
// Devote the remaining buffer for HTTP as otherwise intended.
@ -1615,7 +1615,8 @@ ircd::m::fed::errant(const string_view &origin)
ircd::string_view
ircd::m::fed::server(const mutable_buffer &buf,
const string_view &origin)
const string_view &origin,
const well_known::opts &opts)
{
net::hostport remote
{
@ -1625,7 +1626,7 @@ ircd::m::fed::server(const mutable_buffer &buf,
string_view target
{
!port(remote)?
well_known::get(buf, host(remote)):
well_known::get(buf, host(remote), opts):
origin
};

View file

@ -15,6 +15,7 @@ namespace ircd::m::fed::well_known
static void submit(request &);
static void receive(request &);
static int handle(request &);
static string_view fetch(const mutable_buffer &, const string_view &);
extern log::log log;
}
@ -92,7 +93,8 @@ ircd::m::fed::well_known::fetch_redirects
ircd::string_view
ircd::m::fed::well_known::get(const mutable_buffer &buf,
const string_view &origin)
const string_view &origin,
const opts &opts)
try
{
static const string_view type
@ -112,7 +114,9 @@ try
const m::event::idx event_idx
{
room.get(std::nothrow, type, origin)
likely(opts.cache_check)?
room.get(std::nothrow, type, origin):
0UL
};
const milliseconds origin_server_ts
@ -153,7 +157,7 @@ try
};
// Branch on valid cache hit to return result.
if(valid && !expired)
if(valid && (!expired || opts.expired))
{
char tmbuf[48];
log::debug
@ -168,15 +172,16 @@ try
return cached;
}
// Crucial value that will provide us with a return string for this
// function in any case. This is obtained by either using the value
// found in cache or making a network query for a new value. expired=true
// when a network query needs to be made, otherwise we can return the
// cached value. If the network query fails, this value is still defaulted
// as the origin string to return and we'll also cache that too.
const string_view fetched
{
opts.request?
fetch(buf + size(cached), origin):
string_view{}
};
const string_view delegated
{
fetch(buf + size(cached), origin)
data(buf), move(buf, fetched?: origin)
};
// Conditions for valid expired cache hit w/ failure to reacquire.
@ -201,39 +206,43 @@ try
timef(tmbuf, expires, localtime),
};
assert(opts.cache_check);
return cached;
}
// Any time the well-known result is the same as the origin (that
// includes legitimate errors where fetch_well_known() returns the
// origin to default) we consider that an error and use the error
// TTL value. Sorry, no exponential backoff implemented yet.
const auto cache_ttl
if(likely(opts.request && opts.cache_result))
{
origin == delegated?
seconds(cache_error).count():
seconds(cache_default).count()
};
// Write our record to the cache room; note that this doesn't really
// match the format of other DNS records in this room since it's a bit
// simpler, but we don't share the ircd.dns.rr type prefix anyway.
const auto cache_id
{
m::send(room, m::me(), type, origin, json::members
// Any time the well-known result is the same as the origin (that
// includes legitimate errors where fetch_well_known() returns the
// origin to default) we consider that an error and use the error
// TTL value. Sorry, no exponential backoff implemented yet.
const auto cache_ttl
{
{ "ttl", cache_ttl },
{ "m.server", delegated },
})
};
origin == delegated?
seconds(cache_error).count():
seconds(cache_default).count()
};
log::debug
{
log, "%s caching delegation to %s to cache in %s",
origin,
delegated,
string_view{cache_id},
};
// Write our record to the cache room; note that this doesn't really
// match the format of other DNS records in this room since it's a bit
// simpler, but we don't share the ircd.dns.rr type prefix anyway.
const auto cache_id
{
m::send(room, m::me(), type, origin, json::members
{
{ "ttl", cache_ttl },
{ "m.server", delegated },
})
};
log::debug
{
log, "%s caching delegation to %s to cache in %s",
origin,
delegated,
string_view{cache_id},
};
}
return delegated;
}
@ -289,10 +298,7 @@ try
}
}
return string_view
{
data(user_buf), move(user_buf, target)
};
return {};
}
catch(const ctx::interrupted &)
{
@ -307,10 +313,7 @@ catch(const std::exception &e)
e.what(),
};
return string_view
{
data(user_buf), move(user_buf, target)
};
return {};
}
int
@ -386,12 +389,6 @@ ircd::m::fed::well_known::receive(request &req)
};
}
/// Launch requestReturn a tuple of the HTTP code, any Location header, and the response
/// content. These values are unconditional if this function doesn't throw,
/// but if there's no Location header and/or content then those will be empty
/// string_view's. This function is intended to be run in a loop by the caller
/// to chase redirection. No HTTP codes will throw from here; server and
/// network errors (and others) will.
void
ircd::m::fed::well_known::submit(request &req)
{

View file

@ -15996,9 +15996,13 @@ console_cmd__well_known__matrix__server(opt &out, const string_view &line)
1_KiB
};
m::fed::well_known::opts opts;
opts.cache_check = false;
opts.cache_result = false;
const net::hostport result
{
m::fed::well_known::fetch(buf, remote)
m::fed::well_known::get(buf, remote, opts)
};
out << result << std::endl;