*
* This file is part of x3.
*
- * srvx is free software; you can redistribute it and/or modify
+ * x3 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
ioset_connect(struct sockaddr *local, unsigned int sa_size, const char *peer, unsigned int port, int blocking, void *data, void (*connect_cb)(struct io_fd *fd, int error)) {
int fd, res;
struct io_fd *io_fd;
- struct sockaddr_in sin;
- unsigned long ip;
-
- if (!getipbyname(peer, &ip)) {
- log_module(MAIN_LOG, LOG_ERROR, "getipbyname(%s) failed.", peer);
+ struct addrinfo hints, *ai;
+ char portnum[10];
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = local ? local->sa_family : 0;
+ hints.ai_socktype = SOCK_STREAM;
+ snprintf(portnum, sizeof(portnum), "%u", port);
+ if (getaddrinfo(peer, portnum, &hints, &ai)) {
+ log_module(MAIN_LOG, LOG_ERROR, "getaddrinfo(%s, %s) failed.", peer, portnum);
return NULL;
}
- sin.sin_addr.s_addr = ip;
+
if (local) {
if ((fd = socket(local->sa_family, SOCK_STREAM, 0)) < 0) {
log_module(MAIN_LOG, LOG_ERROR, "socket() for %s returned errno %d (%s)", peer, errno, strerror(errno));
+ freeaddrinfo(ai);
return NULL;
}
if (bind(fd, local, sa_size) < 0) {
} else {
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
log_module(MAIN_LOG, LOG_ERROR, "socket() for %s returned errno %d (%s).", peer, errno, strerror(errno));
+ freeaddrinfo(ai);
return NULL;
}
}
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
+
if (blocking) {
- res = connect(fd, (struct sockaddr*)&sin, sizeof(sin));
+ res = connect(fd, ai->ai_addr, ai->ai_addrlen);
io_fd = ioset_add(fd);
} else {
io_fd = ioset_add(fd);
- res = connect(fd, (struct sockaddr*)&sin, sizeof(sin));
+ res = connect(fd, ai->ai_addr, ai->ai_addrlen);
}
+ freeaddrinfo(ai);
if (!io_fd) {
close(fd);
return NULL;
fd->readable_cb(fd);
}
if (FD_ISSET(nn, &write_fds) && !fd->connected) {
- int rc, arglen = sizeof(rc);
+ socklen_t arglen;
+ int rc;
+
+ arglen = sizeof(rc);
if (getsockopt(fd->fd, SOL_SOCKET, SO_ERROR, &rc, &arglen) < 0)
rc = errno;
fd->connected = 1;