From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS47066 71.19.144.0/20 X-Spam-Status: No, score=-1.2 required=3.0 tests=BAYES_00,FREEMAIL_FROM, FROM_STARTS_WITH_NUMS,MSGID_FROM_MTA_HEADER shortcircuit=no autolearn=no version=3.3.2 Path: news.gmane.org!not-for-mail From: Hleb Valoshka <375gnu@gmail.com> Newsgroups: gmane.comp.lang.ruby.kgio.general Subject: [PATCH] Remove Scope IDs from IPv6 addresses. Date: Thu, 12 Sep 2013 16:31:13 +0300 Message-ID: <1378992673-1667-1-git-send-email-375gnu@gmail.com> References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1378992712 21763 80.91.229.3 (12 Sep 2013 13:31:52 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 12 Sep 2013 13:31:52 +0000 (UTC) To: kgio@librelist.org Original-X-From: kgio@librelist.org Thu Sep 12 15:31:56 2013 Return-path: Envelope-to: gclrkg-kgio@m.gmane.org List-Archive: List-Help: List-Id: List-Post: List-Subscribe: List-Unsubscribe: Precedence: list Original-Sender: kgio@librelist.org Xref: news.gmane.org gmane.comp.lang.ruby.kgio.general:227 Archived-At: Received: from zedshaw2.xen.prgmr.com ([71.19.156.177]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VK6zu-0005M0-O3 for gclrkg-kgio@m.gmane.org; Thu, 12 Sep 2013 15:31:50 +0200 Received: from zedshaw2.xen.prgmr.com (unknown [IPv6:::1]) by zedshaw2.xen.prgmr.com (Postfix) with ESMTP id B99B7750AA for ; Thu, 12 Sep 2013 13:41:25 +0000 (UTC) Scoped ipv6 addresses are defined in rfc4007. Ruby doesn't support them yet and it's unknown whether it will (see http://bugs.ruby-lang.org/issues/8464). So we just remove scope ids. Tested with MRI and Rubinius. --- ext/raindrops/linux_inet_diag.c | 41 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/ext/raindrops/linux_inet_diag.c b/ext/raindrops/linux_inet_diag.c index cd4a876..7b5bae1 100644 --- a/ext/raindrops/linux_inet_diag.c +++ b/ext/raindrops/linux_inet_diag.c @@ -134,12 +134,49 @@ static int st_free_data(st_data_t key, st_data_t value, st_data_t ignored) return ST_DELETE; } +/* + * call-seq: + * remove_scope_id(ip_address) + * + * Returns copy of IP address with Scope ID removed, + * if address has it (only IPv6 actually may have it). + */ +static VALUE remove_scope_id(const char *addr) +{ + VALUE rv = rb_str_new2(addr); + long len = RSTRING_LEN(rv); + char *ptr = RSTRING_PTR(rv); + char *pct = memchr(ptr, '%', len); + + /* + * remove scoped portion + * Ruby equivalent: rv.sub!(/%([^\]]*)\]/, "]") + */ + if (pct) { + size_t newlen = pct - ptr; + char *rbracket = memchr(pct, ']', len - newlen); + + if (rbracket) { + size_t move = len - (rbracket - ptr); + + memmove(pct, rbracket, move); + newlen += move; + + rb_str_set_len(rv, newlen); + } else { + rb_raise(rb_eArgError, + "']' not found in IPv6 addr=%s", ptr); + } + } + return rv; +} + static int st_to_hash(st_data_t key, st_data_t value, VALUE hash) { struct listen_stats *stats = (struct listen_stats *)value; if (stats->listener_p) { - VALUE k = rb_str_new2((const char *)key); + VALUE k = remove_scope_id((const char *)key); VALUE v = rb_listen_stats(stats); OBJ_FREEZE(k); @@ -153,7 +190,7 @@ static int st_AND_hash(st_data_t key, st_data_t value, VALUE hash) struct listen_stats *stats = (struct listen_stats *)value; if (stats->listener_p) { - VALUE k = rb_str_new2((const char *)key); + VALUE k = remove_scope_id((const char *)key); if (rb_hash_lookup(hash, k) == Qtrue) { VALUE v = rb_listen_stats(stats); -- 1.7.10.4