C++ WebRTC DTLS-SRTP OpenSSL服务器握手失败
这是我在OpenSSL服务器模式下的过程, SSL和BIO变量的初始化部分:C++ WebRTC DTLS-SRTP OpenSSL服务器握手失败,c++,openssl,webrtc,wireshark,dtls,C++,Openssl,Webrtc,Wireshark,Dtls,这是我在OpenSSL服务器模式下的过程, SSL和BIO变量的初始化部分: map<int, SSL> m_SSLMap; map<int, BIO> m_BioWriteMap; map<int, BIO> m_BioReadMap; int InitializeServerNegotiationMode(int iFd) { SSL *pServSslFd; BIO *pWb, *pRb; pServSs
map<int, SSL> m_SSLMap;
map<int, BIO> m_BioWriteMap;
map<int, BIO> m_BioReadMap;
int InitializeServerNegotiationMode(int iFd)
{
SSL *pServSslFd;
BIO *pWb, *pRb;
pServSslFd = SSL_new(m_pCtx);
assert(pServSslFd);
if ( SSL_version(pServSslFd) == DTLS1_VERSION)
{
pWb = BIO_new(BIO_s_mem());
pRb = BIO_new(BIO_s_mem());
assert(pWb);
assert(pRb);
SSL_set_bio(pServSslFd, pRb, pWb);
SSL_set_accept_state(pServSslFd);
}
m_SSLMap[iFd] = *pServSslFd;
m_BioReadMap[iFd] = *pRb;
m_BioWriteMap[iFd] = *pWb;
return INITIALIZATION_SUCCESS;
}
map m_SSLMap;
地图m_BioWriteMap;
地图m_BioredMap;
int InitializeServerNegotiationMode(int iFd)
{
SSL*pServSslFd;
生物*pWb,*pRb;
pServSslFd=SSL_new(m_pCtx);
断言(pServSslFd);
if(SSL_版本(pServSslFd)=DTLS1_版本)
{
pWb=BIO_new(BIO_s_mem());
pRb=BIO_new(BIO_s_mem());
(普华永道);
断言(pRb);
SSL_set_bio(pServSslFd、pRb、pWb);
SSL设置接受状态(pServSslFd);
}
m_SSLMap[iFd]=*pServSslFd;
m_BioReadMap[iFd]=*pRb;
m_BioWriteMap[iFd]=*pWb;
返回初始化成功;
}
DTLS数据到达服务器时的服务器模式协商操作:
int ServerModeDTLSNegotiation(int iChannel, const char *pBuff, const int iLen, int iFd)
{
SSL *pServSslFd;
BIO *pRbio;
BIO *pWbio;
pServSslFd = &m_SSLMap[iFd];
pRbio = &m_BioReadMap[iFd];
pWbio = &m_BioWriteMap[iFd];
char buff[4096];
memset(buff, 0, strlen(buff));
BIO_write(pRbio, pBuff, iLen);
if(!SSL_is_init_finished(pServSslFd))
{
int iRet = SSL_do_handshake(pServSslFd);
}
int iNewLen = BIO_read(pWbio, buff, 2048);
if(iNewLen>0)
{
char *pNewData = new char[iNewLen+1];
for(int i=0;i<iNewLen;i++)
pNewData[i] = buff[i];
m_pEventHandler->SendReply(iChannel, (unsigned char *)pNewData, iNewLen);
}
else
{
printf("[DTLS]:: HandShaking Response failed for this data,
return -1;
}
return NEGOTIATION_SUCCESS;
}
int-ServerModeDTLSNegotiation(int-iChannel,const-char*pBuff,const-int-iLen,int-iFd)
{
SSL*pServSslFd;
BIO*pRbio;
BIO*pWbio;
pServSslFd=&m_SSLMap[iFd];
pRbio=&m_生物地图[iFd];
pWbio=&m_BioWriteMap[iFd];
字符buff[4096];
memset(buff,0,strlen(buff));
BIO_写入(pRbio、pBuff、iLen);
如果(!SSL_是_init_finished(pServSslFd))
{
int-iRet=SSL\u-do\u握手(pServSslFd);
}
int iNewLen=BIO_read(pWbio,buff,2048);
如果(iNewLen>0)
{
char*pNewData=新字符[iNewLen+1];
对于(int i=0;iSendReply(iChannel,(unsigned char*)pNewData,iNewLen);
}
其他的
{
printf(“[DTLS]::此数据的握手响应失败,
返回-1;
}
回报谈判成功;
}
这里我附上Wireshark TCP转储,以便更好地监控该问题
现在,我对SSL_CTX变量的初始化很有信心。因为,有时握手成功地协商每个端口。但有时握手在一个或两个端口失败。我花了5天的时间来解决Google Chrome的WebRTC DTLS服务器模式协商。但我还没有找到这个问题的根本原因。的链接TCP转储不工作。 无论如何,您的解决方案似乎应该有效。
由于它是一个服务器程序,它肯定是多线程的。但是初始化SSL变量或在没有锁定的情况下执行握手过程是非常危险的。在这种情况下,如果这两种方法由多线程处理,那么会发生很多事情。
我的建议是为这些方法添加锁定机制。事实上,我很久以前就解决了这个问题。是的,你是对的。我通过添加互斥锁解决了这个问题。@Light Yagami,你能看一下吗?如果你能看一下,我会很感激的。你必须调用SSL\u Do\u握手(pServSslFd)吗;在服务器模式下?我认为在握手之前,服务器应该暗示,或者您应该检查握手是否完成,并得出数据是握手消息的一部分的结论?