We have a makeshift SOAP client written in C# connecting to a CXF service on a desktop from a windows mobile device. When this device is connected via ActiveSync, it creates a virtual adapter for the RNDIS connection. This virtual adapter assigns a gateway IP to the host, 169.254.2.2.
When we attempt to go through the connection with the hostname or the host's IP set as the address in the C# client, everything works perfectly. When we however set the IP to be the RNDIS gateway (169.254.2.2), the connection is periodically lost on the server side. The CXF service keeps trying to connect, and eventually succeeds, but this results in a massive slowdown of the connection. There are no errors reported in our logs on the mobile C# side, only on the CXF server.
Does anyone have any clues as to why this is happening? We need to assert that 169.254.2.2 cannot possibly be used as a valid endpoint before we rule it out.
Oh, and in case it helps, the C# client is granted the IP 169.254.2.1 through DHCP after the ActiveSync connection.
The first issue that comes to my head, especially once I saw that you are using DCHP, is that the lease time on the IP from the DHCP server is expiring and the CXF server is having to wait for the DCHP server to issue a new lease.
Try lengthening the DCHP lease if you know that the IP won't be changing and use a static IP if you are able. That will at least remove that point of failure.
I found out the cause of this, but I feel bad for answering because I doubt there was any way someone else could have guessed that this was the problem:
On our CXF server, we have a call to InetAddress.getHostName() which basically does a reverse DNS lookup on the request sent from the C# client.
When using the ActiveSync IP address, there was no entry in the DNS for 169.254.2.1 (of course), so the java class would hang until the method timed out (which took about 20 seconds before it would write a response to the C# client). At 20 seconds per request, this resulted in the massive slowdown and lost connection errors.
We fixed this by moving the call to an executor thread that force-finished after half a second. Because it was in another thread, the slowdown became nonexistent. Glad to have that over with!
Related
I have a device (esp32s2) which is IoT enabled and communicating with AWS server.
The device is connecting to the internet via router. I want to check from the device, if the router is connected to the internet or not. If not connected, I need to disconnect mqtt broker instantly.
I know there is aws_iot_yield happening, but it is taking too much of time to change the client state (~5-10 mins) after disconnection. So, is there is any other way in which I can come to know if the device is connected to the mqtt broker or not using AWS sdk?
I want to avoid using pinging to some address/server as it will increase the usage of resources.
Thanks in advance!
Since the connectivity to the AWS server trough internet depends on the network elements, the only reliable way to know if you are connected to internet is to send a package to a know address and receive the response. Simplest way to do this is to use ICMP (ping) protocol. Usually the most reliable destination to ping is the Google DNS server 8.8.8.8 or 8.8.4.4 which is a cluster service and it's always replying on the ping.
You can control the pause between two pings and how many pings you will send in one session in order to preserve the resources.
Alternative approach is to use a router that can send messages to a monitoring device that the link state was changed (by example SNMP trap). But this is not fully reliable method since the router can not detect all scenarios where the connectivity to your AWS server is lost.
I am doing some load testing on a service run with Apache2 and my load testing tool has a default timeout of 30 seconds. When I run the tool for a minute with 1 request per second load, it reports that 40 succeeded with 200 OK response and 20 requests were cancelled because client timeout exceeded while awaiting headers.
Now, I was trying to spot this on the server side. I can't see the timeouts logged either in apache access logs or gunicorn access logs. Note that I am interested in connections that weren't accepted as well as that are accepted and times out.
I have some experience working on similar services on Windows. The http.sys error logs would show connection dropped errors and we would know if our server was dropping connections.
When a client times out, all the server knows is that the client has aborted the connection. In mod_log's config, the %X format specifier is used to log the status of the client connection after the request has completed, which is exactly what you want to know in this case.
Configure your logs to use %X, and look for the X character in the log lines.
Bonus: I even found the discussion about this feature in apache's dev forum, from 20 years ago
Update:
Regarding refused connections, these cannot be logged by apache. Connection refusal is done by the kernel, in the tcp stack, and not by apache. The closest solution including only apache that I can think of is keeping track of the amount of open connections (using mod_status). If it reaches the maximum you know you might be refusing connections. Otherwise, you'd need to set up some monitoring solution to track tcp resets sent by the kernel.
I'm using the basic socket functions in C language, the line below:
int res = connect(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
1. when my laptop is can access the internet, connect will return immediately,connection is built as expected.
2. when my laptop is offline, connect will return immediately, the errno is "network is unreachable.
3. when my laptop is connected to a wifi network that cannot access internet directly(need login opration or sth else), connect will block about 20 seconds before return, the errno is "connection refused"
It can be solved by set the sock_fd nonblocking, I want to know why it takes such a long time before connect return a connection mistake in the third situation?
In the 2nd case (network offline), the operating system knows it is offline and so the network libraries can immediately signal a failure.
In the 3rd case (network online, but unable to reach internet) the operating system thinks it is online, but has no way to tell that in advance that the connection won't succeed. The actual failure mode depends on the nature of the network you are connected to:
In the case you are experiencing, the network simply isn't responding at all to to your connection attempt. Your packets are simply being ignored. Eventually you experience a connection timeout, when the connect function gives up waiting for a response. It is normal for it to wait some period of time before giving up, since not all connections on the internet happen instantly (network is slow or congested, or the server on the other end is slow to respond)
In another case, a firewall might be configured to actively reject connections that are not allowed. This means that it will send a packet back in response that says the connection was rejected. If this happens you would quickly get an error back from connect().
There is a third possibility... this is a situation where you are connected to a network that requires you to enter a password on a web page, or click to acknowledge that you acknowledge the policies for using the internet at that business. No matter what internet site you are trying to access with your browser, you first see this page. This is called a captive portal and is implemented by responding to port 80 traffic at any IP address and sending the login page instead. If you were trying to connect a socket to port 80 (the http port) at any IP address, the connection would succeed (even though you are not actually connected to the remote server you expect). If you are using a port other than port 80, it would instead ignore or block the connection. I mention this in case you are trying to write a program that determines if you are connected to the internet or not. Using port 80 wouldn't work well in this case.
I have apache2 setup with several virtual hosts, but I have it setup so that if you visit the IP address in your browser you get an error 403. When I ping the domain name of one of my virtual hosts, it always just responds with request for timeout, never the latency, why is this?
Perhaps your hosting provider (or your Linux distro) has firewalled ICMP protocol which is necessary for ping to work correctly.
Note that Apache needs only TCP to work properly, and does not need ICMP, which is completely different protocol. In other words, ping may be completely firewalled, and yet, your website will respond correctly.
Some websites actively firewall ICMP, most notable example is microsoft.com.
I need one server to receive ip requests from clients(there are not in the same intranet), and I can
route all the response packets to a special gateway server, and then I send the response packages to
clients after some processing. it is like VPN, but I want to do some development based one
opensource project, so i can control it myself.
any suggestion? thanks!
There is OpenVPN which is as the name already suggests open source.
You could set up the server on the local one as a kind of proxy (or reverse-proxy depending on your viewpoint) and have the clients connect to it.
It depends what protocol you're using, maybe it has explicit proxy capability or you can get an existing proxy program, or just proxy it using a simple socket forwarder program.