如何处理SSL连接过早关闭
我正在编写一个代理 SSL 连接的代理服务器,对于正常流量而言,它一切正常。但是,当存在大文件传输(任何超过 20KB)(例如电子邮件附件)时,在文件写入完成之前,连接会在 TCP 级别上重置。我正在使用非阻塞 IO,并为每个特定连接生成一个线程。
当连接到来时,我会执行以下操作:
- 生成一个线程
- 连接到客户端(未加密)并读取连接请求(所有其他请求都将被忽略)
- 创建到服务器的安全连接(使用 openssl api 的 SSL)
- 告诉客户端我们联系服务器(未加密)
- 创建与客户端的安全连接,并使用选择循环开始在两者之间代理数据以确定何时可以进行读写
- 一旦底层套接字关闭,或者出现错误,连接就会关闭,并且线程被终止。
正如我所说,这对于正常大小的数据(常规网页和其他内容)非常有效,但一旦文件太大就会失败,并出现错误代码(取决于所使用的 Web 应用程序)或错误:连接中断。
我不知道是什么导致连接关闭,无论是 TCP、HTTP 还是 SSL 特定的内容,而且我根本找不到任何相关信息。在某些浏览器中,如果我在 SSL_write 之后立即放置 sleep 语句,它将开始工作,但这似乎会在其他浏览器中导致其他问题。睡眠不必太长,只是延迟一下。我目前将其设置为每次写入 4 毫秒,每次读取 2 毫秒,这在较旧的 Firefox、带有 HTTP 上传的 Chrome 和 Opera 中完全修复了这个问题。
任何线索将不胜感激,如果您需要更多信息,请告诉我。提前致谢!
-萨姆
I am writing a proxy server that proxies SSL connections, and it is all working perfectly fine for normal traffic. However when there is a large file transfer (Anything over 20KB) like an email attachment, then the connection is reset on the TCP level before the file is finished being written. I am using non-blocking IO, and am spawning a thread for each specific connection.
When a connection comes in I do the following:
- Spawn a thread
- Connect to the client (unencrypted) and read the connect request (all other requests are ignored)
- Create a secure connection (SSL using openssl api) to the server
- Tell the client that we contacted the server (unencrypted)
- Create secure connection to client, and start proxying data between the two using a select loop to determine when reading and writing can occur
- Once the underlying sockets are closed, or there is an error, the connection is closed, and thread is terminated.
Like I said, this works great for normal sized data (regular webpages, and other things) but fails as soon as a file is too large with either an error code (depending on the webapp being used) or a Error: Connection Interrupted.
I have no idea what is causing the connection to close, whether it's something TCP, HTTP, or SSL specific, and I can't find any information on it at all. In some browsers it will start to work if I put a sleep statement immediately after the SSL_write, but this seems to cause other issues in other browsers. The sleep doesn't have to be long, really just a delay. I currently have it set to 4ms per write, and 2ms per read, and this fixes it completely in older firefox, chrome with HTTP uploads, and opera.
Any leads would be appreciated, and let me know if you need any more information. Thanks in advanced!
-Sam
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果网络应用程序认为上传的文件太大,它会做什么?如果它有权关闭连接,这将导致发送方出现 ECONN:“连接重置”。无论它做什么,当您编写代理时,并假设代码中没有导致此问题的错误,您的任务是将上游连接发生的任何情况镜像回下游连接。在这种情况下,答案就是做你正在做的事情:关闭上游和下游套接字。如果您收到来自服务器的 close_notify 传入消息,请对客户端进行有序的 SSL 关闭;如果你有ECONN,只需直接关闭客户端套接字,绕过SSL。
If the web-app thinks an uploaded file is too large what does it do? If it's entitled to just close the connection, that will cause an ECONN at the sender: 'connection reset'. Whatever it does, as you're writing a proxy, and assuming there are no bugs in your code that are causing this, your mission is to mirror whatever happens to your upstream connection back down the downstream connection. In this case the answer is to just do what you're doing: close the upstream and downstream sockets. If you got an incoming close_notify from the server, do an orderly SSL close to the client; if you got ECONN, just close the client socket directly, bypassing SSL.