[前][次][番号順一覧][スレッド一覧]

ruby-changes:35333

From: nagachika <ko1@a...>
Date: Sat, 6 Sep 2014 00:14:35 +0900 (JST)
Subject: [ruby-changes:35333] nagachika:r47415 (ruby_2_1): merge revision(s) r45046, r45047, r45063, r45087, r45146, r45150, r45151, r45152: [Backport #9525]

nagachika	2014-09-06 00:14:23 +0900 (Sat, 06 Sep 2014)

  New Revision: 47415

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47415

  Log:
    merge revision(s) r45046,r45047,r45063,r45087,r45146,r45150,r45151,r45152: [Backport #9525]
    
    * ext/socket: Wrap struct addrinfo by struct rb_addrinfo.
    
    * ext/socket: Bypass getaddrinfo() if node and serv are numeric.
      Reporeted by Naotoshi Seo.  [ruby-core:60801] [Bug #9525]
    
    * ext/socket/extconf.rb: Detect struct sockaddr_in6.sin6_len.
    
    * ext/socket/sockport.h (SET_SIN6_LEN): New macro.
      (INIT_SOCKADDR_IN6): Ditto.
    
    * ext/socket/rubysocket.h (struct rb_addrinfo): Add
      allocated_by_malloc field.
    
    * ext/socket/raddrinfo.c (numeric_getaddrinfo): New function.
      (rb_getaddrinfo): Call numeric_getaddrinfo at first.
      (rb_freeaddrinfo): Free struct addrinfo properly when it is
      allocated by numeric_getaddrinfo.
    
    * ext/socket/raddrinfo.c (numeric_getaddrinfo): Use xcalloc.
      Suggested by Eric Wong.
      https://bugs.ruby-lang.org/issues/9525#note-14
    
    * ext/socket/raddrinfo.c (rb_getaddrinfo): second argument of
      MEMZERO is type.  Coverity Scan found this bug.
    
    * include/ruby/win32.h, win32/win32.c (rb_w32_inet_pton): add a
      wrapper function for inet_pton minimum supported client is
      Vista, as well as inet_ntop.
    
    * ext/socket/option.c (inet_pton): use rb_w32_inet_pton, instead of
      inet_ntop directly, which is unavailable on older version Windows.
    
    * ext/socket/raddrinfo.c (inet_pton): use rb_w32_inet_pton, instead of
      inet_pton directly, which is unavailable on older version Windows.

  Modified directories:
    branches/ruby_2_1/
  Modified files:
    branches/ruby_2_1/ChangeLog
    branches/ruby_2_1/ext/socket/extconf.rb
    branches/ruby_2_1/ext/socket/raddrinfo.c
    branches/ruby_2_1/ext/socket/rubysocket.h
    branches/ruby_2_1/ext/socket/sockport.h
    branches/ruby_2_1/include/ruby/win32.h
    branches/ruby_2_1/version.h
    branches/ruby_2_1/win32/win32.c
Index: ruby_2_1/include/ruby/win32.h
===================================================================
--- ruby_2_1/include/ruby/win32.h	(revision 47414)
+++ ruby_2_1/include/ruby/win32.h	(revision 47415)
@@ -309,6 +309,7 @@ extern char **rb_w32_get_environ(void); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/include/ruby/win32.h#L309
 extern void   rb_w32_free_environ(char **);
 extern int    rb_w32_map_errno(DWORD);
 extern const char *WSAAPI rb_w32_inet_ntop(int,const void *,char *,size_t);
+extern int WSAAPI rb_w32_inet_pton(int,const char *,void *);
 extern DWORD  rb_w32_osver(void);
 
 extern int chown(const char *, int, int);
@@ -652,6 +653,9 @@ extern char *rb_w32_strerror(int); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/include/ruby/win32.h#L653
 #undef inet_ntop
 #define inet_ntop(f,a,n,l)      rb_w32_inet_ntop(f,a,n,l)
 
+#undef inet_pton
+#define inet_pton(f,s,d)        rb_w32_inet_pton(f,s,d)
+
 #undef accept
 #define accept(s, a, l)		rb_w32_accept(s, a, l)
 
Index: ruby_2_1/ChangeLog
===================================================================
--- ruby_2_1/ChangeLog	(revision 47414)
+++ ruby_2_1/ChangeLog	(revision 47415)
@@ -1,3 +1,42 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1
+Sat Sep  6 00:05:02 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* include/ruby/win32.h, win32/win32.c (rb_w32_inet_pton): add a
+	  wrapper function for inet_pton minimum supported client is
+	  Vista, as well as inet_ntop.
+
+Sat Sep  6 00:05:02 2014  Kazuhiro NISHIYAMA  <zn@m...>
+
+	* ext/socket/raddrinfo.c (rb_getaddrinfo): second argument of
+	  MEMZERO is type.  Coverity Scan found this bug.
+
+Sat Sep  6 00:05:02 2014  Tanaka Akira  <akr@f...>
+
+	* ext/socket/raddrinfo.c (numeric_getaddrinfo): Use xcalloc.
+	  Suggested by Eric Wong.
+	  https://bugs.ruby-lang.org/issues/9525#note-14
+
+Sat Sep  6 00:05:02 2014  Tanaka Akira  <akr@f...>
+
+	* ext/socket: Bypass getaddrinfo() if node and serv are numeric.
+	  Reporeted by Naotoshi Seo.  [ruby-core:60801] [Bug #9525]
+
+	* ext/socket/extconf.rb: Detect struct sockaddr_in6.sin6_len.
+
+	* ext/socket/sockport.h (SET_SIN6_LEN): New macro.
+	  (INIT_SOCKADDR_IN6): Ditto.
+
+	* ext/socket/rubysocket.h (struct rb_addrinfo): Add
+	  allocated_by_malloc field.
+
+	* ext/socket/raddrinfo.c (numeric_getaddrinfo): New function.
+	  (rb_getaddrinfo): Call numeric_getaddrinfo at first.
+	  (rb_freeaddrinfo): Free struct addrinfo properly when it is
+	  allocated by numeric_getaddrinfo.
+
+Sat Sep  6 00:05:02 2014  Tanaka Akira  <akr@f...>
+
+	* ext/socket: Wrap struct addrinfo by struct rb_addrinfo.
+
 Thu Sep  4 00:31:23 2014  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/thread/thread.c (get_array): check instance variables are
Index: ruby_2_1/win32/win32.c
===================================================================
--- ruby_2_1/win32/win32.c	(revision 47414)
+++ ruby_2_1/win32/win32.c	(revision 47415)
@@ -6963,6 +6963,19 @@ rb_w32_inet_ntop(int af, const void *add https://github.com/ruby/ruby/blob/trunk/ruby_2_1/win32/win32.c#L6963
 }
 
 /* License: Ruby's */
+int WSAAPI
+rb_w32_inet_pton(int af, const char *src, void *dst)
+{
+    typedef int (WSAAPI inet_pton_t)(int, const char*, void *);
+    inet_pton_t *pInetPton;
+    pInetPton = (inet_pton_t *)get_proc_address("ws2_32", "inet_pton", NULL);
+    if (pInetPton) {
+	return pInetPton(af, src, dst);
+    }
+    return 0;
+}
+
+/* License: Ruby's */
 char
 rb_w32_fd_is_text(int fd)
 {
Index: ruby_2_1/ext/socket/rubysocket.h
===================================================================
--- ruby_2_1/ext/socket/rubysocket.h	(revision 47414)
+++ ruby_2_1/ext/socket/rubysocket.h	(revision 47415)
@@ -280,6 +280,7 @@ int rsock_getfamily(int sockfd); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ext/socket/rubysocket.h#L280
 
 struct rb_addrinfo {
   struct addrinfo *ai;
+  int allocated_by_malloc;
 };
 int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct rb_addrinfo **res);
 void rb_freeaddrinfo(struct rb_addrinfo *ai);
Index: ruby_2_1/ext/socket/raddrinfo.c
===================================================================
--- ruby_2_1/ext/socket/raddrinfo.c	(revision 47414)
+++ ruby_2_1/ext/socket/raddrinfo.c	(revision 47415)
@@ -171,6 +171,90 @@ nogvl_getaddrinfo(void *arg) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ext/socket/raddrinfo.c#L171
 }
 #endif
 
+static int
+numeric_getaddrinfo(const char *node, const char *service,
+        const struct addrinfo *hints,
+        struct addrinfo **res)
+{
+#ifdef HAVE_INET_PTON
+# if defined __MINGW64__
+#   define inet_pton(f,s,d)        rb_w32_inet_pton(f,s,d)
+# endif
+
+    if (node && (!service || strspn(service, "0123456789") == strlen(service))) {
+	static const struct {
+	    int socktype;
+	    int protocol;
+	} list[] = {
+	    { SOCK_STREAM, IPPROTO_TCP },
+	    { SOCK_DGRAM, IPPROTO_UDP },
+	    { SOCK_RAW, 0 }
+	};
+	struct addrinfo *ai = NULL;
+        int port = service ? (unsigned short)atoi(service): 0;
+        int hint_family = hints ? hints->ai_family : PF_UNSPEC;
+        int hint_socktype = hints ? hints->ai_socktype : 0;
+        int hint_protocol = hints ? hints->ai_protocol : 0;
+        char ipv4addr[4];
+#ifdef AF_INET6
+        char ipv6addr[16];
+        if ((hint_family == PF_UNSPEC || hint_family == PF_INET6) &&
+            strspn(node, "0123456789abcdefABCDEF.:") == strlen(node) &&
+            inet_pton(AF_INET6, node, ipv6addr)) {
+            int i;
+            for (i = numberof(list)-1; 0 <= i; i--) {
+                if ((hint_socktype == 0 || hint_socktype == list[i].socktype) &&
+                    (hint_protocol == 0 || list[i].protocol == 0 || hint_protocol == list[i].protocol)) {
+                    struct addrinfo *ai0 = xcalloc(1, sizeof(struct addrinfo));
+                    struct sockaddr_in6 *sa = xmalloc(sizeof(struct sockaddr_in6));
+                    INIT_SOCKADDR_IN6(sa, sizeof(struct sockaddr_in6));
+                    memcpy(&sa->sin6_addr, ipv6addr, sizeof(ipv6addr));
+                    sa->sin6_port = htons(port);
+                    ai0->ai_family = PF_INET6;
+                    ai0->ai_socktype = list[i].socktype;
+                    ai0->ai_protocol = hint_protocol ? hint_protocol : list[i].protocol;
+                    ai0->ai_addrlen = sizeof(struct sockaddr_in6);
+                    ai0->ai_addr = (struct sockaddr *)sa;
+                    ai0->ai_canonname = NULL;
+                    ai0->ai_next = ai;
+                    ai = ai0;
+                }
+            }
+        }
+        else
+#endif
+        if ((hint_family == PF_UNSPEC || hint_family == PF_INET) &&
+            strspn(node, "0123456789.") == strlen(node) &&
+            inet_pton(AF_INET, node, ipv4addr)) {
+            int i;
+            for (i = numberof(list)-1; 0 <= i; i--) {
+                if ((hint_socktype == 0 || hint_socktype == list[i].socktype) &&
+                    (hint_protocol == 0 || list[i].protocol == 0 || hint_protocol == list[i].protocol)) {
+                    struct addrinfo *ai0 = xcalloc(1, sizeof(struct addrinfo));
+                    struct sockaddr_in *sa = xmalloc(sizeof(struct sockaddr_in));
+                    INIT_SOCKADDR_IN(sa, sizeof(struct sockaddr_in));
+                    memcpy(&sa->sin_addr, ipv4addr, sizeof(ipv4addr));
+                    sa->sin_port = htons(port);
+                    ai0->ai_family = PF_INET;
+                    ai0->ai_socktype = list[i].socktype;
+                    ai0->ai_protocol = hint_protocol ? hint_protocol : list[i].protocol;
+                    ai0->ai_addrlen = sizeof(struct sockaddr_in);
+                    ai0->ai_addr = (struct sockaddr *)sa;
+                    ai0->ai_canonname = NULL;
+                    ai0->ai_next = ai;
+                    ai = ai0;
+                }
+            }
+        }
+        if (ai) {
+            *res = ai;
+            return 0;
+        }
+    }
+#endif
+    return EAI_FAIL;
+}
+
 int
 rb_getaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
@@ -178,21 +262,28 @@ rb_getaddrinfo(const char *node, const c https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ext/socket/raddrinfo.c#L262
 {
     struct addrinfo *ai;
     int ret;
+    int allocated_by_malloc = 0;
 
+    ret = numeric_getaddrinfo(node, service, hints, &ai);
+    if (ret == 0)
+        allocated_by_malloc = 1;
+    else {
 #ifdef GETADDRINFO_EMU
-    ret = getaddrinfo(node, service, hints, &ai);
+        ret = getaddrinfo(node, service, hints, &ai);
 #else
-    struct getaddrinfo_arg arg;
-    MEMZERO(&arg, sizeof arg, 1);
-    arg.node = node;
-    arg.service = service;
-    arg.hints = hints;
-    arg.res = &ai;
-    ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0);
+        struct getaddrinfo_arg arg;
+        MEMZERO(&arg, struct getaddrinfo_arg, 1);
+        arg.node = node;
+        arg.service = service;
+        arg.hints = hints;
+        arg.res = &ai;
+        ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0);
 #endif
+    }
 
     if (ret == 0) {
         *res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo));
+        (*res)->allocated_by_malloc = allocated_by_malloc;
         (*res)->ai = ai;
     }
     return ret;
@@ -201,7 +292,18 @@ rb_getaddrinfo(const char *node, const c https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ext/socket/raddrinfo.c#L292
 void
 rb_freeaddrinfo(struct rb_addrinfo *ai)
 {
-    freeaddrinfo(ai->ai);
+    if (!ai->allocated_by_malloc)
+        freeaddrinfo(ai->ai);
+    else {
+        struct addrinfo *ai1, *ai2;
+        ai1 = ai->ai;
+        while (ai1) {
+            ai2 = ai1->ai_next;
+            xfree(ai1->ai_addr);
+            xfree(ai1);
+            ai1 = ai2;
+        }
+    }
     xfree(ai);
 }
 
Index: ruby_2_1/ext/socket/sockport.h
===================================================================
--- ruby_2_1/ext/socket/sockport.h	(revision 47414)
+++ ruby_2_1/ext/socket/sockport.h	(revision 47415)
@@ -29,6 +29,12 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ext/socket/sockport.h#L29
 # define SET_SIN_LEN(sa, len) SET_SA_LEN((struct sockaddr *)(sa), (len))
 #endif
 
+#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
+# define SET_SIN6_LEN(sa, len) (void)((sa)->sin6_len = (len))
+#else
+# define SET_SIN6_LEN(sa, len) SET_SA_LEN((struct sockaddr *)(sa), (len))
+#endif
+
 #define INIT_SOCKADDR(addr, family, len) \
   do { \
     struct sockaddr *init_sockaddr_ptr = (addr); \
@@ -47,6 +53,15 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ext/socket/sockport.h#L53
     SET_SIN_LEN(init_sockaddr_ptr, init_sockaddr_len); \
   } while (0)
 
+#define INIT_SOCKADDR_IN6(addr, len) \
+  do { \
+    struct sockaddr_in6 *init_sockaddr_ptr = (addr); \
+    socklen_t init_sockaddr_len = (len); \
+    memset(init_sockaddr_ptr, 0, init_sockaddr_len); \
+    init_sockaddr_ptr->sin6_family = AF_INET6; \
+    SET_SIN6_LEN(init_sockaddr_ptr, init_sockaddr_len); \
+  } while (0)
+
 
 /* for strict-aliasing rule */
 #ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN
Index: ruby_2_1/ext/socket/extconf.rb
===================================================================
--- ruby_2_1/ext/socket/extconf.rb	(revision 47414)
+++ ruby_2_1/ext/socket/extconf.rb	(revision 47415)
@@ -332,6 +332,7 @@ end https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ext/socket/extconf.rb#L332
 
 have_struct_member("struct sockaddr", "sa_len", headers) # 4.4BSD
 have_struct_member("struct sockaddr_in", "sin_len", headers) # 4.4BSD
+have_struct_member("struct sockaddr_in6", "sin6_len", headers) # 4.4BSD
 
 if have_type("struct sockaddr_un", headers) # POSIX
   have_struct_member("struct sockaddr_un", "sun_len", headers) # 4.4BSD
Index: ruby_2_1/version.h
===================================================================
--- ruby_2_1/version.h	(revision 47414)
+++ ruby_2_1/version.h	(revision 47415)
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1
 #define RUBY_VERSION "2.1.2"
-#define RUBY_RELEASE_DATE "2014-09-04"
-#define RUBY_PATCHLEVEL 222
+#define RUBY_RELEASE_DATE "2014-09-06"
+#define RUBY_PATCHLEVEL 223
 
 #define RUBY_RELEASE_YEAR 2014
 #define RUBY_RELEASE_MONTH 9
-#define RUBY_RELEASE_DAY 4
+#define RUBY_RELEASE_DAY 6
 
 #include "ruby/version.h"
 

Property changes on: ruby_2_1
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r45047,45063,45087,45146,45150-45152


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]