mirror of
https://github.com/matrix-construct/construct
synced 2024-11-25 08:12:37 +01:00
ircd::server: Require service suffix for peer map keying; refactor host canonization.
This commit is contained in:
parent
2e2b56e89f
commit
f5d5f6de3b
4 changed files with 96 additions and 53 deletions
|
@ -27,8 +27,8 @@ namespace ircd::net
|
|||
string_view &host(hostport &);
|
||||
|
||||
string_view string(const mutable_buffer &out, const hostport &);
|
||||
string_view canonize(const mutable_buffer &out, const hostport &, const uint16_t &port = 0);
|
||||
std::string canonize(const hostport &, const uint16_t &port = 0);
|
||||
string_view canonize(const mutable_buffer &out, const hostport &);
|
||||
std::string canonize(const hostport &);
|
||||
std::ostream &operator<<(std::ostream &, const hostport &);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,7 @@ struct ircd::server::peer
|
|||
|
||||
uint64_t id {++ids};
|
||||
net::ipport remote;
|
||||
std::string hostcanon;
|
||||
std::string service;
|
||||
std::string hostcanon; // hostname:service[:port]
|
||||
net::open_opts open_opts;
|
||||
std::list<link> links;
|
||||
std::unique_ptr<err> e;
|
||||
|
|
37
ircd/net.cc
37
ircd/net.cc
|
@ -4431,40 +4431,49 @@ ircd::net::operator<<(std::ostream &s, const hostport &t)
|
|||
}
|
||||
|
||||
std::string
|
||||
ircd::net::canonize(const hostport &hp,
|
||||
const uint16_t &port)
|
||||
ircd::net::canonize(const hostport &hostport)
|
||||
{
|
||||
const size_t len
|
||||
{
|
||||
size(host(hp)) + 1 + 5 + 1 // optimistic ':' + portnum
|
||||
size(host(hostport)) // host
|
||||
+ 1 + size(service(hostport)) // ':' + service
|
||||
+ 1 + 5 + 1 // ':' + portnum (optimistic)
|
||||
};
|
||||
|
||||
return ircd::string(len, [&hp, &port]
|
||||
return ircd::string(len, [&hostport]
|
||||
(const mutable_buffer &buf)
|
||||
{
|
||||
return canonize(buf, hp, port);
|
||||
return canonize(buf, hostport);
|
||||
});
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::net::canonize(const mutable_buffer &buf,
|
||||
const hostport &hp,
|
||||
const uint16_t &port)
|
||||
const hostport &hostport)
|
||||
{
|
||||
thread_local char tlbuf[rfc3986::DOMAIN_BUFSIZE * 2];
|
||||
thread_local char tlbuf[2][rfc3986::DOMAIN_BUFSIZE * 2];
|
||||
|
||||
if(net::port(hp) == 0 || net::port(hp) == port)
|
||||
assert(service(hostport));
|
||||
if(unlikely(!service(hostport)))
|
||||
throw error
|
||||
{
|
||||
"Missing service suffix in hostname:service string.",
|
||||
};
|
||||
|
||||
if(port(hostport))
|
||||
return fmt::sprintf
|
||||
{
|
||||
buf, "%s",
|
||||
tolower(tlbuf, host(hp)),
|
||||
buf, "%s:%s:%u",
|
||||
tolower(tlbuf[0], host(hostport)),
|
||||
tolower(tlbuf[1], service(hostport)),
|
||||
port(hostport),
|
||||
};
|
||||
|
||||
return fmt::sprintf
|
||||
{
|
||||
buf, "%s:%u",
|
||||
tolower(tlbuf, host(hp)),
|
||||
net::port(hp)
|
||||
buf, "%s:%s",
|
||||
tolower(tlbuf[0], host(hostport)),
|
||||
tolower(tlbuf[1], service(hostport)),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
105
ircd/server.cc
105
ircd/server.cc
|
@ -17,6 +17,7 @@ namespace ircd::server
|
|||
template<class F> static size_t accumulate_peers(F&&);
|
||||
template<class F> static size_t accumulate_links(F&&);
|
||||
template<class F> static size_t accumulate_tags(F&&);
|
||||
static string_view canonize(const hostport &); // TLS buffer
|
||||
|
||||
// Internal control
|
||||
static decltype(ircd::server::peers)::iterator
|
||||
|
@ -126,14 +127,17 @@ ircd::server::init::interrupt()
|
|||
ircd::server::peer &
|
||||
ircd::server::get(const net::hostport &hostport)
|
||||
{
|
||||
thread_local char canonbuf[512];
|
||||
const auto canonized
|
||||
const auto hostcanon
|
||||
{
|
||||
net::canonize(canonbuf, hostport)
|
||||
server::canonize(hostport)
|
||||
};
|
||||
|
||||
auto it(peers.lower_bound(canonized));
|
||||
if(it == peers.end() || it->first != canonized)
|
||||
auto it
|
||||
{
|
||||
peers.lower_bound(hostcanon)
|
||||
};
|
||||
|
||||
if(it == peers.end() || it->first != hostcanon)
|
||||
it = create(hostport, it);
|
||||
|
||||
return *it->second;
|
||||
|
@ -168,28 +172,47 @@ ircd::server::create(const net::hostport &hostport,
|
|||
ircd::server::peer &
|
||||
ircd::server::find(const net::hostport &hostport)
|
||||
{
|
||||
return *peers.at(host(hostport));
|
||||
const auto hostcanon
|
||||
{
|
||||
server::canonize(hostport)
|
||||
};
|
||||
|
||||
return *peers.at(hostcanon);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::server::exists(const net::hostport &hostport)
|
||||
noexcept
|
||||
{
|
||||
return peers.find(host(hostport)) != end(peers);
|
||||
const auto hostcanon
|
||||
{
|
||||
server::canonize(hostport)
|
||||
};
|
||||
|
||||
return peers.find(hostcanon) != end(peers);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::server::errclear(const net::hostport &hostport)
|
||||
{
|
||||
const auto hostcanon
|
||||
{
|
||||
server::canonize(hostport)
|
||||
};
|
||||
|
||||
const auto it
|
||||
{
|
||||
peers.find(host(hostport))
|
||||
peers.find(hostcanon)
|
||||
};
|
||||
|
||||
if(it == end(peers))
|
||||
return false;
|
||||
|
||||
auto &peer(*it->second);
|
||||
auto &peer
|
||||
{
|
||||
*it->second
|
||||
};
|
||||
|
||||
return peer.err_clear();
|
||||
}
|
||||
|
||||
|
@ -197,15 +220,19 @@ ircd::string_view
|
|||
ircd::server::errmsg(const net::hostport &hostport)
|
||||
noexcept
|
||||
{
|
||||
const auto it
|
||||
const auto hostcanon
|
||||
{
|
||||
peers.find(host(hostport))
|
||||
server::canonize(hostport)
|
||||
};
|
||||
|
||||
if(it == end(peers))
|
||||
return {};
|
||||
const auto it
|
||||
{
|
||||
peers.find(hostcanon)
|
||||
};
|
||||
|
||||
return it->second->err_msg();
|
||||
return it != end(peers)?
|
||||
it->second->err_msg():
|
||||
string_view{};
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -316,6 +343,13 @@ ircd::server::accumulate_peers(F&& closure)
|
|||
});
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::server::canonize(const net::hostport &hostport)
|
||||
{
|
||||
thread_local char buf[512];
|
||||
return net::canonize(buf, hostport);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// server/request.h
|
||||
|
@ -383,14 +417,18 @@ __attribute__((stack_protect))
|
|||
ircd::server::submit(const hostport &hostport,
|
||||
request &request)
|
||||
{
|
||||
assert(request.tag == nullptr);
|
||||
if(unlikely(ircd::run::level != ircd::run::level::RUN))
|
||||
throw unavailable
|
||||
{
|
||||
"Unable to fulfill requests at this time."
|
||||
};
|
||||
|
||||
assert(request.tag == nullptr);
|
||||
auto &peer(server::get(hostport));
|
||||
auto &peer
|
||||
{
|
||||
server::get(hostport)
|
||||
};
|
||||
|
||||
peer.submit(request);
|
||||
}
|
||||
|
||||
|
@ -577,34 +615,31 @@ ircd::server::peer::peer(const net::hostport &hostport,
|
|||
{
|
||||
net::canonize(hostport)
|
||||
}
|
||||
,service
|
||||
{
|
||||
// hostport arguments with a port of 0 are normal; if the port is such,
|
||||
// and if we are supplied a service string an SRV query will be performed.
|
||||
// For other port numbers, we ignore any service string and SRV won't be
|
||||
// resolved.
|
||||
!net::port(hostport)?
|
||||
net::service(hostport):
|
||||
string_view{}
|
||||
}
|
||||
,open_opts
|
||||
{
|
||||
std::move(open_opts)
|
||||
open_opts
|
||||
}
|
||||
{
|
||||
const net::hostport &canon{this->hostcanon};
|
||||
const net::hostport &canon
|
||||
{
|
||||
this->hostcanon
|
||||
};
|
||||
|
||||
this->open_opts.hostport.host = this->hostcanon;
|
||||
this->open_opts.hostport.port = net::port(hostport);
|
||||
this->open_opts.hostport.service = this->service;
|
||||
// Ensure references are to this class's members
|
||||
this->open_opts.hostport.host = host(canon);
|
||||
this->open_opts.hostport.service = service(canon);
|
||||
this->open_opts.hostport.port = port(hostport);
|
||||
|
||||
this->open_opts.server_name = this->hostcanon; // Send SNI for this name.
|
||||
this->open_opts.common_name = this->hostcanon; // Cert verify this name.
|
||||
// Send SNI for this name.
|
||||
this->open_opts.server_name = host(canon);
|
||||
|
||||
if(rfc3986::valid(std::nothrow, rfc3986::parser::ip_address, host(this->open_opts.hostport)))
|
||||
// Cert verify this name.
|
||||
this->open_opts.common_name = host(canon);
|
||||
|
||||
if(rfc3986::valid(std::nothrow, rfc3986::parser::ip_address, host(canon)))
|
||||
this->remote =
|
||||
{
|
||||
host(this->open_opts.hostport), port(this->open_opts.hostport)
|
||||
host(canon), port(hostport)
|
||||
};
|
||||
|
||||
this->open_opts.ipport = this->remote;
|
||||
|
|
Loading…
Reference in a new issue