8
class TestSocketAddrinfo < Test::Unit::TestCase
9
HAS_UNIXSOCKET = defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
11
def tcp_unspecified_to_loopback(addrinfo)
12
if addrinfo.ipv4? && addrinfo.ip_address == "0.0.0.0"
13
Addrinfo.tcp("127.0.0.1", addrinfo.ip_port)
14
elsif addrinfo.ipv6? && addrinfo.ipv6_unspecified?
15
Addrinfo.tcp("::1", addrinfo.ip_port)
16
elsif addrinfo.ipv6? && (ai = addrinfo.ipv6_to_ipv4) && ai.ip_address == "0.0.0.0"
17
Addrinfo.tcp("127.0.0.1", addrinfo.ip_port)
24
ai = Addrinfo.ip("127.0.0.1")
25
assert_equal([0, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
26
assert_equal(Socket::AF_INET, ai.afamily)
27
assert_equal(Socket::PF_INET, ai.pfamily)
28
assert_equal(0, ai.socktype)
29
assert_equal(0, ai.protocol)
33
ai = Addrinfo.tcp("127.0.0.1", 80)
34
assert_equal([80, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
35
assert_equal(Socket::AF_INET, ai.afamily)
36
assert_equal(Socket::PF_INET, ai.pfamily)
37
assert_equal(Socket::SOCK_STREAM, ai.socktype)
38
assert_includes([0, Socket::IPPROTO_TCP], ai.protocol)
42
ai = Addrinfo.udp("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_DGRAM, ai.socktype)
47
assert_includes([0, Socket::IPPROTO_UDP], ai.protocol)
50
def test_addrinfo_ip_unpack
51
ai = Addrinfo.tcp("127.0.0.1", 80)
52
assert_equal(["127.0.0.1", 80], ai.ip_unpack)
53
assert_equal("127.0.0.1", ai.ip_address)
54
assert_equal(80, ai.ip_port)
57
def test_addrinfo_inspect_sockaddr
58
ai = Addrinfo.tcp("127.0.0.1", 80)
59
assert_equal("127.0.0.1:80", ai.inspect_sockaddr)
62
def test_addrinfo_new_inet
63
ai = Addrinfo.new(["AF_INET", 46102, "localhost.localdomain", "127.0.0.2"])
64
assert_equal([46102, "127.0.0.2"], Socket.unpack_sockaddr_in(ai))
65
assert_equal(Socket::AF_INET, ai.afamily)
66
assert_equal(Socket::PF_INET, ai.pfamily)
67
assert_equal(0, ai.socktype)
68
assert_equal(0, ai.protocol)
71
def test_addrinfo_predicates
72
ipv4_ai = Addrinfo.new(Socket.sockaddr_in(80, "192.168.0.1"))
75
assert(!ipv4_ai.ipv6?)
76
assert(!ipv4_ai.unix?)
79
def test_ipv4_address_predicates
81
[:ipv4_private?, "10.0.0.0", "10.255.255.255",
82
"172.16.0.0", "172.31.255.255",
83
"192.168.0.0", "192.168.255.255"],
84
[:ipv4_loopback?, "127.0.0.1", "127.0.0.0", "127.255.255.255"],
85
[:ipv4_multicast?, "224.0.0.0", "224.255.255.255"]
87
list.each {|meth, *addrs|
89
assert(Addrinfo.ip(addr).send(meth), "Addrinfo.ip(#{addr.inspect}).#{meth}")
92
assert(!Addrinfo.ip(addr).send(meth2), "!Addrinfo.ip(#{addr.inspect}).#{meth2}")
98
def test_basicsocket_send
99
s1 = Socket.new(:INET, :DGRAM, 0)
100
s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
102
ai = Addrinfo.new(sa)
103
s2 = Socket.new(:INET, :DGRAM, 0)
104
s2.send("test-basicsocket-send", 0, ai)
105
assert_equal("test-basicsocket-send", s1.recv(100))
107
s1.close if s1 && !s1.closed?
108
s2.close if s2 && !s2.closed?
111
def test_udpsocket_send
113
s1.bind("127.0.0.1", 0)
114
ai = Addrinfo.new(s1.getsockname)
116
s2.send("test-udp-send", 0, ai)
117
assert_equal("test-udp-send", s1.recv(100))
119
s1.close if s1 && !s1.closed?
120
s2.close if s2 && !s2.closed?
124
s1 = Socket.new(:INET, :DGRAM, 0)
125
sa = Socket.sockaddr_in(0, "127.0.0.1")
126
ai = Addrinfo.new(sa)
129
s2.send("test-socket-bind", 0, s1.getsockname)
130
assert_equal("test-socket-bind", s1.recv(100))
132
s1.close if s1 && !s1.closed?
133
s2.close if s2 && !s2.closed?
136
def test_socket_connect
137
s1 = Socket.new(:INET, :STREAM, 0)
138
s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
140
ai = Addrinfo.new(s1.getsockname)
141
s2 = Socket.new(:INET, :STREAM, 0)
143
s3, sender_addr = s1.accept
144
s2.send("test-socket-connect", 0)
145
assert_equal("test-socket-connect", s3.recv(100))
147
s1.close if s1 && !s1.closed?
148
s2.close if s2 && !s2.closed?
149
s3.close if s3 && !s3.closed?
152
def test_socket_connect_nonblock
153
s1 = Socket.new(:INET, :STREAM, 0)
154
s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
156
ai = Addrinfo.new(s1.getsockname)
157
s2 = Socket.new(:INET, :STREAM, 0)
159
s2.connect_nonblock(ai)
160
rescue IO::WaitWritable
163
s2.connect_nonblock(ai)
164
rescue Errno::EISCONN
167
s3, sender_addr = s1.accept
168
s2.send("test-socket-connect-nonblock", 0)
169
assert_equal("test-socket-connect-nonblock", s3.recv(100))
171
s1.close if s1 && !s1.closed?
172
s2.close if s2 && !s2.closed?
173
s3.close if s3 && !s3.closed?
176
def test_socket_getnameinfo
177
ai = Addrinfo.udp("127.0.0.1", 8888)
178
assert_equal(["127.0.0.1", "8888"], Socket.getnameinfo(ai, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV))
181
def test_basicsocket_local_address
182
s1 = Socket.new(:INET, :DGRAM, 0)
183
s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
184
e = Socket.unpack_sockaddr_in(s1.getsockname)
185
a = Socket.unpack_sockaddr_in(s1.local_address.to_sockaddr)
187
assert_equal(Socket::AF_INET, s1.local_address.afamily)
188
assert_equal(Socket::PF_INET, s1.local_address.pfamily)
189
assert_equal(Socket::SOCK_DGRAM, s1.local_address.socktype)
191
s1.close if s1 && !s1.closed?
194
def test_basicsocket_remote_address
195
s1 = TCPServer.new("127.0.0.1", 0)
196
s2 = Socket.new(:INET, :STREAM, 0)
197
s2.connect(s1.getsockname)
199
e = Socket.unpack_sockaddr_in(s2.getsockname)
200
a = Socket.unpack_sockaddr_in(s3.remote_address.to_sockaddr)
202
assert_equal(Socket::AF_INET, s3.remote_address.afamily)
203
assert_equal(Socket::PF_INET, s3.remote_address.pfamily)
204
assert_equal(Socket::SOCK_STREAM, s3.remote_address.socktype)
206
s1.close if s1 && !s1.closed?
207
s2.close if s2 && !s2.closed?
208
s3.close if s3 && !s3.closed?
211
def test_socket_accept
212
serv = Socket.new(:INET, :STREAM, 0)
213
serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
215
c = Socket.new(:INET, :STREAM, 0)
216
c.connect(serv.local_address)
219
assert_kind_of(Array, ret)
220
assert_equal(2, ret.length)
221
assert_kind_of(Addrinfo, ai)
222
e = Socket.unpack_sockaddr_in(c.getsockname)
223
a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
226
serv.close if serv && !serv.closed?
227
s.close if s && !s.closed?
228
c.close if c && !c.closed?
231
def test_socket_accept_nonblock
232
serv = Socket.new(:INET, :STREAM, 0)
233
serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
235
c = Socket.new(:INET, :STREAM, 0)
236
c.connect(serv.local_address)
238
ret = serv.accept_nonblock
239
rescue IO::WaitReadable, Errno::EINTR
244
assert_kind_of(Array, ret)
245
assert_equal(2, ret.length)
246
assert_kind_of(Addrinfo, ai)
247
e = Socket.unpack_sockaddr_in(c.getsockname)
248
a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
251
serv.close if serv && !serv.closed?
252
s.close if s && !s.closed?
253
c.close if c && !c.closed?
256
def test_socket_sysaccept
257
serv = Socket.new(:INET, :STREAM, 0)
258
serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
260
c = Socket.new(:INET, :STREAM, 0)
261
c.connect(serv.local_address)
265
assert_kind_of(Array, ret)
266
assert_equal(2, ret.length)
267
assert_kind_of(Addrinfo, ai)
268
e = Socket.unpack_sockaddr_in(c.getsockname)
269
a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
272
serv.close if serv && !serv.closed?
273
s.close if s && !s.closed?
274
c.close if c && !c.closed?
277
def test_socket_recvfrom
278
s1 = Socket.new(:INET, :DGRAM, 0)
279
s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
280
s2 = Socket.new(:INET, :DGRAM, 0)
281
s2.bind(Socket.sockaddr_in(0, "127.0.0.1"))
282
s2.send("test-socket-recvfrom", 0, s1.getsockname)
283
data, ai = s1.recvfrom(100)
284
assert_equal("test-socket-recvfrom", data)
285
assert_kind_of(Addrinfo, ai)
286
e = Socket.unpack_sockaddr_in(s2.getsockname)
287
a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
290
s1.close if s1 && !s1.closed?
291
s2.close if s2 && !s2.closed?
294
def test_socket_recvfrom_nonblock
295
s1 = Socket.new(:INET, :DGRAM, 0)
296
s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
297
s2 = Socket.new(:INET, :DGRAM, 0)
298
s2.bind(Socket.sockaddr_in(0, "127.0.0.1"))
299
s2.send("test-socket-recvfrom", 0, s1.getsockname)
301
data, ai = s1.recvfrom_nonblock(100)
302
rescue IO::WaitReadable
306
assert_equal("test-socket-recvfrom", data)
307
assert_kind_of(Addrinfo, ai)
308
e = Socket.unpack_sockaddr_in(s2.getsockname)
309
a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
312
s1.close if s1 && !s1.closed?
313
s2.close if s2 && !s2.closed?
316
def test_family_addrinfo
317
ai = Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("127.0.0.1", 80)
318
assert_equal(["127.0.0.1", 80], ai.ip_unpack)
319
assert_equal(Socket::SOCK_STREAM, ai.socktype)
320
return unless Addrinfo.respond_to?(:unix)
321
ai = Addrinfo.unix("/testdir/sock").family_addrinfo("/testdir/sock2")
322
assert_equal("/testdir/sock2", ai.unix_path)
323
assert_equal(Socket::SOCK_STREAM, ai.socktype)
324
assert_raise(SocketError) { Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("::1", 80) }
328
# IANA suggests dynamic port for 49152 to 65535
329
# http://www.iana.org/assignments/port-numbers
330
49152 + rand(65535-49152+1)
333
def test_connect_from
334
TCPServer.open("0.0.0.0", 0) {|serv|
335
serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
336
serv_ai = tcp_unspecified_to_loopback(serv_ai)
339
serv_ai.connect_from("0.0.0.0", port) {|s1|
342
assert_equal(port, s2.remote_address.ip_port)
347
rescue Errno::EADDRINUSE
354
TCPServer.open("0.0.0.0", 0) {|serv|
355
serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
356
serv_ai = tcp_unspecified_to_loopback(serv_ai)
358
client_ai = Addrinfo.tcp("0.0.0.0", port)
360
client_ai.connect_to(*serv_ai.ip_unpack) {|s1|
363
assert_equal(port, s2.remote_address.ip_port)
368
rescue Errno::EADDRINUSE
375
TCPServer.open("0.0.0.0", 0) {|serv|
376
serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
377
serv_ai = tcp_unspecified_to_loopback(serv_ai)
379
serv_ai.connect {|s1|
382
assert_equal(s1.local_address.ip_unpack, s2.remote_address.ip_unpack)
383
assert_equal(s2.local_address.ip_unpack, s1.remote_address.ip_unpack)
388
rescue Errno::EADDRINUSE
396
client_ai = Addrinfo.tcp("0.0.0.0", port)
399
assert_equal(port, s.local_address.ip_port)
401
rescue Errno::EADDRINUSE
408
client_ai = Addrinfo.tcp("0.0.0.0", port)
410
client_ai.listen {|serv|
411
assert_equal(port, serv.local_address.ip_port)
412
serv_addr, serv_port = serv.local_address.ip_unpack
414
when "0.0.0.0" then serv_addr = "127.0.0.1"
416
TCPSocket.open(serv_addr, serv_port) {|s1|
417
s2, addr = serv.accept
419
assert_equal(s1.local_address.ip_unpack, addr.ip_unpack)
425
rescue Errno::EADDRINUSE
431
Addrinfo.foreach(nil, 80, nil, :STREAM) {|ai|
432
assert_kind_of(Addrinfo, ai)
437
ai1 = Addrinfo.tcp("127.0.0.1", 80)
438
ai2 = Marshal.load(Marshal.dump(ai1))
439
assert_equal(ai1.afamily, ai2.afamily)
440
assert_equal(ai1.ip_unpack, ai2.ip_unpack)
441
assert_equal(ai1.pfamily, ai2.pfamily)
442
assert_equal(ai1.socktype, ai2.socktype)
443
assert_equal(ai1.protocol, ai2.protocol)
444
assert_equal(ai1.canonname, ai2.canonname)
447
if Socket.const_defined?("AF_INET6") && Socket::AF_INET6.is_a?(Integer)
449
def test_addrinfo_new_inet6
450
ai = Addrinfo.new(["AF_INET6", 42304, "ip6-localhost", "::1"])
451
assert_equal([42304, "::1"], Socket.unpack_sockaddr_in(ai))
452
assert_equal(Socket::AF_INET6, ai.afamily)
453
assert_equal(Socket::PF_INET6, ai.pfamily)
454
assert_equal(0, ai.socktype)
455
assert_equal(0, ai.protocol)
458
def test_addrinfo_ip_unpack_inet6
459
ai = Addrinfo.tcp("::1", 80)
460
assert_equal(["::1", 80], ai.ip_unpack)
461
assert_equal("::1", ai.ip_address)
462
assert_equal(80, ai.ip_port)
465
def test_addrinfo_inspect_sockaddr_inet6
466
ai = Addrinfo.tcp("::1", 80)
467
assert_equal("[::1]:80", ai.inspect_sockaddr)
470
def test_marshal_inet6
471
ai1 = Addrinfo.tcp("::1", 80)
472
ai2 = Marshal.load(Marshal.dump(ai1))
473
assert_equal(ai1.afamily, ai2.afamily)
474
assert_equal(ai1.ip_unpack, ai2.ip_unpack)
475
assert_equal(ai1.pfamily, ai2.pfamily)
476
assert_equal(ai1.socktype, ai2.socktype)
477
assert_equal(ai1.protocol, ai2.protocol)
478
assert_equal(ai1.canonname, ai2.canonname)
482
Addrinfo.getaddrinfo(str, nil, :INET6, :DGRAM).fetch(0)
485
def test_ipv6_address_predicates
487
[:ipv6_unspecified?, "::"],
488
[:ipv6_loopback?, "::1"],
489
[:ipv6_v4compat?, "::0.0.0.2", "::255.255.255.255"],
490
[:ipv6_v4mapped?, "::ffff:0.0.0.0", "::ffff:255.255.255.255"],
491
[:ipv6_linklocal?, "fe80::", "febf::"],
492
[:ipv6_sitelocal?, "fec0::", "feef::"],
493
[:ipv6_multicast?, "ff00::", "ffff::"]
496
[:ipv6_mc_nodelocal?, "ff01::", "ff11::"],
497
[:ipv6_mc_linklocal?, "ff02::", "ff12::"],
498
[:ipv6_mc_sitelocal?, "ff05::", "ff15::"],
499
[:ipv6_mc_orglocal?, "ff08::", "ff18::"],
500
[:ipv6_mc_global?, "ff0e::", "ff1e::"]
502
list.each {|meth, *addrs|
504
addr_exp = "Addrinfo.getaddrinfo(#{addr.inspect}, nil, :INET6, :DGRAM).fetch(0)"
505
if meth == :ipv6_v4compat? || meth == :ipv6_v4mapped?
506
# MacOS X returns IPv4 address for ::ffff:1.2.3.4 and ::1.2.3.4.
507
# Solaris returns IPv4 address for ::ffff:1.2.3.4.
509
assert(ai.ipv4? || ai.send(meth), "ai=#{addr_exp}; ai.ipv4? || .#{meth}")
511
assert(ipv6(addr).send(meth), "#{addr_exp}.#{meth}")
512
assert_equal(addr, ipv6(addr).ip_address)
515
next if meth == meth2
516
assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
520
mlist.each {|meth, *addrs|
522
addr_exp = "Addrinfo.getaddrinfo(#{addr.inspect}, nil, :INET6, :DGRAM).fetch(0)"
523
assert(ipv6(addr).send(meth), "#{addr_exp}.#{meth}")
524
assert(ipv6(addr).ipv6_multicast?, "#{addr_exp}.ipv6_multicast?")
526
next if meth == meth2
527
assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
530
next if :ipv6_multicast? == meth2
531
assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
537
def test_ipv6_to_ipv4
538
ai = Addrinfo.ip("::192.0.2.3")
539
ai = ai.ipv6_to_ipv4 if !ai.ipv4?
541
assert_equal("192.0.2.3", ai.ip_address)
543
ai = Addrinfo.ip("::ffff:192.0.2.3")
544
ai = ai.ipv6_to_ipv4 if !ai.ipv4?
546
assert_equal("192.0.2.3", ai.ip_address)
548
assert_nil(Addrinfo.ip("::1").ipv6_to_ipv4)
549
assert_nil(Addrinfo.ip("192.0.2.3").ipv6_to_ipv4)
551
assert_nil(Addrinfo.unix("/testdir/sock").ipv6_to_ipv4)
558
def test_addrinfo_unix
559
ai = Addrinfo.unix("/testdir/sock")
560
assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
561
assert_equal(Socket::AF_UNIX, ai.afamily)
562
assert_equal(Socket::PF_UNIX, ai.pfamily)
563
assert_equal(Socket::SOCK_STREAM, ai.socktype)
564
assert_equal(0, ai.protocol)
567
def test_addrinfo_unix_dgram
568
ai = Addrinfo.unix("/testdir/sock", :DGRAM)
569
assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
570
assert_equal(Socket::AF_UNIX, ai.afamily)
571
assert_equal(Socket::PF_UNIX, ai.pfamily)
572
assert_equal(Socket::SOCK_DGRAM, ai.socktype)
573
assert_equal(0, ai.protocol)
576
def test_addrinfo_unix_path
577
ai = Addrinfo.unix("/testdir/sock1")
578
assert_equal("/testdir/sock1", ai.unix_path)
581
def test_addrinfo_inspect_sockaddr_unix
582
ai = Addrinfo.unix("/testdir/test_addrinfo_inspect_sockaddr_unix")
583
assert_equal("/testdir/test_addrinfo_inspect_sockaddr_unix", ai.inspect_sockaddr)
586
def test_addrinfo_new_unix
587
ai = Addrinfo.new(["AF_UNIX", "/testdir/sock"])
588
assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
589
assert_equal(Socket::AF_UNIX, ai.afamily)
590
assert_equal(Socket::PF_UNIX, ai.pfamily)
591
assert_equal(Socket::SOCK_STREAM, ai.socktype) # UNIXSocket/UNIXServer is SOCK_STREAM only.
592
assert_equal(0, ai.protocol)
595
def test_addrinfo_predicates_unix
596
unix_ai = Addrinfo.new(Socket.sockaddr_un("/testdir/sososo"))
598
assert(!unix_ai.ipv4?)
599
assert(!unix_ai.ipv6?)
600
assert(unix_ai.unix?)
603
def test_marshal_unix
604
ai1 = Addrinfo.unix("/testdir/sock")
605
ai2 = Marshal.load(Marshal.dump(ai1))
606
assert_equal(ai1.afamily, ai2.afamily)
607
assert_equal(ai1.unix_path, ai2.unix_path)
608
assert_equal(ai1.pfamily, ai2.pfamily)
609
assert_equal(ai1.socktype, ai2.socktype)
610
assert_equal(ai1.protocol, ai2.protocol)
611
assert_equal(ai1.canonname, ai2.canonname)