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:
@@ -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)
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
93
src/bind.c
93
src/bind.c
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user