mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 00:14:07 +01:00
ircd::net::acceptor: Add ALPN negotiation handler support.
This commit is contained in:
parent
fceea7b770
commit
2e525df668
2 changed files with 100 additions and 0 deletions
|
@ -51,6 +51,7 @@ struct ircd::net::acceptor
|
||||||
|
|
||||||
// Handshake stack
|
// Handshake stack
|
||||||
bool handle_sni(SSL &, int &ad);
|
bool handle_sni(SSL &, int &ad);
|
||||||
|
string_view handle_alpn(SSL &, const vector_view<const string_view> &in);
|
||||||
void check_handshake_error(const error_code &ec, socket &);
|
void check_handshake_error(const error_code &ec, socket &);
|
||||||
void handshake(const error_code &ec, std::shared_ptr<socket>, std::weak_ptr<acceptor>) noexcept;
|
void handshake(const error_code &ec, std::shared_ptr<socket>, std::weak_ptr<acceptor>) noexcept;
|
||||||
|
|
||||||
|
|
99
ircd/net.cc
99
ircd/net.cc
|
@ -1870,6 +1870,104 @@ ircd::net::acceptor::check_handshake_error(const error_code &ec,
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ircd::string_view
|
||||||
|
ircd::net::acceptor::handle_alpn(SSL &ssl,
|
||||||
|
const vector_view<const string_view> &in)
|
||||||
|
{
|
||||||
|
if(empty(in))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
log::debug
|
||||||
|
{
|
||||||
|
log, "%s offered %zu ALPN protocols",
|
||||||
|
string(logheadbuf, *this),
|
||||||
|
size(in),
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef IRCD_NET_ACCEPTOR_DEBUG_ALPN
|
||||||
|
for(size_t i(0); i < size(in); ++i)
|
||||||
|
{
|
||||||
|
log::debug
|
||||||
|
{
|
||||||
|
log, "%s ALPN protocol %zu of %zu: '%s'",
|
||||||
|
string(logheadbuf, *this),
|
||||||
|
i,
|
||||||
|
size(in),
|
||||||
|
in[i],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif IRCD_NET_ACCEPTOR_DEBUG_ALPN
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ircd_net_acceptor_handle_alpn(SSL *const s,
|
||||||
|
const unsigned char **out,
|
||||||
|
unsigned char *const outlen,
|
||||||
|
const unsigned char *const in,
|
||||||
|
unsigned int inlen,
|
||||||
|
void *const arg)
|
||||||
|
noexcept try
|
||||||
|
{
|
||||||
|
static const size_t PROTOS_MAX
|
||||||
|
{
|
||||||
|
8
|
||||||
|
};
|
||||||
|
|
||||||
|
auto &acceptor
|
||||||
|
{
|
||||||
|
*reinterpret_cast<ircd::net::acceptor *>(arg)
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t p(0), i(0);
|
||||||
|
ircd::string_view protos[PROTOS_MAX];
|
||||||
|
while(i < inlen && p < PROTOS_MAX)
|
||||||
|
{
|
||||||
|
const uint8_t &len(in[i++]);
|
||||||
|
if(unlikely(!len || i + len >= inlen))
|
||||||
|
break;
|
||||||
|
|
||||||
|
protos[p++] = ircd::string_view
|
||||||
|
{
|
||||||
|
reinterpret_cast<const char *>(in + i), len
|
||||||
|
};
|
||||||
|
|
||||||
|
i += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ircd::vector_view<const ircd::string_view> vec
|
||||||
|
{
|
||||||
|
protos, p
|
||||||
|
};
|
||||||
|
|
||||||
|
const ircd::string_view sel
|
||||||
|
{
|
||||||
|
acceptor.handle_alpn(*s, vec)
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!sel)
|
||||||
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
|
|
||||||
|
*out = reinterpret_cast<const unsigned char *>(data(sel));
|
||||||
|
*outlen = size(sel);
|
||||||
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
}
|
||||||
|
catch(const std::exception &)
|
||||||
|
{
|
||||||
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
ircd::log::critical
|
||||||
|
{
|
||||||
|
ircd::net::acceptor::log,
|
||||||
|
"Acceptor ALPN callback unhandled."
|
||||||
|
};
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ircd::net::acceptor::handle_sni(SSL &ssl,
|
ircd::net::acceptor::handle_sni(SSL &ssl,
|
||||||
int &client_server)
|
int &client_server)
|
||||||
|
@ -2175,6 +2273,7 @@ ircd::net::acceptor::configure(const json::object &opts)
|
||||||
return "foobar";
|
return "foobar";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
SSL_CTX_set_alpn_select_cb(ssl.native_handle(), ircd_net_acceptor_handle_alpn, this);
|
||||||
SSL_CTX_set_tlsext_servername_callback(ssl.native_handle(), ircd_net_acceptor_handle_sni);
|
SSL_CTX_set_tlsext_servername_callback(ssl.native_handle(), ircd_net_acceptor_handle_sni);
|
||||||
SSL_CTX_set_tlsext_servername_arg(ssl.native_handle(), this);
|
SSL_CTX_set_tlsext_servername_arg(ssl.native_handle(), this);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue