PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/test/socket/test_addrinfo.rb

http://github.com/ruby/ruby
Ruby | 696 lines | 624 code | 61 blank | 11 comment | 86 complexity | cb0b48e29f0e5027f4f6c6504c95fd08 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  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. 49152 + rand(65535-49152+1)
  335. end
  336. def errors_addrinuse
  337. [Errno::EADDRINUSE]
  338. end
  339. def test_connect_from
  340. TCPServer.open("0.0.0.0", 0) {|serv|
  341. serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
  342. serv_ai = tcp_unspecified_to_loopback(serv_ai)
  343. port = random_port
  344. begin
  345. serv_ai.connect_from("0.0.0.0", port) {|s1|
  346. s2 = serv.accept
  347. begin
  348. assert_equal(port, s2.remote_address.ip_port)
  349. ensure
  350. s2.close
  351. end
  352. }
  353. rescue *errors_addrinuse
  354. # not test failure
  355. end
  356. }
  357. TCPServer.open("0.0.0.0", 0) {|serv|
  358. serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
  359. serv_ai = tcp_unspecified_to_loopback(serv_ai)
  360. port = random_port
  361. begin
  362. serv_ai.connect_from(Addrinfo.tcp("0.0.0.0", port)) {|s1|
  363. s2 = serv.accept
  364. begin
  365. assert_equal(port, s2.remote_address.ip_port)
  366. ensure
  367. s2.close
  368. end
  369. }
  370. rescue *errors_addrinuse
  371. # not test failure
  372. end
  373. }
  374. end
  375. def test_connect_to
  376. TCPServer.open("0.0.0.0", 0) {|serv|
  377. serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
  378. serv_ai = tcp_unspecified_to_loopback(serv_ai)
  379. port = random_port
  380. client_ai = Addrinfo.tcp("0.0.0.0", port)
  381. begin
  382. client_ai.connect_to(*serv_ai.ip_unpack) {|s1|
  383. s2 = serv.accept
  384. begin
  385. assert_equal(port, s2.remote_address.ip_port)
  386. ensure
  387. s2.close
  388. end
  389. }
  390. rescue *errors_addrinuse
  391. # not test failure
  392. end
  393. }
  394. end
  395. def test_connect
  396. TCPServer.open("0.0.0.0", 0) {|serv|
  397. serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
  398. serv_ai = tcp_unspecified_to_loopback(serv_ai)
  399. begin
  400. serv_ai.connect {|s1|
  401. s2 = serv.accept
  402. begin
  403. assert_equal(s1.local_address.ip_unpack, s2.remote_address.ip_unpack)
  404. assert_equal(s2.local_address.ip_unpack, s1.remote_address.ip_unpack)
  405. ensure
  406. s2.close
  407. end
  408. }
  409. rescue *errors_addrinuse
  410. # not test failure
  411. end
  412. }
  413. end
  414. def test_bind
  415. port = random_port
  416. client_ai = Addrinfo.tcp("0.0.0.0", port)
  417. begin
  418. client_ai.bind {|s|
  419. assert_equal(port, s.local_address.ip_port)
  420. }
  421. rescue *errors_addrinuse
  422. # not test failure
  423. end
  424. end
  425. def test_listen
  426. port = random_port
  427. client_ai = Addrinfo.tcp("0.0.0.0", port)
  428. begin
  429. client_ai.listen {|serv|
  430. assert_equal(port, serv.local_address.ip_port)
  431. serv_addr, serv_port = serv.local_address.ip_unpack
  432. case serv_addr
  433. when "0.0.0.0" then serv_addr = "127.0.0.1"
  434. end
  435. TCPSocket.open(serv_addr, serv_port) {|s1|
  436. s2, addr = serv.accept
  437. begin
  438. assert_equal(s1.local_address.ip_unpack, addr.ip_unpack)
  439. ensure
  440. s2.close
  441. end
  442. }
  443. }
  444. rescue *errors_addrinuse
  445. # not test failure
  446. end
  447. end
  448. def test_s_foreach
  449. Addrinfo.foreach(nil, 80, nil, :STREAM) {|ai|
  450. assert_kind_of(Addrinfo, ai)
  451. }
  452. end
  453. def test_marshal
  454. ai1 = Addrinfo.tcp("127.0.0.1", 80)
  455. ai2 = Marshal.load(Marshal.dump(ai1))
  456. assert_equal(ai1.afamily, ai2.afamily)
  457. assert_equal(ai1.ip_unpack, ai2.ip_unpack)
  458. assert_equal(ai1.pfamily, ai2.pfamily)
  459. assert_equal(ai1.socktype, ai2.socktype)
  460. assert_equal(ai1.protocol, ai2.protocol)
  461. assert_equal(ai1.canonname, ai2.canonname)
  462. end
  463. def test_marshal_memory_leak
  464. bug11051 = '[ruby-dev:48923] [Bug #11051]'
  465. assert_no_memory_leak(%w[-rsocket], <<-PREP, <<-CODE, bug11051, rss: true)
  466. d = Marshal.dump(Addrinfo.tcp("127.0.0.1", 80))
  467. 1000.times {Marshal.load(d)}
  468. PREP
  469. GC.start
  470. 20_000.times {Marshal.load(d)}
  471. CODE
  472. end
  473. if Socket.const_defined?("AF_INET6") && Socket::AF_INET6.is_a?(Integer)
  474. def test_addrinfo_new_inet6
  475. ai = Addrinfo.new(["AF_INET6", 42304, "ip6-localhost", "::1"])
  476. assert_equal([42304, "::1"], Socket.unpack_sockaddr_in(ai))
  477. assert_equal(Socket::AF_INET6, ai.afamily)
  478. assert_equal(Socket::PF_INET6, ai.pfamily)
  479. assert_equal(0, ai.socktype)
  480. assert_equal(0, ai.protocol)
  481. end
  482. def test_addrinfo_ip_unpack_inet6
  483. ai = Addrinfo.tcp("::1", 80)
  484. assert_equal(["::1", 80], ai.ip_unpack)
  485. assert_equal("::1", ai.ip_address)
  486. assert_equal(80, ai.ip_port)
  487. end
  488. def test_addrinfo_inspect_sockaddr_inet6
  489. ai = Addrinfo.tcp("::1", 80)
  490. assert_equal("[::1]:80", ai.inspect_sockaddr)
  491. end
  492. def test_marshal_inet6
  493. ai1 = Addrinfo.tcp("::1", 80)
  494. ai2 = Marshal.load(Marshal.dump(ai1))
  495. assert_equal(ai1.afamily, ai2.afamily)
  496. assert_equal(ai1.ip_unpack, ai2.ip_unpack)
  497. assert_equal(ai1.pfamily, ai2.pfamily)
  498. assert_equal(ai1.socktype, ai2.socktype)
  499. assert_equal(ai1.protocol, ai2.protocol)
  500. assert_equal(ai1.canonname, ai2.canonname)
  501. end
  502. def ipv6(str)
  503. Addrinfo.getaddrinfo(str, nil, :INET6, :DGRAM).fetch(0)
  504. end
  505. def test_ipv6_address_predicates
  506. list = [
  507. [:ipv6_unspecified?, "::"],
  508. [:ipv6_loopback?, "::1"],
  509. [:ipv6_v4compat?, "::0.0.0.2", "::255.255.255.255"],
  510. [:ipv6_v4mapped?, "::ffff:0.0.0.0", "::ffff:255.255.255.255"],
  511. [:ipv6_linklocal?, "fe80::", "febf::"],
  512. [:ipv6_sitelocal?, "fec0::", "feef::"],
  513. [:ipv6_multicast?, "ff00::", "ffff::"],
  514. [:ipv6_unique_local?, "fc00::", "fd00::"],
  515. ]
  516. mlist = [
  517. [:ipv6_mc_nodelocal?, "ff01::", "ff11::"],
  518. [:ipv6_mc_linklocal?, "ff02::", "ff12::"],
  519. [:ipv6_mc_sitelocal?, "ff05::", "ff15::"],
  520. [:ipv6_mc_orglocal?, "ff08::", "ff18::"],
  521. [:ipv6_mc_global?, "ff0e::", "ff1e::"]
  522. ]
  523. list.each {|meth, *addrs|
  524. addrs.each {|addr|
  525. addr_exp = "Addrinfo.getaddrinfo(#{addr.inspect}, nil, :INET6, :DGRAM).fetch(0)"
  526. if meth == :ipv6_v4compat? || meth == :ipv6_v4mapped?
  527. # MacOS X returns IPv4 address for ::ffff:1.2.3.4 and ::1.2.3.4.
  528. # Solaris returns IPv4 address for ::ffff:1.2.3.4.
  529. ai = ipv6(addr)
  530. begin
  531. assert(ai.ipv4? || ai.send(meth), "ai=#{addr_exp}; ai.ipv4? || .#{meth}")
  532. rescue Minitest::Assertion
  533. if /aix/ =~ RUBY_PLATFORM
  534. skip "Known bug in IN6_IS_ADDR_V4COMPAT and IN6_IS_ADDR_V4MAPPED on AIX"
  535. end
  536. raise $!
  537. end
  538. else
  539. assert(ipv6(addr).send(meth), "#{addr_exp}.#{meth}")
  540. assert_equal(addr, ipv6(addr).ip_address)
  541. end
  542. list.each {|meth2,|
  543. next if meth == meth2
  544. assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
  545. }
  546. }
  547. }
  548. mlist.each {|meth, *addrs|
  549. addrs.each {|addr|
  550. addr_exp = "Addrinfo.getaddrinfo(#{addr.inspect}, nil, :INET6, :DGRAM).fetch(0)"
  551. assert(ipv6(addr).send(meth), "#{addr_exp}.#{meth}")
  552. assert(ipv6(addr).ipv6_multicast?, "#{addr_exp}.ipv6_multicast?")
  553. mlist.each {|meth2,|
  554. next if meth == meth2
  555. assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
  556. }
  557. list.each {|meth2,|
  558. next if :ipv6_multicast? == meth2
  559. assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
  560. }
  561. }
  562. }
  563. end
  564. def test_ipv6_to_ipv4
  565. ai = Addrinfo.ip("::192.0.2.3")
  566. ai = ai.ipv6_to_ipv4 if !ai.ipv4?
  567. assert(ai.ipv4?)
  568. assert_equal("192.0.2.3", ai.ip_address)
  569. ai = Addrinfo.ip("::ffff:192.0.2.3")
  570. ai = ai.ipv6_to_ipv4 if !ai.ipv4?
  571. assert(ai.ipv4?)
  572. assert_equal("192.0.2.3", ai.ip_address)
  573. assert_nil(Addrinfo.ip("::1").ipv6_to_ipv4)
  574. assert_nil(Addrinfo.ip("192.0.2.3").ipv6_to_ipv4)
  575. if HAS_UNIXSOCKET
  576. assert_nil(Addrinfo.unix("/testdir/sock").ipv6_to_ipv4)
  577. end
  578. end
  579. end
  580. if HAS_UNIXSOCKET
  581. def test_addrinfo_unix
  582. ai = Addrinfo.unix("/testdir/sock")
  583. assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
  584. assert_equal(Socket::AF_UNIX, ai.afamily)
  585. assert_equal(Socket::PF_UNIX, ai.pfamily)
  586. assert_equal(Socket::SOCK_STREAM, ai.socktype)
  587. assert_equal(0, ai.protocol)
  588. end
  589. def test_addrinfo_unix_dgram
  590. ai = Addrinfo.unix("/testdir/sock", :DGRAM)
  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_DGRAM, ai.socktype)
  595. assert_equal(0, ai.protocol)
  596. end
  597. def test_addrinfo_unix_path
  598. ai = Addrinfo.unix("/testdir/sock1")
  599. assert_equal("/testdir/sock1", ai.unix_path)
  600. end
  601. def test_addrinfo_inspect_sockaddr_unix
  602. ai = Addrinfo.unix("/testdir/test_addrinfo_inspect_sockaddr_unix")
  603. assert_equal("/testdir/test_addrinfo_inspect_sockaddr_unix", ai.inspect_sockaddr)
  604. end
  605. def test_addrinfo_new_unix
  606. ai = Addrinfo.new(["AF_UNIX", "/testdir/sock"])
  607. assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
  608. assert_equal(Socket::AF_UNIX, ai.afamily)
  609. assert_equal(Socket::PF_UNIX, ai.pfamily)
  610. assert_equal(Socket::SOCK_STREAM, ai.socktype) # UNIXSocket/UNIXServer is SOCK_STREAM only.
  611. assert_equal(0, ai.protocol)
  612. end
  613. def test_addrinfo_predicates_unix
  614. unix_ai = Addrinfo.new(Socket.sockaddr_un("/testdir/sososo"))
  615. assert(!unix_ai.ip?)
  616. assert(!unix_ai.ipv4?)
  617. assert(!unix_ai.ipv6?)
  618. assert(unix_ai.unix?)
  619. end
  620. def test_marshal_unix
  621. ai1 = Addrinfo.unix("/testdir/sock")
  622. ai2 = Marshal.load(Marshal.dump(ai1))
  623. assert_equal(ai1.afamily, ai2.afamily)
  624. assert_equal(ai1.unix_path, ai2.unix_path)
  625. assert_equal(ai1.pfamily, ai2.pfamily)
  626. assert_equal(ai1.socktype, ai2.socktype)
  627. assert_equal(ai1.protocol, ai2.protocol)
  628. assert_equal(ai1.canonname, ai2.canonname)
  629. end
  630. def test_addrinfo_timeout
  631. ai = Addrinfo.getaddrinfo("localhost", "ssh", Socket::PF_INET, Socket::SOCK_STREAM, timeout: 1).fetch(0)
  632. assert_equal(22, ai.ip_port)
  633. end
  634. end
  635. end