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


------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to