本文主要是介绍tars源码漫谈第30篇------tc_openssl.h/tc_openssl.cpp(openssl操作的封装),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
来看下tc_openssl, 其中的TC_OpenSSL是对开源openssl基本操作的封装, 可以看到:
#include <openssl/ssl.h>
#include <openssl/err.h>
可以将_ssl理解为一个广义socket, 如下是初始化和销毁的相关操作:
TC_OpenSSL::~TC_OpenSSL()
{Release();
}void TC_OpenSSL::Release()
{if (_ssl){SSL_free(_ssl);_ssl = NULL;}_bHandshaked = false;_err = 0;
}void TC_OpenSSL::Init(SSL* ssl, bool isServer)
{assert (_ssl == NULL);_ssl = ssl;_bHandshaked = false;_isServer = isServer;_err = 0;
}
然后握手:
std::string TC_OpenSSL::DoHandshake(const void* data, size_t size)
{assert (!_bHandshaked);assert (_ssl);if (data && size){// 写入ssl内存缓冲区BIO_write(SSL_get_rbio(_ssl), data, size);}ERR_clear_error(); int ret = _isServer ? SSL_accept(_ssl) : SSL_connect(_ssl);if (ret <= 0){_err = SSL_get_error(_ssl, ret);if (_err != SSL_ERROR_WANT_READ){return std::string();}}_err = 0;if (ret == 1){_bHandshaked = true;}// the encrypted data from write bufferstd::string out;TC_Buffer outdata; GetMemData(SSL_get_wbio(_ssl), outdata);if (!outdata.IsEmpty()) {out.assign(outdata.ReadAddr(), outdata.ReadableSize());}return out;
}
然后写,读:
std::string TC_OpenSSL::Write(const void* data, size_t size)
{if (!_bHandshaked)return std::string((const char*)data, size); //握手数据不用加密// 会话数据需加密ERR_clear_error(); int ret = SSL_write(_ssl, data, size); if (ret <= 0) {_err = SSL_get_error(_ssl, ret);return std::string();}_err = 0;TC_Buffer toSend; GetMemData(SSL_get_wbio(_ssl), toSend);return std::string(toSend.ReadAddr(), toSend.ReadableSize());
}bool TC_OpenSSL::Read(const void* data, size_t size, std::string& out)
{bool usedData = false;if (!_bHandshaked){usedData = true;_plainBuf.clear();std::string out2 = DoHandshake(data, size);out.swap(out2);if (_err != 0)return false;if (_bHandshaked); // TODO onHandshake}// 不要用else,因为数据可能紧跟着最后的握手而来if (_bHandshaked){if (!usedData){// 写入ssl内存缓冲区BIO_write(SSL_get_rbio(_ssl), data, size);}string data;if (DoSSLRead(_ssl, data)){_plainBuf.append(data.begin(), data.end());}else{_err = SSL_ERROR_SSL;return false;}}return true;
}
可以看到, 基本都是对广义socket _ssl进行操作。
在tars源码中, 处处可见类似的广义socket, 后面我们会涉及到communicator, 也是抽象物, 也可以理解为广义socket.
这篇关于tars源码漫谈第30篇------tc_openssl.h/tc_openssl.cpp(openssl操作的封装)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!