aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cynapses.org>2010-12-27 21:40:18 +0100
committerAndreas Schneider <asn@cynapses.org>2010-12-27 21:51:55 +0100
commitb4c62ac9ea7cc41a1c8c3fa062dee01f13d98e66 (patch)
tree8a38c144af789b2ca40522a08554313a81a5d3df
parenta0e98f585a36e0032545107dbd90c6adab40e09b (diff)
downloadlibssh-b4c62ac9ea7cc41a1c8c3fa062dee01f13d98e66.tar.gz
libssh-b4c62ac9ea7cc41a1c8c3fa062dee01f13d98e66.tar.xz
libssh-b4c62ac9ea7cc41a1c8c3fa062dee01f13d98e66.zip
server: Replace gethostbyname() with getaddrinfo().
Fixes rlo#13.
-rw-r--r--ConfigureChecks.cmake6
-rw-r--r--config.h.cmake3
-rw-r--r--src/bind.c99
3 files changed, 56 insertions, 52 deletions
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 8723496..17025c5 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -91,11 +91,6 @@ if (UNIX)
if (HAVE_LIBSOCKET)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} socket)
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
check_library_exists(resolv hstrerror "" HAVE_LIBRESOLV)
if (HAVE_LIBRESOLV)
@@ -109,7 +104,6 @@ if (UNIX)
endif (NOT LINUX)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
- check_function_exists(gethostbyname HAVE_GETHOSTBYNAME)
check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT)
check_function_exists(cfmakeraw HAVE_CFMAKERAW)
diff --git a/config.h.cmake b/config.h.cmake
index ba98214..462f513 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -68,9 +68,6 @@
/* Define to 1 if you have the `getaddrinfo' function. */
#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. */
#cmakedefine HAVE_POLL 1
diff --git a/src/bind.c b/src/bind.c
index c002035..d0dfa88 100644
--- a/src/bind.c
+++ b/src/bind.c
@@ -51,11 +51,14 @@
#include <winsock2.h>
#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 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;
}
@@ -68,53 +71,63 @@ static char *hstrerror(int h_errno_val) {
#endif /* _WIN32 */
-/* TODO FIXME: must use getaddrinfo */
static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
int port) {
- struct sockaddr_in myaddr;
- struct hostent *hp=NULL;
- socket_t s;
- int opt = 1;
-
- s = socket(PF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- ssh_set_error(sshbind, SSH_FATAL, "%s", strerror(errno));
- return -1;
- }
-
-#ifdef HAVE_GETHOSTBYNAME
- hp = gethostbyname(hostname);
-#endif
-
- if (hp == NULL) {
- ssh_set_error(sshbind, SSH_FATAL,
- "Resolving %s: %s", hostname, hstrerror(h_errno));
- close(s);
- return -1;
- }
+ char port_c[6];
+ struct addrinfo *ai;
+ struct addrinfo hints;
+ int opt = 1;
+ socket_t s;
+ int rc;
+
+ ZERO_STRUCT(hints);
+
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_socktype = SOCK_STREAM;
+
+ snprintf(port_c, 6, "%d", port);
+ rc = getaddrinfo(hostname, port_c, &hints, &ai);
+ if (rc != 0) {
+ ssh_set_error(sshbind,
+ SSH_FATAL,
+ "Resolving %s: %s", hostname, gai_strerror(rc));
+ return -1;
+ }
- memset(&myaddr, 0, sizeof(myaddr));
- memcpy(&myaddr.sin_addr, hp->h_addr, hp->h_length);
- myaddr.sin_family = hp->h_addrtype;
- myaddr.sin_port = htons(port);
+ s = socket (ai->ai_family,
+ ai->ai_socktype,
+ ai->ai_protocol);
+ 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) {
- ssh_set_error(sshbind, SSH_FATAL,
- "Setting socket options failed: %s", hstrerror(h_errno));
- close(s);
- return -1;
- }
+ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&opt, sizeof(opt)) < 0) {
+ ssh_set_error(sshbind,
+ SSH_FATAL,
+ "Setting socket options failed: %s",
+ hstrerror(h_errno));
+ freeaddrinfo (ai);
+ close(s);
+ return -1;
+ }
- if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {
- ssh_set_error(sshbind, SSH_FATAL, "Binding to %s:%d: %s",
- hostname,
- port,
- strerror(errno));
- close(s);
- return -1;
- }
+ if (bind(s, ai->ai_addr, ai->ai_addrlen) != 0) {
+ ssh_set_error(sshbind,
+ SSH_FATAL,
+ "Binding to %s:%d: %s",
+ hostname,
+ port,
+ strerror(errno));
+ freeaddrinfo (ai);
+ close(s);
+ return -1;
+ }
- return s;
+ freeaddrinfo (ai);
+ return s;
}
ssh_bind ssh_bind_new(void) {