Browse Source

[core] inet_pton(), inet_ntop() on (sock_addr *)

shared code to provide inet_pton() and inet_ntop() behavior on
lighttpd (sock_addr *) and (buffer *) data structures.
personal/stbuehler/mod-csrf
Glenn Strauss 5 years ago
parent
commit
a448886485
  1. 13
      src/http-header-glue.c
  2. 89
      src/inet_ntop_cache.c
  3. 7
      src/inet_ntop_cache.h
  4. 21
      src/mod_proxy.c
  5. 27
      src/request.c
  6. 14
      src/sys-socket.h

13
src/http-header-glue.c

@ -7,6 +7,7 @@
#include "log.h"
#include "etag.h"
#include "http_chunk.h"
#include "inet_ntop_cache.h"
#include "response.h"
#include "stat_cache.h"
@ -1536,8 +1537,8 @@ int http_cgi_headers (server *srv, connection *con, http_cgi_opts *opts, http_cg
break;
}
}
s = inet_ntop(AF_INET6, (const void *) &(addr->ipv6.sin6_addr),
b2, sizeof(b2)-1);
s = sock_addr_inet_ntop(addr, b2, sizeof(b2)-1);
if (NULL == s) s = "";
break;
#endif
case AF_INET:
@ -1550,12 +1551,8 @@ int http_cgi_headers (server *srv, connection *con, http_cgi_opts *opts, http_cg
break;
}
}
#ifdef HAVE_IPV6
s = inet_ntop(AF_INET, (const void *) &(addr->ipv4.sin_addr),
b2, sizeof(b2)-1);
#else
s = inet_ntoa(addr->ipv4.sin_addr);
#endif
s = sock_addr_inet_ntop(addr, b2, sizeof(b2)-1);
if (NULL == s) s = "";
break;
default:
s = "";

89
src/inet_ntop_cache.c

@ -1,13 +1,90 @@
#include "first.h"
#include "base.h"
#include "inet_ntop_cache.h"
#include "sys-socket.h"
#include "base.h"
#include "sys-socket.h"
#include <sys/types.h>
#include <errno.h>
#include <string.h>
int sock_addr_inet_pton(sock_addr *addr, const char *str,
int family, unsigned short port)
{
if (AF_INET == family) {
memset(&addr->ipv4, 0, sizeof(struct sockaddr_in));
addr->ipv4.sin_family = AF_INET;
addr->ipv4.sin_port = htons(port);
#if defined(HAVE_INET_ATON) /*(Windows does not provide inet_aton())*/
return (0 != inet_aton(str, &addr->ipv4.sin_addr));
#else
return ((addr->ipv4.sin_addr.s_addr = inet_addr(str)) != INADDR_NONE);
#endif
}
#ifdef HAVE_IPV6
else if (AF_INET6 == family) {
memset(&addr->ipv6, 0, sizeof(struct sockaddr_in6));
addr->ipv6.sin6_family = AF_INET6;
addr->ipv6.sin6_port = htons(port);
return inet_pton(AF_INET6, str, &addr->ipv6.sin6_addr);
}
#endif
else {
errno = EAFNOSUPPORT;
return -1;
}
}
const char * sock_addr_inet_ntop(const sock_addr *addr, char *buf, socklen_t sz)
{
if (addr->plain.sa_family == AF_INET) {
#if defined(HAVE_INET_PTON) /*(expect inet_ntop if inet_pton)*/
return inet_ntop(AF_INET,(const void *)&addr->ipv4.sin_addr,buf,sz);
#else /*(inet_ntoa() not thread-safe)*/
return inet_ntoa(addr->ipv4.sin_addr);
#endif
}
#ifdef HAVE_IPV6
else if (addr->plain.sa_family == AF_INET6) {
return inet_ntop(AF_INET6,(const void *)&addr->ipv6.sin6_addr,buf,sz);
}
#endif
#ifdef HAVE_SYS_UN_H
else if (addr->plain.sa_family == AF_UNIX) {
return addr->un.sun_path;
}
#endif
else {
errno = EAFNOSUPPORT;
return NULL;
}
}
int sock_addr_inet_ntop_copy_buffer(buffer *b, const sock_addr *addr)
{
/*(incur cost of extra copy to avoid potential extra memory allocation)*/
char buf[UNIX_PATH_MAX];
const char *s = sock_addr_inet_ntop(addr, buf, sizeof(buf));
if (NULL == s) return -1; /*(buffer not modified if any error occurs)*/
buffer_copy_string(b, s);
return 0;
}
int sock_addr_inet_ntop_append_buffer(buffer *b, const sock_addr *addr)
{
/*(incur cost of extra copy to avoid potential extra memory allocation)*/
char buf[UNIX_PATH_MAX];
const char *s = sock_addr_inet_ntop(addr, buf, sizeof(buf));
if (NULL == s) return -1; /*(buffer not modified if any error occurs)*/
buffer_append_string(b, s);
return 0;
}
const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {
#ifdef HAVE_IPV6
size_t ndx = 0, i;
@ -28,13 +105,19 @@ const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {
if (i == INET_NTOP_CACHE_MAX) {
/* not found in cache */
const char *s;
/* TODO: ndx is never modified above;
* inet_ntop_cache is effectively a 1-element cache */
i = ndx;
s =
inet_ntop(addr->plain.sa_family,
addr->plain.sa_family == AF_INET6 ?
(const void *) &(addr->ipv6.sin6_addr) :
(const void *) &(addr->ipv4.sin_addr),
srv->inet_ntop_cache[i].b2, INET6_ADDRSTRLEN);
if (NULL == s) return "";
srv->inet_ntop_cache[i].ts = srv->cur_ts;
srv->inet_ntop_cache[i].family = addr->plain.sa_family;

7
src/inet_ntop_cache.h

@ -3,6 +3,13 @@
#include "first.h"
#include "base.h"
int sock_addr_inet_pton(sock_addr *addr, const char *str, int family, unsigned short port);
const char * sock_addr_inet_ntop(const sock_addr *addr, char *buf, socklen_t sz);
int sock_addr_inet_ntop_copy_buffer(buffer *b, const sock_addr *addr);
int sock_addr_inet_ntop_append_buffer(buffer *b, const sock_addr *addr);
const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr);
#endif

21
src/mod_proxy.c

@ -7,6 +7,7 @@
#include "http_chunk.h"
#include "fdevent.h"
#include "inet_ntop_cache.h"
#include "connections.h"
#include "response.h"
#include "joblist.h"
@ -809,31 +810,15 @@ static void proxy_set_Forwarded(connection *con, const unsigned int flags) {
buffer_append_string_len(ds->value, CONST_STR_LEN("\""));
if (addr->plain.sa_family == AF_INET) {
if (0==getsockname(con->fd,(struct sockaddr *)&addrbuf,&addrlen)) {
#if defined(HAVE_INET_PTON)/*(expect inet_ntop if inet_pton)*/
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
char buf[INET_ADDRSTRLEN];
buf[0] = '\0';
inet_ntop(AF_INET, (const void *)&addrbuf.ipv4.sin_addr,
buf, sizeof(buf));
buffer_append_string(ds->value, buf);
#else
buffer_append_string(ds->value,/*(inet_ntoa() not thread-safe)*/
inet_ntoa(addrbuf.ipv4.sin_addr));
#endif
sock_addr_inet_ntop_append_buffer(ds->value, &addrbuf);
}
buffer_append_string_len(ds->value, CONST_STR_LEN(":"));
buffer_append_int(ds->value, ntohs(addr->ipv4.sin_port));
#ifdef HAVE_IPV6
} else if (addr->plain.sa_family == AF_INET6) {
if (0 == getsockname(con->fd,(struct sockaddr *)&addrbuf,&addrlen)){
char buf[INET6_ADDRSTRLEN];
buf[0] = '\0';
inet_ntop(AF_INET6, (const void *)&addrbuf.ipv6.sin6_addr,
buf, sizeof(buf));
buffer_append_string_len(ds->value, CONST_STR_LEN("["));
buffer_append_string(ds->value, buf);
sock_addr_inet_ntop_append_buffer(ds->value, &addrbuf);
buffer_append_string_len(ds->value, CONST_STR_LEN("]"));
buffer_append_string_len(ds->value, CONST_STR_LEN(":"));
buffer_append_int(ds->value, ntohs(addr->ipv6.sin6_port));

27
src/request.c

@ -3,6 +3,7 @@
#include "request.h"
#include "keyvalue.h"
#include "log.h"
#include "inet_ntop_cache.h"
#include <sys/stat.h>
@ -250,29 +251,15 @@ int http_request_host_normalize(buffer *b) {
if (light_isdigit(*p)) {
/* (IPv4 address literal or domain starting w/ digit (e.g. 3com))*/
struct in_addr addr;
#if defined(HAVE_INET_ATON) /*(Windows does not provide inet_aton())*/
if (0 != inet_aton(p, &addr))
#else
if ((addr.s_addr = inet_addr(p)) != INADDR_NONE)
#endif
{
#if defined(HAVE_INET_PTON)/*(expect inet_ntop() if inet_pton())*/
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
char buf[INET_ADDRSTRLEN];
inet_ntop(AF_INET, (const void *)&addr, buf, sizeof(buf));
buffer_copy_string(b, buf);
#else
buffer_copy_string(b, inet_ntoa(addr)); /*(not thread-safe)*/
#endif
sock_addr addr;
if (1 == sock_addr_inet_pton(&addr, p, AF_INET, 0)) {
sock_addr_inet_ntop_copy_buffer(b, &addr);
}
}
} else { /* IPv6 addr */
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
struct in6_addr addr;
sock_addr addr;
char *bracket = b->ptr+blen-1;
char *percent = strchr(b->ptr+1, '%');
size_t len;
@ -297,12 +284,12 @@ int http_request_host_normalize(buffer *b) {
*bracket = '\0';/*(terminate IPv6 string)*/
if (percent) *percent = '\0'; /*(remove %interface from address)*/
rc = inet_pton(AF_INET6, b->ptr+1, &addr);
rc = sock_addr_inet_pton(&addr, b->ptr+1, AF_INET6, 0);
if (percent) *percent = '%'; /*(restore %interface)*/
*bracket = ']'; /*(restore bracket)*/
if (1 != rc) return -1;
inet_ntop(AF_INET6,(const void *)&addr, buf, sizeof(buf));
sock_addr_inet_ntop(&addr, buf, sizeof(buf));
len = strlen(buf);
if (percent) {
if (percent > bracket) return -1;

14
src/sys-socket.h

@ -10,12 +10,26 @@
#define EINPROGRESS WSAEINPROGRESS
#define EALREADY WSAEALREADY
#define ECONNABORTED WSAECONNABORTED
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/un.h>
#include <arpa/inet.h>
#endif
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX 108
#endif
#endif

Loading…
Cancel
Save