commits
tags
#include "net.h"
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#define NET_TIMEOUT_SEC 10
int net_connect(const char *host, int port, char *err, size_t errlen)
{
char portstr[16];
snprintf(portstr, sizeof(portstr), "%d", port);
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *res = NULL;
int rc = getaddrinfo(host, portstr, &hints, &res);
if (rc != 0) {
snprintf(err, errlen, "cannot resolve %s: %s", host, gai_strerror(rc));
return -1;
}
int fd = -1;
for (struct addrinfo *ai = res; ai != NULL; ai = ai->ai_next) {
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (fd < 0)
continue;
struct timeval tv;
tv.tv_sec = NET_TIMEOUT_SEC;
tv.tv_usec = 0;
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) {
break;
}
close(fd);
fd = -1;
}
freeaddrinfo(res);
if (fd < 0) {
snprintf(err, errlen, "cannot connect to %s:%d: %s", host, port, strerror(errno));
return -1;
}
return fd;
}