[MINOR] make use of addr_to_str() and get_host_port() to replace many inet_ntop()
Many inet_ntop calls were partially right, which was hard to detect given the complex combinations. Some of them were relying on the listener's proto instead of the address itself, which could have been different when dealing with an accept-proxy connection. The new addr_to_str() function does the dirty job and returns the family, which makes it particularly suited to calls from switch/case statements. A large number of if/else statements were removed and the stats output could even be cleaned up in the case of session dump. As a side effect of doing this, the resulting code is smaller by almost 1kB. All changed parts have been tested and provided expected output.
This commit is contained in:
parent
3c92c5f682
commit
631f01c2f1
@ -212,6 +212,14 @@ int url2ipv4(const char *addr, struct in_addr *dst);
|
||||
*/
|
||||
int url2sa(const char *url, int ulen, struct sockaddr_storage *addr);
|
||||
|
||||
/* Tries to convert a sockaddr_storage address to text form. Upon success, the
|
||||
* address family is returned so that it's easy for the caller to adapt to the
|
||||
* output format. Zero is returned if the address family is not supported. -1
|
||||
* is returned upon error, with errno set. AF_INET, AF_INET6 and AF_UNIX are
|
||||
* supported.
|
||||
*/
|
||||
int addr_to_str(struct sockaddr_storage *addr, char *str, int size);
|
||||
|
||||
/* will try to encode the string <string> replacing all characters tagged in
|
||||
* <map> with the hexadecimal representation of their ASCII-code (2 digits)
|
||||
* prefixed by <escape>, and will store the result between <start> (included)
|
||||
|
124
src/dumpstats.c
124
src/dumpstats.c
@ -2201,36 +2201,29 @@ static int stats_dump_proxy(struct stream_interface *si, struct proxy *px, struc
|
||||
chunk_printf(&msg, "<td class=ac");
|
||||
|
||||
if (uri->flags&ST_SHLGNDS) {
|
||||
char str[INET6_ADDRSTRLEN], *fmt = NULL;
|
||||
char str[INET6_ADDRSTRLEN];
|
||||
int port;
|
||||
|
||||
chunk_printf(&msg, " title=\"IP: ");
|
||||
chunk_printf(&msg, " title=\"");
|
||||
|
||||
port = (l->addr.ss_family == AF_INET6)
|
||||
? ntohs(((struct sockaddr_in6 *)(&l->addr))->sin6_port)
|
||||
: ntohs(((struct sockaddr_in *)(&l->addr))->sin_port);
|
||||
|
||||
if (l->addr.ss_family == AF_INET) {
|
||||
if (inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)&l->addr)->sin_addr,
|
||||
str, sizeof(str)))
|
||||
fmt = "%s:%d";
|
||||
} else {
|
||||
if (inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)(&l->addr))->sin6_addr,
|
||||
str, sizeof(str)))
|
||||
fmt = "[%s]:%d";
|
||||
port = get_host_port(&l->addr);
|
||||
switch (addr_to_str(&l->addr, str, sizeof(str))) {
|
||||
case AF_INET:
|
||||
chunk_printf(&msg, "IPv4: %s:%d, ", str, port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
chunk_printf(&msg, "IPv6: [%s]:%d, ", str, port);
|
||||
break;
|
||||
case AF_UNIX:
|
||||
chunk_printf(&msg, "unix, ");
|
||||
break;
|
||||
case -1:
|
||||
chunk_printf(&msg, "(%s), ", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (fmt)
|
||||
chunk_printf(&msg, fmt, str, port);
|
||||
else
|
||||
chunk_printf(&msg, "(%s)", strerror(errno));
|
||||
|
||||
/* id */
|
||||
chunk_printf(&msg, ", id: %d", l->luid);
|
||||
|
||||
chunk_printf(&msg, "\"");
|
||||
chunk_printf(&msg, "id: %d\"", l->luid);
|
||||
}
|
||||
|
||||
chunk_printf(&msg,
|
||||
@ -2393,26 +2386,27 @@ static int stats_dump_proxy(struct stream_interface *si, struct proxy *px, struc
|
||||
if (uri->flags&ST_SHLGNDS) {
|
||||
char str[INET6_ADDRSTRLEN];
|
||||
|
||||
chunk_printf(&msg, " title=\"IP: ");
|
||||
chunk_printf(&msg, " title=\"");
|
||||
|
||||
/* IP */
|
||||
switch (sv->addr.ss_family) {
|
||||
switch (addr_to_str(&sv->addr, str, sizeof(str))) {
|
||||
case AF_INET:
|
||||
if (inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)&sv->addr)->sin_addr, str, sizeof(str)))
|
||||
chunk_printf(&msg, "%s:%d", str, htons(((struct sockaddr_in *)&sv->addr)->sin_port));
|
||||
else
|
||||
chunk_printf(&msg, "(%s)", strerror(errno));
|
||||
chunk_printf(&msg, "IPv4: %s:%d, ", str, get_host_port(&sv->addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)&sv->addr)->sin6_addr, str, sizeof(str)))
|
||||
chunk_printf(&msg, "%s:%d", str, htons(((struct sockaddr_in6 *)&sv->addr)->sin6_port));
|
||||
else
|
||||
chunk_printf(&msg, "(%s)", strerror(errno));
|
||||
chunk_printf(&msg, "IPv6: [%s]:%d, ", str, get_host_port(&sv->addr));
|
||||
break;
|
||||
case AF_UNIX:
|
||||
chunk_printf(&msg, "unix, ");
|
||||
break;
|
||||
case -1:
|
||||
chunk_printf(&msg, "(%s), ", strerror(errno));
|
||||
break;
|
||||
default: /* address family not supported */
|
||||
break;
|
||||
}
|
||||
|
||||
/* id */
|
||||
chunk_printf(&msg, ", id: %d", sv->puid);
|
||||
chunk_printf(&msg, "id: %d", sv->puid);
|
||||
|
||||
/* cookie */
|
||||
if (sv->cookie) {
|
||||
@ -2997,30 +2991,14 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
|
||||
sess->uniq_id,
|
||||
sess->listener->proto->name);
|
||||
|
||||
switch (sess->listener->proto->sock_family) {
|
||||
switch (addr_to_str(&sess->si[0].addr.c.from, pn, sizeof(pn))) {
|
||||
case AF_INET:
|
||||
inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)&sess->si[0].addr.c.from)->sin_addr,
|
||||
pn, sizeof(pn));
|
||||
|
||||
chunk_printf(&msg,
|
||||
" source=%s:%d\n",
|
||||
pn,
|
||||
ntohs(((struct sockaddr_in *)&sess->si[0].addr.c.from)->sin_port));
|
||||
break;
|
||||
case AF_INET6:
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)(&sess->si[0].addr.c.from))->sin6_addr,
|
||||
pn, sizeof(pn));
|
||||
|
||||
chunk_printf(&msg,
|
||||
" source=%s:%d\n",
|
||||
pn,
|
||||
ntohs(((struct sockaddr_in6 *)&sess->si[0].addr.c.from)->sin6_port));
|
||||
chunk_printf(&msg, " source=%s:%d\n",
|
||||
pn, get_host_port(&sess->si[0].addr.c.from));
|
||||
break;
|
||||
case AF_UNIX:
|
||||
chunk_printf(&msg,
|
||||
" source=unix:%d\n", sess->listener->luid);
|
||||
chunk_printf(&msg, " source=unix:%d\n", sess->listener->luid);
|
||||
break;
|
||||
default:
|
||||
/* no more information to print right now */
|
||||
@ -3236,35 +3214,18 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
|
||||
curr_sess,
|
||||
curr_sess->listener->proto->name);
|
||||
|
||||
switch (curr_sess->listener->proto->sock_family) {
|
||||
|
||||
switch (addr_to_str(&curr_sess->si[0].addr.c.from, pn, sizeof(pn))) {
|
||||
case AF_INET:
|
||||
inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)&curr_sess->si[0].addr.c.from)->sin_addr,
|
||||
pn, sizeof(pn));
|
||||
|
||||
chunk_printf(&msg,
|
||||
" src=%s:%d fe=%s be=%s srv=%s",
|
||||
pn,
|
||||
ntohs(((struct sockaddr_in *)&curr_sess->si[0].addr.c.from)->sin_port),
|
||||
curr_sess->fe->id,
|
||||
curr_sess->be->id,
|
||||
target_srv(&curr_sess->target) ? target_srv(&curr_sess->target)->id : "<none>"
|
||||
);
|
||||
break;
|
||||
case AF_INET6:
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)(&curr_sess->si[0].addr.c.from))->sin6_addr,
|
||||
pn, sizeof(pn));
|
||||
|
||||
chunk_printf(&msg,
|
||||
" src=%s:%d fe=%s be=%s srv=%s",
|
||||
pn,
|
||||
ntohs(((struct sockaddr_in6 *)&curr_sess->si[0].addr.c.from)->sin6_port),
|
||||
get_host_port(&curr_sess->si[0].addr.c.from),
|
||||
curr_sess->fe->id,
|
||||
curr_sess->be->id,
|
||||
target_srv(&curr_sess->target) ? target_srv(&curr_sess->target)->id : "<none>"
|
||||
);
|
||||
|
||||
break;
|
||||
case AF_UNIX:
|
||||
chunk_printf(&msg,
|
||||
@ -3670,16 +3631,7 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si)
|
||||
tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(es->when.tv_usec/1000));
|
||||
|
||||
|
||||
if (es->src.ss_family == AF_INET)
|
||||
inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)&es->src)->sin_addr,
|
||||
pn, sizeof(pn));
|
||||
else
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)(&es->src))->sin6_addr,
|
||||
pn, sizeof(pn));
|
||||
|
||||
addr_to_str(&es->src, pn, sizeof(pn));
|
||||
switch (si->applet.ctx.errors.buf) {
|
||||
case 0:
|
||||
chunk_printf(&msg,
|
||||
|
@ -151,76 +151,51 @@ int frontend_accept(struct session *s)
|
||||
if (!(s->logs.logwait &= ~LW_CLIP))
|
||||
s->do_log(s);
|
||||
}
|
||||
else if (s->si[0].addr.c.from.ss_family == AF_INET) {
|
||||
char pn[INET_ADDRSTRLEN], sn[INET_ADDRSTRLEN];
|
||||
|
||||
if (!(s->flags & SN_FRT_ADDR_SET))
|
||||
get_frt_addr(s);
|
||||
|
||||
if (inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)&s->si[0].addr.c.to)->sin_addr,
|
||||
sn, sizeof(sn)) &&
|
||||
inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)&s->si[0].addr.c.from)->sin_addr,
|
||||
pn, sizeof(pn))) {
|
||||
send_log(s->fe, LOG_INFO, "Connect from %s:%d to %s:%d (%s/%s)\n",
|
||||
pn, ntohs(((struct sockaddr_in *)&s->si[0].addr.c.from)->sin_port),
|
||||
sn, ntohs(((struct sockaddr_in *)&s->si[0].addr.c.to)->sin_port),
|
||||
s->fe->id, (s->fe->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
|
||||
}
|
||||
}
|
||||
else if (s->si[0].addr.c.from.ss_family == AF_INET6) {
|
||||
else {
|
||||
char pn[INET6_ADDRSTRLEN], sn[INET6_ADDRSTRLEN];
|
||||
|
||||
if (!(s->flags & SN_FRT_ADDR_SET))
|
||||
get_frt_addr(s);
|
||||
|
||||
if (inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)&s->si[0].addr.c.to)->sin6_addr,
|
||||
sn, sizeof(sn)) &&
|
||||
inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)&s->si[0].addr.c.from)->sin6_addr,
|
||||
pn, sizeof(pn))) {
|
||||
switch (addr_to_str(&s->req->prod->addr.c.from, pn, sizeof(pn))) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
addr_to_str(&s->req->prod->addr.c.to, sn, sizeof(sn));
|
||||
send_log(s->fe, LOG_INFO, "Connect from %s:%d to %s:%d (%s/%s)\n",
|
||||
pn, ntohs(((struct sockaddr_in6 *)&s->si[0].addr.c.from)->sin6_port),
|
||||
sn, ntohs(((struct sockaddr_in6 *)&s->si[0].addr.c.to)->sin6_port),
|
||||
pn, get_host_port(&s->req->prod->addr.c.from),
|
||||
sn, get_host_port(&s->req->prod->addr.c.to),
|
||||
s->fe->id, (s->fe->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
|
||||
break;
|
||||
case AF_UNIX:
|
||||
/* UNIX socket, only the destination is known */
|
||||
send_log(s->fe, LOG_INFO, "Connect to unix:%d (%s/%s)\n",
|
||||
s->listener->luid,
|
||||
s->fe->id, (s->fe->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* UNIX socket, only the destination is known */
|
||||
send_log(s->fe, LOG_INFO, "Connect to unix:%d (%s/%s)\n",
|
||||
s->listener->luid,
|
||||
s->fe->id, (s->fe->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
|
||||
char pn[INET6_ADDRSTRLEN];
|
||||
int len;
|
||||
|
||||
if (!(s->flags & SN_FRT_ADDR_SET))
|
||||
get_frt_addr(s);
|
||||
|
||||
if (s->si[0].addr.c.from.ss_family == AF_INET) {
|
||||
char pn[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)&s->si[0].addr.c.from)->sin_addr,
|
||||
pn, sizeof(pn));
|
||||
|
||||
switch (addr_to_str(&s->req->prod->addr.c.from, pn, sizeof(pn))) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
len = sprintf(trash, "%08x:%s.accept(%04x)=%04x from [%s:%d]\n",
|
||||
s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
|
||||
pn, ntohs(((struct sockaddr_in *)&s->si[0].addr.c.from)->sin_port));
|
||||
}
|
||||
else if (s->si[0].addr.c.from.ss_family == AF_INET6) {
|
||||
char pn[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)(&s->si[0].addr.c.from))->sin6_addr,
|
||||
pn, sizeof(pn));
|
||||
|
||||
len = sprintf(trash, "%08x:%s.accept(%04x)=%04x from [%s:%d]\n",
|
||||
s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
|
||||
pn, ntohs(((struct sockaddr_in6 *)(&s->si[0].addr.c.from))->sin6_port));
|
||||
}
|
||||
else {
|
||||
pn, get_host_port(&s->req->prod->addr.c.from));
|
||||
break;
|
||||
case AF_UNIX:
|
||||
/* UNIX socket, only the destination is known */
|
||||
len = sprintf(trash, "%08x:%s.accept(%04x)=%04x from [unix:%d]\n",
|
||||
s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
|
||||
s->listener->luid);
|
||||
break;
|
||||
}
|
||||
|
||||
write(1, trash, len);
|
||||
|
10
src/log.c
10
src/log.c
@ -317,15 +317,7 @@ void tcp_sess_log(struct session *s)
|
||||
if (!err && (fe->options2 & PR_O2_NOLOGNORM))
|
||||
return;
|
||||
|
||||
if (s->si[0].addr.c.from.ss_family == AF_INET)
|
||||
inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)&s->si[0].addr.c.from)->sin_addr,
|
||||
pn, sizeof(pn));
|
||||
else if (s->si[0].addr.c.from.ss_family == AF_INET6)
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)(&s->si[0].addr.c.from))->sin6_addr,
|
||||
pn, sizeof(pn));
|
||||
|
||||
addr_to_str(&s->si[0].addr.c.from, pn, sizeof(pn));
|
||||
get_localtime(s->logs.tv_accept.tv_sec, &tm);
|
||||
|
||||
if (fe->logfac1 < 0 && fe->logfac2 < 0)
|
||||
|
@ -865,15 +865,7 @@ void http_sess_clflog(struct session *s)
|
||||
(s->req->cons->conn_retries != be->conn_retries) ||
|
||||
txn->status >= 500;
|
||||
|
||||
if (s->req->prod->addr.c.from.ss_family == AF_INET)
|
||||
inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)&s->req->prod->addr.c.from)->sin_addr,
|
||||
pn, sizeof(pn));
|
||||
else if (s->req->prod->addr.c.from.ss_family == AF_INET6)
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)(&s->req->prod->addr.c.from))->sin6_addr,
|
||||
pn, sizeof(pn));
|
||||
else
|
||||
if (addr_to_str(&s->req->prod->addr.c.from, pn, sizeof(pn)) == AF_UNIX)
|
||||
snprintf(pn, sizeof(pn), "unix:%d", s->listener->luid);
|
||||
|
||||
get_gmtime(s->logs.accept_date.tv_sec, &tm);
|
||||
@ -1107,14 +1099,8 @@ void http_sess_log(struct session *s)
|
||||
if (prx_log->options2 & PR_O2_CLFLOG)
|
||||
return http_sess_clflog(s);
|
||||
|
||||
if (s->req->prod->addr.c.from.ss_family == AF_INET)
|
||||
inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)&s->req->prod->addr.c.from)->sin_addr,
|
||||
pn, sizeof(pn));
|
||||
else if (s->req->prod->addr.c.from.ss_family == AF_INET6)
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)(&s->req->prod->addr.c.from))->sin6_addr,
|
||||
pn, sizeof(pn));
|
||||
if (addr_to_str(&s->req->prod->addr.c.from, pn, sizeof(pn)) == AF_UNIX)
|
||||
snprintf(pn, sizeof(pn), "unix:%d", s->listener->luid);
|
||||
|
||||
get_localtime(s->logs.accept_date.tv_sec, &tm);
|
||||
|
||||
|
@ -589,18 +589,8 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
||||
if (msg && errlen) {
|
||||
char pn[INET6_ADDRSTRLEN];
|
||||
|
||||
if (listener->addr.ss_family == AF_INET) {
|
||||
inet_ntop(AF_INET,
|
||||
&((struct sockaddr_in *)&listener->addr)->sin_addr,
|
||||
pn, sizeof(pn));
|
||||
snprintf(errmsg, errlen, "%s [%s:%d]", msg, pn, ntohs(((struct sockaddr_in *)&listener->addr)->sin_port));
|
||||
}
|
||||
else {
|
||||
inet_ntop(AF_INET6,
|
||||
&((struct sockaddr_in6 *)(&listener->addr))->sin6_addr,
|
||||
pn, sizeof(pn));
|
||||
snprintf(errmsg, errlen, "%s [%s:%d]", msg, pn, ntohs(((struct sockaddr_in6 *)&listener->addr)->sin6_port));
|
||||
}
|
||||
addr_to_str(&listener->addr, pn, sizeof(pn));
|
||||
snprintf(errmsg, errlen, "%s [%s:%d]", msg, pn, get_host_port(&listener->addr));
|
||||
}
|
||||
return err;
|
||||
|
||||
|
@ -553,6 +553,42 @@ int url2sa(const char *url, int ulen, struct sockaddr_storage *addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Tries to convert a sockaddr_storage address to text form. Upon success, the
|
||||
* address family is returned so that it's easy for the caller to adapt to the
|
||||
* output format. Zero is returned if the address family is not supported. -1
|
||||
* is returned upon error, with errno set. AF_INET, AF_INET6 and AF_UNIX are
|
||||
* supported.
|
||||
*/
|
||||
int addr_to_str(struct sockaddr_storage *addr, char *str, int size)
|
||||
{
|
||||
|
||||
void *ptr;
|
||||
|
||||
if (size < 5)
|
||||
return 0;
|
||||
*str = '\0';
|
||||
|
||||
switch (addr->ss_family) {
|
||||
case AF_INET:
|
||||
ptr = &((struct sockaddr_in *)addr)->sin_addr;
|
||||
break;
|
||||
case AF_INET6:
|
||||
ptr = &((struct sockaddr_in6 *)addr)->sin6_addr;
|
||||
break;
|
||||
case AF_UNIX:
|
||||
memcpy(str, "unix", 5);
|
||||
return addr->ss_family;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inet_ntop(addr->ss_family, ptr, str, size))
|
||||
return addr->ss_family;
|
||||
|
||||
/* failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* will try to encode the string <string> replacing all characters tagged in
|
||||
* <map> with the hexadecimal representation of their ASCII-code (2 digits)
|
||||
* prefixed by <escape>, and will store the result between <start> (included)
|
||||
|
Loading…
x
Reference in New Issue
Block a user