diff --git a/include/common/standard.h b/include/common/standard.h index 769aec661..ac31cc813 100644 --- a/include/common/standard.h +++ b/include/common/standard.h @@ -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 replacing all characters tagged in * with the hexadecimal representation of their ASCII-code (2 digits) * prefixed by , and will store the result between (included) diff --git a/src/dumpstats.c b/src/dumpstats.c index a3dc52e31..95bcd4c3d 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -2201,36 +2201,29 @@ static int stats_dump_proxy(struct stream_interface *si, struct proxy *px, struc chunk_printf(&msg, "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 : "" - ); - 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 : "" ); - 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, diff --git a/src/frontend.c b/src/frontend.c index b2bc5d8a7..a295729b2 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -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); diff --git a/src/log.c b/src/log.c index 16ace2fe4..d75034940 100644 --- a/src/log.c +++ b/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) diff --git a/src/proto_http.c b/src/proto_http.c index 32f9f2635..35c2f9db0 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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); diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 8a04f16aa..913e04efb 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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; diff --git a/src/standard.c b/src/standard.c index e37171725..adc66f52f 100644 --- a/src/standard.c +++ b/src/standard.c @@ -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 replacing all characters tagged in * with the hexadecimal representation of their ASCII-code (2 digits) * prefixed by , and will store the result between (included)