rubysl-socket 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +70 -16
  3. data/lib/rubysl/socket.rb +201 -1396
  4. data/lib/rubysl/socket/ancillary_data.rb +56 -0
  5. data/lib/rubysl/socket/bsd.rb +28 -0
  6. data/lib/rubysl/socket/error.rb +67 -0
  7. data/lib/rubysl/socket/foreign.rb +324 -0
  8. data/lib/rubysl/socket/foreign/addrinfo.rb +10 -0
  9. data/lib/rubysl/socket/foreign/hostent.rb +36 -0
  10. data/lib/rubysl/socket/foreign/ifaddrs.rb +129 -0
  11. data/lib/rubysl/socket/foreign/iovec.rb +18 -0
  12. data/lib/rubysl/socket/foreign/linger.rb +41 -0
  13. data/lib/rubysl/socket/foreign/msghdr.rb +41 -0
  14. data/lib/rubysl/socket/foreign/servent.rb +17 -0
  15. data/lib/rubysl/socket/foreign/sockaddr.rb +21 -0
  16. data/lib/rubysl/socket/foreign/sockaddr_in.rb +25 -0
  17. data/lib/rubysl/socket/foreign/sockaddr_in6.rb +25 -0
  18. data/lib/rubysl/socket/foreign/sockaddr_un.rb +29 -0
  19. data/lib/rubysl/socket/ipv6.rb +38 -0
  20. data/lib/rubysl/socket/linux.rb +16 -0
  21. data/lib/rubysl/socket/socket_options.rb +84 -0
  22. data/lib/rubysl/socket/version.rb +1 -1
  23. data/lib/socket.rb +45 -1
  24. data/lib/socket/addrinfo.rb +453 -0
  25. data/lib/socket/ancillary_data.rb +114 -0
  26. data/lib/socket/basic_socket.rb +295 -0
  27. data/lib/socket/constants.rb +41 -0
  28. data/lib/socket/ifaddr.rb +29 -0
  29. data/lib/socket/ip_socket.rb +37 -0
  30. data/lib/socket/mri.rb +928 -0
  31. data/lib/socket/option.rb +96 -0
  32. data/lib/socket/socket.rb +353 -0
  33. data/lib/socket/socket_error.rb +2 -0
  34. data/lib/socket/tcp_server.rb +78 -0
  35. data/lib/socket/tcp_socket.rb +109 -0
  36. data/lib/socket/udp_socket.rb +73 -0
  37. data/lib/socket/unix_server.rb +35 -0
  38. data/lib/socket/unix_socket.rb +78 -0
  39. data/rubysl-socket.gemspec +15 -10
  40. metadata +78 -293
  41. data/.gitignore +0 -17
  42. data/.travis.yml +0 -9
  43. data/Gemfile +0 -4
  44. data/Rakefile +0 -1
  45. data/spec/addrinfo/afamily_spec.rb +0 -5
  46. data/spec/addrinfo/bind_spec.rb +0 -5
  47. data/spec/addrinfo/canonname_spec.rb +0 -5
  48. data/spec/addrinfo/connect_from_spec.rb +0 -5
  49. data/spec/addrinfo/connect_spec.rb +0 -5
  50. data/spec/addrinfo/connect_to_spec.rb +0 -5
  51. data/spec/addrinfo/family_addrinfo_spec.rb +0 -5
  52. data/spec/addrinfo/foreach_spec.rb +0 -5
  53. data/spec/addrinfo/getaddrinfo_spec.rb +0 -5
  54. data/spec/addrinfo/getnameinfo_spec.rb +0 -5
  55. data/spec/addrinfo/inspect_sockaddr_spec.rb +0 -5
  56. data/spec/addrinfo/inspect_spec.rb +0 -5
  57. data/spec/addrinfo/ip_address_spec.rb +0 -5
  58. data/spec/addrinfo/ip_port_spec.rb +0 -5
  59. data/spec/addrinfo/ip_spec.rb +0 -9
  60. data/spec/addrinfo/ip_unpack_spec.rb +0 -5
  61. data/spec/addrinfo/ipv4_loopback_spec.rb +0 -5
  62. data/spec/addrinfo/ipv4_multicast_spec.rb +0 -5
  63. data/spec/addrinfo/ipv4_private_spec.rb +0 -5
  64. data/spec/addrinfo/ipv4_spec.rb +0 -5
  65. data/spec/addrinfo/ipv6_linklocal_spec.rb +0 -5
  66. data/spec/addrinfo/ipv6_loopback_spec.rb +0 -5
  67. data/spec/addrinfo/ipv6_mc_global_spec.rb +0 -5
  68. data/spec/addrinfo/ipv6_mc_linklocal_spec.rb +0 -5
  69. data/spec/addrinfo/ipv6_mc_nodelocal_spec.rb +0 -5
  70. data/spec/addrinfo/ipv6_mc_orglocal_spec.rb +0 -5
  71. data/spec/addrinfo/ipv6_mc_sitelocal_spec.rb +0 -5
  72. data/spec/addrinfo/ipv6_multicast_spec.rb +0 -5
  73. data/spec/addrinfo/ipv6_sitelocal_spec.rb +0 -5
  74. data/spec/addrinfo/ipv6_spec.rb +0 -5
  75. data/spec/addrinfo/ipv6_to_ipv4_spec.rb +0 -5
  76. data/spec/addrinfo/ipv6_unspecified_spec.rb +0 -5
  77. data/spec/addrinfo/ipv6_v4compat_spec.rb +0 -5
  78. data/spec/addrinfo/ipv6_v4mapped_spec.rb +0 -5
  79. data/spec/addrinfo/listen_spec.rb +0 -5
  80. data/spec/addrinfo/marshal_dump_spec.rb +0 -5
  81. data/spec/addrinfo/marshal_load_spec.rb +0 -5
  82. data/spec/addrinfo/pfamily_spec.rb +0 -5
  83. data/spec/addrinfo/protocol_spec.rb +0 -5
  84. data/spec/addrinfo/socktype_spec.rb +0 -5
  85. data/spec/addrinfo/tcp_spec.rb +0 -5
  86. data/spec/addrinfo/to_s_spec.rb +0 -5
  87. data/spec/addrinfo/to_sockaddr_spec.rb +0 -5
  88. data/spec/addrinfo/udp_spec.rb +0 -5
  89. data/spec/addrinfo/unix_path_spec.rb +0 -5
  90. data/spec/addrinfo/unix_spec.rb +0 -9
  91. data/spec/basicsocket/close_read_spec.rb +0 -42
  92. data/spec/basicsocket/close_write_spec.rb +0 -42
  93. data/spec/basicsocket/do_not_reverse_lookup_spec.rb +0 -78
  94. data/spec/basicsocket/for_fd_spec.rb +0 -37
  95. data/spec/basicsocket/getpeername_spec.rb +0 -24
  96. data/spec/basicsocket/getsockname_spec.rb +0 -27
  97. data/spec/basicsocket/getsockopt_spec.rb +0 -54
  98. data/spec/basicsocket/ioctl_spec.rb +0 -22
  99. data/spec/basicsocket/recv_nonblock_spec.rb +0 -6
  100. data/spec/basicsocket/recv_spec.rb +0 -76
  101. data/spec/basicsocket/send_spec.rb +0 -81
  102. data/spec/basicsocket/setsockopt_spec.rb +0 -333
  103. data/spec/basicsocket/shutdown_spec.rb +0 -5
  104. data/spec/constants/constants_spec.rb +0 -63
  105. data/spec/fixtures/classes.rb +0 -174
  106. data/spec/fixtures/send_io.txt +0 -1
  107. data/spec/ipsocket/addr_spec.rb +0 -72
  108. data/spec/ipsocket/getaddress_spec.rb +0 -26
  109. data/spec/ipsocket/peeraddr_spec.rb +0 -79
  110. data/spec/ipsocket/recvfrom_spec.rb +0 -64
  111. data/spec/option/int_spec.rb +0 -27
  112. data/spec/option/linger_spec.rb +0 -52
  113. data/spec/option/new_spec.rb +0 -32
  114. data/spec/shared/pack_sockaddr.rb +0 -26
  115. data/spec/shared/partially_closable_sockets.rb +0 -13
  116. data/spec/shared/recv_nonblock.rb +0 -33
  117. data/spec/shared/socketpair.rb +0 -35
  118. data/spec/socket/accept_nonblock_spec.rb +0 -27
  119. data/spec/socket/accept_spec.rb +0 -1
  120. data/spec/socket/bind_spec.rb +0 -80
  121. data/spec/socket/connect_nonblock_spec.rb +0 -62
  122. data/spec/socket/connect_spec.rb +0 -1
  123. data/spec/socket/for_fd_spec.rb +0 -29
  124. data/spec/socket/getaddrinfo_spec.rb +0 -120
  125. data/spec/socket/gethostbyaddr_spec.rb +0 -1
  126. data/spec/socket/gethostbyname_spec.rb +0 -26
  127. data/spec/socket/gethostname_spec.rb +0 -9
  128. data/spec/socket/getnameinfo_spec.rb +0 -57
  129. data/spec/socket/getservbyname_spec.rb +0 -24
  130. data/spec/socket/listen_spec.rb +0 -21
  131. data/spec/socket/new_spec.rb +0 -109
  132. data/spec/socket/pack_sockaddr_in_spec.rb +0 -6
  133. data/spec/socket/pack_sockaddr_un_spec.rb +0 -6
  134. data/spec/socket/pair_spec.rb +0 -6
  135. data/spec/socket/recvfrom_nonblock_spec.rb +0 -1
  136. data/spec/socket/recvfrom_spec.rb +0 -1
  137. data/spec/socket/sockaddr_in_spec.rb +0 -6
  138. data/spec/socket/sockaddr_un_spec.rb +0 -6
  139. data/spec/socket/socket_spec.rb +0 -37
  140. data/spec/socket/socketpair_spec.rb +0 -6
  141. data/spec/socket/sysaccept_spec.rb +0 -1
  142. data/spec/socket/unpack_sockaddr_in_spec.rb +0 -16
  143. data/spec/socket/unpack_sockaddr_un_spec.rb +0 -2
  144. data/spec/tcpserver/accept_nonblock_spec.rb +0 -30
  145. data/spec/tcpserver/accept_spec.rb +0 -60
  146. data/spec/tcpserver/gets_spec.rb +0 -17
  147. data/spec/tcpserver/listen_spec.rb +0 -1
  148. data/spec/tcpserver/new_spec.rb +0 -88
  149. data/spec/tcpserver/output_spec.rb +0 -8
  150. data/spec/tcpserver/readpartial_spec.rb +0 -8
  151. data/spec/tcpserver/sysaccept_spec.rb +0 -1
  152. data/spec/tcpsocket/gethostbyname_spec.rb +0 -62
  153. data/spec/tcpsocket/new_spec.rb +0 -5
  154. data/spec/tcpsocket/open_spec.rb +0 -5
  155. data/spec/tcpsocket/partially_closable_spec.rb +0 -20
  156. data/spec/tcpsocket/recv_nonblock_spec.rb +0 -31
  157. data/spec/tcpsocket/setsockopt_spec.rb +0 -49
  158. data/spec/tcpsocket/shared/new.rb +0 -85
  159. data/spec/udpsocket/bind_spec.rb +0 -33
  160. data/spec/udpsocket/connect_spec.rb +0 -1
  161. data/spec/udpsocket/new_spec.rb +0 -1
  162. data/spec/udpsocket/open_spec.rb +0 -12
  163. data/spec/udpsocket/recvfrom_nonblock_spec.rb +0 -1
  164. data/spec/udpsocket/send_spec.rb +0 -57
  165. data/spec/unixserver/accept_nonblock_spec.rb +0 -33
  166. data/spec/unixserver/accept_spec.rb +0 -64
  167. data/spec/unixserver/for_fd_spec.rb +0 -32
  168. data/spec/unixserver/new_spec.rb +0 -5
  169. data/spec/unixserver/open_spec.rb +0 -25
  170. data/spec/unixserver/shared/new.rb +0 -23
  171. data/spec/unixsocket/addr_spec.rb +0 -37
  172. data/spec/unixsocket/new_spec.rb +0 -5
  173. data/spec/unixsocket/open_spec.rb +0 -26
  174. data/spec/unixsocket/pair_spec.rb +0 -38
  175. data/spec/unixsocket/partially_closable_spec.rb +0 -25
  176. data/spec/unixsocket/path_spec.rb +0 -29
  177. data/spec/unixsocket/peeraddr_spec.rb +0 -29
  178. data/spec/unixsocket/recv_io_spec.rb +0 -40
  179. data/spec/unixsocket/recvfrom_spec.rb +0 -48
  180. data/spec/unixsocket/send_io_spec.rb +0 -30
  181. data/spec/unixsocket/shared/new.rb +0 -25
@@ -0,0 +1,16 @@
1
+ # This file is only available on Linux systems.
2
+
3
+ module RubySL
4
+ module Socket
5
+ module Foreign
6
+ def self.getpeereid(descriptor)
7
+ data = Foreign
8
+ .getsockopt(descriptor, ::Socket::SOL_SOCKET, ::Socket::SO_PEERCRED)
9
+
10
+ _, euid, egid = data.unpack('iii')
11
+
12
+ [euid, egid]
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,84 @@
1
+ module RubySL
2
+ module Socket
3
+ module SocketOptions
4
+ def self.socket_level(level, family = nil)
5
+ if level.is_a?(Symbol) or level.is_a?(String)
6
+ if ::Socket.const_defined?(level)
7
+ ::Socket.const_get(level)
8
+ else
9
+ if family and is_ip_family?(family)
10
+ ip_level_to_int(level)
11
+ elsif level.to_s == 'SOCKET'
12
+ ::Socket::SOL_SOCKET
13
+ else
14
+ constant("IPPROTO", level)
15
+ end
16
+ end
17
+ elsif level.respond_to?(:to_str)
18
+ socket_level(Socket.coerce_to_string(level), family)
19
+ else
20
+ level
21
+ end
22
+ end
23
+
24
+ def self.socket_option(level, optname)
25
+ case optname
26
+ when Symbol, String
27
+ if ::Socket.const_defined?(optname)
28
+ ::Socket.const_get(optname)
29
+ else
30
+ case level
31
+ when ::Socket::SOL_SOCKET
32
+ constant("SO", optname)
33
+ when ::Socket::IPPROTO_IP
34
+ constant("IP", optname)
35
+ when ::Socket::IPPROTO_TCP
36
+ constant("TCP", optname)
37
+ when ::Socket::IPPROTO_UDP
38
+ constant("UDP", optname)
39
+ when ::Socket.const_defined?(:IPPROTO_IPV6) && ::Socket::IPPROTO_IPV6
40
+ constant("IPV6", optname)
41
+ else
42
+ raise SocketError,
43
+ "Unsupported socket level option name: #{optname}"
44
+ end
45
+ end
46
+ else
47
+ if optname.respond_to?(:to_str)
48
+ socket_option(level, Socket.coerce_to_string(optname))
49
+ else
50
+ optname
51
+ end
52
+ end
53
+ end
54
+
55
+ def self.is_ip_family?(family)
56
+ family == "AF_INET" || family == "AF_INET6"
57
+ end
58
+
59
+ def self.ip_level_to_int(level)
60
+ prefixes = ["IPPROTO", "SOL", "IPV6"]
61
+
62
+ prefixes.each do |prefix|
63
+ const = "#{prefix}_#{level}"
64
+
65
+ if ::Socket.const_defined?(const)
66
+ return ::Socket.const_get(const)
67
+ end
68
+ end
69
+
70
+ nil
71
+ end
72
+
73
+ def self.constant(prefix, suffix)
74
+ const = "#{prefix}_#{suffix}"
75
+
76
+ if ::Socket.const_defined?(const)
77
+ ::Socket.const_get(const)
78
+ else
79
+ raise SocketError, "Undefined socket constant: #{const}"
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,5 +1,5 @@
1
1
  module RubySL
2
2
  module Socket
3
- VERSION = "2.0.1"
3
+ VERSION = "2.1.0"
4
4
  end
5
5
  end
@@ -1 +1,45 @@
1
- require "rubysl/socket"
1
+ require 'fcntl'
2
+
3
+ require 'rubysl/socket'
4
+ require 'rubysl/socket/version'
5
+ require 'rubysl/socket/socket_options'
6
+
7
+ require 'socket/socket_error'
8
+ require 'socket/basic_socket'
9
+ require 'socket/constants'
10
+
11
+ require 'rubysl/socket/foreign/addrinfo'
12
+ require 'rubysl/socket/foreign/linger'
13
+ require 'rubysl/socket/foreign/ifaddrs'
14
+ require 'rubysl/socket/foreign/sockaddr'
15
+ require 'rubysl/socket/foreign/sockaddr_in'
16
+ require 'rubysl/socket/foreign/sockaddr_in6'
17
+
18
+ if RubySL::Socket.unix_socket_support?
19
+ require 'rubysl/socket/foreign/sockaddr_un'
20
+ end
21
+
22
+ require 'rubysl/socket/foreign/iovec'
23
+ require 'rubysl/socket/foreign/msghdr'
24
+ require 'rubysl/socket/foreign/hostent'
25
+ require 'rubysl/socket/foreign/servent'
26
+
27
+ require 'rubysl/socket/ipv6'
28
+ require 'rubysl/socket/ancillary_data'
29
+ require 'rubysl/socket/foreign'
30
+ require 'rubysl/socket/error'
31
+ require 'rubysl/socket/bsd' if RubySL::Socket.bsd_support?
32
+ require 'rubysl/socket/linux' if RubySL::Socket.linux_support?
33
+
34
+ require 'socket/socket'
35
+ require 'socket/option'
36
+ require 'socket/ancillary_data'
37
+ require 'socket/mri'
38
+ require 'socket/unix_socket'
39
+ require 'socket/unix_server'
40
+ require 'socket/ip_socket'
41
+ require 'socket/udp_socket'
42
+ require 'socket/tcp_socket'
43
+ require 'socket/tcp_server'
44
+ require 'socket/addrinfo'
45
+ require 'socket/ifaddr'
@@ -0,0 +1,453 @@
1
+ class Addrinfo
2
+ attr_reader :afamily, :pfamily, :socktype, :protocol
3
+
4
+ attr_reader :canonname
5
+
6
+ def self.getaddrinfo(nodename, service, family = nil, socktype = nil,
7
+ protocol = nil, flags = nil)
8
+
9
+ raw = Socket
10
+ .getaddrinfo(nodename, service, family, socktype, protocol, flags)
11
+
12
+ raw.map do |pair|
13
+ lfamily, lport, lhost, laddress, _, lsocktype, lprotocol = pair
14
+
15
+ sockaddr = Socket.pack_sockaddr_in(lport, laddress)
16
+ addr = Addrinfo.new(sockaddr, lfamily, lsocktype, lprotocol)
17
+
18
+ if flags and flags | Socket::AI_CANONNAME
19
+ addr.instance_variable_set(:@canonname, lhost)
20
+ end
21
+
22
+ addr
23
+ end
24
+ end
25
+
26
+ def self.ip(ip)
27
+ sockaddr = Socket.sockaddr_in(0, ip)
28
+ family = RubySL::Socket.family_for_sockaddr_in(sockaddr)
29
+
30
+ new(sockaddr, family)
31
+ end
32
+
33
+ def self.tcp(ip, port)
34
+ sockaddr = Socket.sockaddr_in(port, ip)
35
+ pfamily = RubySL::Socket.family_for_sockaddr_in(sockaddr)
36
+
37
+ new(sockaddr, pfamily, Socket::SOCK_STREAM, Socket::IPPROTO_TCP)
38
+ end
39
+
40
+ def self.udp(ip, port)
41
+ sockaddr = Socket.sockaddr_in(port, ip)
42
+ pfamily = RubySL::Socket.family_for_sockaddr_in(sockaddr)
43
+
44
+ new(sockaddr, pfamily, Socket::SOCK_DGRAM, Socket::IPPROTO_UDP)
45
+ end
46
+
47
+ def self.unix(socket, socktype = nil)
48
+ socktype ||= Socket::SOCK_STREAM
49
+
50
+ new(Socket.pack_sockaddr_un(socket), Socket::PF_UNIX, socktype)
51
+ end
52
+
53
+ # Addrinfo#initialize has a bunch of checks that prevent us from setting
54
+ # certain address families (e.g. AF_PACKET). Meanwhile methods such as
55
+ # Socket.getifaddrs need to create Addrinfo instances with exactly those
56
+ # address families.
57
+ #
58
+ # Because modifying #initialize would break compatibility we have to define a
59
+ # separate new-like method that completely ignores #initialize. You can thank
60
+ # Ruby for being such a well designed language.
61
+ #
62
+ # For the sake of simplicity `family` **must** be a Fixnum, a String based
63
+ # address family is not supported.
64
+ def self.raw_with_family(family)
65
+ instance = allocate
66
+
67
+ instance.instance_variable_set(:@afamily, family)
68
+
69
+ instance
70
+ end
71
+
72
+ def initialize(sockaddr, pfamily = nil, socktype = 0, protocol = 0)
73
+ if sockaddr.kind_of?(Array)
74
+ @afamily = RubySL::Socket.address_family(sockaddr[0])
75
+ @ip_port = sockaddr[1]
76
+ @ip_address = sockaddr[3]
77
+
78
+ # When using AF_INET6 the protocol family can only be PF_INET6
79
+ if @afamily == Socket::AF_INET6 and !pfamily
80
+ pfamily = Socket::PF_INET6
81
+ end
82
+ else
83
+ if sockaddr.bytesize == RubySL::Socket::Foreign::SockaddrUn.size
84
+ @unix_path = Socket.unpack_sockaddr_un(sockaddr)
85
+ @afamily = Socket::AF_UNIX
86
+ else
87
+ @ip_port, @ip_address = Socket.unpack_sockaddr_in(sockaddr)
88
+
89
+ if sockaddr.bytesize == 28
90
+ @afamily = Socket::AF_INET6
91
+ else
92
+ @afamily = Socket::AF_INET
93
+ end
94
+ end
95
+ end
96
+
97
+ @pfamily ||= RubySL::Socket.protocol_family(pfamily)
98
+
99
+ @socktype = RubySL::Socket.socket_type(socktype || 0)
100
+ @protocol = protocol || 0
101
+
102
+ # Per MRI behaviour setting the protocol family should also set the address
103
+ # family, but only if the address and protocol families are compatible.
104
+ if @pfamily && @pfamily != 0
105
+ if @afamily == Socket::AF_INET6 and
106
+ @pfamily != Socket::PF_INET and
107
+ @pfamily != Socket::PF_INET6
108
+ raise SocketError, 'The given protocol and address families are incompatible'
109
+ end
110
+
111
+ @afamily = @pfamily
112
+ end
113
+
114
+ # MRI only checks this if "sockaddr" is an Array.
115
+ if sockaddr.kind_of?(Array)
116
+ if @afamily == Socket::AF_INET6
117
+ if Socket.sockaddr_in(0, @ip_address).bytesize != 28
118
+ raise SocketError, "Invalid IPv6 address: #{@ip_address.inspect}"
119
+ end
120
+ end
121
+ end
122
+
123
+ # Based on MRI's (re-)implementation of getaddrinfo()
124
+ if @afamily != Socket::AF_UNIX and
125
+ @afamily != Socket::AF_UNSPEC and
126
+ @afamily != Socket::AF_INET and
127
+ @afamily != Socket::AF_INET6
128
+ raise(
129
+ SocketError,
130
+ 'Address family must be AF_UNIX, AF_INET, AF_INET6, PF_INET or PF_INET6'
131
+ )
132
+ end
133
+
134
+ # Per MRI this validation should only happen when "sockaddr" is an Array.
135
+ if sockaddr.is_a?(Array)
136
+ case @socktype
137
+ when 0, nil
138
+ if @protocol != 0 and @protocol != nil and @protocol != Socket::IPPROTO_UDP
139
+ raise SocketError, 'Socket protocol must be IPPROTO_UDP or left unset'
140
+ end
141
+ when Socket::SOCK_RAW
142
+ # nothing to do
143
+ when Socket::SOCK_DGRAM
144
+ if @protocol != Socket::IPPROTO_UDP and @protocol != 0
145
+ raise SocketError, 'Socket protocol must be IPPROTO_UDP or left unset'
146
+ end
147
+ when Socket::SOCK_STREAM
148
+ if @protocol != Socket::IPPROTO_TCP and @protocol != 0
149
+ raise SocketError, 'Socket protocol must be IPPROTO_TCP or left unset'
150
+ end
151
+ # Based on MRI behaviour, though MRI itself doesn't seem to explicitly
152
+ # handle this case (possibly handled by getaddrinfo()).
153
+ when Socket::SOCK_SEQPACKET
154
+ if @protocol != 0
155
+ raise SocketError, 'SOCK_SEQPACKET can not be used with an explicit protocol'
156
+ end
157
+ else
158
+ raise SocketError, 'Unsupported socket type'
159
+ end
160
+ end
161
+ end
162
+
163
+ def unix?
164
+ @afamily == Socket::AF_UNIX
165
+ end
166
+
167
+ def ipv4?
168
+ @afamily == Socket::AF_INET
169
+ end
170
+
171
+ def ipv6?
172
+ @afamily == Socket::AF_INET6
173
+ end
174
+
175
+ def ip?
176
+ ipv4? || ipv6?
177
+ end
178
+
179
+ def ip_address
180
+ unless ip?
181
+ raise SocketError, 'An IPv4/IPv6 address is required'
182
+ end
183
+
184
+ @ip_address
185
+ end
186
+
187
+ def ip_port
188
+ unless ip?
189
+ raise SocketError, 'An IPv4/IPv6 address is required'
190
+ end
191
+
192
+ @ip_port
193
+ end
194
+
195
+ def unix_path
196
+ unless unix?
197
+ raise SocketError, 'The address family must be AF_UNIX'
198
+ end
199
+
200
+ @unix_path
201
+ end
202
+
203
+ def to_sockaddr
204
+ if unix?
205
+ Socket.sockaddr_un(@unix_path)
206
+ else
207
+ Socket.sockaddr_in(@ip_port.to_i, @ip_address.to_s)
208
+ end
209
+ end
210
+
211
+ alias_method :to_s, :to_sockaddr
212
+
213
+ def getnameinfo(flags = 0)
214
+ Socket.getnameinfo(to_sockaddr, flags)
215
+ end
216
+
217
+ def inspect_sockaddr
218
+ if ipv4?
219
+ if ip_port and ip_port != 0
220
+ "#{ip_address}:#{ip_port}"
221
+ elsif ip_address
222
+ ip_address.dup
223
+ else
224
+ 'UNKNOWN'
225
+ end
226
+ elsif ipv6?
227
+ if ip_port and ip_port != 0
228
+ "[#{ip_address}]:#{ip_port}"
229
+ else
230
+ ip_address.dup
231
+ end
232
+ elsif unix?
233
+ if unix_path.start_with?(File::SEPARATOR)
234
+ unix_path.dup
235
+ else
236
+ "UNIX #{unix_path}"
237
+ end
238
+ else
239
+ RubySL::Socket.address_family_name(afamily)
240
+ end
241
+ end
242
+
243
+ def inspect
244
+ if socktype and socktype != 0
245
+ if ip?
246
+ case socktype
247
+ when Socket::SOCK_STREAM
248
+ suffix = 'TCP'
249
+ when Socket::SOCK_DGRAM
250
+ suffix = 'UDP'
251
+ else
252
+ suffix = RubySL::Socket.socket_type_name(socktype)
253
+ end
254
+ else
255
+ suffix = RubySL::Socket.socket_type_name(socktype)
256
+ end
257
+
258
+ "#<Addrinfo: #{inspect_sockaddr} #{suffix}>"
259
+ else
260
+ "#<Addrinfo: #{inspect_sockaddr}>"
261
+ end
262
+ end
263
+
264
+ def ip_unpack
265
+ unless ip?
266
+ raise SocketError, 'An IPv4/IPv6 address is required'
267
+ end
268
+
269
+ [ip_address, ip_port]
270
+ end
271
+
272
+ def ipv4_loopback?
273
+ return false unless ipv4?
274
+
275
+ RubySL::Socket::Foreign.inet_network(ip_address) & 0xff000000 == 0x7f000000
276
+ end
277
+
278
+ def ipv4_multicast?
279
+ return false unless ipv4?
280
+
281
+ RubySL::Socket::Foreign.inet_network(ip_address) & 0xf0000000 == 0xe0000000
282
+ end
283
+
284
+ def ipv4_private?
285
+ return false unless ipv4?
286
+
287
+ num = RubySL::Socket::Foreign.inet_network(ip_address)
288
+
289
+ num & 0xff000000 == 0x0a000000 ||
290
+ num & 0xfff00000 == 0xac100000 ||
291
+ num & 0xffff0000 == 0xc0a80000
292
+ end
293
+
294
+ def ipv6_loopback?
295
+ return false unless ipv6?
296
+
297
+ RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address) ==
298
+ RubySL::Socket::IPv6::LOOPBACK
299
+ end
300
+
301
+ def ipv6_linklocal?
302
+ return false unless ipv6?
303
+
304
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
305
+
306
+ bytes[0] == 0xfe && bytes[1] >= 0x80
307
+ end
308
+
309
+ def ipv6_multicast?
310
+ return false unless ipv6?
311
+
312
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
313
+
314
+ bytes[0] == 0xff
315
+ end
316
+
317
+ def ipv6_sitelocal?
318
+ return false unless ipv6?
319
+
320
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
321
+
322
+ bytes[0] == 0xfe && bytes[1] >= 0xe0
323
+ end
324
+
325
+ def ipv6_mc_global?
326
+ return false unless ipv6?
327
+
328
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
329
+
330
+ bytes[0] == 0xff && bytes[1] & 0xf == 0xe
331
+ end
332
+
333
+ def ipv6_mc_linklocal?
334
+ return false unless ipv6?
335
+
336
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
337
+
338
+ bytes[0] == 0xff && bytes[1] & 0xf == 0x2
339
+ end
340
+
341
+ def ipv6_mc_nodelocal?
342
+ return false unless ipv6?
343
+
344
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
345
+
346
+ bytes[0] == 0xff && bytes[1] & 0xf == 0x1
347
+ end
348
+
349
+ def ipv6_mc_orglocal?
350
+ return false unless ipv6?
351
+
352
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
353
+
354
+ bytes[0] == 0xff && bytes[1] & 0xf == 0x8
355
+ end
356
+
357
+ def ipv6_mc_sitelocal?
358
+ return false unless ipv6?
359
+
360
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
361
+
362
+ bytes[0] == 0xff && bytes[1] & 0xf == 0x5
363
+ end
364
+
365
+ def ipv6_to_ipv4
366
+ return unless ipv6?
367
+
368
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
369
+
370
+ if RubySL::Socket::IPv6.ipv4_embedded?(bytes)
371
+ Addrinfo.ip(bytes.last(4).join('.'))
372
+ else
373
+ nil
374
+ end
375
+ end
376
+
377
+ def ipv6_unspecified?
378
+ return false unless ipv6?
379
+
380
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
381
+
382
+ bytes == RubySL::Socket::IPv6::UNSPECIFIED
383
+ end
384
+
385
+ def ipv6_v4compat?
386
+ return false unless ipv6?
387
+
388
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
389
+
390
+ RubySL::Socket::IPv6.ipv4_compatible?(bytes)
391
+ end
392
+
393
+ def ipv6_v4mapped?
394
+ return false unless ipv6?
395
+
396
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
397
+
398
+ RubySL::Socket::IPv6.ipv4_mapped?(bytes)
399
+ end
400
+
401
+ def ipv6_unique_local?
402
+ return false unless ipv6?
403
+
404
+ bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)
405
+
406
+ bytes[0] == 0xfc || bytes[0] == 0xfd
407
+ end
408
+
409
+ def marshal_dump
410
+ if unix?
411
+ address = unix_path
412
+ else
413
+ address = [ip_address, ip_port.to_s]
414
+ end
415
+
416
+ if unix?
417
+ protocol = 0
418
+ else
419
+ protocol = RubySL::Socket.protocol_name(self.protocol)
420
+ end
421
+
422
+ [
423
+ RubySL::Socket.address_family_name(afamily),
424
+ address,
425
+ RubySL::Socket.protocol_family_name(pfamily),
426
+ RubySL::Socket.socket_type_name(socktype),
427
+ protocol,
428
+ canonname
429
+ ]
430
+ end
431
+
432
+ def marshal_load(array)
433
+ afamily, address, pfamily, socktype, protocol, canonname = array
434
+
435
+ @afamily = RubySL::Socket.address_family(afamily)
436
+ @pfamily = RubySL::Socket.protocol_family(pfamily)
437
+ @socktype = RubySL::Socket.socket_type(socktype)
438
+
439
+ if protocol and protocol != 0
440
+ @protocol = ::Socket.const_get(protocol)
441
+ else
442
+ @protocol = protocol
443
+ end
444
+
445
+ if unix?
446
+ @unix_path = address
447
+ else
448
+ @ip_address = address[0]
449
+ @ip_port = address[1].to_i
450
+ @canonname = canonname
451
+ end
452
+ end
453
+ end