PageRenderTime 59ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/test/socket/test_addrinfo.rb

https://github.com/ruby/ruby
Ruby | 704 lines | 631 code | 61 blank | 12 comment | 87 complexity | a1b06392efba2c96bc8a819339351e2d MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. # frozen_string_literal: true
  2. begin
  3. require "socket"
  4. rescue LoadError
  5. end
  6. require "test/unit"
  7. class TestSocketAddrinfo < Test::Unit::TestCase
  8. HAS_UNIXSOCKET = defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
  9. def tcp_unspecified_to_loopback(addrinfo)
  10. if addrinfo.ipv4? && addrinfo.ip_address == "0.0.0.0"
  11. Addrinfo.tcp("127.0.0.1", addrinfo.ip_port)
  12. elsif addrinfo.ipv6? && addrinfo.ipv6_unspecified?
  13. Addrinfo.tcp("::1", addrinfo.ip_port)
  14. elsif addrinfo.ipv6? && (ai = addrinfo.ipv6_to_ipv4) && ai.ip_address == "0.0.0.0"
  15. Addrinfo.tcp("127.0.0.1", addrinfo.ip_port)
  16. else
  17. addrinfo
  18. end
  19. end
  20. def test_addrinfo_ip
  21. ai = Addrinfo.ip("127.0.0.1")
  22. assert_equal([0, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
  23. assert_equal(Socket::AF_INET, ai.afamily)
  24. assert_equal(Socket::PF_INET, ai.pfamily)
  25. assert_equal(0, ai.socktype)
  26. assert_equal(0, ai.protocol)
  27. ai = Addrinfo.ip("<any>")
  28. assert_equal([0, "0.0.0.0"], Socket.unpack_sockaddr_in(ai))
  29. ai = Addrinfo.ip("<broadcast>")
  30. assert_equal([0, "255.255.255.255"], Socket.unpack_sockaddr_in(ai))
  31. ai = assert_nothing_raised(SocketError) do
  32. base_str = "127.0.0.1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  33. addr = base_str[0, 9]
  34. Addrinfo.ip(addr)
  35. end
  36. assert_equal([0, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
  37. assert_raise(ArgumentError) do
  38. Addrinfo.ip("127.0.0.1\000x")
  39. end
  40. end
  41. def test_addrinfo_tcp
  42. ai = Addrinfo.tcp("127.0.0.1", 80)
  43. assert_equal([80, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
  44. assert_equal(Socket::AF_INET, ai.afamily)
  45. assert_equal(Socket::PF_INET, ai.pfamily)
  46. assert_equal(Socket::SOCK_STREAM, ai.socktype)
  47. assert_include([0, Socket::IPPROTO_TCP], ai.protocol)
  48. ai = assert_nothing_raised(SocketError) do
  49. Addrinfo.tcp("127.0.0.1", "0000000000000000000000080x".chop)
  50. end
  51. assert_equal([80, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
  52. assert_raise(ArgumentError) do
  53. Addrinfo.ip("127.0.0.1", "80\000x")
  54. end
  55. end
  56. def test_addrinfo_udp
  57. ai = Addrinfo.udp("127.0.0.1", 80)
  58. assert_equal([80, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
  59. assert_equal(Socket::AF_INET, ai.afamily)
  60. assert_equal(Socket::PF_INET, ai.pfamily)
  61. assert_equal(Socket::SOCK_DGRAM, ai.socktype)
  62. assert_include([0, Socket::IPPROTO_UDP], ai.protocol)
  63. end
  64. def test_addrinfo_ip_unpack
  65. ai = Addrinfo.tcp("127.0.0.1", 80)
  66. assert_equal(["127.0.0.1", 80], ai.ip_unpack)
  67. assert_equal("127.0.0.1", ai.ip_address)
  68. assert_equal(80, ai.ip_port)
  69. end
  70. def test_addrinfo_inspect_sockaddr
  71. ai = Addrinfo.tcp("127.0.0.1", 80)
  72. assert_equal("127.0.0.1:80", ai.inspect_sockaddr)
  73. end
  74. def test_addrinfo_new_inet
  75. ai = Addrinfo.new(["AF_INET", 46102, "localhost.localdomain", "127.0.0.2"])
  76. assert_equal([46102, "127.0.0.2"], Socket.unpack_sockaddr_in(ai))
  77. assert_equal(Socket::AF_INET, ai.afamily)
  78. assert_equal(Socket::PF_INET, ai.pfamily)
  79. assert_equal(0, ai.socktype)
  80. assert_equal(0, ai.protocol)
  81. end
  82. def test_addrinfo_predicates
  83. ipv4_ai = Addrinfo.new(Socket.sockaddr_in(80, "192.168.0.1"))
  84. assert(ipv4_ai.ip?)
  85. assert(ipv4_ai.ipv4?)
  86. assert(!ipv4_ai.ipv6?)
  87. assert(!ipv4_ai.unix?)
  88. end
  89. def test_error_message
  90. e = assert_raise_with_message(SocketError, /getaddrinfo/) do
  91. Addrinfo.ip("...")
  92. end
  93. m = e.message
  94. assert_not_equal([false, Encoding::ASCII_8BIT], [m.ascii_only?, m.encoding], proc {m.inspect})
  95. end
  96. def test_ipv4_address_predicates
  97. list = [
  98. [:ipv4_private?, "10.0.0.0", "10.255.255.255",
  99. "172.16.0.0", "172.31.255.255",
  100. "192.168.0.0", "192.168.255.255"],
  101. [:ipv4_loopback?, "127.0.0.1", "127.0.0.0", "127.255.255.255"],
  102. [:ipv4_multicast?, "224.0.0.0", "224.255.255.255"]
  103. ]
  104. list.each {|meth, *addrs|
  105. addrs.each {|addr|
  106. assert(Addrinfo.ip(addr).send(meth), "Addrinfo.ip(#{addr.inspect}).#{meth}")
  107. list.each {|meth2,|
  108. next if meth == meth2
  109. assert(!Addrinfo.ip(addr).send(meth2), "!Addrinfo.ip(#{addr.inspect}).#{meth2}")
  110. }
  111. }
  112. }
  113. end
  114. def test_basicsocket_send
  115. s1 = Socket.new(:INET, :DGRAM, 0)
  116. s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  117. sa = s1.getsockname
  118. ai = Addrinfo.new(sa)
  119. s2 = Socket.new(:INET, :DGRAM, 0)
  120. s2.send("test-basicsocket-send", 0, ai)
  121. assert_equal("test-basicsocket-send", s1.recv(100))
  122. ensure
  123. s1.close if s1 && !s1.closed?
  124. s2.close if s2 && !s2.closed?
  125. end
  126. def test_udpsocket_send
  127. s1 = UDPSocket.new
  128. s1.bind("127.0.0.1", 0)
  129. ai = Addrinfo.new(s1.getsockname)
  130. s2 = UDPSocket.new
  131. s2.send("test-udp-send", 0, ai)
  132. assert_equal("test-udp-send", s1.recv(100))
  133. ensure
  134. s1.close if s1 && !s1.closed?
  135. s2.close if s2 && !s2.closed?
  136. end
  137. def test_socket_bind
  138. s1 = Socket.new(:INET, :DGRAM, 0)
  139. sa = Socket.sockaddr_in(0, "127.0.0.1")
  140. ai = Addrinfo.new(sa)
  141. s1.bind(ai)
  142. s2 = UDPSocket.new
  143. s2.send("test-socket-bind", 0, s1.getsockname)
  144. assert_equal("test-socket-bind", s1.recv(100))
  145. ensure
  146. s1.close if s1 && !s1.closed?
  147. s2.close if s2 && !s2.closed?
  148. end
  149. def test_socket_connect
  150. s1 = Socket.new(:INET, :STREAM, 0)
  151. s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  152. s1.listen(5)
  153. ai = Addrinfo.new(s1.getsockname)
  154. s2 = Socket.new(:INET, :STREAM, 0)
  155. s2.connect(ai)
  156. s3, _ = s1.accept
  157. s2.send("test-socket-connect", 0)
  158. assert_equal("test-socket-connect", s3.recv(100))
  159. ensure
  160. s1.close if s1 && !s1.closed?
  161. s2.close if s2 && !s2.closed?
  162. s3.close if s3 && !s3.closed?
  163. end
  164. def test_socket_connect_nonblock
  165. s1 = Socket.new(:INET, :STREAM, 0)
  166. s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  167. s1.listen(5)
  168. ai = Addrinfo.new(s1.getsockname)
  169. s2 = Socket.new(:INET, :STREAM, 0)
  170. begin
  171. s2.connect_nonblock(ai)
  172. rescue IO::WaitWritable
  173. IO.select(nil, [s2])
  174. r = s2.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR)
  175. assert_equal(0, r.int, "NOERROR is expected but #{r.inspect}")
  176. begin
  177. s2.connect_nonblock(ai)
  178. rescue Errno::EISCONN
  179. end
  180. end
  181. s3, _ = s1.accept
  182. s2.send("test-socket-connect-nonblock", 0)
  183. assert_equal("test-socket-connect-nonblock", s3.recv(100))
  184. ensure
  185. s1.close if s1 && !s1.closed?
  186. s2.close if s2 && !s2.closed?
  187. s3.close if s3 && !s3.closed?
  188. end
  189. def test_socket_getnameinfo
  190. ai = Addrinfo.udp("127.0.0.1", 8888)
  191. assert_equal(["127.0.0.1", "8888"], Socket.getnameinfo(ai, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV))
  192. end
  193. def test_basicsocket_local_address
  194. s1 = Socket.new(:INET, :DGRAM, 0)
  195. s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  196. e = Socket.unpack_sockaddr_in(s1.getsockname)
  197. a = Socket.unpack_sockaddr_in(s1.local_address.to_sockaddr)
  198. assert_equal(e, a)
  199. assert_equal(Socket::AF_INET, s1.local_address.afamily)
  200. assert_equal(Socket::PF_INET, s1.local_address.pfamily)
  201. assert_equal(Socket::SOCK_DGRAM, s1.local_address.socktype)
  202. ensure
  203. s1.close if s1 && !s1.closed?
  204. end
  205. def test_basicsocket_remote_address
  206. s1 = TCPServer.new("127.0.0.1", 0)
  207. s2 = Socket.new(:INET, :STREAM, 0)
  208. s2.connect(s1.getsockname)
  209. s3, _ = s1.accept
  210. e = Socket.unpack_sockaddr_in(s2.getsockname)
  211. a = Socket.unpack_sockaddr_in(s3.remote_address.to_sockaddr)
  212. assert_equal(e, a)
  213. assert_equal(Socket::AF_INET, s3.remote_address.afamily)
  214. assert_equal(Socket::PF_INET, s3.remote_address.pfamily)
  215. assert_equal(Socket::SOCK_STREAM, s3.remote_address.socktype)
  216. ensure
  217. s1.close if s1 && !s1.closed?
  218. s2.close if s2 && !s2.closed?
  219. s3.close if s3 && !s3.closed?
  220. end
  221. def test_socket_accept
  222. serv = Socket.new(:INET, :STREAM, 0)
  223. serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  224. serv.listen(5)
  225. c = Socket.new(:INET, :STREAM, 0)
  226. c.connect(serv.local_address)
  227. ret = serv.accept
  228. s, ai = ret
  229. assert_kind_of(Array, ret)
  230. assert_equal(2, ret.length)
  231. assert_kind_of(Addrinfo, ai)
  232. e = Socket.unpack_sockaddr_in(c.getsockname)
  233. a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
  234. assert_equal(e, a)
  235. ensure
  236. serv.close if serv && !serv.closed?
  237. s.close if s && !s.closed?
  238. c.close if c && !c.closed?
  239. end
  240. def test_socket_accept_nonblock
  241. serv = Socket.new(:INET, :STREAM, 0)
  242. serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  243. serv.listen(5)
  244. c = Socket.new(:INET, :STREAM, 0)
  245. c.connect(serv.local_address)
  246. begin
  247. ret = serv.accept_nonblock
  248. rescue IO::WaitReadable, Errno::EINTR
  249. IO.select([serv])
  250. retry
  251. end
  252. s, ai = ret
  253. assert_kind_of(Array, ret)
  254. assert_equal(2, ret.length)
  255. assert_kind_of(Addrinfo, ai)
  256. e = Socket.unpack_sockaddr_in(c.getsockname)
  257. a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
  258. assert_equal(e, a)
  259. ensure
  260. serv.close if serv && !serv.closed?
  261. s.close if s && !s.closed?
  262. c.close if c && !c.closed?
  263. end
  264. def test_socket_sysaccept
  265. serv = Socket.new(:INET, :STREAM, 0)
  266. serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  267. serv.listen(5)
  268. c = Socket.new(:INET, :STREAM, 0)
  269. c.connect(serv.local_address)
  270. ret = serv.sysaccept
  271. fd, ai = ret
  272. s = IO.new(fd)
  273. assert_kind_of(Array, ret)
  274. assert_equal(2, ret.length)
  275. assert_kind_of(Addrinfo, ai)
  276. e = Socket.unpack_sockaddr_in(c.getsockname)
  277. a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
  278. assert_equal(e, a)
  279. ensure
  280. serv.close if serv && !serv.closed?
  281. s.close if s && !s.closed?
  282. c.close if c && !c.closed?
  283. end
  284. def test_socket_recvfrom
  285. s1 = Socket.new(:INET, :DGRAM, 0)
  286. s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  287. s2 = Socket.new(:INET, :DGRAM, 0)
  288. s2.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  289. s2.send("test-socket-recvfrom", 0, s1.getsockname)
  290. data, ai = s1.recvfrom(100)
  291. assert_equal("test-socket-recvfrom", data)
  292. assert_kind_of(Addrinfo, ai)
  293. e = Socket.unpack_sockaddr_in(s2.getsockname)
  294. a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
  295. assert_equal(e, a)
  296. ensure
  297. s1.close if s1 && !s1.closed?
  298. s2.close if s2 && !s2.closed?
  299. end
  300. def test_socket_recvfrom_nonblock
  301. s1 = Socket.new(:INET, :DGRAM, 0)
  302. s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  303. s2 = Socket.new(:INET, :DGRAM, 0)
  304. s2.bind(Socket.sockaddr_in(0, "127.0.0.1"))
  305. s2.send("test-socket-recvfrom", 0, s1.getsockname)
  306. begin
  307. data, ai = s1.recvfrom_nonblock(100)
  308. rescue IO::WaitReadable
  309. IO.select([s1])
  310. retry
  311. end
  312. assert_equal("test-socket-recvfrom", data)
  313. assert_kind_of(Addrinfo, ai)
  314. e = Socket.unpack_sockaddr_in(s2.getsockname)
  315. a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
  316. assert_equal(e, a)
  317. ensure
  318. s1.close if s1 && !s1.closed?
  319. s2.close if s2 && !s2.closed?
  320. end
  321. def test_family_addrinfo
  322. ai = Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("127.0.0.1", 80)
  323. assert_equal(["127.0.0.1", 80], ai.ip_unpack)
  324. assert_equal(Socket::SOCK_STREAM, ai.socktype)
  325. return unless Addrinfo.respond_to?(:unix)
  326. ai = Addrinfo.unix("/testdir/sock").family_addrinfo("/testdir/sock2")
  327. assert_equal("/testdir/sock2", ai.unix_path)
  328. assert_equal(Socket::SOCK_STREAM, ai.socktype)
  329. assert_raise(SocketError) { Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("::1", 80) }
  330. end
  331. def random_port
  332. # IANA suggests dynamic port for 49152 to 65535
  333. # http://www.iana.org/assignments/port-numbers
  334. case RUBY_PLATFORM
  335. when /mingw|mswin/
  336. rand(50000..65535)
  337. else
  338. rand(49152..65535)
  339. end
  340. end
  341. def errors_addrinuse
  342. errs = [Errno::EADDRINUSE]
  343. # MinGW fails with "Errno::EACCES: Permission denied - bind(2) for 0.0.0.0:49721"
  344. errs << Errno::EACCES if /mingw/ =~ RUBY_PLATFORM
  345. errs
  346. end
  347. def test_connect_from
  348. TCPServer.open("0.0.0.0", 0) {|serv|
  349. serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
  350. serv_ai = tcp_unspecified_to_loopback(serv_ai)
  351. port = random_port
  352. begin
  353. serv_ai.connect_from("0.0.0.0", port) {|s1|
  354. s2 = serv.accept
  355. begin
  356. assert_equal(port, s2.remote_address.ip_port)
  357. ensure
  358. s2.close
  359. end
  360. }
  361. rescue *errors_addrinuse
  362. # not test failure
  363. end
  364. }
  365. TCPServer.open("0.0.0.0", 0) {|serv|
  366. serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
  367. serv_ai = tcp_unspecified_to_loopback(serv_ai)
  368. port = random_port
  369. begin
  370. serv_ai.connect_from(Addrinfo.tcp("0.0.0.0", port)) {|s1|
  371. s2 = serv.accept
  372. begin
  373. assert_equal(port, s2.remote_address.ip_port)
  374. ensure
  375. s2.close
  376. end
  377. }
  378. rescue *errors_addrinuse
  379. # not test failure
  380. end
  381. }
  382. end
  383. def test_connect_to
  384. TCPServer.open("0.0.0.0", 0) {|serv|
  385. serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
  386. serv_ai = tcp_unspecified_to_loopback(serv_ai)
  387. port = random_port
  388. client_ai = Addrinfo.tcp("0.0.0.0", port)
  389. begin
  390. client_ai.connect_to(*serv_ai.ip_unpack) {|s1|
  391. s2 = serv.accept
  392. begin
  393. assert_equal(port, s2.remote_address.ip_port)
  394. ensure
  395. s2.close
  396. end
  397. }
  398. rescue *errors_addrinuse
  399. # not test failure
  400. end
  401. }
  402. end
  403. def test_connect
  404. TCPServer.open("0.0.0.0", 0) {|serv|
  405. serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
  406. serv_ai = tcp_unspecified_to_loopback(serv_ai)
  407. begin
  408. serv_ai.connect {|s1|
  409. s2 = serv.accept
  410. begin
  411. assert_equal(s1.local_address.ip_unpack, s2.remote_address.ip_unpack)
  412. assert_equal(s2.local_address.ip_unpack, s1.remote_address.ip_unpack)
  413. ensure
  414. s2.close
  415. end
  416. }
  417. rescue *errors_addrinuse
  418. # not test failure
  419. end
  420. }
  421. end
  422. def test_bind
  423. port = random_port
  424. client_ai = Addrinfo.tcp("0.0.0.0", port)
  425. begin
  426. client_ai.bind {|s|
  427. assert_equal(port, s.local_address.ip_port)
  428. }
  429. rescue *errors_addrinuse
  430. # not test failure
  431. end
  432. end
  433. def test_listen
  434. port = random_port
  435. client_ai = Addrinfo.tcp("0.0.0.0", port)
  436. begin
  437. client_ai.listen {|serv|
  438. assert_equal(port, serv.local_address.ip_port)
  439. serv_addr, serv_port = serv.local_address.ip_unpack
  440. case serv_addr
  441. when "0.0.0.0" then serv_addr = "127.0.0.1"
  442. end
  443. TCPSocket.open(serv_addr, serv_port) {|s1|
  444. s2, addr = serv.accept
  445. begin
  446. assert_equal(s1.local_address.ip_unpack, addr.ip_unpack)
  447. ensure
  448. s2.close
  449. end
  450. }
  451. }
  452. rescue *errors_addrinuse
  453. # not test failure
  454. end
  455. end
  456. def test_s_foreach
  457. Addrinfo.foreach(nil, 80, nil, :STREAM) {|ai|
  458. assert_kind_of(Addrinfo, ai)
  459. }
  460. end
  461. def test_marshal
  462. ai1 = Addrinfo.tcp("127.0.0.1", 80)
  463. ai2 = Marshal.load(Marshal.dump(ai1))
  464. assert_equal(ai1.afamily, ai2.afamily)
  465. assert_equal(ai1.ip_unpack, ai2.ip_unpack)
  466. assert_equal(ai1.pfamily, ai2.pfamily)
  467. assert_equal(ai1.socktype, ai2.socktype)
  468. assert_equal(ai1.protocol, ai2.protocol)
  469. assert_equal(ai1.canonname, ai2.canonname)
  470. end
  471. def test_marshal_memory_leak
  472. bug11051 = '[ruby-dev:48923] [Bug #11051]'
  473. assert_no_memory_leak(%w[-rsocket], <<-PREP, <<-CODE, bug11051, rss: true)
  474. d = Marshal.dump(Addrinfo.tcp("127.0.0.1", 80))
  475. 1000.times {Marshal.load(d)}
  476. PREP
  477. GC.start
  478. 20_000.times {Marshal.load(d)}
  479. CODE
  480. end
  481. if Socket.const_defined?("AF_INET6") && Socket::AF_INET6.is_a?(Integer)
  482. def test_addrinfo_new_inet6
  483. ai = Addrinfo.new(["AF_INET6", 42304, "ip6-localhost", "::1"])
  484. assert_equal([42304, "::1"], Socket.unpack_sockaddr_in(ai))
  485. assert_equal(Socket::AF_INET6, ai.afamily)
  486. assert_equal(Socket::PF_INET6, ai.pfamily)
  487. assert_equal(0, ai.socktype)
  488. assert_equal(0, ai.protocol)
  489. end
  490. def test_addrinfo_ip_unpack_inet6
  491. ai = Addrinfo.tcp("::1", 80)
  492. assert_equal(["::1", 80], ai.ip_unpack)
  493. assert_equal("::1", ai.ip_address)
  494. assert_equal(80, ai.ip_port)
  495. end
  496. def test_addrinfo_inspect_sockaddr_inet6
  497. ai = Addrinfo.tcp("::1", 80)
  498. assert_equal("[::1]:80", ai.inspect_sockaddr)
  499. end
  500. def test_marshal_inet6
  501. ai1 = Addrinfo.tcp("::1", 80)
  502. ai2 = Marshal.load(Marshal.dump(ai1))
  503. assert_equal(ai1.afamily, ai2.afamily)
  504. assert_equal(ai1.ip_unpack, ai2.ip_unpack)
  505. assert_equal(ai1.pfamily, ai2.pfamily)
  506. assert_equal(ai1.socktype, ai2.socktype)
  507. assert_equal(ai1.protocol, ai2.protocol)
  508. assert_equal(ai1.canonname, ai2.canonname)
  509. end
  510. def ipv6(str)
  511. Addrinfo.getaddrinfo(str, nil, :INET6, :DGRAM).fetch(0)
  512. end
  513. def test_ipv6_address_predicates
  514. list = [
  515. [:ipv6_unspecified?, "::"],
  516. [:ipv6_loopback?, "::1"],
  517. [:ipv6_v4compat?, "::0.0.0.2", "::255.255.255.255"],
  518. [:ipv6_v4mapped?, "::ffff:0.0.0.0", "::ffff:255.255.255.255"],
  519. [:ipv6_linklocal?, "fe80::", "febf::"],
  520. [:ipv6_sitelocal?, "fec0::", "feef::"],
  521. [:ipv6_multicast?, "ff00::", "ffff::"],
  522. [:ipv6_unique_local?, "fc00::", "fd00::"],
  523. ]
  524. mlist = [
  525. [:ipv6_mc_nodelocal?, "ff01::", "ff11::"],
  526. [:ipv6_mc_linklocal?, "ff02::", "ff12::"],
  527. [:ipv6_mc_sitelocal?, "ff05::", "ff15::"],
  528. [:ipv6_mc_orglocal?, "ff08::", "ff18::"],
  529. [:ipv6_mc_global?, "ff0e::", "ff1e::"]
  530. ]
  531. list.each {|meth, *addrs|
  532. addrs.each {|addr|
  533. addr_exp = "Addrinfo.getaddrinfo(#{addr.inspect}, nil, :INET6, :DGRAM).fetch(0)"
  534. if meth == :ipv6_v4compat? || meth == :ipv6_v4mapped?
  535. # MacOS X returns IPv4 address for ::ffff:1.2.3.4 and ::1.2.3.4.
  536. # Solaris returns IPv4 address for ::ffff:1.2.3.4.
  537. ai = ipv6(addr)
  538. begin
  539. assert(ai.ipv4? || ai.send(meth), "ai=#{addr_exp}; ai.ipv4? || .#{meth}")
  540. rescue Test::Unit::AssertionFailedError
  541. if /aix/ =~ RUBY_PLATFORM
  542. skip "Known bug in IN6_IS_ADDR_V4COMPAT and IN6_IS_ADDR_V4MAPPED on AIX"
  543. end
  544. raise $!
  545. end
  546. else
  547. assert(ipv6(addr).send(meth), "#{addr_exp}.#{meth}")
  548. assert_equal(addr, ipv6(addr).ip_address)
  549. end
  550. list.each {|meth2,|
  551. next if meth == meth2
  552. assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
  553. }
  554. }
  555. }
  556. mlist.each {|meth, *addrs|
  557. addrs.each {|addr|
  558. addr_exp = "Addrinfo.getaddrinfo(#{addr.inspect}, nil, :INET6, :DGRAM).fetch(0)"
  559. assert(ipv6(addr).send(meth), "#{addr_exp}.#{meth}")
  560. assert(ipv6(addr).ipv6_multicast?, "#{addr_exp}.ipv6_multicast?")
  561. mlist.each {|meth2,|
  562. next if meth == meth2
  563. assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
  564. }
  565. list.each {|meth2,|
  566. next if :ipv6_multicast? == meth2
  567. assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
  568. }
  569. }
  570. }
  571. end
  572. def test_ipv6_to_ipv4
  573. ai = Addrinfo.ip("::192.0.2.3")
  574. ai = ai.ipv6_to_ipv4 if !ai.ipv4?
  575. assert(ai.ipv4?)
  576. assert_equal("192.0.2.3", ai.ip_address)
  577. ai = Addrinfo.ip("::ffff:192.0.2.3")
  578. ai = ai.ipv6_to_ipv4 if !ai.ipv4?
  579. assert(ai.ipv4?)
  580. assert_equal("192.0.2.3", ai.ip_address)
  581. assert_nil(Addrinfo.ip("::1").ipv6_to_ipv4)
  582. assert_nil(Addrinfo.ip("192.0.2.3").ipv6_to_ipv4)
  583. if HAS_UNIXSOCKET
  584. assert_nil(Addrinfo.unix("/testdir/sock").ipv6_to_ipv4)
  585. end
  586. end
  587. end
  588. if HAS_UNIXSOCKET
  589. def test_addrinfo_unix
  590. ai = Addrinfo.unix("/testdir/sock")
  591. assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
  592. assert_equal(Socket::AF_UNIX, ai.afamily)
  593. assert_equal(Socket::PF_UNIX, ai.pfamily)
  594. assert_equal(Socket::SOCK_STREAM, ai.socktype)
  595. assert_equal(0, ai.protocol)
  596. end
  597. def test_addrinfo_unix_dgram
  598. ai = Addrinfo.unix("/testdir/sock", :DGRAM)
  599. assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
  600. assert_equal(Socket::AF_UNIX, ai.afamily)
  601. assert_equal(Socket::PF_UNIX, ai.pfamily)
  602. assert_equal(Socket::SOCK_DGRAM, ai.socktype)
  603. assert_equal(0, ai.protocol)
  604. end
  605. def test_addrinfo_unix_path
  606. ai = Addrinfo.unix("/testdir/sock1")
  607. assert_equal("/testdir/sock1", ai.unix_path)
  608. end
  609. def test_addrinfo_inspect_sockaddr_unix
  610. ai = Addrinfo.unix("/testdir/test_addrinfo_inspect_sockaddr_unix")
  611. assert_equal("/testdir/test_addrinfo_inspect_sockaddr_unix", ai.inspect_sockaddr)
  612. end
  613. def test_addrinfo_new_unix
  614. ai = Addrinfo.new(["AF_UNIX", "/testdir/sock"])
  615. assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
  616. assert_equal(Socket::AF_UNIX, ai.afamily)
  617. assert_equal(Socket::PF_UNIX, ai.pfamily)
  618. assert_equal(Socket::SOCK_STREAM, ai.socktype) # UNIXSocket/UNIXServer is SOCK_STREAM only.
  619. assert_equal(0, ai.protocol)
  620. end
  621. def test_addrinfo_predicates_unix
  622. unix_ai = Addrinfo.new(Socket.sockaddr_un("/testdir/sososo"))
  623. assert(!unix_ai.ip?)
  624. assert(!unix_ai.ipv4?)
  625. assert(!unix_ai.ipv6?)
  626. assert(unix_ai.unix?)
  627. end
  628. def test_marshal_unix
  629. ai1 = Addrinfo.unix("/testdir/sock")
  630. ai2 = Marshal.load(Marshal.dump(ai1))
  631. assert_equal(ai1.afamily, ai2.afamily)
  632. assert_equal(ai1.unix_path, ai2.unix_path)
  633. assert_equal(ai1.pfamily, ai2.pfamily)
  634. assert_equal(ai1.socktype, ai2.socktype)
  635. assert_equal(ai1.protocol, ai2.protocol)
  636. assert_equal(ai1.canonname, ai2.canonname)
  637. end
  638. def test_addrinfo_timeout
  639. ai = Addrinfo.getaddrinfo("localhost", "ssh", Socket::PF_INET, Socket::SOCK_STREAM, timeout: 1).fetch(0)
  640. assert_equal(22, ai.ip_port)
  641. end
  642. end
  643. end