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/