1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-16 00:00:07 +01:00

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: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2015-01-28 21:03:49 +08:00
parent 6a779771f4
commit 7e37d10e47
4 changed files with 103 additions and 81 deletions

View file

@ -12,7 +12,6 @@ struct libwebsocket *libwebsocket_client_connect_2(
#endif
struct sockaddr_in server_addr4;
struct sockaddr_in client_addr4;
struct hostent *server_hostent;
struct sockaddr *v;
int n;
@ -97,15 +96,32 @@ struct libwebsocket *libwebsocket_client_connect_2(
} else
#endif
{
server_hostent = gethostbyname(ads);
if (!server_hostent) {
lwsl_err("Unable to get host name from %s\n", ads);
struct addrinfo ai, *res;
void *p = NULL;
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;
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_addr =
*((struct in_addr *)server_hostent->h_addr);
server_addr4.sin_addr = *((struct in_addr *)p);
bzero(&server_addr4.sin_zero, 8);
}

View file

@ -295,6 +295,71 @@ just_kill_connection:
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
* @context: Libwebsockets context
@ -321,15 +386,8 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
struct sockaddr_in6 sin6;
#endif
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;
void *p;
rip[0] = '\0';
name[0] = '\0';
@ -338,83 +396,26 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {
len = sizeof(sin6);
if (getpeername(fd, (struct sockaddr *) &sin6, &len) < 0) {
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);
p = &sin6;
} else
#endif
{
len = sizeof(sin4);
if (getpeername(fd, (struct sockaddr *) &sin4, &len) < 0) {
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);
name[name_len - 1] = '\0';
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';
}
p = &sin4;
}
ret = 0;
if (getpeername(fd, p, &len) < 0) {
lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
goto bail;
}
ret = libwebsockets_get_addresses(context, p, name, name_len, rip, rip_len);
bail:
lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1);
}
/**
* libwebsocket_context_user() - get the user data associated with the context
* @context: Websocket context

View file

@ -1,7 +1,7 @@
/*
* 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
* modify it under the terms of the GNU Lesser General Public
@ -62,6 +62,7 @@ extern "C" {
#include <poll.h>
#include <unistd.h>
#include <netdb.h>
#if defined(__GNUC__)
#define LWS_VISIBLE __attribute__((visibility("default")))

View file

@ -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 lws_handshake_server(_a, _b, _c, _d) (0)
#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