1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-05 20:55:46 +03:00

server: Replace gethostbyname() with getaddrinfo().

Fixes rlo#13.
This commit is contained in:
Andreas Schneider
2010-12-27 21:40:18 +01:00
parent a0e98f585a
commit b4c62ac9ea
3 changed files with 53 additions and 49 deletions

View File

@@ -91,11 +91,6 @@ if (UNIX)
if (HAVE_LIBSOCKET) if (HAVE_LIBSOCKET)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} socket) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} socket)
endif (HAVE_LIBSOCKET) endif (HAVE_LIBSOCKET)
# libnsl (Solaris)
check_library_exists(nsl gethostbyname "" HAVE_LIBNSL)
if (HAVE_LIBNSL)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} nsl)
endif (HAVE_LIBNSL)
# libresolv # libresolv
check_library_exists(resolv hstrerror "" HAVE_LIBRESOLV) check_library_exists(resolv hstrerror "" HAVE_LIBRESOLV)
if (HAVE_LIBRESOLV) if (HAVE_LIBRESOLV)
@@ -109,7 +104,6 @@ if (UNIX)
endif (NOT LINUX) endif (NOT LINUX)
check_function_exists(getaddrinfo HAVE_GETADDRINFO) check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_function_exists(gethostbyname HAVE_GETHOSTBYNAME)
check_function_exists(poll HAVE_POLL) check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT) check_function_exists(select HAVE_SELECT)
check_function_exists(cfmakeraw HAVE_CFMAKERAW) check_function_exists(cfmakeraw HAVE_CFMAKERAW)

View File

@@ -68,9 +68,6 @@
/* Define to 1 if you have the `getaddrinfo' function. */ /* Define to 1 if you have the `getaddrinfo' function. */
#cmakedefine HAVE_GETADDRINFO 1 #cmakedefine HAVE_GETADDRINFO 1
/* Define to 1 if you have the `gethostbyname' function. */
#cmakedefine HAVE_GETHOSTBYNAME 1
/* Define to 1 if you have the `poll' function. */ /* Define to 1 if you have the `poll' function. */
#cmakedefine HAVE_POLL 1 #cmakedefine HAVE_POLL 1

View File

@@ -51,11 +51,14 @@
#include <winsock2.h> #include <winsock2.h>
#define SOCKOPT_TYPE_ARG4 char #define SOCKOPT_TYPE_ARG4 char
/* We need to provide hstrerror. Not we can't call the parameter h_errno because it's #defined */ /*
* We need to provide hstrerror. Not we can't call the parameter h_errno
* because it's #defined
*/
static char *hstrerror(int h_errno_val) { static char *hstrerror(int h_errno_val) {
static char text[50] = {0}; static char text[50] = {0};
snprintf(text, sizeof(text), "gethostbyname error %d\n", h_errno_val); snprintf(text, sizeof(text), "getaddrino error %d\n", h_errno_val);
return text; return text;
} }
@@ -68,53 +71,63 @@ static char *hstrerror(int h_errno_val) {
#endif /* _WIN32 */ #endif /* _WIN32 */
/* TODO FIXME: must use getaddrinfo */
static socket_t bind_socket(ssh_bind sshbind, const char *hostname, static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
int port) { int port) {
struct sockaddr_in myaddr; char port_c[6];
struct hostent *hp=NULL; struct addrinfo *ai;
socket_t s; struct addrinfo hints;
int opt = 1; int opt = 1;
socket_t s;
int rc;
s = socket(PF_INET, SOCK_STREAM, 0); ZERO_STRUCT(hints);
if (s < 0) {
ssh_set_error(sshbind, SSH_FATAL, "%s", strerror(errno));
return -1;
}
#ifdef HAVE_GETHOSTBYNAME hints.ai_flags = AI_PASSIVE;
hp = gethostbyname(hostname); hints.ai_socktype = SOCK_STREAM;
#endif
if (hp == NULL) { snprintf(port_c, 6, "%d", port);
ssh_set_error(sshbind, SSH_FATAL, rc = getaddrinfo(hostname, port_c, &hints, &ai);
"Resolving %s: %s", hostname, hstrerror(h_errno)); if (rc != 0) {
close(s); ssh_set_error(sshbind,
return -1; SSH_FATAL,
} "Resolving %s: %s", hostname, gai_strerror(rc));
return -1;
}
memset(&myaddr, 0, sizeof(myaddr)); s = socket (ai->ai_family,
memcpy(&myaddr.sin_addr, hp->h_addr, hp->h_length); ai->ai_socktype,
myaddr.sin_family = hp->h_addrtype; ai->ai_protocol);
myaddr.sin_port = htons(port); if (s == SSH_INVALID_SOCKET) {
ssh_set_error(sshbind, SSH_FATAL, "%s", strerror(errno));
freeaddrinfo (ai);
return -1;
}
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) { if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
ssh_set_error(sshbind, SSH_FATAL, (char *)&opt, sizeof(opt)) < 0) {
"Setting socket options failed: %s", hstrerror(h_errno)); ssh_set_error(sshbind,
close(s); SSH_FATAL,
return -1; "Setting socket options failed: %s",
} hstrerror(h_errno));
freeaddrinfo (ai);
close(s);
return -1;
}
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) { if (bind(s, ai->ai_addr, ai->ai_addrlen) != 0) {
ssh_set_error(sshbind, SSH_FATAL, "Binding to %s:%d: %s", ssh_set_error(sshbind,
hostname, SSH_FATAL,
port, "Binding to %s:%d: %s",
strerror(errno)); hostname,
close(s); port,
return -1; strerror(errno));
} freeaddrinfo (ai);
close(s);
return -1;
}
return s; freeaddrinfo (ai);
return s;
} }
ssh_bind ssh_bind_new(void) { ssh_bind ssh_bind_new(void) {