Post

Replies

Boosts

Views

Activity

Reply to When the Network Extension(NETransparentProxyProvider) is installed and enabled, data cannot be sent to the UDP server
I have completed the submission of the bug. It is FB18495149. In the above discussion, there is also the issue of EADDRINUSE. After the NE Provider is started, when the port bound by the UDP client is rebound again, the situation of EADDRINUSE will occur for a period of time (just like being in the FIN_WAIT_2 state of TCP). Why is this? Neither netstat nor lsof found the connection of the corresponding port. This situation will not occur when there is no Network Extension.
Jun ’25
Reply to When the Network Extension(NETransparentProxyProvider) is installed and enabled, data cannot be sent to the UDP server
It might be regarded as a problem in practice. In my test environment, there is a UDP client implemented by someone else. This UDP client will send an authentication packet to the gateway device at regular times (that is, quickly close the socket after each sendto), and then it is found that this authentication packet has not been sent successfully. After the investigation, the problem currently under discussion, "Network Extension causes UDP data packets to fail to be sent successfully", was obtained. I guess, when [MyTransparentProxyProvider handleNewFlow:] return NO, system to connect to the server's operation, Like call [NEAppProxyUDPFlow openWithLocalEndpoint:completionHandler:], and then got a error("The peer closed the flow"), Then the data of this Flow was not sent out.
Jun ’25
Reply to When the Network Extension(NETransparentProxyProvider) is installed and enabled, data cannot be sent to the UDP server
It seems to be related to the quick close of the socket after sendto in the UDP client. If you wait for a while and then close the socket again, this problem will not occur. // // main.cpp // #include <iostream> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> int main(int argc, const char * argv[]) { // arg check int nLocalPort = -1; const char *lpcszRemoteIP = "192.168.1.123"; int nRemotePort = 12345; const char *lpcszData = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (argc > 1) { // arg 1 lpcszRemoteIP = argv[1]; if (argc > 2) { const char *lpcszRemotePort = argv[2]; nRemotePort = atoi(lpcszRemotePort); if (argc > 3) { const char *lpcszLocalPort = argv[3]; nLocalPort = atoi(lpcszLocalPort); if (argc > 4) { lpcszData = argv[4]; } } } } size_t stDataSize = strlen(lpcszData) * sizeof(char); printf("Role : UDP Client\n"); if (nLocalPort != -1) printf("Local : local:%d\n", nLocalPort); printf("Remote: %s:%d\n", lpcszRemoteIP, nRemotePort); printf("Data : [%ld]%s\n", stDataSize, lpcszData); int nSocket = -1; do { nSocket = socket(AF_INET, SOCK_DGRAM, 0); if (nSocket == -1) { printf("socket() == -1\n"); break; } if (nLocalPort != -1) { struct sockaddr_in addrLocal; addrLocal.sin_family = AF_INET; addrLocal.sin_port = htons(nLocalPort); addrLocal.sin_addr.s_addr = htonl(INADDR_ANY); int nBind = bind(nSocket, (const struct sockaddr *)&addrLocal, sizeof(addrLocal)); if (nBind != 0) { printf("bind(%d) error. ret: %d errno: %d\n", nLocalPort, nBind, errno); break; } else { printf("bind(%d)\n", nLocalPort); } } struct sockaddr_in addrServer; addrServer.sin_family = AF_INET; addrServer.sin_port = htons(nRemotePort); if (inet_pton(AF_INET, lpcszRemoteIP, &addrServer.sin_addr.s_addr) != 1) { printf("inet_pton() != 1\n"); break; } // Send Data ssize_t nSend = sendto(nSocket, lpcszData, stDataSize, 0, (const struct sockaddr *)&addrServer, sizeof(addrServer)); if (nSend < stDataSize) { printf("sendto() error. ret: %ld errno: %d\n", nSend, errno); } } while (false); /* int nTime = 0; while (true) { sleep(1); nTime++; if (nTime >= 5) break; } */ if (nSocket != -1) { close(nSocket); nSocket = -1; } return 0; } How should it be dealt with in [MyTransparentProxyProvider handleNewFlow:] or [MyTransparentProxyProvider handleNewUDPFlow:initialRemoteEndpoint:]?Perhaps when The error "The peer closed the flow" occurs in [NEAppProxyUDPFlow openWithLocalEndpoint:completionHandler:], should the Network Extension take over this flow instead of returning NO?
Jun ’25
Reply to When the Network Extension(NETransparentProxyProvider) is installed and enabled, data cannot be sent to the UDP server
Another issue was also discovered. When a UDP client binds a port via bind() (for example, 12345), and then uses sendto() and close(), when it attempts to bind this port again using bind(), it will fail, with errno being 48(at this time, handleNewFlow always returns NO). There is no such problem if the network extension is disabled.
Jun ’25
Reply to When DHCP is used, the Network Extension will cause the machine to fail to obtain an IP address
In the log of the Console.app, it was seen that the configd binding to port 68 failed, causing it not to receive the DHCP OFFER. configd Process interface attach: en8 ...... configd DHCP en8: start configd en8 link INACTIVE configd RTADV en8: start configd en8: link inactive timer fired configd DHCP en8: status = 'media inactive' configd DHCP en8: INACTIVE configd RTADV en8: Inactive configd RTADV en8: Inactive configd AUTOMATIC-V6 en8: status = 'media inactive' configd Process interface link status active: en8 configd en8 link ACTIVE configd DHCP en8: INIT configd DHCP en8: supplying hostname 'xxx' configd bootp_session: bind port 68 failed, Address already in use configd bootp_session_open_socket: S_open_bootp_socket() failed, Address already in use configd bootp_session_open_socket failed configd bootp_client_enable_receive(en8): failed configd DHCP en8: INIT waiting at 0 for 1.627353 configd RTADV en8: link-local address is ready, starting configd RTADV en8: Solicit configd RTADV en8: sending Router Solicitation (1 of 3) configd bootp_session_delayed_close(): socket is already closed configd DHCP en8: INIT waiting at 1.63551 for 2.155144 configd DHCP en8: INIT waiting at 3.79642 for 4.810702 configd RTADV en8: sending Router Solicitation (2 of 3) configd DHCP en8: ARP router: No leases to query for configd DHCP en8: INIT waiting at 8.61294 for 8.428934 configd RTADV en8: sending Router Solicitation (3 of 3) configd DHCP en8: ARP router: No leases to query for configd DHCP en8: INIT waiting at 17.0444 for 8.628138 configd LINKLOCAL en8: setting 169.254.93.15 netmask 255.255.0.0 broadcast 169.254.255.255 configd LINKLOCAL en8: publish success { IPv4 } configd network changed configd DHCP en8: ARP router: No leases to query for configd DHCP en8: INIT waiting at 25.6759 for 8.528784
Jun ’25
Reply to When DHCP is used, the Network Extension will cause the machine to fail to obtain an IP address
getnameinfo() doesn't always fail. Its failure has nothing to do with being in this problematic state, but it is indeed because of this problem that I consider using getnameinfo() for reverse DNS. In fact, MyTransparentProxyProvider will obtain some domain names set by the extension user, which indicates that the user wants to block access to these domain names. Initially, MyTransparentProxyProvider, when intercepted UDP Flow, if the target port is 53, would take over the Flow, and deal with the relationship between the Flow data to get the IP addresses to domain names table. However, due to this DHCP issue, I added an exclusion rule, which made me no longer obtain the UDP Flow on port 53. In this case, I consider using getnameinfo() to have a look. During the process of using getnameinfo(), I will first check whether -[NEAppProxyTCPFlow remoteHostname] is available. If it can be used, there is no need for reverse DNS; otherwise, I will try reverse DNS. For Safari's Flow, the value of -[NEAppProxyTCPFlow remoteHostname] can always be used without the need for active reverse DNS. I guess it might be related to Safari's use of nw_endpoint_create_host(). For Google Chrome's Flow, there is a situation where -[NEAppProxyTCPFlow remoteHostname] are all unavailable. At this point, when reverse DNS is performed, it fails. As described in the https://stackoverflow.com/questions/56118048/getnameinfo-fails-to-perform-a-reverse-dns. Returning to the issue of DHCP, when the problem occurs, observe the log in Console.app and see that the configd process is handling DHCP. After the message "DHCP en8: INIT waiting at xxx for xxx" appears, there is no more information. Under normal circumstances, there will be processes such as "DHCP en8: INIT", "DHCP en8: SELECT", and "DHCP en8: BOUND". I don't know if this information is helpful for problem checking.
Jun ’25