about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-03-12 09:39:49 +0000
committerEric Wong <normalperson@yhbt.net>2011-03-12 09:41:21 +0000
commit79be320c3e4baf1af4b36fb269f08448c5400e47 (patch)
treec58edbecbc8cc71f0f03c8d64772732387ca0e5e
parentbf0a3c731ec3573160b9ee40cbfd7e2817d91080 (diff)
downloadraindrops-79be320c3e4baf1af4b36fb269f08448c5400e47.tar.gz
It's slow, but at least it works.
-rw-r--r--ext/raindrops/linux_inet_diag.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/ext/raindrops/linux_inet_diag.c b/ext/raindrops/linux_inet_diag.c
index dcb4199..8d26288 100644
--- a/ext/raindrops/linux_inet_diag.c
+++ b/ext/raindrops/linux_inet_diag.c
@@ -470,6 +470,18 @@ static VALUE tcp_stats(struct nogvl_args *args, VALUE addr)
         return rb_listen_stats(&args->stats);
 }
 
+/* this is slow with multiple addresses */
+static VALUE ipv6_fallback(struct nogvl_args *args, VALUE addrs)
+{
+        VALUE *ary = RARRAY_PTR(addrs);
+        long i;
+        VALUE rv = rb_hash_new();
+
+        for (i = RARRAY_LEN(addrs); --i >= 0; ary++)
+                rb_hash_aset(rv, *ary, tcp_stats(args, *ary));
+        return rv;
+}
+
 /*
  * call-seq:
  *      Raindrops::Linux.tcp_listener_stats([addrs]) => hash
@@ -479,6 +491,8 @@ static VALUE tcp_stats(struct nogvl_args *args, VALUE addr)
  * keys and ListenStats objects as the values or a hash of all addresses.
  *
  *      addrs = %w(0.0.0.0:80 127.0.0.1:8080)
+ *
+ * If +addr+ is nil or not specified, all (IPv4) addresses are returned.
  */
 static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self)
 {
@@ -512,7 +526,10 @@ static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self)
                 }
                 for (; --i >= 0; ary++) {
                         struct sockaddr_storage check;
+
                         parse_addr(&check, *ary);
+                        if (check.ss_family == AF_INET6)
+                                return ipv6_fallback(&args, addrs);
                         rb_hash_aset(rv, *ary, Qtrue);
                 }
                 /* fall through */