PJSIP connection errors on ios 11 when coming from background during Push Notification - ios11

How do we recover a lost PJSIP UDP socket when coming from background during a CallKit Push notification? We get the following errors when trying to register with Asterisk server.
ioq_select Error replacing socket [120009]: Bad file descriptor
We've tried closing and recreating the pjsip transport when we encounter these errors, but that is effective only ~50% of the time. By the time the transport is successfully created the call is lost. Is there a more robust way to handle the UDP socket loss?
Any attempt to proactively close down the socket/transport when entering the background (in application:applicationDidEnterBackground) results in an unregister packet being sent to asterisks server. Any background calls go straight to voicemail.
We are testing on ios 11 and 12 using pjsip 2.8

Related

Detecting disconnected client side socket connection (cross-platform applicability)

I know there are hundreds of answers for this question, but I cannot get it done with respect to my situation. The scenario is like this, we have a server written in TCP/IP protocol, we have multiple clients connected to this server. The client here is a software module which before starting on a client machine, registers its presence in the server and loads the functionalities. But the problem is that this software module getting crashed and there by no socket.close() is called, this will make its footprints still present in the server even though its crashed. How to recognize this?
I am using select() method in the client to notify any info from client and server (vice-versa)
I cannot create a process separately for each client request in the server, neither can I create a parent-child mechanism in the client machine.
tcp-keepalive is not applicable as we need to tweak the registry in Windows? I need a x-platform compatible solution.
I have read that recv() to the connected socket in the server code will return some values from 'that' client such as 0 for socket closed? Can I use this to clear off the client socket registration in the server database? Will this work?
You didn't specify what method you are using to handle socket events in your server side code. Whatever method for polling your sockets you are using, recv() will return 0 or possibly -1/SOCKET_ERROR when a client crashes.
To detect inactive client connections most server applications send out some form of heartbeat or ping message periodically within the application layer protocol. When an ACK fails to be sent from the client the server application will then get notification the client disconnected via recv() returning 0 or SOCKET_ERROR with an error code of something like WSAENETRESET, WSAECONNABORTED, WSAETIMEDOUT, or WSAECONNRESET (see the various error codes here). Often after the server sends the heartbeat to a client TCP port that is no longer active an ICMP packet is sent in response that will alert your server that the port or host not active (recv() will immediately notify you of this event).
If you wish to turn the TCP keep alive timer on you can use the socket option SO_KEEPALIVE. The interval can also be set using SIO_KEEPALIVE_VALS.
Edit: Keep in mind the various error codes and option SIO_KEEPALIVE_VALS are Win32 specific. To handle these events for other operating systems you will need to use operating specific ways of retrieving error codes and setting the TCP keep alive interval if you choose to do so. My best suggestion to keeping your code cross platform compatible is to simply implement an application layer heartbeat message into your protocol or some other application layer specific timeout. Doing so will allow you to forget about managing TCP keep alives.
Update
I cannot comment on EJP's answer, but it's important to point out that by calling send() he is effectively recommending you implement a heartbeat/ping message in the application layer of your protocol. While checking the return value of send() is important, if you are polling/selecting read events you will be notified of the TCP connection being disconnected immediately upon calling recv() the moment the connection is deemed broken by the TCP stack. If you wait for your application timer to try to send some data using send() that could be many seconds (depending on the length of your interval timer) after recv() has already notified you that the connection is broken. In other words: pay attention to the recv() return values as well as your send() return values.
tcp-keepalive is not applicable as we need to tweak the registry in Windows?
TCP keepalive is an option if you can accept the default timeout of two hours.
I need a x-platform compatible solution.
TCP keepalive is cross-platform.
I have read that recv() to the connected socket in the server code will return some values from 'that' client such as 0 for socket closed?
it will return zero if the peer closes its socket, and on some platforms if the peer process merely exits without closing it.
Can I use this to clear off the client socket registration in the server database? Will this work?
Only if you can rely on the peer closing the socket properly.
It seems to me that what you should be doing is debugging the client code so it doesn't crash, and using TCP keepalive as a long-term backup.
You should also be aware that send() to a peer that has exited will sooner or later fail with an ECONNRESET error.

Sending and receiving messages using Bluetooth sockets in C

I am working on a Windows application that when launches starts a BT / SPP (RFCOMM) connection to a device, and then continuously receives and sends data.
So far I have been able to detect the device and to use socket() and connect() to start the connection and I am able to send data using send(). However I am not able to receive any data.
When I connect I use the SerialPortServiceClass_UUID GUID with port = 0.
Out of all the methods I have tried the one that I think should make most sense is to use recv() with the same socket used to open the connection. Alternatively I tried installing a service etc. and nothing worked.
All the examples that I googled only have one-way communication, so I am now wondering if 2-way communication is supposed to work or am I missing something?
Thank you for the help!!!

Programmatically detect if local web server has hung

I realise that I'll get at least one answer along the lines of "(re)write the code so it doesn't hang" but let's assume we don't live in that shiny happy utopia just yet...
In our embedded system we have a big SDK including a web-server (Boa) which is the primary method of user interaction.
It's possible, during certain phases of the moon, that something can cause the web server to hang or become otherwise stuck in such a way that the process appears running normally (not crashed/dead/using 100% CPU) but does not serve any web pages.
So, the question is, how do we test/detect this situation?
To test whether the server is hung, create a TCP socket and connect to port 80 on IP address 127.0.0.1 (loopback address). Then send the following text over the socket
GET / HTTP/1.1\r\n\r\n
Most servers will interpret that as a request for index.html. Alternatively, you could implement an undocumented URL for testing (which allows for a shorter, predetermined response), e.g.
GET /test/fdoaoqfaf12491r2h1rfda HTTP/1.1\r\n\r\n
You then need to read the response from the server. This involves using select with a reasonable timeout to determine whether any data came back from the server, and if so, use recv to read the data. The response from the server will consist of a header followed by content. The header consists of lines of text, with a blank line at the end of the header. Lines end with \r\n, so the end of the header is \r\n\r\n.
Getting the content involves calling select and recv until recv returns 0. This assumes that the server will send the response and then close the socket. Some sophisticated servers will leave a socket open to allow multiple requests over the same socket. A simple embedded server should not be doing that. (If your server is trying to use the same socket for multiple requests, then you need to figure out how to turn that feature off.)
That's all very well and good, but you really need to rewrite your code so it doesn't hang.
The mostly likely cause of the problem is that the server has a bunch of dangling sockets, i.e. connections from clients that were never properly cleaned up. Dangling sockets will eventually prevent the server from accepting more connections, either because the server has a limit on the number of open connections, or because the process that's running the server uses up all of its file descriptors.
The first thing to check is the TCP timeout value. One project that I worked on had a default timeout of 5 hours, which meant that dangling sockets stayed open for 5 hours. A reasonable timeout is 1 minute.
Then you need to create a client that deliberately misbehaves. Clients can misbehave by
leaving a socket open without reading the server's response
abruptly closing the socket while reading the response
gracefully closing the socket while reading the response
The first situation should be handled by the TCP timeout. The other two need to be properly handled by the server code. Graceful and abrupt socket closure is controlled via the SO_LINGER option of ioctl and the shutdown function. After the client misbehaves, check the number of open file descriptors in the server process, to verify that the server has handled the situation correctly.

TCP connection broken detection (If intermediate link goes down)?

Assuming the implementation in C.
If the intermediate link goes down, through which the TCP connection was sending the data. Will the sockets at both ends become unusable to send and receive data immediately?
If the link comes up after 5-6 secs, Can the same sockets be used to send and receive the packets?
The TCP/IP protocol suite was designed to work over unreliable links. If the connection comes back after a few seconds the applications only notice a drop in throughput.

windows C program perform action on shutdown

I am making a program that sends "heartbeats" for a server to keep track of nodes. They are packets with the following payloads:
'start' when it starts up
'running' every 5 seconds
'stopping' at shutdown
The first two are easy. The thread/loop can set the message on first and subsequent runs. How do I make the loop "catch" a shutdown so that it can send a last packet?
I use the minGW compiler for C in WinXP platform.
Edit: I added the relevant details I missed (thanks walkingTarget and Ferruccio)
It is an in-progress app that contains messy stuff in implementation :-)
It uses libCURL, the HTTP client library to send the packets
It is a console app, which I (much later) intend as a service
It needs to save a file and send a packet at shutdown
It needs to capture a system shutdown
In your WindowProc() you can check for the message WM_QueryEndSession, which Windows sends to all open processes before shutting down. For more info on that message see the following link, but i understand that it is as trivial as checking for a WM_SIZE:
http://msdn.microsoft.com/en-us/library/aa376890%28VS.85%29.aspx

Resources