Transparent proxy UDP flows

Hello,

I am implementing transparent proxy for both TCP and UDP flows. With TCP everything works as expected, UDP flows break although I use same implementation as for TCP flows. Is there something different that has to be done for UDP flows?

Best regards

Is there something different that has to be done for UDP flows?

Yes, UDP flow copying is done a bit differently than TCP based flows. See this post for more information on getting started here.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Thanks, I managed to develop solution for UDP packets.

Now I experience other issue with transparent proxy. Once I enable transparent proxy it is not possible to ping any server, I get "Protocol wrong type for socket". You can find details in attachment. Does transparent proxy block all other network traffic except TCP and UDP? It shouldn't be related with my proxy implementation because ping doesn't work even if I create dummy proxy that just returns "false" in handleNewFlow callback and causes the flow to proceed to communicate directly with the flow's ultimate destination.

It shouldn't be related with my proxy implementation because ping doesn't work even if I create dummy proxy that just returns "false" in handleNewFlow callback and causes the flow to proceed to communicate directly with the flow's ultimate destination.

Right, NEAppProxyProvider or NETransparentProxyProvider only support TCP and UDP based flows. I would open an enhancement request for other protocol types.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

As far as I remember, "Protocol wrong type for socket" error for ICMP ping may indicated that you set includeAllNetworks=true during VPN initialization. Please try set to false.

Hi, I am experiencing issue with NETransparentProxyProvider. I use transparent proxy to bind some sockets to physical interface when VPN is active. It works fine for all apps, except Safari. With Safari I get errors when reading from the connection in inbound copier. I use following code snippet:


        let reader: TCPFlowCopierControl.Reader = { completionHandler in

            self.connection.receive(minimumIncompleteLength: 1, maximumLength: 2048) { (dataQ, _, isComplete, errorQ) in

                switch (dataQ, isComplete, errorQ) {

                case (_, true, _): completionHandler(.success(Data()))

                case (let data?, _, _): completionHandler(.success(data))

                case (_, _, let error?):

                    NSLog("TCP attempt 1: \(self.connection.currentPath?.localEndpoint) \(self.connection.endpoint)")

                    completionHandler(.failure(error))

                default: assert(false) // No data, no EOF, and no error.  Wha?

                }

            }

        }

        let writer: TCPFlowCopierControl.Writer = { data, completionHandler in

            self.flow.write(for: self, data: data) { errorQ in

                self.queue.async {

                    switch errorQ {

                    case nil: completionHandler(.success(()))

                    case let error?:

                        NSLog("TCP attempt 2: \(self.connection.currentPath?.localEndpoint)")

                        completionHandler(.failure(error))

                    }

                }

            }

        }

        return TCPFlowCopierControl(reader: reader, writer: writer, done: self.copierDone(errorQ:))

    }

In "TCP attempt 1" log I can see that self.connection.currentPath?.localEndpoint is nil, even though it wasn't at the time .ready state was hit. Safari itself shows "No connection" messages. This issue happens only in safari, chrome and firefox work fine. I'm also not experiencing the issue if I use NEAppProxyProvider instead of NETransparentProxyProvider, but I need to use NETransparentProxyProvider because it doesn't drop excluded sockets. Do you have any idea why this would happen?

@Galactico

Hi, I am experiencing issue with NETransparentProxyProvider. I use transparent proxy to bind some sockets to physical interface when VPN is active. It works fine for all apps, except Safari.

I am not sure if you are referring to the proxy provider as the VPN or if you do actually have a VPN in your suite of applications as well. Either way, if you wish to not handle a flow from the proxy, return false and let the system handle it. If this is actually a tunnel, then exclude that route and do not encompass that traffic. I'm not sure what is happening in your case, but the workaround that seems like would work across all of your platforms is to ignore this flow completely.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Transparent proxy UDP flows
 
 
Q