Skip to content
Snippets Groups Projects
Commit 7e37d10e authored by Andy Green's avatar Andy Green
Browse files

gethostbyname removal from lws get peer addresses


This replaces gethostbyname in libwebsockets_get_peer_addresses and
in the client handshake path.

There's one left in lws-plat-win but that can be done another time.

Let's see how much damage that did to the cross-platform and option
builds...

Signed-off-by: default avatarAndy Green <andy.green@linaro.org>
parent 6a779771
No related branches found
No related tags found
No related merge requests found
...@@ -12,7 +12,6 @@ struct libwebsocket *libwebsocket_client_connect_2( ...@@ -12,7 +12,6 @@ struct libwebsocket *libwebsocket_client_connect_2(
#endif #endif
struct sockaddr_in server_addr4; struct sockaddr_in server_addr4;
struct sockaddr_in client_addr4; struct sockaddr_in client_addr4;
struct hostent *server_hostent;
struct sockaddr *v; struct sockaddr *v;
int n; int n;
...@@ -97,15 +96,32 @@ struct libwebsocket *libwebsocket_client_connect_2( ...@@ -97,15 +96,32 @@ struct libwebsocket *libwebsocket_client_connect_2(
} else } else
#endif #endif
{ {
server_hostent = gethostbyname(ads); struct addrinfo ai, *res;
if (!server_hostent) { void *p = NULL;
lwsl_err("Unable to get host name from %s\n", ads);
memset (&ai, 0, sizeof ai);
ai.ai_family = PF_UNSPEC;
ai.ai_socktype = SOCK_STREAM;
ai.ai_flags = AI_CANONNAME;
if (getaddrinfo(ads, NULL, &ai, &res))
goto oom4; goto oom4;
while (!p && res) {
switch (res->ai_family) {
case AF_INET:
p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
break;
}
res = res->ai_next;
} }
if (!p)
goto oom4;
server_addr4.sin_family = AF_INET; server_addr4.sin_family = AF_INET;
server_addr4.sin_addr = server_addr4.sin_addr = *((struct in_addr *)p);
*((struct in_addr *)server_hostent->h_addr);
bzero(&server_addr4.sin_zero, 8); bzero(&server_addr4.sin_zero, 8);
} }
......
...@@ -295,6 +295,71 @@ just_kill_connection: ...@@ -295,6 +295,71 @@ just_kill_connection:
lws_free(wsi); lws_free(wsi);
} }
LWS_VISIBLE int
libwebsockets_get_addresses(struct libwebsocket_context *context,
void *ads, char *name, int name_len,
char *rip, int rip_len)
{
struct addrinfo ai, *res;
void *p = NULL;
rip[0] = '\0';
name[0] = '\0';
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {
if (!lws_plat_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ads)->sin6_addr, rip, rip_len)) {
lwsl_err("inet_ntop", strerror(LWS_ERRNO));
return -1;
}
// Strip off the IPv4 to IPv6 header if one exists
if (strncmp(rip, "::ffff:", 7) == 0)
memmove(rip, rip + 7, strlen(rip) - 6);
getnameinfo((struct sockaddr *)ads,
sizeof(struct sockaddr_in6), name,
name_len, NULL, 0, 0);
return 0;
} else
#endif
{
memset(&ai, 0, sizeof ai);
ai.ai_family = PF_UNSPEC;
ai.ai_socktype = SOCK_STREAM;
ai.ai_flags = AI_CANONNAME;
if (getnameinfo((struct sockaddr *)ads,
sizeof(struct sockaddr_in),
name, name_len, NULL, 0, 0))
return -1;
if (!rip)
return 0;
if (getaddrinfo(name, NULL, &ai, &res))
return -1;
while (!p && res) {
switch (res->ai_family) {
case AF_INET:
p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
break;
}
res = res->ai_next;
}
}
if (!p)
return -1;
inet_ntop(AF_INET, p, rip, rip_len);
return 0;
}
/** /**
* libwebsockets_get_peer_addresses() - Get client address information * libwebsockets_get_peer_addresses() - Get client address information
* @context: Libwebsockets context * @context: Libwebsockets context
...@@ -321,15 +386,8 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context, ...@@ -321,15 +386,8 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
#endif #endif
struct sockaddr_in sin4; struct sockaddr_in sin4;
struct hostent *host;
struct hostent *host1;
char ip[128];
unsigned char *p;
int n;
#ifdef AF_LOCAL
struct sockaddr_un *un;
#endif
int ret = -1; int ret = -1;
void *p;
rip[0] = '\0'; rip[0] = '\0';
name[0] = '\0'; name[0] = '\0';
...@@ -338,83 +396,26 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context, ...@@ -338,83 +396,26 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
#ifdef LWS_USE_IPV6 #ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) { if (LWS_IPV6_ENABLED(context)) {
len = sizeof(sin6); len = sizeof(sin6);
if (getpeername(fd, (struct sockaddr *) &sin6, &len) < 0) { p = &sin6;
lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
goto bail;
}
if (!lws_plat_inet_ntop(AF_INET6, &sin6.sin6_addr, rip, rip_len)) {
lwsl_err("inet_ntop", strerror(LWS_ERRNO));
goto bail;
}
// Strip off the IPv4 to IPv6 header if one exists
if (strncmp(rip, "::ffff:", 7) == 0)
memmove(rip, rip + 7, strlen(rip) - 6);
getnameinfo((struct sockaddr *)&sin6,
sizeof(struct sockaddr_in6), name,
name_len, NULL, 0, 0);
} else } else
#endif #endif
{ {
len = sizeof(sin4); len = sizeof(sin4);
if (getpeername(fd, (struct sockaddr *) &sin4, &len) < 0) { p = &sin4;
lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO)); }
goto bail;
}
host = gethostbyaddr((char *) &sin4.sin_addr,
sizeof(sin4.sin_addr), AF_INET);
if (host == NULL) {
lwsl_warn("gethostbyaddr: %s\n", strerror(LWS_ERRNO));
goto bail;
}
strncpy(name, host->h_name, name_len); if (getpeername(fd, p, &len) < 0) {
name[name_len - 1] = '\0'; lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
goto bail;
host1 = gethostbyname(host->h_name);
if (host1 == NULL)
goto bail;
p = (unsigned char *)host1;
n = 0;
while (p != NULL) {
p = (unsigned char *)host1->h_addr_list[n++];
if (p == NULL)
continue;
if ((host1->h_addrtype != AF_INET)
#ifdef AF_LOCAL
&& (host1->h_addrtype != AF_LOCAL)
#endif
)
continue;
if (host1->h_addrtype == AF_INET)
sprintf(ip, "%u.%u.%u.%u",
p[0], p[1], p[2], p[3]);
#ifdef AF_LOCAL
else {
un = (struct sockaddr_un *)p;
strncpy(ip, un->sun_path, sizeof(ip) - 1);
ip[sizeof(ip) - 1] = '\0';
}
#endif
p = NULL;
strncpy(rip, ip, rip_len);
rip[rip_len - 1] = '\0';
}
} }
ret = libwebsockets_get_addresses(context, p, name, name_len, rip, rip_len);
ret = 0;
bail: bail:
lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1); lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1);
} }
/** /**
* libwebsocket_context_user() - get the user data associated with the context * libwebsocket_context_user() - get the user data associated with the context
* @context: Websocket context * @context: Websocket context
......
/* /*
* libwebsockets - small server side websockets and web server implementation * libwebsockets - small server side websockets and web server implementation
* *
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com> * Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -62,6 +62,7 @@ extern "C" { ...@@ -62,6 +62,7 @@ extern "C" {
#include <poll.h> #include <poll.h>
#include <unistd.h> #include <unistd.h>
#include <netdb.h>
#if defined(__GNUC__) #if defined(__GNUC__)
#define LWS_VISIBLE __attribute__((visibility("default"))) #define LWS_VISIBLE __attribute__((visibility("default")))
......
...@@ -1162,6 +1162,10 @@ lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int l ...@@ -1162,6 +1162,10 @@ lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int l
#define _libwebsocket_rx_flow_control(_a) (0) #define _libwebsocket_rx_flow_control(_a) (0)
#define lws_handshake_server(_a, _b, _c, _d) (0) #define lws_handshake_server(_a, _b, _c, _d) (0)
#endif #endif
LWS_EXTERN int libwebsockets_get_addresses(struct libwebsocket_context *context,
void *ads, char *name, int name_len,
char *rip, int rip_len);
/* /*
* custom allocator * custom allocator
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment