in adapters/socketio_berkeley.c [514:637]
static int initiate_socket_connection(SOCKET_IO_INSTANCE* socket_io_instance)
{
int result;
int flags;
struct addrinfo* addr = NULL;
struct sockaddr_un addrInfoUn;
if(socket_io_instance->address_type == ADDRESS_TYPE_IP)
{
if(!dns_resolver_is_lookup_complete(socket_io_instance->dns_resolver))
{
LogError("DNS did not resolve hostname IP address. Hostname:%s", socket_io_instance->hostname);
result = MU_FAILURE;
}
else
{
addr = dns_resolver_get_addrInfo(socket_io_instance->dns_resolver);
if (addr == NULL)
{
LogError("DNS resolution failed. Hostname:%s", socket_io_instance->hostname);
result = MU_FAILURE;
}
else
{
result = 0;
}
}
}
else
{
if (socket_io_instance->hostname != NULL)
{
size_t hostname_len = strlen(socket_io_instance->hostname);
if (hostname_len + 1 > sizeof(addrInfoUn.sun_path))
{
LogError("Hostname %s is too long for a unix socket (max len = %lu)", socket_io_instance->hostname, (unsigned long)sizeof(addrInfoUn.sun_path));
result = MU_FAILURE;
}
else
{
memset(&addrInfoUn, 0, sizeof(addrInfoUn));
addrInfoUn.sun_family = AF_UNIX;
// No need to add NULL terminator due to the above memset
(void)memcpy(addrInfoUn.sun_path, socket_io_instance->hostname, hostname_len);
result = 0;
}
}
else
{
LogError("Hostname is NULL");
result = MU_FAILURE;
}
}
if(result == 0)
{
if (socket_io_instance->address_type == ADDRESS_TYPE_IP)
{
socket_io_instance->socket = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
}
else
{
socket_io_instance->socket = socket(AF_UNIX, SOCK_STREAM, 0);
}
if (socket_io_instance->socket < SOCKET_SUCCESS)
{
LogError("Failure: socket create failure %d.", socket_io_instance->socket);
result = MU_FAILURE;
}
#ifndef __APPLE__
else if (socket_io_instance->target_mac_address != NULL &&
set_target_network_interface(socket_io_instance->socket, socket_io_instance->target_mac_address) != 0)
{
LogError("Failure: failed selecting target network interface (MACADDR=%s).", socket_io_instance->target_mac_address);
result = MU_FAILURE;
}
#endif //__APPLE__
else if ((-1 == (flags = fcntl(socket_io_instance->socket, F_GETFL, 0))) ||
(fcntl(socket_io_instance->socket, F_SETFL, flags | O_NONBLOCK) == -1))
{
LogError("Failure: fcntl failure.");
result = MU_FAILURE;
}
else
{
if (socket_io_instance->address_type == ADDRESS_TYPE_IP)
{
result = connect(socket_io_instance->socket, addr->ai_addr, addr->ai_addrlen);
}
else
{
result = connect(socket_io_instance->socket, (struct sockaddr *)&addrInfoUn, sizeof(addrInfoUn));
}
if ((result != 0) && (errno != EINPROGRESS))
{
LogError("Failure: connect failure %d.", errno);
result = MU_FAILURE;
}
else // result == 0 || errno == EINPROGRESS
{
// Async connect will return -1.
result = 0;
if (socket_io_instance->on_io_open_complete != NULL)
{
socket_io_instance->on_io_open_complete(socket_io_instance->on_io_open_complete_context, IO_OPEN_OK /*: IO_OPEN_ERROR*/);
}
}
}
if (result != 0)
{
if (socket_io_instance->socket >= SOCKET_SUCCESS)
{
close(socket_io_instance->socket);
}
socket_io_instance->socket = INVALID_SOCKET;
}
}
return result;
}