rubysl-socket 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,10 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class Addrinfo < Rubinius::FFI::Struct
5
+ config("rbx.platform.addrinfo", :ai_flags, :ai_family, :ai_socktype,
6
+ :ai_protocol, :ai_addrlen, :ai_addr, :ai_canonname, :ai_next)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,36 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class Hostent < Rubinius::FFI::Struct
5
+ config('rbx.platform.hostent', :h_name, :h_aliases, :h_addrtype,
6
+ :h_length, :h_addr_list)
7
+
8
+ def hostname
9
+ self[:h_name]
10
+ end
11
+
12
+ def type
13
+ self[:h_addrtype]
14
+ end
15
+
16
+ def aliases
17
+ return [] unless self[:h_aliases]
18
+
19
+ RubySL::Socket::Foreign.pointers_of_type(self[:h_aliases], :string)
20
+ .map(&:read_string)
21
+ end
22
+
23
+ def addresses
24
+ return [] unless self[:h_addr_list]
25
+
26
+ RubySL::Socket::Foreign.pointers_of_type(self[:h_addr_list], :string)
27
+ .map { |pointer| pointer.read_string(self[:h_length]) }
28
+ end
29
+
30
+ def to_s
31
+ pointer.read_string(size)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,129 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ # Class representing an "ifaddrs" C structure.
5
+ #
6
+ # The memory used by this structure should be free'd using
7
+ # `RubySL::Socket::Foreign.freeifaddrs` _only_ as following:
8
+ #
9
+ # RubySL::Socket::Foreign.freeifaddrs(initial_ifaddrs_struct)
10
+ #
11
+ # To ensure Rubinius doesn't accidentally free invalid pointers all
12
+ # pointers (including the pointer of "self") stored in this class have the
13
+ # "autorelease" option set to false.
14
+ class Ifaddrs < Rubinius::FFI::Struct
15
+ config("rbx.platform.ifaddrs", :ifa_next, :ifa_name, :ifa_flags,
16
+ :ifa_addr, :ifa_netmask, :ifa_broadaddr, :ifa_dstaddr)
17
+
18
+ POINTERS = [
19
+ :address, :next, :broadcast_address, :destination_address,
20
+ :netmask_address
21
+ ]
22
+
23
+ def initialize(*args)
24
+ super
25
+
26
+ POINTERS.each do |name|
27
+ pointer = __send__(name)
28
+
29
+ pointer.autorelease = false if pointer
30
+ end
31
+
32
+ pointer.autorelease = false
33
+ end
34
+
35
+ def name
36
+ self[:ifa_name]
37
+ end
38
+
39
+ def flags
40
+ self[:ifa_flags]
41
+ end
42
+
43
+ def data
44
+ @data ||= self[:ifa_data]
45
+ end
46
+
47
+ def next
48
+ @next ||= self[:ifa_next]
49
+ end
50
+
51
+ def address
52
+ @address ||= self[:ifa_addr]
53
+ end
54
+
55
+ def broadcast_address
56
+ @broadcast_address ||= self[:ifa_broadaddr]
57
+ end
58
+
59
+ def destination_address
60
+ @destination_address ||= self[:ifa_dstaddr]
61
+ end
62
+
63
+ def netmask_address
64
+ @netmask_address ||= self[:ifa_netmask]
65
+ end
66
+
67
+ def each_address
68
+ next_pointer = self.next
69
+
70
+ while next_pointer
71
+ struct = self.class.new(next_pointer)
72
+
73
+ yield struct
74
+
75
+ next_pointer = struct.next
76
+ end
77
+ end
78
+
79
+ def broadcast?
80
+ flags & ::Socket::IFF_BROADCAST > 0
81
+ end
82
+
83
+ def point_to_point?
84
+ flags & ::Socket::IFF_POINTOPOINT > 0
85
+ end
86
+
87
+ def address_to_addrinfo
88
+ return unless address
89
+
90
+ sockaddr = Sockaddr.new(address)
91
+
92
+ if sockaddr.family == ::Socket::AF_INET
93
+ ::Addrinfo.new(SockaddrIn.new(address).to_s)
94
+ elsif sockaddr.family == ::Socket::AF_INET6
95
+ ::Addrinfo.new(SockaddrIn6.new(address).to_s)
96
+ else
97
+ nil
98
+ end
99
+ end
100
+
101
+ def broadcast_to_addrinfo
102
+ return if !broadcast? || !broadcast_address
103
+
104
+ ::Addrinfo.raw_with_family(Sockaddr.new(broadcast_address).family)
105
+ end
106
+
107
+ def destination_to_addrinfo
108
+ return if !point_to_point? || !destination_address
109
+
110
+ ::Addrinfo.raw_with_family(Sockaddr.new(destination_address).family)
111
+ end
112
+
113
+ def netmask_to_addrinfo
114
+ return unless netmask_address
115
+
116
+ sockaddr = Sockaddr.new(netmask_address)
117
+
118
+ if sockaddr.family == ::Socket::AF_INET
119
+ ::Addrinfo.new(SockaddrIn.new(netmask_address).to_s)
120
+ elsif sockaddr.family == ::Socket::AF_INET6
121
+ ::Addrinfo.new(SockaddrIn6.new(netmask_address).to_s)
122
+ else
123
+ ::Addrinfo.raw_with_family(sockaddr.family)
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,18 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class Iovec < Rubinius::FFI::Struct
5
+ config('rbx.platform.iovec', :iov_base, :iov_len)
6
+
7
+ def self.with_buffer(buffer)
8
+ vec = new
9
+
10
+ vec[:iov_base] = buffer
11
+ vec[:iov_len] = buffer.total
12
+
13
+ vec
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class Linger < Rubinius::FFI::Struct
5
+ config('rbx.platform.linger', :l_onoff, :l_linger)
6
+
7
+ def self.from_string(string)
8
+ linger = new
9
+
10
+ linger.pointer.write_string(string, string.bytesize)
11
+
12
+ linger
13
+ end
14
+
15
+ def on_off
16
+ self[:l_onoff]
17
+ end
18
+
19
+ def linger
20
+ self[:l_linger].to_i
21
+ end
22
+
23
+ def on_off=(value)
24
+ if value.is_a?(Integer)
25
+ self[:l_onoff] = value
26
+ else
27
+ self[:l_onoff] = value ? 1 : 0
28
+ end
29
+ end
30
+
31
+ def linger=(value)
32
+ self[:l_linger] = value
33
+ end
34
+
35
+ def to_s
36
+ pointer.read_string(pointer.total)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class Msghdr < Rubinius::FFI::Struct
5
+ config('rbx.platform.msghdr', :msg_name, :msg_namelen, :msg_iov,
6
+ :msg_iovlen, :msg_control, :msg_controllen, :msg_flags)
7
+
8
+ def self.with_buffers(address, io_vec)
9
+ header = new
10
+
11
+ header.address = address
12
+ header.message = io_vec
13
+
14
+ header
15
+ end
16
+
17
+ def address=(address)
18
+ self[:msg_name] = address.pointer
19
+ self[:msg_namelen] = address.pointer.total
20
+ end
21
+
22
+ def message=(vec)
23
+ self[:msg_iov] = vec.pointer
24
+ self[:msg_iovlen] = 1
25
+ end
26
+
27
+ def address_size
28
+ self[:msg_namelen]
29
+ end
30
+
31
+ def flags
32
+ self[:msg_flags]
33
+ end
34
+
35
+ def message_truncated?
36
+ flags & ::Socket::MSG_TRUNC > 0
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class Servent < Rubinius::FFI::Struct
5
+ config('rbx.platform.servent', :s_name, :s_aliases, :s_port, :s_proto)
6
+
7
+ def name
8
+ self[:s_name].read_string
9
+ end
10
+
11
+ def port
12
+ self[:s_port]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class Sockaddr < Rubinius::FFI::Struct
5
+ config("rbx.platform.sockaddr", :sa_data, :sa_family)
6
+
7
+ def data
8
+ self[:sa_data]
9
+ end
10
+
11
+ def family
12
+ self[:sa_family]
13
+ end
14
+
15
+ def to_s
16
+ pointer.read_string(self.class.size)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class SockaddrIn < Rubinius::FFI::Struct
5
+ config("rbx.platform.sockaddr_in",
6
+ :sin_family, :sin_port, :sin_addr, :sin_zero)
7
+
8
+ def self.with_sockaddr(addr)
9
+ pointer = Foreign.memory_pointer(addr.bytesize)
10
+ pointer.write_string(addr, addr.bytesize)
11
+
12
+ new(pointer)
13
+ end
14
+
15
+ def family
16
+ self[:sin_family]
17
+ end
18
+
19
+ def to_s
20
+ pointer.read_string(self.class.size)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class SockaddrIn6 < Rubinius::FFI::Struct
5
+ config("rbx.platform.sockaddr_in6", :sin6_family, :sin6_port,
6
+ :sin6_flowinfo, :sin6_addr, :sin6_scope_id)
7
+
8
+ def self.with_sockaddr(addr)
9
+ pointer = Foreign.memory_pointer(addr.bytesize)
10
+ pointer.write_string(addr, addr.bytesize)
11
+
12
+ new(pointer)
13
+ end
14
+
15
+ def family
16
+ self[:sin6_family]
17
+ end
18
+
19
+ def to_s
20
+ pointer.read_string(self.class.size)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+ module RubySL
2
+ module Socket
3
+ module Foreign
4
+ class SockaddrUn < Rubinius::FFI::Struct
5
+ config('rbx.platform.sockaddr_un', :sun_family, :sun_path)
6
+
7
+ def self.with_sockaddr(addr)
8
+ if addr.bytesize > size
9
+ raise ArgumentError,
10
+ "UNIX socket path is too long (max: #{size} bytes)"
11
+ end
12
+
13
+ pointer = Foreign.memory_pointer(size)
14
+ pointer.write_string(addr, addr.bytesize)
15
+
16
+ new(pointer)
17
+ end
18
+
19
+ def family
20
+ self[:sun_family]
21
+ end
22
+
23
+ def to_s
24
+ pointer.read_string(pointer.total)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ module RubySL
2
+ module Socket
3
+ module IPv6
4
+ # The IPv6 loopback address as produced by inet_pton(INET6, "::1")
5
+ LOOPBACK = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
6
+
7
+ # The bytes used for an unspecified IPv6 address.
8
+ UNSPECIFIED = [0] * 16
9
+
10
+ # The first 10 bytes of an IPv4 compatible IPv6 address.
11
+ COMPAT_PREFIX = [0] * 10
12
+
13
+ def self.ipv4_embedded?(bytes)
14
+ ipv4_mapped?(bytes) || ipv4_compatible?(bytes)
15
+ end
16
+
17
+ def self.ipv4_mapped?(bytes)
18
+ prefix = bytes.first(10)
19
+ follow = bytes[10..11]
20
+
21
+ prefix == COMPAT_PREFIX &&
22
+ follow[0] == 255 &&
23
+ follow[1] == 255 &&
24
+ (bytes[-4] > 0 || bytes[-3] > 0 || bytes[-2] > 0)
25
+ end
26
+
27
+ def self.ipv4_compatible?(bytes)
28
+ prefix = bytes.first(10)
29
+ follow = bytes[10..11]
30
+
31
+ prefix == COMPAT_PREFIX &&
32
+ follow[0] == 0 &&
33
+ follow[1] == 0 &&
34
+ (bytes[-4] > 0 || bytes[-3] > 0 || bytes[-2] > 0)
35
+ end
36
+ end
37
+ end
38
+ end