0

Today, I was making small changes to my Linux code. The code is a kind of ping-pong network program. The client writes "Hello", the server responds with "Hello". That is all to it.

Now I use FreeBSD. So naturally epoll mechanism being replaced by kqueue. The part of code that did a connect had caught my attention. The below is trimmed down code to show how I do non-blocking connect with Linux.

n = epoll_wait (ep_fd, ep_evs, YPOLL_EPOLL_NEVENTS, timeout_ms);
/* check epoll return for errors */

/* ... */

for(i = 0; i < n; ++i) { /* service epoll events */
 sock  = (sock*)ep_evs[i].data.ptr; /* user data */
 state = sock->state; /* store socket state: paired, connecting, closed, listening */
 mask  = ep_evs[i].events;

 /* connection in progress may have errors at the very start */
 if(state != CONNECTION_IN_PROGRESS){ 
  if(mask & EPOLLHUP){ /* hang up, both read/write not possible */
   /* do something */
   continue; /* next event */
  }
  if(mask & EPOLLERR) { /* error, or pipe read end has been closed */
   /* do something */
   continue; /* next event */
  }
 }

 /* test for various events */
 /* ... */

 /* fd is a socket that is yet to be connected */
 else if((state == CONNECTION_IN_PROGRESS) && (mask & EPOLLOUT)) {
  int v = /* call getsockopt for `SO_ERROR` */
  if(v != 0){ /* connection failed */
   /* do something, maybe print error */
   continue; /* next event */
  }
  /* connection passed */
  /* maybe add the socket to the list of connected sockets ? */
  continue; /* next event */
 }

}

The above works for me to do a non-blocking connect to a server. With Linux. And here I get closer to the question part. The kqueue interface has flags and fflags set for the event.

The plan is to do the same with FreeBSD, so that code will do a non-blocking connect. Do I have to call getsockopt to test for the error, or I would better check for an error with flags and fflags?

Update

I see that the question somewhat unclear in wording. I rephrase and explain. With Linux, the only way, for me, to catch an error with a non-blocking connect, - is to call getsockopt, getting SO_ERROR. Tests for epoll masks, like EPOLLHUP, does not catch all errors. The code with getsockopt, is the only option for me. I had tested various setups, and the check with SO_ERROR does cover some error paths that epoll error reporting does not. Again, I have to admit, that the above is for my system, with my network setup, etc.

My question is, will kqueue set EOF and fflags in case of an error with non-blocking connect? And preferably, can I safely assume that testing for EOF will cover all error cases?

Update

Since the last write up, I've tested some code paths of an error with a non-blocking connection. The flags are set for the following: TIMEDOUT, CONNRESET, CONNREFUSED. I can not test all possible code paths, so I just settle for testing EV_EOF, for now.

user14063792468
  • 839
  • 12
  • 28
  • Check out this question and (self-)answer. It's not completely clear but looks like it might get you well on your way. https://stackoverflow.com/q/55319444/1076479 – Gil Hamilton Jun 10 '22 at 23:47
  • @GilHamilton tweak Linux code to be a FreeBSD code. From the fact - the question, maybe, stated somewhat unclear. The problem is, on my system with Linux, I have to call `getsockopt` to find out, if the were a connect error. On Linux, testing the flags did not help. – user14063792468 Jun 11 '22 at 09:33
  • @GilHamilton I will rephrase a question, as I see it is stated in wrong words. From the above comment, my system has this case with `getsockopt` being the only way to securely test for connected socket(not counting other error tests). – user14063792468 Jun 11 '22 at 09:36
  • @GilHamilton So I ask about does `kqueue` always, and in every case, sets `EOF` and socket error in `fflags`? – user14063792468 Jun 11 '22 at 09:38

0 Answers0