optimize and test openssl used in acl ssl module

This commit is contained in:
zhengshuxin 2022-08-21 22:01:51 +08:00
parent 8e6d37f1a0
commit 9fbdfc6502
16 changed files with 98 additions and 43 deletions

View File

@ -70,6 +70,9 @@ private:
mbedtls_conf& conf_;
void* ssl_;
void* ssn_;
char* ebf_;
const char* ssl_strerror(int err);
private:
static int sock_read(void *ctx, unsigned char *buf, size_t len);

View File

@ -1,4 +1,4 @@
base_path = ../../..
include ../../Makefile.in
PROG = aio_client
EXTLIBS += -ldl -lz
EXTLIBS += -L/usr/local/lib -lssl -lcrypto -ldl -lz

View File

@ -3,6 +3,7 @@
#include "lib_acl.h"
#include "../../util.h"
#include "acl_cpp/lib_acl.hpp"
#include "acl_cpp/stream/openssl_conf.hpp"
typedef struct
{
@ -65,6 +66,8 @@ public:
*/
bool read_callback(char*, int len)
{
//printf(">>>>read len=%d\n", len);
nread_ += len;
ctx_->nread_total++;
@ -149,20 +152,23 @@ public:
return false;
}
printf(">>>%s: begin handshake\n", __FUNCTION__);
// 尝试进行 SSL 握手
if (!hook->handshake()) {
logger_error("ssl handshake failed");
logger_error("%s: ssl handshake failed", __FUNCTION__);
return false;
}
printf(">>>%s: end handshake\r\n", __FUNCTION__);
// SSL 握手还未完成,等待本函数再次被触发
if (!hook->handshake_ok()) {
printf(">>>%s: not handshake ok\r\n", __FUNCTION__);
return true;
}
// 如果 SSL 握手已经成功,则开始读数据
printf("ssl handshake ok\r\n");
printf(">>>%s: ssl handshake ok\r\n", __FUNCTION__);
// 由 reactor 模式转为 proactor 模式,从而取消
// read_wakeup 回调过程
@ -230,8 +236,15 @@ private:
return false;
}
// 开始异步 SSL 握手过程,满足可读条件时将触发 read_wakeup
client_->read_wait(10);
if (ssl->handshake_ok()) {
printf("%s: ssl handshake ok\r\n", __FUNCTION__);
client_->disable_read();
return begin_run();
} else {
// 开始异步 SSL 握手过程,满足可读条件时将触发
// read_wakeup
client_->read_wait(10);
}
return true;
}
@ -308,7 +321,7 @@ int main(int argc, char* argv[])
{
bool use_kernel = false, use_ssl = false;
IO_CTX ctx;
acl::string libpath("../libpolarssl.so");
acl::string libpath;
acl::sslbase_conf* ssl_conf = NULL;
int ch;
int check_fds_inter = 10, delay_ms = 100;
@ -405,6 +418,8 @@ int main(int argc, char* argv[])
} else {
printf("load %s error\r\n", libpath.c_str());
}
} else if (libpath.find("libssl") != NULL) {
ssl_conf = new acl::openssl_conf(false);
}
}

View File

@ -1,4 +1,4 @@
base_path = ../../..
include ../../Makefile.in
PROG = aio_server
EXTLIBS += -ldl -lz
EXTLIBS += -L/usr/local/lib -lssl -lcrypto -ldl -lz

View File

@ -13,6 +13,7 @@
#include "acl_cpp/stream/aio_istream.hpp"
#include "acl_cpp/stream/aio_listen_stream.hpp"
#include "acl_cpp/stream/aio_socket_stream.hpp"
#include "acl_cpp/stream/openssl_conf.hpp"
static int __max = 0;
static int __timeout = 0;
@ -116,6 +117,7 @@ public:
client_->get_handle().stop();
}
//printf(">>data=%s\n", data);
// 向远程客户端回写收到的数据
client_->write(data, len);
@ -209,6 +211,7 @@ public:
// 将客户端置于读监听状态以触发 read_wakeup 回调过程,
// SSL 握手过程将在 read_wakeup 中完成
printf(">>>begin wait for ssl handshake\r\n");
client->read_wait(__timeout);
}
@ -225,7 +228,7 @@ public:
static void usage(const char* procname)
{
printf("usage: %s -h[help]\r\n"
" -d path_to_polarssl\r\n"
" -d path_to_polarssl_or_mbedtls\r\n"
" -l server_addr[ip:port, default: 127.0.0.1:9800]\r\n"
" -L line_max_length\r\n"
" -t timeout\r\n"
@ -241,7 +244,7 @@ int main(int argc, char* argv[])
{
// 事件引擎是否采用内核中的高效模式
bool use_kernel = false, use_polarssl = true;
acl::string key_file, cert_file, libpath("../libpolarssl.so");
acl::string key_file, cert_file, libpath;
acl::string addr("127.0.0.1:9800");
int ch, delay_ms = 100, check_fds_inter = 10;
@ -315,6 +318,9 @@ int main(int argc, char* argv[])
cert_file.clear();
printf("load %s error\r\n", libpath.c_str());
}
} else if (libpath.find("libssl") != NULL) {
__ssl_conf = new acl::openssl_conf(true);
printf("use openssl_conf now\r\n");
}
// 当私钥及证书都存在时才采用 SSL 通信方式
@ -350,9 +356,6 @@ int main(int argc, char* argv[])
}
}
if (__ssl_conf) {
}
// 构建异步引擎类对象
acl::aio_handle handle(use_kernel ? acl::ENGINE_KERNEL : acl::ENGINE_SELECT);

View File

@ -10,3 +10,4 @@
// TODO: 在此处引用程序要求的附加头文件
#include "acl_cpp/lib_acl.hpp"
#include "acl_cpp/stream/openssl_conf.hpp"

View File

@ -14,4 +14,4 @@ ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin)
endif
CFLAGS += -I../..
EXTLIBS += -lz -ldl
EXTLIBS += -L/usr/local/lib -lssl -lcrypto -lz -ldl

View File

@ -6,8 +6,8 @@
static void usage(const char* procname)
{
printf("usage: %s -h [help]\r\n"
" -f path of libpolarssl.so\r\n"
" -s server_addr [default: 127.0.0.1:8888]\r\n"
" -f path of mbedtls or polarss\r\n"
" -s server_addr [default: 127.0.0.1:1443]\r\n"
" -k [keep alive, default: false]\r\n"
" -L data_length [default: 1024]\r\n"
" -c cocurrent [default: 1]\r\n"
@ -20,7 +20,7 @@ int main(int argc, char* argv[])
int ch, cocurrent = 1, count = 10, length = 1024;
bool keep_alive = false, use_ssl = false;
acl::string server_addr("127.0.0.1:1443");
acl::string domain, libpath("libpolarssl.so");
acl::string domain, libpath;
acl::acl_cpp_init();
acl::log::stdout_open(true);
@ -79,7 +79,7 @@ int main(int argc, char* argv[])
return 1;
}
} else {
use_ssl = false;
ssl_conf = new acl::openssl_conf(false);
}
@ -90,7 +90,7 @@ int main(int argc, char* argv[])
struct timeval begin;
gettimeofday(&begin, NULL);
#if 0
#if 1
std::list<https_client*> threads;
for (int i = 0; i < cocurrent; i++) {

View File

@ -10,8 +10,9 @@
// TODO: 在此处引莹<E5BC95>序要求的附加头文件
#include "acl_cpp/lib_acl.hpp"
#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"
#include "acl_cpp/stream/openssl_conf.hpp"
#ifdef WIN32
#define snprintf _snprintf

View File

@ -14,4 +14,4 @@ ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin)
endif
CFLAGS += -I../..
EXTLIBS += -lz -ldl
EXTLIBS += -L/usr/local/lib -lssl -lcrypto -lz -ldl

View File

@ -11,6 +11,7 @@ https_request::https_request(acl::sslbase_conf* ssl_conf, const char* addr,
printf("server addr: %s\r\n", addr);
printf("host: %s\r\n", host);
printf("url: %s\r\n", url);
printf("ssl_conf: %p\r\n", ssl_conf);
printf("\r\n");
if (ssl_conf) {

View File

@ -5,8 +5,8 @@
static void usage(const char* procname)
{
printf("usage: %s -h [help]\r\n"
" -f path of libpolarssl.so\r\n"
" -s server_addr [default: 127.0.0.1:8888]\r\n"
" -f path of mbedtls or polarssl\r\n"
" -s server_addr [default: 127.0.0.1:1443]\r\n"
" -H host\r\n"
" -U url\r\n"
" -L data_length [default: 1024]\r\n"
@ -20,7 +20,7 @@ int main(int argc, char* argv[])
int ch, cocurrent = 1, count = 10;
bool use_ssl = false;
acl::string server_addr("127.0.0.1:1443"), host;
acl::string libpath("libpolarssl.so");
acl::string libpath;
acl::string url("/");
acl::acl_cpp_init();
@ -73,7 +73,7 @@ int main(int argc, char* argv[])
return 1;
}
} else {
use_ssl = false;
ssl_conf = new acl::openssl_conf(false);
}
if (host.empty()) {

View File

@ -10,8 +10,9 @@
// TODO: 在此处引莹<E5BC95>序要求的附加头文件
#include "acl_cpp/lib_acl.hpp"
#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"
#include "acl_cpp/stream/openssl_conf.hpp"
#ifdef WIN32
#define snprintf _snprintf

View File

@ -79,6 +79,6 @@ bool http_servlet::doPost(acl::HttpServletRequest& req,
// 发送 http 响应体,因为设置了 chunk 传输模式,所以需要多调用一次
// res.write 且两个参数均为 0 以表示 chunk 传输数据结束
bool ret = res.write(buf) && res.write(NULL, 0) && keep_alive;
printf(">>>write ret: %s\r\n", ret ? "ok":"err");
printf(">>>write %s\r\n", ret ? "ok":"error");
return ret;
}

View File

@ -39,6 +39,7 @@
# define SSL_GET_VERIFY_RESULT_NAME "mbedtls_ssl_get_verify_result"
# define SSL_GET_PEER_CERT_NAME "mbedtls_ssl_get_peer_cert"
# define SSL_GET_BYTES_AVAIL_NAME "mbedtls_ssl_get_bytes_avail"
# define SSL_STRERROR "mbedtls_strerror"
typedef void (*ssl_init_fn)(mbedtls_ssl_context*);
typedef void (*ssl_free_fn)(mbedtls_ssl_context*);
@ -57,6 +58,7 @@ typedef int (*ssl_close_notify_fn)(mbedtls_ssl_context*);
typedef unsigned (*ssl_get_verify_result_fn)(const mbedtls_ssl_context*);
typedef const mbedtls_x509_crt *(*ssl_get_peer_cert_fn)(const mbedtls_ssl_context*);
typedef size_t (*ssl_get_bytes_avail_fn)(const mbedtls_ssl_context*);
typedef void (*ssl_strerror_fn)(int, char*, size_t);
static ssl_init_fn __ssl_init;
static ssl_free_fn __ssl_free;
@ -72,6 +74,7 @@ static ssl_close_notify_fn __ssl_close_notify;
static ssl_get_verify_result_fn __ssl_get_verify_result;
static ssl_get_peer_cert_fn __ssl_get_peer_cert;
static ssl_get_bytes_avail_fn __ssl_get_bytes_avail;
static ssl_strerror_fn __ssl_strerror;
extern ACL_DLL_HANDLE __tls_dll; // defined in mbedtls_conf.cpp
@ -101,6 +104,7 @@ bool mbedtls_load_io(void)
LOAD(SSL_GET_VERIFY_RESULT_NAME, ssl_get_verify_result_fn, __ssl_get_verify_result);
LOAD(SSL_GET_PEER_CERT_NAME, ssl_get_peer_cert_fn, __ssl_get_peer_cert);
LOAD(SSL_GET_BYTES_AVAIL_NAME, ssl_get_bytes_avail_fn, __ssl_get_bytes_avail);
LOAD(SSL_STRERROR, ssl_strerror_fn, __ssl_strerror);
return true;
}
@ -120,6 +124,7 @@ bool mbedtls_load_io(void)
# define __ssl_get_verify_result ::mbedtls_ssl_get_verify_result
# define __ssl_get_peer_cert ::mbedtls_ssl_get_peer_cert
# define __ssl_get_bytes_avail ::mbedtls_ssl_get_bytes_avail
# define __ssl_strerror ::mbedtls_strerror
#endif
@ -131,6 +136,7 @@ mbedtls_io::mbedtls_io(mbedtls_conf& conf, bool server_side,
, conf_(conf)
, ssl_(NULL)
, ssn_(NULL)
, ebf_(NULL)
{
#ifdef HAS_MBEDTLS
conf.init_once();
@ -153,6 +159,9 @@ mbedtls_io::~mbedtls_io(void)
acl_myfree(ssn_);
}
#endif
if (ebf_) {
acl_myfree(ebf_);
}
}
void mbedtls_io::destroy(void)
@ -162,6 +171,17 @@ void mbedtls_io::destroy(void)
}
}
const char* mbedtls_io::ssl_strerror(int err)
{
size_t len = 256;
if (ebf_ == NULL) {
ebf_ = (char*) acl_mymalloc(len);
}
ebf_[0] = 0;
__ssl_strerror(err, ebf_, len);
return ebf_;
}
#ifdef DEBUG_SSL
static void my_debug( void *ctx, int level acl_unused, const char *str )
{
@ -268,7 +288,8 @@ bool mbedtls_io::on_close(bool alive)
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE ) {
logger_warn("ssl_close_notify error: -0x%04x", ret);
logger_warn("ssl_close_notify error: -0x%04x, %s",
ret, ssl_strerror(ret));
return false;
}
}
@ -298,7 +319,8 @@ bool mbedtls_io::handshake(void)
if (ret != MBEDTLS_ERR_SSL_WANT_READ
&& ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
logger_error("ssl_handshake failed: -0x%04x", -ret);
logger_error("ssl_handshake failed: -0x%04x, %s",
-ret, ssl_strerror(ret));
return false;
}

View File

@ -117,7 +117,7 @@ bool openssl_io::on_close(bool alive)
SSL_set_shutdown((SSL*) ssl_, mode);
int ret = SSL_shutdown((SSL*) ssl_);
if (ret == 1 && ERR_peek_error() == 0) {
if (ret == 1 || ERR_peek_error() == 0) {
return true;
}
@ -134,16 +134,17 @@ bool openssl_io::on_close(bool alive)
int openssl_io::read(void* buf, size_t len)
{
size_t total_bytes = 0;
size_t nbytes = 0;
char* ptr = (char*) buf;
while (total_bytes < len) {
while (len > 0) {
int ret = SSL_read((SSL*) ssl_, ptr, len);
if (ret > 0) {
total_bytes += ret;
nbytes += ret;
ptr += ret;
len -= ret;
if (!nblock_) {
if (nblock_) {
break;
}
continue;
@ -168,26 +169,32 @@ int openssl_io::read(void* buf, size_t len)
break;
}
return total_bytes > 0 ? (int) total_bytes : ACL_VSTREAM_EOF;
if (len == 0) {
this->stream_->read_ready = 1;
}
return nbytes > 0 ? (int) nbytes : ACL_VSTREAM_EOF;
}
int openssl_io::send(const void* buf, size_t len)
{
size_t total_bytes = 0;
int bytes_written = 0;
size_t nbytes = 0;
char* ptr = (char*) buf;
while (total_bytes < len) {
bytes_written = SSL_write((SSL*) ssl_, buf, len);
if (bytes_written > 0) {
total_bytes += bytes_written;
while (len > 0) {
int ret = SSL_write((SSL*) ssl_, ptr, len);
if (ret > 0) {
nbytes += ret;
ptr += ret;
len -= ret;
if (!nblock_) {
if (nblock_) {
break;
}
continue;
}
int err = SSL_get_error((SSL*) ssl_, bytes_written);
int err = SSL_get_error((SSL*) ssl_, ret);
switch (err) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
@ -196,9 +203,10 @@ int openssl_io::send(const void* buf, size_t len)
default:
break;
}
break;
}
return total_bytes > 0 ? (int) total_bytes : ACL_VSTREAM_EOF;
return nbytes > 0 ? (int) nbytes : ACL_VSTREAM_EOF;
}
} // namespace acl