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.

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

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