So, I think I understood how things work. Since the transport layer(my transparent proxy) can't decide if more data is coming from the remote side of the connection or not it should not do that. And rely on the app layer which can.
From practical tests, readDatagrams callback will not return empty the datagrams and remote endpoints arrays(EOF sign) until the app that opened socket(flow) is satisfied with the number of datagrams received from the remote side.
So, to summarize:
Close connection and flow in case of errors
Close flow as per documentation to readDatagrams function:
If the datagrams and remoteEndpoints arrays are non-nil but are empty, then no more datagrams can be subsequently read from the flow.