Commit Graph

5 Commits

Author SHA1 Message Date
Holger Hans Peter Freyther 37c2254f5d evpoll: Add workaround for usage of IP_RECVERR in sofia-sip
We are using glib to benefit from the sofia-sip-glib eventloop
integration and set a poll func (evpoll) to be called by glib
to integrate with the rest of libosmocore.

Sofia-sip will use IP_RECVERR to enable error reporting on the
socket and then sets SU_WAIT_ERR (mapped to POLLERR if not using
kqueue) in the internal events flag of the socket. This will
be registered with a su_wait (mapped to struct pollfd) and then
glib will be called with g_source_add_poll. At this point the
the fd->events will still have the POLLERR bit set.

Before glib is calling its internal poll routine or our one
it will copy all registered fd into an array and mask the
events flags:

      /* In direct contradiction to the Unix98 spec, IRIX runs into
       * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
       * flags in the events field of the pollfd while it should
       * just ignoring them. So we mask them out here.
       */
      events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);

This leads to the POLLERR flag never been set in the revents
of the struct poll_fd and as such we never put them in the
exceptionset and as such:

	static int tport_base_wakeup(tport_t *self, int events)
	{
  	int error = 0;

  	if (events & SU_WAIT_ERR)
    		error = tport_error_event(self);

tport_base_wakeup will never call tport_error_event. And the error
will be stuck in the socket data forever and recvmsg will return
a zero length packet. And this will repeat until the end of time.

As a first hack I mapped SU_WAIT_ERR to POLLPRI but when using
select the Linux kernel will not put the socket error into the
except queue unless the sockopt SOCK_SELECT_ERR_QUEUE is used.

One option is to use poll and then map the select requirements
to poll. Right now I just signal POLLERR as well to trigger
tport_error_event. This will result in extra syscalls for each
received UDP message right now.

Change-Id: I5bec4a7b70f421ab670e649e5bc1ea6faf59707c
2017-03-08 10:32:13 +01:00
Holger Hans Peter Freyther 42b073a233 evpoll: Don't try to be more smart than g_poll
gpoll.c:g_poll maps G_IO_PRI (which is POLLPRI) to the errorfds of
the select call. Let's do the same.

Change-Id: I8c9163f7495e0b237bde2d48beffea3b0776a1dd
Related: OS#1934
2017-02-11 13:06:32 +07:00
Holger Hans Peter Freyther e19f9ce39f evpoll: Always initialize revents for the output
Even if we have not selected the fd (e.g. fd < 0), initialize revents
to 0. This seems to match gpoll.c:g_poll of glib.

Change-Id: I9e16a6d5a74a204c85808ba67a8f0f7af3045059
2017-02-11 13:01:12 +07:00
Holger Hans Peter Freyther 70926c8bb5 evpoll: Use {} in the middle of the if/else if/else block
Curly braces are used the lines above and below, don't make the middle
stick out like this.

Change-Id: I48a15a8665a47db206f8a7ccbc792f6bec8549c2
2017-02-11 13:00:19 +07:00
Holger Hans Peter Freyther a1909e6c80 Initial commit for a MNCC to SIP gateway (and maybe auth GW too)
* It is written in C and using libosmovty and other data structures
* It is using sofia-sip for the SIP handling as a good library for
such a task
* It is using glib for the sofia-sip event loop integration. In the
future we can write our own root context but right now that looks
like a necessary evil. No glib usage is allowed in this code and
only sofia-glib is linked.
2016-03-21 09:54:37 +01:00