-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Server support ALPN with OpenSSL #2102
Conversation
Client端的实现还有点问题,暂时先提交Server端的代码。还请大佬们给Review下~ |
src/brpc/adaptive_protocol_type.h
Outdated
@@ -44,6 +44,7 @@ class AdaptiveProtocolType { | |||
public: | |||
explicit AdaptiveProtocolType() : _type(PROTOCOL_UNKNOWN) {} | |||
explicit AdaptiveProtocolType(ProtocolType type) : _type(type) {} | |||
explicit AdaptiveProtocolType(butil::StringPiece name) { AssignWithString(name); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里可以直接调用operator=(name),就不用改那么多了
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好的,这个我改下
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/details/ssl_helper.cpp
Outdated
name = name.substr(0, CHAR_MAX); | ||
} | ||
|
||
char lenght = static_cast<char>(name.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lenght -> length
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/details/ssl_helper.cpp
Outdated
@@ -521,6 +558,10 @@ SSL_CTX* CreateServerSSLContext(const std::string& certificate, | |||
|
|||
#endif // OPENSSL_NO_DH | |||
|
|||
// Set ALPN callback to choose application protocol. | |||
if (SetServerALPNCallback(ssl_ctx.get(), alpns) != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
如果alpns为空串,则不需要SetServerALPNCallback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/server.h
Outdated
@@ -686,6 +688,10 @@ friend class Controller; | |||
ServerOptions _options; | |||
butil::EndPoint _listen_addr; | |||
|
|||
// ALPN extention protocol-list format. Server initialize this with alpns options. | |||
// OpenSSL API use this variable to avoid conversion at each handshake. | |||
std::string _row_alpns; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
row在这里是什么意思?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
和options.alpns做区分,这儿为格式转化后TLS使用的原始数据
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
row -> raw?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是的,手误~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/server.cpp
Outdated
@@ -642,6 +642,33 @@ int Server::InitializeOnce() { | |||
return 0; | |||
} | |||
|
|||
int Server::InitALPNOptions(ServerSSLOptions* options) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里options不会被修改
int Server::InitALPNOptions(const ServerSSLOptions* options);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/server.cpp
Outdated
butil::StringSplitter split(alpns.data(), alpns.data() + alpns.size(), ','); | ||
|
||
std::string row_protocol; | ||
for (; split; split++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (butil::StringSplitter split(alpns.data(), ','); split; ++split) {
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
写法参考的src/brpc/details/ssl_helper.cpp文件中ParseSSLProtocols函数里的实现
可能的1个改动点:split++ => ++split
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
split在for 循环外并没有用到,应该包在for 里面。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/server.cpp
Outdated
@@ -1913,7 +1946,7 @@ int Server::AddCertificate(const CertInfo& cert) { | |||
ssl_ctx.filters = cert.sni_filters; | |||
ssl_ctx.ctx = std::make_shared<SocketSSLContext>(); | |||
SSL_CTX* raw_ctx = CreateServerSSLContext(cert.certificate, cert.private_key, | |||
_options.ssl_options(), &ssl_ctx.filters); | |||
_options.ssl_options(), &_row_alpns, &ssl_ctx.filters); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
代码缩进
SSL_CTX* raw_ctx = CreateServerSSLContext(
cert.certificate, cert.private_key,
_options.ssl_options(), &_row_alpns, &ssl_ctx.filters);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/details/ssl_helper.cpp
Outdated
@@ -441,6 +441,42 @@ static int SetSSLOptions(SSL_CTX* ctx, const std::string& ciphers, | |||
return 0; | |||
} | |||
|
|||
static int ServerALPNCallback(SSL* ssl, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
代码缩进
static int ServerALPNCallback(
SSL* ssl, const unsigned char** out, unsigned char* outlen,
const unsigned char* in, unsigned int inlen, void* arg)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好像第1个参数都没单独换行。是说第2、3行没有和第1个参数缩进对齐?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
嗯
static int ServerALPNCallback(SSL* ssl, const unsigned char** out, unsigned char* outlen,
const unsigned char* in, unsigned int inlen, void* arg);
或者这样
static int ServerALPNCallback(
SSL* ssl, const unsigned char** out, unsigned char* outlen,
const unsigned char* in, unsigned int inlen, void* arg)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/details/ssl_helper.cpp
Outdated
if (select_result == OPENSSL_NPN_NEGOTIATED) { | ||
return SSL_TLSEXT_ERR_OK; | ||
} | ||
return SSL_TLSEXT_ERR_NOACK; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return select_result == OPENSSL_NPN_NEGOTIATED ? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/brpc/details/ssl_helper.cpp
Outdated
@@ -833,6 +874,23 @@ void Print(std::ostream& os, X509* cert, const char* sep) { | |||
os << butil::StringPiece(bufp, len); | |||
} | |||
|
|||
std::string ALPNProtocolToString(const AdaptiveProtocolType& protocol) { | |||
std::string name = protocol.name(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
用butil::StringPiece
butil::StringPiece name(protocol.name());
if (name.starts_with("http")) {
name.set("http/1.1");
}
....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
能加一下文档说明下这个实现逻辑,以及补充一下UT么? 牵涉到协议实现,希望尽量能严谨和完整一点 |
6f3f1e3
to
bfc4fa5
Compare
@chenzhangyi 可以的,文档&UT后续我都补充下。Client端还没实现完,UT可能需要使用OpenSSL命令来验证协商是否正确 |
UT编译失败了: |
const_cast<unsigned char**>(out), outlen, | ||
reinterpret_cast<const unsigned char*>(alpns->data()), alpns->size(), | ||
in, inlen); | ||
return (select_result == OPENSSL_NPN_NEGOTIATED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
如果没选择到,返回SSL_TLSEXT_ERR_NOACK会直接断开SSL链接吗?
和返回SSL_TLSEXT_ERR_ALERT_FATAL区别是啥?
@@ -642,6 +642,31 @@ int Server::InitializeOnce() { | |||
return 0; | |||
} | |||
|
|||
int Server::InitALPNOptions(const ServerSSLOptions* options) { | |||
if (options == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
如果openssl版本不支持,这里就直接报错?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
并不是 这儿是判断ServerSSLOptions是否为nullptr
c82a471
to
1ecfa2c
Compare
@wwbmmm 编译失败已解决,同时补充了本次功能的UT和文档 |
docs/cn/server.md
Outdated
|
||
```c++ | ||
ServerSSLOptions ssl_options; | ||
ssl_options->alpns = "http, h2, baidu_std"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
应该是ssl_options.alpns吧?
docs/cn/server.md
Outdated
const ::example::EchoRequest* request, | ||
::example::EchoResponse* response, | ||
::google::protobuf::Closure* done) { | ||
void Echo(::google::protobuf::RpcController* cntl_base, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
无关的改动,有点多
@wwbmmm 请问下PR还有需要修改的地儿嘛 |
LGTM |
@wwbmmm 大佬 求问考虑合入了嘛~ |
What problem does this PR solve?
Issue Number: #1991
Problem Summary: 当前bRPC中进行SSL/TLS握手阶段没有支持ALPN扩展协议。
What is changed and the side effects?
Changed: 在ServerSSLOptions中扩展ALPN配置项。
Side effects:
Performance effects(性能影响): 当用户在ServerSSLOptions中设置ALPN选项时,server启动时会将ALPN选项序列化为标准格式并设置好回调函数。在SSL/TLS握手阶段会调用回调函数选择匹配的协议并返回给客户端。
Breaking backward compatibility(向后兼容性): 是
Check List: