最近对https有兴趣,所以决定开始学习使用openssl。
所谓https, 是建立在安全通道之上的http协议。http 与 https的区别:
普通http模式:
http client ==> client socket ===> server socket ==> httpserver
https 模式:
http client ==> SSL client ==> client socket ===> serversocket ==> SSL server ==> http server
为什么要搞openssl呢?
对于高性能服务器的开发,很多人都封装了自己的框架。而且,很多人也希望能增加对https的支持。而自己开发一套ssl库,成本、风险都很高。
有什么问题?为什么不能直接使用?
在复用能力、性能、和复杂度之间,各个框架都会有权衡。所以,与网络io相关的模块要想在这些框架中应用,还是有些麻烦的。不巧的是,openssl的常见使用方法就是使用openssl库里边内置的socketBIO。不过还好,路并没有被堵死,他是支持异步io的,这样,我们就可以通过替换掉socketBIO的办法来达到我们的目的。
先来说说openssl中BIO的机制:
BIO工作模式是以一种链式方式工作的,每个BIO对象就是链条上的一个环节,接收上一个环节的调用,经过过滤,向下一个环节发起调用。调用的功能包括BIO对象创建,销毁,读、写、控制。如下图:
这里的箭头就代表调用关系。包括读、写、控制。
写数据自上而下是很自然的,通过SSL编码,然后BIO调用框架的接口发送数据,这是毫无疑问的。
问题在读操作上。读的行为不该由应用发起。如果以这种方式工作,就会破坏大部分高性能的网络框架结构,导致低效的网络io。而且,也不符合网络数据传输的自然规则:此端的数据是否能收到和收到多少,取决于彼端发送者和传输链路!!!
那么我们需要一个什么样SSL层呢?
对于一个应用来说,当然是越简单越好:设想有这样的SSL层,有数据要发的时候,调用SSL层的接口发出去;有数据进来的时候,SSL层调用应用提供的接口传进来,应用于SSL层之间都是明文通信。这样足够简单了吧。
而对于网络框架来说,就是SSL层有数据要发,传给网络框架,有数据来了,调用SSL层的接口去处理。因为高性能的框架通常就是这样为应用提供服务的,SSL层对他来讲也是一个应用而已。所以,我们需要的SSL看起来像下面这个样子: