static sock_t new_listening_TCP_socket(int family, uint16_t port) { sock_t sock = socket(family, SOCK_STREAM, IPPROTO_TCP); if (!sock_valid(sock)) { return ~0; } int ok = set_socket_nonblock(sock); if (ok && family == AF_INET6) { ok = set_socket_dualstack(sock); } if (ok) { ok = set_socket_reuseaddr(sock); } ok = ok && bind_to_port(sock, family, port) && (listen(sock, TCP_MAX_BACKLOG) == 0); if (!ok) { kill_sock(sock); return ~0; } return sock; }
static int kr_interweb_server_socket_setup(char *interface, int port) { char port_string[6]; struct addrinfo hints; struct addrinfo *result, *rp; int s; int sfd = 0; char *interface_actual; interface_actual = interface; printk ("Krad Interweb Server: interface: %s port %d", interface, port); snprintf (port_string, 6, "%d", port); memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ hints.ai_flags = AI_PASSIVE; /* All interfaces */ if ((strlen(interface) == 7) && (strncmp(interface, "0.0.0.0", 7) == 0)) { hints.ai_family = AF_INET; interface_actual = NULL; } if ((strlen(interface) == 4) && (strncmp(interface, "[::]", 4) == 0)) { hints.ai_family = AF_INET6; interface_actual = NULL; } s = getaddrinfo (interface_actual, port_string, &hints, &result); if (s != 0) { printke ("getaddrinfo: %s\n", gai_strerror (s)); return -1; } for (rp = result; rp != NULL; rp = rp->ai_next) { sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd == -1) { continue; } set_socket_reuseaddr(sfd); s = bind (sfd, rp->ai_addr, rp->ai_addrlen); if (s == 0) { /* We managed to bind successfully! */ break; } close (sfd); } if (rp == NULL) { printke ("Could not bind %d\n", port); return -1; } freeaddrinfo (result); return sfd; }