From: Jeremy Harris Date: Sat, 2 May 2020 13:22:31 +0000 (+0100) Subject: Debug: socket details X-Git-Url: https://git.exim.org/users/heiko/exim.git/commitdiff_plain/a8e46b3b7147d214072bc34beff184724f3f2be6 Debug: socket details --- diff --git a/src/src/debug.c b/src/src/debug.c index de9796232..806573f1c 100644 --- a/src/src/debug.c +++ b/src/src/debug.c @@ -315,4 +315,82 @@ if (debug_ptr[-1] == '\n') errno = save_errno; } + + +/* Output the details of a socket */ + +void +debug_print_socket(int fd) +{ +struct stat s; +if (fstat(fd, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK) + { + gstring * g = NULL; + int val; + socklen_t vlen = sizeof(val); + struct sockaddr a; + socklen_t alen = sizeof(a); + struct sockaddr_in * sinp = (struct sockaddr_in *)&a; + struct sockaddr_in6 * sin6p = (struct sockaddr_in6 *)&a; + struct sockaddr_un * sa_unp ; (struct sockaddr_un *)&a; + + if (getsockname(fd, &a, &alen) == 0) + switch (sinp->sin_family) + { + case AF_INET: + g = string_cat(g, US" domain AF_INET"); + g = string_fmt_append(g, " lcl [%s]:%u", + inet_ntoa(sinp->sin_addr), ntohs(sinp->sin_port)); + if (getpeername(fd, &a, &alen) == 0) + g = string_fmt_append(g, " rmt [%s]:%u", + inet_ntoa(sinp->sin_addr), ntohs(sinp->sin_port)); + break; + case AF_INET6: + { + uschar buf[46]; + g = string_cat(g, US" domain AF_INET6"); + g = string_fmt_append(g, " lcl [%s]:%u", + inet_ntop(AF_INET6, &sin6p->sin6_addr, CS buf, sizeof(buf)), + ntohs(sin6p->sin6_port)); + if (getpeername(fd, &a, &alen) == 0) + g = string_fmt_append(g, " rmt [%s]:%u", + inet_ntop(AF_INET6, &sin6p->sin6_addr, CS buf, sizeof(buf)), + ntohs(sin6p->sin6_port)); + break; + } + case AF_UNIX: + g = string_cat(g, US" domain AF_UNIX"); + g = string_fmt_append(g, " lcl %s%s", + sa_unp->sun_path[0] ? US"" : US"@", + sa_unp->sun_path[0] ? sa_unp->sun_path : sa_unp->sun_path+1); + if (getpeername(fd, &a, &alen) == 0) + g = string_fmt_append(g, " rmt %s%s", + sa_unp->sun_path[0] ? US"" : US"@", + sa_unp->sun_path[0] ? sa_unp->sun_path : sa_unp->sun_path+1); + break; + default: + g = string_fmt_append(g, " domain %u", sinp->sin_family); + break; + } + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &val, &vlen) == 0) + switch (val) + { + case SOCK_STREAM: g = string_cat(g, US" type SOCK_STREAM"); break; + case SOCK_DGRAM: g = string_cat(g, US" type SOCK_DGRAM"); break; + default: g = string_fmt_append(g, " type %d", val); break; + } + if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &val, &vlen) == 0) + { + struct protoent * p = getprotobynumber(val); + g = p + ? string_fmt_append(g, " proto %s\n", p->p_name) + : string_fmt_append(g, " proto %d", val); + } + debug_printf_indent(" socket: %s\n", string_from_gstring(g)); + } +else + debug_printf_indent(" fd st_mode 0%o\n", s.st_mode); +} + + /* End of debug.c */ diff --git a/src/src/functions.h b/src/src/functions.h index fbddd3519..0028deb0d 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -184,6 +184,8 @@ extern void debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2); extern void debug_print_string(uschar *); extern void debug_print_tree(tree_node *); extern void debug_vprintf(int, const char *, va_list); +extern void debug_print_socket(int); + extern void decode_bits(unsigned int *, size_t, int *, uschar *, bit_table *, int, uschar *, int); extern void delete_pid_file(void); diff --git a/src/src/malware.c b/src/src/malware.c index 5ed469f30..7ed4d358d 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -262,6 +262,7 @@ static inline int m_panic_defer_3(struct scan * scanent, const uschar * hostport, const uschar * str, int fd_to_close) { +DEBUG(D_acl) debug_print_socket(fd_to_close); (void) close(fd_to_close); return m_panic_defer(scanent, hostport, str); } @@ -338,6 +339,7 @@ else return cre; } + /* Simple though inefficient wrapper for reading a line. Drop CRs and the trailing newline. Can return early on buffer full. Null-terminate. @@ -369,8 +371,12 @@ while ((rcv = read(fd, p, 1)) > 0) } if (!ok) { - DEBUG(D_acl) debug_printf_indent("Malware scan: read %s (%s)\n", + DEBUG(D_acl) + { + debug_printf_indent("Malware scan: read %s (%s)\n", rcv==0 ? "EOF" : "error", strerror(errno)); + debug_print_socket(fd); + } return rcv==0 ? -1 : -2; } *p = '\0';