For resolving the peer address of socket, all combinations of families (AF_INET, AF_INET6) and protocols(IPPROTO_TCP, IPPROTO_UDP) were tried.
This patch utilizes the protocol name, getting via getxattr, to specify the combination. * util.c (printfd): Pass the protocol name for the given path to print_sockaddr_by_inode as the 2nd argument. * socketutils.c (print_sockaddr_by_inode): Utilize the protocol name for the target inode for resolving the peer address of socket. If the name is NULL, resolve the address as in the past. Use inet_print in the case when no hint is given. (inet_print): New helper function for print_sockaddr_by_inode. Changes in v2 patch (suggested by ldv): * Simplify inet_print; just use a logical operator. * Use inet_print in the case when no hint is given. Signed-off-by: Masatake YAMATO <yam...@redhat.com> --- defs.h | 2 +- socketutils.c | 46 +++++++++++++++++++++++++++++++--------------- util.c | 11 +++++------ 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/defs.h b/defs.h index 708adf6..a80d1f8 100644 --- a/defs.h +++ b/defs.h @@ -696,7 +696,7 @@ extern void printsiginfo(siginfo_t *, int); extern void printsiginfo_at(struct tcb *tcp, long addr); #endif extern void printfd(struct tcb *, int); -extern bool print_sockaddr_by_inode(const unsigned long); +extern bool print_sockaddr_by_inode(const unsigned long, const char *); extern void print_dirfd(struct tcb *, int); extern void printsock(struct tcb *, long, int); extern void print_sock_optmgmt(struct tcb *, long, int); diff --git a/socketutils.c b/socketutils.c index 80abed5..f57c304 100644 --- a/socketutils.c +++ b/socketutils.c @@ -138,33 +138,49 @@ receive_responses(const int fd, const unsigned long inode) } } +static bool +inet_print(int fd, int family, int protocol, const unsigned long inode) +{ + return send_query(fd, family, protocol) + && receive_responses(fd, inode); +} + /* Given an inode number of a socket, print out the details * of the ip address and port. */ bool -print_sockaddr_by_inode(const unsigned long inode) +print_sockaddr_by_inode(const unsigned long inode, const char *proto_name) { - const int families[] = {AF_INET, AF_INET6}; - const int protocols[] = {IPPROTO_TCP, IPPROTO_UDP}; - const size_t flen = ARRAY_SIZE(families); - const size_t plen = ARRAY_SIZE(protocols); - size_t fi, pi; int fd; + bool r = false; fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG); if (fd < 0) return false; - for (fi = 0; fi < flen; ++fi) { - for (pi = 0; pi < plen; ++pi) { - if (!send_query(fd, families[fi], protocols[pi])) - continue; - if (receive_responses(fd, inode)) { - close(fd); - return true; + if (proto_name) { + if (strcmp(proto_name, "TCP") == 0) + r = inet_print(fd, AF_INET, IPPROTO_TCP, inode); + else if (strcmp(proto_name, "UDP") == 0) + r = inet_print(fd, AF_INET, IPPROTO_UDP, inode); + else if (strcmp(proto_name, "TCPv6") == 0) + r = inet_print(fd, AF_INET6, IPPROTO_TCP, inode); + else if (strcmp(proto_name, "UDPv6") == 0) + r = inet_print(fd, AF_INET6, IPPROTO_UDP, inode); + } else { + const int families[] = {AF_INET, AF_INET6}; + const int protocols[] = {IPPROTO_TCP, IPPROTO_UDP}; + const size_t flen = ARRAY_SIZE(families); + const size_t plen = ARRAY_SIZE(protocols); + size_t fi, pi; + + for (fi = 0; fi < flen; ++fi) { + for (pi = 0; pi < plen; ++pi) { + if ((r = inet_print(fd, families[fi], protocols[pi], inode))) + goto out; } } } - +out: close(fd); - return false; + return r; } diff --git a/util.c b/util.c index cd4b802..9f4caac 100644 --- a/util.c +++ b/util.c @@ -461,14 +461,13 @@ printfd(struct tcb *tcp, int fd) strncmp(path, socket_prefix, socket_prefix_len) == 0 && path[(path_len = strlen(path)) - 1] == ']') { unsigned long inodenr; +#define PROTO_NAME_LEN 32 + char proto_buf[PROTO_NAME_LEN]; + const char *proto = + getfdproto(tcp, fd, proto_buf, PROTO_NAME_LEN); inodenr = strtoul(path + socket_prefix_len, NULL, 10); tprintf("%d<", fd); - if (!print_sockaddr_by_inode(inodenr)) { -#define PROTO_NAME_LEN 32 - char proto_buf[PROTO_NAME_LEN]; - const char *proto = - getfdproto(tcp, fd, proto_buf, PROTO_NAME_LEN); - + if (!print_sockaddr_by_inode(inodenr, proto)) { if (proto) tprintf("%s:[%lu]", proto, inodenr); else -- 1.9.3 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming! The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel