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 buffer
    std::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.

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值