Index: sys/kern/uipc_socket.c =================================================================== --- sys/kern/uipc_socket.c +++ sys/kern/uipc_socket.c @@ -130,6 +130,7 @@ #include #include #include +#include #include #include #include @@ -140,9 +141,12 @@ #include #include #include +#include +#include #include #include #include +#include #include #include @@ -587,8 +591,17 @@ static struct timeval overinterval = { 60, 0 }; static int overcount; + struct sbuf descrsb; struct socket *so; u_int over; + int len; + const char localprefix[] = "local:"; + char descrbuf[SUNPATHLEN + sizeof(localprefix)]; +#if defined(INET6) + char addrbuf[INET6_ADDRSTRLEN]; +#elif defined(INET) + char addrbuf[INET_ADDRSTRLEN]; +#endif SOLISTEN_LOCK(head); over = (head->sol_qlen > 3 * head->sol_qlimit / 2); @@ -601,10 +614,80 @@ overcount++; if (ratecheck(&lastover, &overinterval)) { - log(LOG_DEBUG, "%s: pcb %p: Listen queue overflow: " + /* + * Try to print something descriptive about the + * socket for the error message. + */ + sbuf_new(&descrsb, descrbuf, sizeof(descrbuf), + SBUF_FIXEDLEN); + switch (head->so_proto->pr_domain->dom_family) { +#if defined(INET) || defined(INET6) +#ifdef INET + case AF_INET: +#endif +#ifdef INET6 + case AF_INET6: + if (head->so_proto->pr_domain->dom_family == + AF_INET6 || + (sotoinpcb(head)->inp_inc.inc_flags & + INC_ISIPV6)) { + ip6_sprintf(addrbuf, + &sotoinpcb(head)->inp_inc.inc6_laddr); + sbuf_printf(&descrsb, "[%s]", addrbuf); + } else +#endif + { +#ifdef INET + inet_ntoa_r( + sotoinpcb(head)->inp_inc.inc_laddr, + addrbuf); + sbuf_cat(&descrsb, addrbuf); +#endif + } + sbuf_printf(&descrsb, ":%hu (proto %u)", + ntohs(sotoinpcb(head)->inp_inc.inc_lport), + head->so_proto->pr_protocol); + break; +#endif /* INET || INET6 */ + case AF_UNIX: + sbuf_cat(&descrsb, localprefix); + if (sotounpcb(head)->unp_addr != NULL) + len = + sotounpcb(head)->unp_addr->sun_len - + offsetof(struct sockaddr_un, + sun_path); + else + len = 0; + if (len > 0) + sbuf_bcat(&descrsb, + sotounpcb(head)->unp_addr->sun_path, + len); + else + sbuf_cat(&descrsb, "(unknown)"); + break; + } + + /* + * If we can't print something more specific, at least + * print the domain name. + */ + if (sbuf_finish(&descrsb) != 0 || + sbuf_len(&descrsb) <= 0) { + sbuf_clear(&descrsb); + sbuf_cat(&descrsb, + head->so_proto->pr_domain->dom_name ?: + "unknown"); + sbuf_finish(&descrsb); + } + KASSERT(sbuf_len(&descrsb) > 0, + ("%s: sbuf creation failed", __func__)); + log(LOG_DEBUG, + "%s: pcb %p (%s): Listen queue overflow: " "%i already in queue awaiting acceptance " "(%d occurrences)\n", - __func__, head->so_pcb, head->sol_qlen, overcount); + __func__, head->so_pcb, sbuf_data(&descrsb), + head->sol_qlen, overcount); + sbuf_delete(&descrsb); overcount = 0; } Index: sys/sys/un.h =================================================================== --- sys/sys/un.h +++ sys/sys/un.h @@ -43,13 +43,21 @@ #define _SA_FAMILY_T_DECLARED #endif +/* + * Historically, (struct sockaddr) needed to fit inside an MBUF. + * For this reason, UNIX domain sockets were therefore limited to + * 104 bytes. While this limit is no longer necessary, it is kept for + * binary compatibility reasons. + */ +#define SUNPATHLEN 104 + /* * Definitions for UNIX IPC domain. */ struct sockaddr_un { unsigned char sun_len; /* sockaddr len including null */ sa_family_t sun_family; /* AF_UNIX */ - char sun_path[104]; /* path name (gag) */ + char sun_path[SUNPATHLEN]; /* path name (gag) */ }; #if __BSD_VISIBLE