Commit 52b904f0 authored by Neel Goyal's avatar Neel Goyal Committed by Facebook Github Bot

Remove NPN Support

Summary: ALPN is the preferred way to do this.  We should only use that and not provide NPN support anymore.

Reviewed By: knekritz

Differential Revision: D10110626

fbshipit-source-id: 5ec91fe51252bed0a8d8047e481df76a395e1286
parent c42a131a
......@@ -855,37 +855,22 @@ void AsyncSSLSocket::setSSLSession(SSL_SESSION* session, bool takeOwnership) {
void AsyncSSLSocket::getSelectedNextProtocol(
const unsigned char** protoName,
unsigned* protoLen,
SSLContext::NextProtocolType* protoType) const {
if (!getSelectedNextProtocolNoThrow(protoName, protoLen, protoType)) {
unsigned* protoLen) const {
if (!getSelectedNextProtocolNoThrow(protoName, protoLen)) {
throw AsyncSocketException(
AsyncSocketException::NOT_SUPPORTED, "NPN not supported");
AsyncSocketException::NOT_SUPPORTED, "ALPN not supported");
}
}
bool AsyncSSLSocket::getSelectedNextProtocolNoThrow(
const unsigned char** protoName,
unsigned* protoLen,
SSLContext::NextProtocolType* protoType) const {
unsigned* protoLen) const {
*protoName = nullptr;
*protoLen = 0;
#if FOLLY_OPENSSL_HAS_ALPN
SSL_get0_alpn_selected(ssl_, protoName, protoLen);
if (*protoLen > 0) {
if (protoType) {
*protoType = SSLContext::NextProtocolType::ALPN;
}
return true;
}
#endif
#ifdef OPENSSL_NPN_NEGOTIATED
SSL_get0_next_proto_negotiated(ssl_, protoName, protoLen);
if (protoType) {
*protoType = SSLContext::NextProtocolType::NPN;
}
return true;
#else
(void)protoType;
return false;
#endif
}
......
......@@ -465,8 +465,7 @@ class AsyncSSLSocket : public virtual AsyncSocket {
/**
* Get the name of the protocol selected by the client during
* Next Protocol Negotiation (NPN) or Application Layer Protocol Negotiation
* (ALPN)
* Application Layer Protocol Negotiation (ALPN)
*
* Throw an exception if openssl does not support NPN
*
......@@ -480,8 +479,7 @@ class AsyncSSLSocket : public virtual AsyncSocket {
*/
virtual void getSelectedNextProtocol(
const unsigned char** protoName,
unsigned* protoLen,
SSLContext::NextProtocolType* protoType = nullptr) const;
unsigned* protoLen) const;
/**
* Get the name of the protocol selected by the client during
......@@ -499,8 +497,7 @@ class AsyncSSLSocket : public virtual AsyncSocket {
*/
virtual bool getSelectedNextProtocolNoThrow(
const unsigned char** protoName,
unsigned* protoLen,
SSLContext::NextProtocolType* protoType = nullptr) const;
unsigned* protoLen) const;
/**
* Determine if the session specified during setSSLSession was reused
......
......@@ -78,7 +78,7 @@ SSLContext::~SSLContext() {
ctx_ = nullptr;
}
#ifdef OPENSSL_NPN_NEGOTIATED
#if FOLLY_OPENSSL_HAS_ALPN
deleteNextProtocolsStrings();
#endif
}
......@@ -425,19 +425,14 @@ int SSLContext::alpnSelectCallback(
}
return SSL_TLSEXT_ERR_OK;
}
#endif // FOLLY_OPENSSL_HAS_ALPN
#ifdef OPENSSL_NPN_NEGOTIATED
bool SSLContext::setAdvertisedNextProtocols(
const std::list<std::string>& protocols,
NextProtocolType protocolType) {
return setRandomizedAdvertisedNextProtocols({{1, protocols}}, protocolType);
const std::list<std::string>& protocols) {
return setRandomizedAdvertisedNextProtocols({{1, protocols}});
}
bool SSLContext::setRandomizedAdvertisedNextProtocols(
const std::list<NextProtocolsItem>& items,
NextProtocolType protocolType) {
const std::list<NextProtocolsItem>& items) {
unsetNextProtocols();
if (items.size() == 0) {
return false;
......@@ -480,25 +475,16 @@ bool SSLContext::setRandomizedAdvertisedNextProtocols(
nextProtocolDistribution_ = std::discrete_distribution<>(
advertisedNextProtocolWeights_.begin(),
advertisedNextProtocolWeights_.end());
if ((uint8_t)protocolType & (uint8_t)NextProtocolType::NPN) {
SSL_CTX_set_next_protos_advertised_cb(
ctx_, advertisedNextProtocolCallback, this);
SSL_CTX_set_next_proto_select_cb(ctx_, selectNextProtocolCallback, this);
}
#if FOLLY_OPENSSL_HAS_ALPN
if ((uint8_t)protocolType & (uint8_t)NextProtocolType::ALPN) {
SSL_CTX_set_alpn_select_cb(ctx_, alpnSelectCallback, this);
// Client cannot really use randomized alpn
// Note that this function reverses the typical return value convention
// of openssl and returns 0 on success.
if (SSL_CTX_set_alpn_protos(
ctx_,
advertisedNextProtocols_[0].protocols,
advertisedNextProtocols_[0].length) != 0) {
return false;
}
SSL_CTX_set_alpn_select_cb(ctx_, alpnSelectCallback, this);
// Client cannot really use randomized alpn
// Note that this function reverses the typical return value convention
// of openssl and returns 0 on success.
if (SSL_CTX_set_alpn_protos(
ctx_,
advertisedNextProtocols_[0].protocols,
advertisedNextProtocols_[0].length) != 0) {
return false;
}
#endif
return true;
}
......@@ -512,15 +498,11 @@ void SSLContext::deleteNextProtocolsStrings() {
void SSLContext::unsetNextProtocols() {
deleteNextProtocolsStrings();
SSL_CTX_set_next_protos_advertised_cb(ctx_, nullptr, nullptr);
SSL_CTX_set_next_proto_select_cb(ctx_, nullptr, nullptr);
#if FOLLY_OPENSSL_HAS_ALPN
SSL_CTX_set_alpn_select_cb(ctx_, nullptr, nullptr);
SSL_CTX_set_alpn_protos(ctx_, nullptr, 0);
// clear the error stack here since openssl internals sometimes add a
// malloc failure when doing a memdup of NULL, 0..
ERR_clear_error();
#endif
}
size_t SSLContext::pickNextProtocols() {
......@@ -529,80 +511,7 @@ size_t SSLContext::pickNextProtocols() {
return size_t(nextProtocolDistribution_(rng));
}
int SSLContext::advertisedNextProtocolCallback(
SSL* ssl,
const unsigned char** out,
unsigned int* outlen,
void* data) {
static int nextProtocolsExDataIndex = SSL_get_ex_new_index(
0, (void*)"Advertised next protocol index", nullptr, nullptr, nullptr);
SSLContext* context = (SSLContext*)data;
if (context == nullptr || context->advertisedNextProtocols_.empty()) {
*out = nullptr;
*outlen = 0;
} else if (context->advertisedNextProtocols_.size() == 1) {
*out = context->advertisedNextProtocols_[0].protocols;
*outlen = context->advertisedNextProtocols_[0].length;
} else {
uintptr_t selected_index = reinterpret_cast<uintptr_t>(
SSL_get_ex_data(ssl, nextProtocolsExDataIndex));
if (selected_index) {
--selected_index;
*out = context->advertisedNextProtocols_[selected_index].protocols;
*outlen = context->advertisedNextProtocols_[selected_index].length;
} else {
auto i = context->pickNextProtocols();
uintptr_t selected = i + 1;
SSL_set_ex_data(ssl, nextProtocolsExDataIndex, (void*)selected);
*out = context->advertisedNextProtocols_[i].protocols;
*outlen = context->advertisedNextProtocols_[i].length;
}
}
return SSL_TLSEXT_ERR_OK;
}
int SSLContext::selectNextProtocolCallback(
SSL* ssl,
unsigned char** out,
unsigned char* outlen,
const unsigned char* server,
unsigned int server_len,
void* data) {
(void)ssl; // Make -Wunused-parameters happy
SSLContext* ctx = (SSLContext*)data;
if (ctx->advertisedNextProtocols_.size() > 1) {
VLOG(3) << "SSLContext::selectNextProcolCallback() "
<< "client should be deterministic in selecting protocols.";
}
unsigned char* client = nullptr;
unsigned int client_len = 0;
bool filtered = false;
auto cpf = ctx->getClientProtocolFilterCallback();
if (cpf) {
filtered = (*cpf)(&client, &client_len, server, server_len);
}
if (!filtered) {
if (ctx->advertisedNextProtocols_.empty()) {
client = (unsigned char*)"";
client_len = 0;
} else {
client = ctx->advertisedNextProtocols_[0].protocols;
client_len = ctx->advertisedNextProtocols_[0].length;
}
}
int retval = SSL_select_next_proto(
out, outlen, server, server_len, client, client_len);
if (retval != OPENSSL_NPN_NEGOTIATED) {
VLOG(3) << "SSLContext::selectNextProcolCallback() "
<< "unable to pick a next protocol.";
}
return SSL_TLSEXT_ERR_OK;
}
#endif // OPENSSL_NPN_NEGOTIATED
#endif // FOLLY_OPENSSL_HAS_ALPN
SSL* SSLContext::createSSL() const {
SSL* ssl = SSL_new(ctx_);
......
......@@ -430,42 +430,33 @@ class SSLContext {
*/
void setOptions(long options);
enum class NextProtocolType : uint8_t {
NPN = 0x1,
ALPN = 0x2,
ANY = NPN | ALPN
};
#ifdef OPENSSL_NPN_NEGOTIATED
#if FOLLY_OPENSSL_HAS_ALPN
/**
* Set the list of protocols that this SSL context supports. In server
* mode, this is the list of protocols that will be advertised for Next
* Protocol Negotiation (NPN) or Application Layer Protocol Negotiation
* (ALPN). In client mode, the first protocol advertised by the server
* that is also on this list is chosen. Invoking this function with a list
* of length zero causes NPN to be disabled.
* Set the list of protocols that this SSL context supports. In client
* mode, this is the list of protocols that will be advertised for Application
* Layer Protocol Negotiation (ALPN). In server mode, the first protocol
* advertised by the client that is also on this list is chosen.
* Invoking this function with a list of length zero causes ALPN to be
* disabled.
*
* @param protocols List of protocol names. This method makes a copy,
* so the caller needn't keep the list in scope after
* the call completes. The list must have at least
* one element to enable NPN. Each element must have
* one element to enable ALPN. Each element must have
* a string length < 256.
* @param protocolType What type of protocol negotiation to support.
* @return true if NPN/ALPN has been activated. False if NPN/ALPN is disabled.
* @return true if ALPN has been activated. False if ALPN is disabled.
*/
bool setAdvertisedNextProtocols(
const std::list<std::string>& protocols,
NextProtocolType protocolType = NextProtocolType::ANY);
bool setAdvertisedNextProtocols(const std::list<std::string>& protocols);
/**
* Set weighted list of lists of protocols that this SSL context supports.
* In server mode, each element of the list contains a list of protocols that
* could be advertised for Next Protocol Negotiation (NPN) or Application
* Layer Protocol Negotiation (ALPN). The list of protocols that will be
* advertised to a client is selected randomly, based on weights of elements.
* Client mode doesn't support randomized NPN/ALPN, so this list should
* contain only 1 element. The first protocol advertised by the server that
* is also on the list of protocols of this element is chosen. Invoking this
* function with a list of length zero causes NPN/ALPN to be disabled.
* could be advertised for Application Layer Protocol Negotiation (ALPN).
* The list of protocols that will be advertised to a client is selected
* randomly, based on weights of elements. Client mode doesn't support
* randomized ALPN, so this list should contain only 1 element. The first
* protocol advertised by the client that is also on the list of protocols
* of this element is chosen. Invoking this function with a list of length
* zero causes ALPN to be disabled.
*
* @param items List of NextProtocolsItems, Each item contains a list of
* protocol names and weight. After the call of this fucntion
......@@ -475,27 +466,17 @@ class SSLContext {
* completes. The list must have at least one element with
* non-zero weight and non-empty protocols list to enable NPN.
* Each name of the protocol must have a string length < 256.
* @param protocolType What type of protocol negotiation to support.
* @return true if NPN/ALPN has been activated. False if NPN/ALPN is disabled.
* @return true if ALPN has been activated. False if ALPN is disabled.
*/
bool setRandomizedAdvertisedNextProtocols(
const std::list<NextProtocolsItem>& items,
NextProtocolType protocolType = NextProtocolType::ANY);
void setClientProtocolFilterCallback(ClientProtocolFilterCallback cb) {
clientProtoFilter_ = cb;
}
ClientProtocolFilterCallback getClientProtocolFilterCallback() {
return clientProtoFilter_;
}
const std::list<NextProtocolsItem>& items);
/**
* Disables NPN on this SSL context.
* Disables ALPN on this SSL context.
*/
void unsetNextProtocols();
void deleteNextProtocolsStrings();
#endif // OPENSSL_NPN_NEGOTIATED
#endif // FOLLY_OPENSSL_HAS_ALPN
/**
* Gets the underlying SSL_CTX for advanced usage
......@@ -553,7 +534,7 @@ class SSLContext {
static bool initialized_;
#ifdef OPENSSL_NPN_NEGOTIATED
#if FOLLY_OPENSSL_HAS_ALPN
struct AdvertisedNextProtocolsItem {
unsigned char* protocols;
......@@ -572,15 +553,7 @@ class SSLContext {
const unsigned char** out,
unsigned int* outlen,
void* data);
static int selectNextProtocolCallback(
SSL* ssl,
unsigned char** out,
unsigned char* outlen,
const unsigned char* server,
unsigned int server_len,
void* args);
#if FOLLY_OPENSSL_HAS_ALPN
static int alpnSelectCallback(
SSL* ssl,
const unsigned char** out,
......@@ -588,10 +561,10 @@ class SSLContext {
const unsigned char* in,
unsigned int inlen,
void* data);
#endif
size_t pickNextProtocols();
#endif // OPENSSL_NPN_NEGOTIATED
#endif // FOLLY_OPENSSL_HAS_ALPN
static int passwordCallback(char* password, int size, int, void* data);
......
......@@ -429,10 +429,8 @@ TEST(AsyncSSLSocketTest, SocketWithDelay) {
cerr << "SocketWithDelay test completed" << endl;
}
using NextProtocolTypePair =
std::pair<SSLContext::NextProtocolType, SSLContext::NextProtocolType>;
class NextProtocolTest : public testing::TestWithParam<NextProtocolTypePair> {
#if FOLLY_OPENSSL_HAS_ALPN
class NextProtocolTest : public Test {
// For matching protos
public:
void SetUp() override {
......@@ -452,8 +450,8 @@ class NextProtocolTest : public testing::TestWithParam<NextProtocolTypePair> {
new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
AsyncSSLSocket::UniquePtr serverSock(
new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
client = std::make_unique<NpnClient>(std::move(clientSock));
server = std::make_unique<NpnServer>(std::move(serverSock));
client = std::make_unique<AlpnClient>(std::move(clientSock));
server = std::make_unique<AlpnServer>(std::move(serverSock));
eventBase.loop();
}
......@@ -477,26 +475,6 @@ class NextProtocolTest : public testing::TestWithParam<NextProtocolTypePair> {
EXPECT_EQ(server->nextProto, nullptr);
}
void expectProtocolType() {
expectHandshakeSuccess();
if (GetParam().first == SSLContext::NextProtocolType::ANY &&
GetParam().second == SSLContext::NextProtocolType::ANY) {
EXPECT_EQ(client->protocolType, server->protocolType);
} else if (
GetParam().first == SSLContext::NextProtocolType::ANY ||
GetParam().second == SSLContext::NextProtocolType::ANY) {
// Well not much we can say
} else {
expectProtocolType(GetParam());
}
}
void expectProtocolType(NextProtocolTypePair expected) {
expectHandshakeSuccess();
EXPECT_EQ(client->protocolType, expected.first);
EXPECT_EQ(server->protocolType, expected.second);
}
void expectHandshakeSuccess() {
EXPECT_FALSE(client->except.hasValue())
<< "client handshake error: " << client->except->what();
......@@ -515,131 +493,45 @@ class NextProtocolTest : public testing::TestWithParam<NextProtocolTypePair> {
std::shared_ptr<SSLContext> clientCtx{std::make_shared<SSLContext>()};
std::shared_ptr<SSLContext> serverCtx{std::make_shared<SSLContext>()};
int fds[2];
std::unique_ptr<NpnClient> client;
std::unique_ptr<NpnServer> server;
};
class NextProtocolTLSExtTest : public NextProtocolTest {
// For extended TLS protos
std::unique_ptr<AlpnClient> client;
std::unique_ptr<AlpnServer> server;
};
class NextProtocolNPNOnlyTest : public NextProtocolTest {
// For mismatching protos
};
class NextProtocolMismatchTest : public NextProtocolTest {
// For mismatching protos
};
TEST_P(NextProtocolTest, NpnTestOverlap) {
clientCtx->setAdvertisedNextProtocols({"blub", "baz"}, GetParam().first);
serverCtx->setAdvertisedNextProtocols(
{"foo", "bar", "baz"}, GetParam().second);
TEST_F(NextProtocolTest, AlpnTestOverlap) {
clientCtx->setAdvertisedNextProtocols({"blub", "baz"});
serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"});
connect();
expectProtocol("baz");
expectProtocolType();
}
TEST_P(NextProtocolTest, NpnTestUnset) {
TEST_F(NextProtocolTest, AlpnTestUnset) {
// Identical to above test, except that we want unset NPN before
// looping.
clientCtx->setAdvertisedNextProtocols({"blub", "baz"}, GetParam().first);
serverCtx->setAdvertisedNextProtocols(
{"foo", "bar", "baz"}, GetParam().second);
clientCtx->setAdvertisedNextProtocols({"blub", "baz"});
serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"});
connect(true /* unset */);
// if alpn negotiation fails, type will appear as npn
expectNoProtocol();
EXPECT_EQ(client->protocolType, server->protocolType);
}
TEST_P(NextProtocolMismatchTest, NpnAlpnTestNoOverlap) {
clientCtx->setAdvertisedNextProtocols({"foo"}, GetParam().first);
serverCtx->setAdvertisedNextProtocols(
{"foo", "bar", "baz"}, GetParam().second);
TEST_F(NextProtocolTest, AlpnTestNoOverlap) {
clientCtx->setAdvertisedNextProtocols({"blub"});
serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"});
connect();
expectNoProtocol();
expectProtocolType(
{SSLContext::NextProtocolType::NPN, SSLContext::NextProtocolType::NPN});
}
TEST_P(NextProtocolTest, NpnTestNoOverlap) {
clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
serverCtx->setAdvertisedNextProtocols(
{"foo", "bar", "baz"}, GetParam().second);
connect();
if (GetParam().first == SSLContext::NextProtocolType::ALPN ||
GetParam().second == SSLContext::NextProtocolType::ALPN) {
// This is arguably incorrect behavior since RFC7301 states an ALPN protocol
// mismatch should result in a fatal alert, but this is the current behavior
// on all OpenSSL versions/variants, and we want to know if it changes.
expectNoProtocol();
} else if (
GetParam().first == SSLContext::NextProtocolType::ANY &&
GetParam().second == SSLContext::NextProtocolType::ANY) {
#if FOLLY_OPENSSL_IS_110
// OpenSSL 1.1.0 sends a fatal alert on mismatch, which is probably the
// correct behavior per RFC7301
expectHandshakeError();
#else
// Behavior varies for other OpenSSL versions.
expectHandshakeSuccess();
if (client->nextProtoLength == 0) {
// BoringSSL and OpenSSL 1.0.2 before 1.0.2h
expectNoProtocol();
} else {
// OpenSSL 1.0.2h+
expectProtocol("blub");
expectProtocolType({SSLContext::NextProtocolType::NPN,
SSLContext::NextProtocolType::NPN});
}
#endif
} else {
expectProtocol("blub");
expectProtocolType(
{SSLContext::NextProtocolType::NPN, SSLContext::NextProtocolType::NPN});
}
}
TEST_P(NextProtocolNPNOnlyTest, NpnTestClientProtoFilterHit) {
clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickPony);
serverCtx->setAdvertisedNextProtocols(
{"foo", "bar", "baz"}, GetParam().second);
connect();
expectProtocol("ponies");
expectProtocolType();
}
TEST_P(NextProtocolNPNOnlyTest, NpnTestClientProtoFilterMiss) {
clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickNone);
serverCtx->setAdvertisedNextProtocols(
{"foo", "bar", "baz"}, GetParam().second);
connect();
expectProtocol("blub");
expectProtocolType();
}
TEST_P(NextProtocolTest, RandomizedNpnTest) {
TEST_F(NextProtocolTest, RandomizedAlpnTest) {
// Probability that this test will fail is 2^-64, which could be considered
// as negligible.
const int kTries = 64;
clientCtx->setAdvertisedNextProtocols(
{"foo", "bar", "baz"}, GetParam().first);
serverCtx->setRandomizedAdvertisedNextProtocols(
{{1, {"foo"}}, {1, {"bar"}}}, GetParam().second);
clientCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"});
serverCtx->setRandomizedAdvertisedNextProtocols({{1, {"foo"}}, {1, {"bar"}}});
std::set<string> selectedProtocols;
for (int i = 0; i < kTries; ++i) {
......@@ -652,59 +544,10 @@ TEST_P(NextProtocolTest, RandomizedNpnTest) {
0);
string selected((const char*)client->nextProto, client->nextProtoLength);
selectedProtocols.insert(selected);
expectProtocolType();
expectHandshakeSuccess();
}
EXPECT_EQ(selectedProtocols.size(), 2);
}
INSTANTIATE_TEST_CASE_P(
AsyncSSLSocketTest,
NextProtocolTest,
::testing::Values(
NextProtocolTypePair(
SSLContext::NextProtocolType::NPN,
SSLContext::NextProtocolType::NPN),
NextProtocolTypePair(
SSLContext::NextProtocolType::NPN,
SSLContext::NextProtocolType::ANY),
NextProtocolTypePair(
SSLContext::NextProtocolType::ANY,
SSLContext::NextProtocolType::ANY)));
#if FOLLY_OPENSSL_HAS_ALPN
INSTANTIATE_TEST_CASE_P(
AsyncSSLSocketTest,
NextProtocolTLSExtTest,
::testing::Values(
NextProtocolTypePair(
SSLContext::NextProtocolType::ALPN,
SSLContext::NextProtocolType::ALPN),
NextProtocolTypePair(
SSLContext::NextProtocolType::ALPN,
SSLContext::NextProtocolType::ANY),
NextProtocolTypePair(
SSLContext::NextProtocolType::ANY,
SSLContext::NextProtocolType::ALPN)));
#endif
INSTANTIATE_TEST_CASE_P(
AsyncSSLSocketTest,
NextProtocolNPNOnlyTest,
::testing::Values(NextProtocolTypePair(
SSLContext::NextProtocolType::NPN,
SSLContext::NextProtocolType::NPN)));
#if FOLLY_OPENSSL_HAS_ALPN
INSTANTIATE_TEST_CASE_P(
AsyncSSLSocketTest,
NextProtocolMismatchTest,
::testing::Values(
NextProtocolTypePair(
SSLContext::NextProtocolType::NPN,
SSLContext::NextProtocolType::ALPN),
NextProtocolTypePair(
SSLContext::NextProtocolType::ALPN,
SSLContext::NextProtocolType::NPN)));
#endif
#ifndef OPENSSL_NO_TLSEXT
......
......@@ -914,23 +914,21 @@ class BlockingWriteServer : private AsyncSSLSocket::HandshakeCB,
std::unique_ptr<uint8_t[]> buf_;
};
class NpnClient : private AsyncSSLSocket::HandshakeCB,
private AsyncTransportWrapper::WriteCallback {
class AlpnClient : private AsyncSSLSocket::HandshakeCB,
private AsyncTransportWrapper::WriteCallback {
public:
explicit NpnClient(AsyncSSLSocket::UniquePtr socket)
explicit AlpnClient(AsyncSSLSocket::UniquePtr socket)
: nextProto(nullptr), nextProtoLength(0), socket_(std::move(socket)) {
socket_->sslConn(this);
}
const unsigned char* nextProto;
unsigned nextProtoLength;
SSLContext::NextProtocolType protocolType;
folly::Optional<AsyncSocketException> except;
private:
void handshakeSuc(AsyncSSLSocket*) noexcept override {
socket_->getSelectedNextProtocol(
&nextProto, &nextProtoLength, &protocolType);
socket_->getSelectedNextProtocol(&nextProto, &nextProtoLength);
}
void handshakeErr(
AsyncSSLSocket*,
......@@ -950,23 +948,21 @@ class NpnClient : private AsyncSSLSocket::HandshakeCB,
AsyncSSLSocket::UniquePtr socket_;
};
class NpnServer : private AsyncSSLSocket::HandshakeCB,
private AsyncTransportWrapper::ReadCallback {
class AlpnServer : private AsyncSSLSocket::HandshakeCB,
private AsyncTransportWrapper::ReadCallback {
public:
explicit NpnServer(AsyncSSLSocket::UniquePtr socket)
explicit AlpnServer(AsyncSSLSocket::UniquePtr socket)
: nextProto(nullptr), nextProtoLength(0), socket_(std::move(socket)) {
socket_->sslAccept(this);
}
const unsigned char* nextProto;
unsigned nextProtoLength;
SSLContext::NextProtocolType protocolType;
folly::Optional<AsyncSocketException> except;
private:
void handshakeSuc(AsyncSSLSocket*) noexcept override {
socket_->getSelectedNextProtocol(
&nextProto, &nextProtoLength, &protocolType);
socket_->getSelectedNextProtocol(&nextProto, &nextProtoLength);
}
void handshakeErr(
AsyncSSLSocket*,
......
......@@ -53,12 +53,12 @@ class MockAsyncSSLSocket : public AsyncSSLSocket {
MOCK_CONST_METHOD0(good, bool());
MOCK_CONST_METHOD0(readable, bool());
MOCK_CONST_METHOD0(hangup, bool());
MOCK_CONST_METHOD3(
MOCK_CONST_METHOD2(
getSelectedNextProtocol,
void(const unsigned char**, unsigned*, SSLContext::NextProtocolType*));
MOCK_CONST_METHOD3(
void(const unsigned char**, unsigned*));
MOCK_CONST_METHOD2(
getSelectedNextProtocolNoThrow,
bool(const unsigned char**, unsigned*, SSLContext::NextProtocolType*));
bool(const unsigned char**, unsigned*));
MOCK_METHOD1(setReadCB, void(ReadCallback*));
void sslConn(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment