struct tls *ctx;
};
-static int setsockint(int sockfd, int level, int optname, int optval)
-{
- return setsockopt(sockfd, level, optname, (void *)&optval, sizeof(optval));
-}
static listener create_listen_sock(const char *ip, const char *port, struct tls *ctx)
{
- struct addrinfo hints, *res;
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
- hints.ai_socktype = SOCK_STREAM;
- int err = getaddrinfo(ip, port, &hints, &res);
- if (err) {
- fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
- exit(EXIT_FAILURE);
- }
+ net_addrinfo ai(ip, port, 0, SOCK_STREAM, 0, AI_NUMERICHOST | AI_NUMERICSERV);
+ if (ai.err)
+ ai.perror("getaddrinfo"), exit(1);
- SOCKET sock;
- // Create socket
- sock = socket(res->ai_family, res->ai_socktype|SOCK_CLOEXEC, res->ai_protocol);
- if(sock == (SOCKET)INVALID_SOCKET) {
- net_perror("socket");
- freeaddrinfo(res);
- exit(EXIT_FAILURE);
- }
- // Set socket options
- if (setsockint(sock, SOL_SOCKET, SO_REUSEADDR, 1) == -1) {
- net_perror("setsockopt(SO_REUSEADDR)");
- freeaddrinfo(res);
- exit(EXIT_FAILURE);
- }
- if (res->ai_family == AF_INET6 && setsockint(sock, IPPROTO_IPV6, IPV6_V6ONLY, 1) == -1) {
- net_perror("setsockopt(IPV6_V6ONLY)");
- freeaddrinfo(res);
- exit(EXIT_FAILURE);
- }
- // Bind to socket
- if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
- net_perror("bind");
- freeaddrinfo(res);
- exit(EXIT_FAILURE);
- }
- freeaddrinfo(res);
- // Listen to socket
- if(listen(sock, SOMAXCONN) == -1) {
- net_perror("listen");
- exit(EXIT_FAILURE);
- }
+ SOCKET sock = socket(ai->ai_family, ai->ai_socktype|SOCK_CLOEXEC, ai->ai_protocol);
+ if(sock == INVALID_SOCKET)
+ net_perror("socket"), exit(1);
+ if (net_setsockint(sock, SOL_SOCKET, SO_REUSEADDR, 1) == -1)
+ net_perror("setsockopt(SO_REUSEADDR)"), exit(1);
+ if (ai->ai_family == AF_INET6 && net_setsockint(sock, IPPROTO_IPV6, IPV6_V6ONLY, 1) == -1)
+ net_perror("setsockopt(IPV6_V6ONLY)"), exit(1);
+ if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1)
+ net_perror("bind"), exit(1);
+ if (listen(sock, SOMAXCONN) == -1)
+ net_perror("listen"), exit(1);
return listener{sock, ctx};
}
struct sockaddr_storage addr;
socklen_t len = sizeof(addr);
SOCKET newSocket = accept4(listener->sock, (struct sockaddr *)&addr, &len, SOCK_CLOEXEC);
- if (newSocket == (SOCKET)INVALID_SOCKET) {
+ if (newSocket == INVALID_SOCKET) {
if (!net_wouldblock())
net_perror("accept4");
break;
{
// enable keepalive
- setsockint(newSocket, SOL_SOCKET, SO_KEEPALIVE, 1);
+ net_setsockint(newSocket, SOL_SOCKET, SO_KEEPALIVE, 1);
#ifdef TCP_KEEPIDLE
- setsockint(newSocket, IPPROTO_TCP, TCP_KEEPIDLE, 30);
+ net_setsockint(newSocket, IPPROTO_TCP, TCP_KEEPIDLE, 30);
#endif
#ifdef TCP_KEEPINTVL
- setsockint(newSocket, IPPROTO_TCP, TCP_KEEPINTVL, 1);
+ net_setsockint(newSocket, IPPROTO_TCP, TCP_KEEPINTVL, 1);
#endif
#ifdef TCP_KEEPCNT
- setsockint(newSocket, IPPROTO_TCP, TCP_KEEPCNT, 10);
+ net_setsockint(newSocket, IPPROTO_TCP, TCP_KEEPCNT, 10);
#endif
}
{
struct sockaddr_storage sockname;
socklen_t socknamelen = sizeof(sockname);
- if (getsockname(newSocket, (struct sockaddr *)&sockname, &socknamelen) == -1) {
- net_perror("getsockname");
- exit(EXIT_FAILURE);
- }
+ if (getsockname(newSocket, (struct sockaddr *)&sockname, &socknamelen) == -1)
+ net_perror("getsockname"), abortf("getsockname failure during accept");
if (sockname.ss_family == AF_INET) {
struct in_addr *ia = &((struct sockaddr_in *)&sockname)->sin_addr;
// onion if connecting to 127.0.0.2
else
fprintf(stderr, "%s\n", net_strerror(net_errno()));
}
+
+net_addrinfo::net_addrinfo(const char *node, const char *service, int ai_family, int ai_socktype, int ai_protocol, int ai_flags) {
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = ai_flags;
+ hints.ai_family = ai_family;
+ hints.ai_socktype = ai_socktype;
+ hints.ai_protocol = ai_protocol;
+ res = 0;
+ err = getaddrinfo(node, service, &hints, &res);
+}
+net_addrinfo::~net_addrinfo() {
+ if (err == 0)
+ freeaddrinfo(res);
+}
+void net_addrinfo::perror(const char *p) {
+ if (p && *p)
+ fprintf(stderr, "%s: %s\n", p, gai_strerror(err));
+ else
+ fprintf(stderr, " %s\n", gai_strerror(err));
+}
+struct addrinfo *net_addrinfo::operator->() {
+ return res;
+}
+
+int net_setsockint(int sockfd, int level, int optname, int optval)
+{
+ return setsockopt(sockfd, level, optname, (void *)&optval, sizeof(optval));
+}