OpenSSL中SSL_write()与SSL_read()能否同时执行?是否需加锁?
OpenSSL中SSL_read()与SSL_write()的线程安全问题
是的,必须给同一SSL对象上的SSL_read()和SSL_write()加锁,禁止二者并发执行
原因很直白:
- 操作系统原生socket的
read()/write()之所以能并发,是因为TCP读写缓冲区分离,内核会处理好同步。但OpenSSL的SSL*对象内部维护着TLS状态机、加密上下文、握手会话等共享数据结构,不管是读还是写操作,都可能修改这些状态——甚至在某些场景下(比如重握手),SSL_write()会主动发起读操作,SSL_read()也可能触发写(比如发送ACK或握手响应),两个操作会互相干扰共享状态。 - 举个实际场景:如果一个线程在调用
SSL_write()时触发了重握手,正在读取对方的握手消息;另一个线程同时调用SSL_read()处理应用数据,就会导致SSL对象的状态被同时修改,直接引发数据乱码、内存错误或者连接异常断开。 - 按照OpenSSL的设计规则,同一个SSL连接对应的
SSL*对象,所有操作都必须序列化执行。不同的SSL对象之间不需要额外加锁(OpenSSL已经对全局共享资源做了线程安全处理)。
正确的处理方式:
- 给每个
SSL*对象绑定一个独立的互斥锁,在调用任何SSL相关操作(包括SSL_read()、SSL_write()、SSL_connect()、SSL_accept()等)之前加锁,操作完成后解锁。 - 注意不要把锁加在socket层面,socket本身的读写是安全的,问题核心在于SSL对象的共享状态。
内容的提问来源于stack exchange,提问作者benrush
相关产品推荐
相关产品推荐

