使用SSL + NIO时的线程安全性

3

有一些有用的信息可以帮助实现使用Java的NIO(SocketChannel和SSLEngine)SSL,而不是使用netty等框架。

我正在尝试设计一个SSL实现,它可以与阻塞/非阻塞通道一起工作,并且遇到了一些基本问题。

关于线程安全性的问题,当操作appData和Net缓冲区时,没有太多信息需要处理。根据SSLEngine的文档:

"有两个并发问题需要注意:

wrap()unwrap()方法可能同时执行。

SSL/TLS协议使用有序数据包。应用程序必须注意确保生成的数据包按顺序传递。如果数据包乱序,可能会导致意外或致命的结果。"

这对阻塞和非阻塞都适用吗?能否有人解释一下?谢谢。

此外,设置初始缓冲区大小的一般建议似乎基于(session.getApplicationBufferSize()/getPacketBufferSize()),如何设置这些值?这些是否比使用标准缓冲区大小(例如32k)更好?

1个回答

1
  1. 通常情况下,您不会在多个线程中执行SSLEngine操作,因此这个问题不会出现。唯一需要使用另一个线程的时候是执行SSLEngine任务时,但这并不使用SSLEngine

这是否适用于阻塞和非阻塞模式?

  1. 是的,当然可以。

设置初始缓冲区大小的一般建议似乎基于(session.getApplicationBufferSize()/getPacketBufferSize()),如何设置这些值?

  1. 将网络缓冲区大小设置为getPacketBufferSize(),将应用程序缓冲区大小设置为getApplicationBufferSize()

与32k左右的标准缓冲区大小相比,这些缓冲区大小更好吗?

  1. 如果您愿意,可以使用不同的缓冲区大小,但为什么呢?您可能会浪费太大的空间来存储过大的缓冲区,或者提供太小以致无法使用的缓冲区。

谢谢@EJP。像往常一样,您对此话题的评论非常有帮助。请您详细阐述一下可能出现的并发问题,因为通常我不会看到这些问题被明确处理:“wrap()和unwrap()方法可能会同时执行。SSL/TLS协议采用有序数据包。应用程序必须小心确保生成的数据包按顺序传递。如果数据包乱序到达,则可能会出现意外或致命错误。” 客户端实例化SSLEngine时是否需要明确处理此问题? - Krishna Mothukuri
“May execute concurrently of each other” 的意思是 可以同时执行它们。如果你只使用一个线程,这也是 NIO 的全部意义,那么就没有数据包顺序问题需要处理。 - user207421
请最后确认一下,再次引用SSLEngine文档中的内容:“通过将SSL/TLS抽象与I/O传输机制分离,SSLEngine可用于各种I/O类型,例如非阻塞I/O(轮询),可选择的非阻塞I/O,Socket和传统的Input/OutputStreams,本地的ByteBuffers或字节数组等。”这是否意味着SSLEngine可以在除NIO之外的其他传输中使用,例如常规套接字?难道不是应该使用SSLSocket进行基于常规套接字的阻塞IO的SSL,而使用SSLEngine进行NIO(阻塞IO)? - Krishna Mothukuri
@KrishnaMothukuri 是的, 你可以使用 SSLEngine 和普通的 Sockets, 但有些困难。不过这么做没有多大意义。在我看来 SSLEngine 的设计有点牵强附会。他们本应该提供一个 SSLSocketChannel, 或者两者都提供。大部分不能这么做的原因都站不住脚。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接