Why udp port 53 traffic is captured?

Hi there,

I am using NEAppProxyProvider to filter a scope of port traffics. Am I am trying to capture all port traffic (except udp port 53) like below.

There are mainly two problems with below approach:
  1. Sometimes it works that can capture all traffic, but sometimes it cannot.

  2. All the time, udp 53 traffic is always captured in.

Is this a bug?


Code Block
private func buildRules(fullMode: Bool) -> [NENetworkRule] {
var hosts = [("", "")]
var rules: [NENetworkRule] = []
hosts = [("0.0.0.0", "0...52"),
("0.0.0.0", "54...65535"),]
for host in hosts {
let ep = NWHostEndpoint(hostname: host.0, port: host.1)
let rule = NENetworkRule.init(remoteNetwork: ep, remotePrefix: 0, localNetwork: nil, localPrefix: 0, protocol: .any, direction: .outbound)
rules.append(rule)
}
}
...
let settings = NETransparentProxyNetworkSettings.init(tunnelRemoteAddress: "127.0.0.1")
settings.includedNetworkRules = buildRules()
settings.excludedNetworkRules = nil
settings.dnsSettings = NEDNSSettings(servers: ["1.1.1.1", "1.0.0.1", "8.8.8.8", "8.8.4.4"])
setTunnelNetworkSettings(settings) { [unowned self] (error) in
...


Attach the full mode crash log:



You encountered a segmentation fault when you tried to start a new connection.

Code Block
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000020
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [79060]
Thread 15 Crashed:: Dispatch queue: Network.framework
0 libobjc.A.dylib 0x7fff202ec9bf objc_release + 31
1 com.apple.Foundation 0x7fff212c420d NSKVOPendingNotificationRelease + 67
2 com.apple.CoreFoundation 0x7fff2051d512 __CFArrayReleaseValues + 477
3 com.apple.CoreFoundation 0x7fff205e38d7 _CFArrayReplaceValues + 365
4 com.apple.Foundation 0x7fff2136e294 NSKeyValuePopPendingNotificationPerThread + 267
5 com.apple.Foundation 0x7fff2136dd01 NSKeyValueDidChange + 107
6 com.apple.Foundation 0x7fff2140e539 NSKeyValueDidChangeWithPerThreadPendingNotifications + 146
7 com.apple.Network 0x7fff2641cda6 __21-[NWConnection start]_block_invoke.38 + 422 <----- SEG FAULT
8 libdispatch.dylib 0x7fff202b01d5 _dispatch_block_async_invoke2 + 83
9 libdispatch.dylib 0x7fff202a37c7 _dispatch_client_callout + 8
10 libdispatch.dylib 0x7fff202a95fe _dispatch_lane_serial_drain + 606
11 libdispatch.dylib 0x7fff202aa0fe _dispatch_lane_invoke + 426
12 libdispatch.dylib 0x7fff202b3c5d _dispatch_workloop_worker_thread + 819 (
13 libsystem_pthread.dylib 0x7fff2044b499 _pthread_wqthread + 314
14 libsystem_pthread.dylib 0x00007fff2044a467 start_wqthread + 15

Take a look at this part of your code as well as any KVO surrounding this logic.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Thanks for the good point.

To rule out whether it is tcp or udp that caused the crash, I would like to have a try with NWConnection rather than NWUDPSession (I am currently in use).

The question is:
If I want to try NWConnection for udp flow handle (with .udp option), how to handle the multi datagrams with connection.send?

Code Block
udpflow.readDatagrams(completionHandler: { [unowned self] (datagrams: [Data]?, endpoints: [NWEndpoint]?, readError) in


Confirmed that only by doing all udp traffic capturing like below will cause network crash.

Would like to try NWConnection .udp rather than NWUDPSession currently in use.
Do you have any sample code for using NWconnection together with NEAppProxyUDPFlow?

Code Block
for seg in 1...254 {
if seg != 127 {
hosts = [("\(seg).0.0.0", "0")]
for host in hosts {
let ep = NWHostEndpoint(hostname: host.0, port: host.1)
let rule = NENetworkRule.init(remoteNetwork: ep, remotePrefix: 8, localNetwork: nil, localPrefix: 0, protocol: .UDP, direction: .outbound)
rules.append(rule)
}
}
}


Sorry for the possible off topic, but I have noticed that the port defined in the rules as "0...52" and "54...65535". Is this range notation legal at all? If so, I was unable to find any reference to it in the documentation. Can
you please confirm?
Thanks.
@richard_wang

If I want to try NWConnection for udp flow handle (with .udp option), how to handle the multi datagrams with connection.send?

I recommend that you create a new managing class for each one of your outbound datagrams and then use NWConnection inside of that.

Do you have any sample code for using NWconnection together with NEAppProxyUDPFlow?

No.

@SerusMac

I have noticed that the port defined in the rules as "0...52" and "54...65535". Is this range notation legal at all?

This is something on my to-do list to research. I've tested it and it does seem to work, but just because it works does not mean it is valid and thus why I have not called it out one way or the other. (Usually I would call it out right away.) I will keep this thread updated as I find out more.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
As confirmed that by only capturing all udp traffic can cause the network crash. Tried different approaches around udp, but all failed. That include exclude reserved ip segments for local network, exclude multicast segments, only include 1.0.0.0/8 to 127.0.0.0/8 for udp traffic.

So far, I do believe that if there is any way to exclude udp 53 traffic, should get resolved. But as you see, I am using none zero default route as suggested, but udp 53 packets still comes in. Furthermore, as you side noted that " you cannot filter localNetwork traffic with NEAppProxyProvider either", does it mean that we have no way to eliminate udp 53 traffic with NEAppProvider?

Thanks in advance for any suggestion.

I do believe that if there is any way to exclude udp 53 traffic, should get resolved. But as you see, I am using none zero default route as suggested, but udp 53 packets still comes in.

Just as a clarification here; when I tested your workflow, you were not receiving post 53 UDP flows in handleNewFlow, but when your Network Extension acted upon the UDP flows being proxied your Network Extension was receiving these flows. For example, a UDP flow with the local endpoint of 0.0.0.0: 6244 might be handled in handleNewFlow and then when the flow was proxied the outbound datagrams might contain port 53 traffic, x.x.x.x:53.

does it mean that we have no way to eliminate udp 53 traffic with NEAppProvider?

Building up my above description, you can do a few things here; You can let the system handle all UDP flows. You can attempt to target a small subset of UDP flows and if you receive port 53 flows, you can proxy them. Proxying UDP flows is something that can be done without a crash.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

You can let the system handle all UDP flows. You can attempt to target a small subset of UDP flows and if you
receive port 53 flows, you can proxy them. Proxying UDP flows is something that can be done without a crash.

That is what I am trying at the moment. But when letting all udp traffic through with filter setting like below, within around three hours, network is gone like below. Crash might not happen though.
Code Block
ping apple.com
...
Request timeout for icmp_seq 14745
ping: sendto: No route to host
Request timeout for icmp_seq 14746
ping: sendto: No route to host

I have tried both udp session and NWConnection for remote connection, same result.
Any suggestion?
Code Block
for seg in 1...254 {
if seg != 127 {
hosts = [("\(seg).0.0.0", "0")]
for host in hosts {
let ep = NWHostEndpoint(hostname: host.0, port: host.1)
let rule = NENetworkRule.init(remoteNetwork: ep, remotePrefix: 8, localNetwork: nil, localPrefix: 0, protocol: .UDP, direction: .outbound)
rules.append(rule)
}
}
}

Also, can you help indicate how to update in the tsi ticket? I would like to go on discussion fromTSI case 767665663, but don't know what is the link for it.
Thanks in advance.

Also, can you help indicate how to update in the tsi ticket? I would like to go on discussion fromTSI case 767665663, but don't know what is the link for it.

To continue the discussion on 767665663, simply reply on the thread. However, if your reply is outside the context of the original question, I will request that you open a new TSI.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
@meaton

I have noticed that the port defined in the rules as "0...52" and "54...65535". Is this range notation legal at all?

This is something on my to-do list to research. I've tested it and it does seem to work, but just because it works does not mean it is valid and thus why I have not called it out one way or the other. (Usually I would call it out right away.) I will keep this thread updated as I find out more.

Is there any update on this? (Please let me know if it is better to create a new thread).

Is there any update on this?

Not at this time, no.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Why udp port 53 traffic is captured?
 
 
Q