int connection_init (connection_t *con, sock_t sock, const char *addr) { if (con) { memset (con, 0, sizeof (connection_t)); con->sock = sock; if (sock == SOCK_ERROR) return -1; if (addr) { char *ip; if (strncmp (addr, "::ffff:", 7) == 0) ip = strdup (addr+7); else ip = strdup (addr); if (accept_ip_address (ip)) { con->ip = ip; con->id = _next_connection_id(); return 0; } free (ip); } con->sock = SOCK_ERROR; } return -1; }
static connection_t *_accept_connection(int duration) { sock_t sock, serversock; char *ip; serversock = wait_for_serversock (duration); if (serversock == SOCK_ERROR) return NULL; /* malloc enough room for a full IP address (including ipv6) */ ip = (char *)malloc(MAX_ADDR_LEN); sock = sock_accept(serversock, ip, MAX_ADDR_LEN); if (sock != SOCK_ERROR) { connection_t *con = NULL; /* Make any IPv4 mapped IPv6 address look like a normal IPv4 address */ if (strncmp (ip, "::ffff:", 7) == 0) memmove (ip, ip+7, strlen (ip+7)+1); if (accept_ip_address (ip)) con = connection_create (sock, serversock, ip); if (con) return con; sock_close (sock); } else { if (!sock_recoverable(sock_error())) { WARN2("accept() failed with error %d: %s", sock_error(), strerror(sock_error())); thread_sleep (500000); } } free(ip); return NULL; }