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

ruby-changes:63101

From: Masaki <ko1@a...>
Date: Fri, 25 Sep 2020 15:19:50 +0900 (JST)
Subject: [ruby-changes:63101] 511fe23fa2 (master): Add resolve_timeout to TCPSocket [Feature #17134]

https://git.ruby-lang.org/ruby.git/commit/?id=511fe23fa2

From 511fe23fa2bdf1f17faa91e0558be47b5bb62b2a Mon Sep 17 00:00:00 2001
From: Masaki Matsushita <glass.saga@g...>
Date: Fri, 28 Aug 2020 13:07:31 +0900
Subject: Add resolve_timeout to TCPSocket [Feature #17134]


diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c
index a2cb6e0..e2b7308 100644
--- a/ext/socket/ipsocket.c
+++ b/ext/socket/ipsocket.c
@@ -19,6 +19,7 @@ struct inetsock_arg https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L19
     } remote, local;
     int type;
     int fd;
+    VALUE resolv_timeout;
 };
 
 static VALUE
@@ -49,10 +50,20 @@ init_inetsock_internal(VALUE v) https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L50
     int fd, status = 0, local = 0;
     int family = AF_UNSPEC;
     const char *syscall = 0;
-
+    VALUE resolv_timeout = arg->resolv_timeout;
+
+#ifdef HAVE_GETADDRINFO_A
+    arg->remote.res = rsock_addrinfo_a(arg->remote.host, arg->remote.serv,
+				       family, SOCK_STREAM,
+				       (type == INET_SERVER) ? AI_PASSIVE : 0,
+				       resolv_timeout);
+#else
     arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv,
 				     family, SOCK_STREAM,
 				     (type == INET_SERVER) ? AI_PASSIVE : 0);
+#endif
+
+
     /*
      * Maybe also accept a local address
      */
@@ -157,7 +168,8 @@ init_inetsock_internal(VALUE v) https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L168
 
 VALUE
 rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv,
-	            VALUE local_host, VALUE local_serv, int type)
+	            VALUE local_host, VALUE local_serv, int type,
+		    VALUE resolv_timeout)
 {
     struct inetsock_arg arg;
     arg.sock = sock;
@@ -169,6 +181,7 @@ rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L181
     arg.local.res = 0;
     arg.type = type;
     arg.fd = -1;
+    arg.resolv_timeout = resolv_timeout;
     return rb_ensure(init_inetsock_internal, (VALUE)&arg,
 		     inetsock_cleanup, (VALUE)&arg);
 }
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index 4dd2867..211f05c 100644
--- a/ext/socket/raddrinfo.c
+++ b/ext/socket/raddrinfo.c
@@ -662,6 +662,20 @@ rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags) https://github.com/ruby/ruby/blob/trunk/ext/socket/raddrinfo.c#L662
     return rsock_getaddrinfo(host, port, &hints, 1);
 }
 
+#ifdef HAVE_GETADDRINFO_A
+struct rb_addrinfo*
+rsock_addrinfo_a(VALUE host, VALUE port, int family, int socktype, int flags, VALUE timeout)
+{
+    struct addrinfo hints;
+
+    MEMZERO(&hints, struct addrinfo, 1);
+    hints.ai_family = family;
+    hints.ai_socktype = socktype;
+    hints.ai_flags = flags;
+    return rsock_getaddrinfo_a(host, port, &hints, 1, timeout);
+}
+#endif
+
 VALUE
 rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup)
 {
diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h
index 30b7a77..91b446d 100644
--- a/ext/socket/rubysocket.h
+++ b/ext/socket/rubysocket.h
@@ -321,6 +321,7 @@ int rsock_fd_family(int fd); https://github.com/ruby/ruby/blob/trunk/ext/socket/rubysocket.h#L321
 struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags);
 struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack);
 #ifdef HAVE_GETADDRINFO_A
+struct rb_addrinfo *rsock_addrinfo_a(VALUE host, VALUE port, int family, int socktype, int flags, VALUE timeout);
 struct rb_addrinfo *rsock_getaddrinfo_a(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack, VALUE timeout);
 #endif
 
@@ -349,7 +350,7 @@ int rsock_socket(int domain, int type, int proto); https://github.com/ruby/ruby/blob/trunk/ext/socket/rubysocket.h#L350
 int rsock_detect_cloexec(int fd);
 VALUE rsock_init_sock(VALUE sock, int fd);
 VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass);
-VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type);
+VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type, VALUE resolv_timeout);
 VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server);
 
 struct rsock_send_arg {
diff --git a/ext/socket/sockssocket.c b/ext/socket/sockssocket.c
index 82789ee..78b0055 100644
--- a/ext/socket/sockssocket.c
+++ b/ext/socket/sockssocket.c
@@ -34,7 +34,7 @@ socks_init(VALUE sock, VALUE host, VALUE port) https://github.com/ruby/ruby/blob/trunk/ext/socket/sockssocket.c#L34
 	init = 1;
     }
 
-    return rsock_init_inetsock(sock, host, port, Qnil, Qnil, INET_SOCKS);
+    return rsock_init_inetsock(sock, host, port, Qnil, Qnil, INET_SOCKS, Qnil);
 }
 
 #ifdef SOCKS5
diff --git a/ext/socket/tcpserver.c b/ext/socket/tcpserver.c
index 1bbb31a..ad31e16 100644
--- a/ext/socket/tcpserver.c
+++ b/ext/socket/tcpserver.c
@@ -36,7 +36,7 @@ tcp_svr_init(int argc, VALUE *argv, VALUE sock) https://github.com/ruby/ruby/blob/trunk/ext/socket/tcpserver.c#L36
     VALUE hostname, port;
 
     rb_scan_args(argc, argv, "011", &hostname, &port);
-    return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER);
+    return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER, Qnil);
 }
 
 /*
diff --git a/ext/socket/tcpsocket.c b/ext/socket/tcpsocket.c
index f3fcee7..6baf367 100644
--- a/ext/socket/tcpsocket.c
+++ b/ext/socket/tcpsocket.c
@@ -23,12 +23,28 @@ tcp_init(int argc, VALUE *argv, VALUE sock) https://github.com/ruby/ruby/blob/trunk/ext/socket/tcpsocket.c#L23
 {
     VALUE remote_host, remote_serv;
     VALUE local_host, local_serv;
+    VALUE opt;
+    static ID keyword_ids[1];
+    VALUE kwargs[1];
+    VALUE resolv_timeout = Qnil;
 
-    rb_scan_args(argc, argv, "22", &remote_host, &remote_serv,
-			&local_host, &local_serv);
+    if (!keyword_ids[0]) {
+	CONST_ID(keyword_ids[0], "resolv_timeout");
+    }
+
+    rb_scan_args(argc, argv, "22:", &remote_host, &remote_serv,
+			&local_host, &local_serv, &opt);
+
+    if (!NIL_P(opt)) {
+	rb_get_kwargs(opt, keyword_ids, 0, 1, kwargs);
+	if (kwargs[0] != Qundef) {
+	    resolv_timeout = kwargs[0];
+	}
+    }
 
     return rsock_init_inetsock(sock, remote_host, remote_serv,
-			       local_host, local_serv, INET_CLIENT);
+			       local_host, local_serv, INET_CLIENT,
+			       resolv_timeout);
 }
 
 static VALUE
diff --git a/test/socket/test_tcp.rb b/test/socket/test_tcp.rb
index 11325fd..15c79b7 100644
--- a/test/socket/test_tcp.rb
+++ b/test/socket/test_tcp.rb
@@ -55,6 +55,20 @@ class TestSocket_TCPSocket < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/socket/test_tcp.rb#L55
     t.close if t && !t.closed?
   end
 
+  def test_initialize_resolv_timeout
+    TCPServer.open("localhost", 0) do |svr|
+      th = Thread.new {
+        c = svr.accept
+        c.close
+      }
+      addr = svr.addr
+      s = TCPSocket.new(addr[3], addr[1], resolv_timeout: 10)
+      th.join
+    ensure
+      s.close()
+    end
+  end
+
   def test_recvfrom
     TCPServer.open("localhost", 0) {|svr|
       th = Thread.new {
-- 
cgit v0.10.2


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

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