I modified the libevent code to detect socket errors during the connect event.
void CBDidConnect(evutil_socket_t socketID,short eventNum,void * arg){
CBEvent * event = arg;
if (eventNum & EV_TIMEOUT) {
// Timeout for the connection
event->loop->onTimeOut(event->loop->communicator,event->node,CB_TIMEOUT_CONNECT);
}else{
int optval = -1;
socklen_t optlen = sizeof(optval);
getsockopt(socketID, SOL_SOCKET, SO_ERROR, &optval, &optlen);
if (optval)
// Act as timeout
event->loop->onTimeOut(event->loop->communicator,event->node,CB_TIMEOUT_CONNECT);
else
// Connection successful
event->onEvent.ptr(event->loop->communicator,event->node);
}
}
Occasionally optval is given as 61 (ECONNREFUSED). Still begs the question, why is there a ECONNREFUSED for a loopback connection?
Edit: Fixed it, needed to use SO_REUSEADDR.
Problem now seems to be that the connecting CBNetworkCommunicator is not replying to getaddr requests.
Edit 2: Well the reason why is because the addresses are not broadcast. So you might expect the connecting CBNetworkCommunicator to relay the addresses when they are broadcast but this is only done for unsolicited addr messages and at the time the CBNetworkCommunicator has made the original getaddr request so it does not relay the addresses. As far as I can tell this is successfully following the behaviour of the original client. I'll simply set the addresses as being public so that they are always given in getaddr responses.