NEAppProxyTCPFlow: How to distinguish half-close from full connection close

I'm implementing a NETransparentProxyProvider and trying to preserve the original TCP connection semantics as transparently as possible.

The current API of NEAppProxyTCPFlow appears not to provide a way to distinguish between the following situations:

  1. The client has performed a half-close by calling shutdown(SHUT_WR) (i.e. closed only its write side).
  2. The client has fully closed the socket/connection.

When readData(completionHandler:) returns empty data, indicating EOF, I cannot determine which of the two cases above has occurred.

This creates a problem when forwarding the connection to the upstream server. Upon receiving empty data from the flow, should the corresponding server-side connection:

  • Perform a half-close (close only the write side / send FIN)?
  • Be fully closed?

Currently, I always perform a half-close on the server-side connection. While this almost preserves the original flow semantics, it can lead to leaked connections, since the upstream connection may remain in FIN_WAIT_2 indefinitely. Is there any supported way to determine whether the originating connection was half-closed or fully closed? If not, what is the recommended approach for implementing a transparent TCP proxy that needs to accurately preserve TCP shutdown semantics? Any guidance would be appreciated.

Answered by Engineer in 891780022

Currently there's no public API to distinguish these two scenarios. Please file a feedback so we'll investigate this use case.

Currently there's no public API to distinguish these two scenarios. Please file a feedback so we'll investigate this use case.

We've described our scenarios in FB22874828. Thank you!

NEAppProxyTCPFlow: How to distinguish half-close from full connection close
 
 
Q