Web服务器为了支持https访问,通常会使用第三方库openssl实现,而且为了高性能采用异步事件驱动模型,因此连接套接字被设为非阻塞类型,本文在nginx ssl模块的基础上,简化提取它的核心框架,使用面向对象的方式描述,从握手、读写和关闭3个方面进行了分析,由于这3个操作都是异步的,因此操作失败后要调用SSL_get_error来获取错误码,有如下4种情况。
● SSL_ERROR_WANT_READ:操作没完成,需要在下一次读事件中继续
● SSL_ERROR_WANT_WRITE:操作没完成,需要在下一次写事件中继续
● SSL_ERROR_ZERO_RETURN:连接正常关闭
● 其它:连接出错
下面的示例代码使用了libevent实现IO事件驱动,connection表示普通连接类,假设已经处理好了http数据的逻辑,实现在成员函数handle_read和handle_write内,虚函数recv、send和close分别调用系统的API recv、send和close;ssl_conn_t表示安全连接类,由于只是IO处理不同:收到数据后解密,发送数据前加密。解密后的操作和connection是一样的,因此ssl_conn_t继承connection,重写了recv、send和close,其中close调用了shutdown。
异步握手
当在SSL端口接受到连接时,首先要进行握手,握手成功后才能收发数据,如果握手失败而且返回前2种错误码,那么要在下一次操作中继续握手。
1
void ssl_conn_t::empty_handler(short ev)
2
{
3
}
4
5
void ssl_conn_t::handshake_handler(short ev)
6
{
7
handshake();
8
}
9
10
void ssl_conn_t::handshake()
11
{
12
int ret = do_handshake();
13
14
switch(ret){
15
case OP_OK:
16
read_handler_ = &connection::handle_read;
17
write_handler_ = &connection::handle_write;
18
handle_read(EV_READ);
19
break;
20
21
}
22
}
23
24
int ssl_conn_t::do_handshake()
25
{
26
ssl_clear_error();
27
28
int ret = SSL_do_handshake(ssl_);
29
if(1==ret){
30

31
return OP_OK;
32


1087

被折叠的 条评论
为什么被折叠?



