Class: Addrinfo

Inherits:
Object
  • Object
show all
Defined in:
lib/socket/mri.rb,
lib/socket/addrinfo.rb

Overview

Everything below is copied from the MRI codebase. The Ruby license is attached below.

Ruby is copyrighted free software by Yukihiro Matsumoto <[email protected]>. You can redistribute it and/or modify it under either the terms of the 2-clause BSDL (see the file BSDL), or the conditions below:

1. You may make and give away verbatim copies of the source form of the
   software without restriction, provided that you duplicate all of the
   original copyright notices and associated disclaimers.

2. You may modify your copy of the software in any way, provided that
   you do at least ONE of the following:

     a) place your modifications in the Public Domain or otherwise
        make them Freely Available, such as by posting said

modifications to Usenet or an equivalent medium, or by allowing the author to include your modifications in the software.

     b) use the modified software only within your corporation or
        organization.

     c) give non-standard binaries non-standard names, with
        instructions on where to get the original software distribution.

     d) make other distribution arrangements with the author.

3. You may distribute the software in object code or binary form,
   provided that you do at least ONE of the following:

     a) distribute the binaries and library files of the software,

together with instructions (in the manual page or equivalent) on where to get the original distribution.

b) accompany the distribution with the machine-readable source of

the software.

     c) give non-standard binaries non-standard names, with
        instructions on where to get the original software distribution.

     d) make other distribution arrangements with the author.

4. You may modify and include the part of the software into any other
   software (possibly commercial).  But some files in the distribution
   are not written by the author, so that they are not under these terms.

   For the list of those files and their copying conditions, see the
   file LEGAL.

5. The scripts and library files supplied as input to or produced as
   output from the software do not automatically fall under the
   copyright of the software, but belong to whomever generated them,
   and may be sold commercially, and may be aggregated with this
   software.

6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   PURPOSE.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sockaddr, pfamily = nil, socktype = 0, protocol = 0) ⇒ Addrinfo

Returns a new instance of Addrinfo.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/socket/addrinfo.rb', line 72

def initialize(sockaddr, pfamily = nil, socktype = 0, protocol = 0)
  if sockaddr.kind_of?(Array)
    @afamily    = RubySL::Socket.address_family(sockaddr[0])
    @ip_port    = sockaddr[1]
    @ip_address = sockaddr[3]

    # When using AF_INET6 the protocol family can only be PF_INET6
    if @afamily == Socket::AF_INET6 and !pfamily
      pfamily = Socket::PF_INET6
    end
  else
    if sockaddr.bytesize == RubySL::Socket::Foreign::SockaddrUn.size
      @unix_path = Socket.unpack_sockaddr_un(sockaddr)
      @afamily   = Socket::AF_UNIX
    else
      @ip_port, @ip_address = Socket.unpack_sockaddr_in(sockaddr)

      if sockaddr.bytesize == 28
        @afamily = Socket::AF_INET6
      else
        @afamily = Socket::AF_INET
      end
    end
  end

  @pfamily ||= RubySL::Socket.protocol_family(pfamily)

  @socktype = RubySL::Socket.socket_type(socktype || 0)
  @protocol = protocol || 0

  # Per MRI behaviour setting the protocol family should also set the address
  # family, but only if the address and protocol families are compatible.
  if @pfamily && @pfamily != 0
    if @afamily == Socket::AF_INET6 and
    @pfamily != Socket::PF_INET and
    @pfamily != Socket::PF_INET6
      raise SocketError, 'The given protocol and address families are incompatible'
    end

    @afamily = @pfamily
  end

  # MRI only checks this if "sockaddr" is an Array.
  if sockaddr.kind_of?(Array)
    if @afamily == Socket::AF_INET6
      if Socket.sockaddr_in(0, @ip_address).bytesize != 28
        raise SocketError, "Invalid IPv6 address: #{@ip_address.inspect}"
      end
    end
  end

  # Based on MRI's (re-)implementation of getaddrinfo()
  if @afamily != Socket::AF_UNIX and
  @afamily != Socket::AF_UNSPEC and
  @afamily != Socket::AF_INET and
  @afamily != Socket::AF_INET6
    raise(
      SocketError,
      'Address family must be AF_UNIX, AF_INET, AF_INET6, PF_INET or PF_INET6'
    )
  end

  # Per MRI this validation should only happen when "sockaddr" is an Array.
  if sockaddr.is_a?(Array)
    case @socktype
    when 0, nil
      if @protocol != 0 and @protocol != nil and @protocol != Socket::IPPROTO_UDP
        raise SocketError, 'Socket protocol must be IPPROTO_UDP or left unset'
      end
    when Socket::SOCK_RAW
      # nothing to do
    when Socket::SOCK_DGRAM
      if @protocol != Socket::IPPROTO_UDP and @protocol != 0
        raise SocketError, 'Socket protocol must be IPPROTO_UDP or left unset'
      end
    when Socket::SOCK_STREAM
      if @protocol != Socket::IPPROTO_TCP and @protocol != 0
        raise SocketError, 'Socket protocol must be IPPROTO_TCP or left unset'
      end
    # Based on MRI behaviour, though MRI itself doesn't seem to explicitly
    # handle this case (possibly handled by getaddrinfo()).
    when Socket::SOCK_SEQPACKET
      if @protocol != 0
        raise SocketError, 'SOCK_SEQPACKET can not be used with an explicit protocol'
      end
    else
      raise SocketError, 'Unsupported socket type'
    end
  end
end

Instance Attribute Details

#afamilyObject (readonly)

Returns the value of attribute afamily.



2
3
4
# File 'lib/socket/addrinfo.rb', line 2

def afamily
  @afamily
end

#canonnameObject (readonly)

Returns the value of attribute canonname.



4
5
6
# File 'lib/socket/addrinfo.rb', line 4

def canonname
  @canonname
end

#pfamilyObject (readonly)

Returns the value of attribute pfamily.



2
3
4
# File 'lib/socket/addrinfo.rb', line 2

def pfamily
  @pfamily
end

#protocolObject (readonly)

Returns the value of attribute protocol.



2
3
4
# File 'lib/socket/addrinfo.rb', line 2

def protocol
  @protocol
end

#socktypeObject (readonly)

Returns the value of attribute socktype.



2
3
4
# File 'lib/socket/addrinfo.rb', line 2

def socktype
  @socktype
end

Class Method Details

.foreach(nodename, service, family = nil, socktype = nil, protocol = nil, flags = nil, &block) ⇒ Object

iterates over the list of Addrinfo objects obtained by Addrinfo.getaddrinfo.

Addrinfo.foreach(nil, 80) {|x| p x }
#=> #<Addrinfo: 127.0.0.1:80 TCP (:80)>
#   #<Addrinfo: 127.0.0.1:80 UDP (:80)>
#   #<Addrinfo: [::1]:80 TCP (:80)>
#   #<Addrinfo: [::1]:80 UDP (:80)>


289
290
291
# File 'lib/socket/mri.rb', line 289

def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, &block)
  Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags).each(&block)
end

.getaddrinfo(nodename, service, family = nil, socktype = nil, protocol = nil, flags = nil) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/socket/addrinfo.rb', line 6

def self.getaddrinfo(nodename, service, family = nil, socktype = nil,
                     protocol = nil, flags = nil)

  raw = Socket
    .getaddrinfo(nodename, service, family, socktype, protocol, flags)

  raw.map do |pair|
    lfamily, lport, lhost, laddress, _, lsocktype, lprotocol = pair

    sockaddr = Socket.pack_sockaddr_in(lport, laddress)
    addr     = Addrinfo.new(sockaddr, lfamily, lsocktype, lprotocol)

    if flags and flags | Socket::AI_CANONNAME
      addr.instance_variable_set(:@canonname, lhost)
    end

    addr
  end
end

.ip(ip) ⇒ Object



26
27
28
29
30
31
# File 'lib/socket/addrinfo.rb', line 26

def self.ip(ip)
  sockaddr = Socket.sockaddr_in(0, ip)
  family   = RubySL::Socket.family_for_sockaddr_in(sockaddr)

  new(sockaddr, family)
end

.raw_with_family(family) ⇒ Object

Addrinfo#initialize has a bunch of checks that prevent us from setting certain address families (e.g. AF_PACKET). Meanwhile methods such as Socket.getifaddrs need to create Addrinfo instances with exactly those address families.

Because modifying #initialize would break compatibility we have to define a separate new-like method that completely ignores #initialize. You can thank Ruby for being such a well designed language.

For the sake of simplicity ‘family` must be a Fixnum, a String based address family is not supported.



64
65
66
67
68
69
70
# File 'lib/socket/addrinfo.rb', line 64

def self.raw_with_family(family)
  instance = allocate

  instance.instance_variable_set(:@afamily, family)

  instance
end

.tcp(ip, port) ⇒ Object



33
34
35
36
37
38
# File 'lib/socket/addrinfo.rb', line 33

def self.tcp(ip, port)
  sockaddr = Socket.sockaddr_in(port, ip)
  pfamily  = RubySL::Socket.family_for_sockaddr_in(sockaddr)

  new(sockaddr, pfamily, Socket::SOCK_STREAM, Socket::IPPROTO_TCP)
end

.udp(ip, port) ⇒ Object



40
41
42
43
44
45
# File 'lib/socket/addrinfo.rb', line 40

def self.udp(ip, port)
  sockaddr = Socket.sockaddr_in(port, ip)
  pfamily  = RubySL::Socket.family_for_sockaddr_in(sockaddr)

  new(sockaddr, pfamily, Socket::SOCK_DGRAM, Socket::IPPROTO_UDP)
end

.unix(socket, socktype = nil) ⇒ Object



47
48
49
50
51
# File 'lib/socket/addrinfo.rb', line 47

def self.unix(socket, socktype = nil)
  socktype ||= Socket::SOCK_STREAM

  new(Socket.pack_sockaddr_un(socket), Socket::PF_UNIX, socktype)
end

Instance Method Details

#bindObject

creates a socket bound to self.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.udp("0.0.0.0", 9981).bind {|s|
  s.local_address.connect {|s| s.send "hello", 0 }
  p s.recv(10) #=> "hello"
}


237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/socket/mri.rb', line 237

def bind
  sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  begin
    sock.ipv6only! if self.ipv6?
    sock.setsockopt(:SOCKET, :REUSEADDR, 1)
    sock.bind(self)
  rescue Exception
    sock.close
    raise
  end
  if block_given?
    begin
      yield sock
    ensure
      sock.close if !sock.closed?
    end
  else
    sock
  end
end

#connect(opts = {}, &block) ⇒ Object

:call-seq:

addrinfo.connect([opts]) {|socket| ... }
addrinfo.connect([opts])

creates a socket connected to the address of self.

The optional argument opts is options represented by a hash. opts may have following options:

:timeout

specify the timeout in seconds.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("www.ruby-lang.org", 80).connect {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}


197
198
199
# File 'lib/socket/mri.rb', line 197

def connect(opts={}, &block)
  connect_internal(nil, opts[:timeout], &block)
end

#connect_from(*args, &block) ⇒ Object

:call-seq:

addrinfo.connect_from([local_addr_args], [opts]) {|socket| ... }
addrinfo.connect_from([local_addr_args], [opts])

creates a socket connected to the address of self.

If one or more arguments given as local_addr_args, it is used as the local address of the socket. local_addr_args is given for family_addrinfo to obtain actual address.

If local_addr_args is not given, the local address of the socket is not bound.

The optional last argument opts is options represented by a hash. opts may have following options:

:timeout

specify the timeout in seconds.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("www.ruby-lang.org", 80).connect_from("0.0.0.0", 4649) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}

# Addrinfo object can be taken for the argument.
Addrinfo.tcp("www.ruby-lang.org", 80).connect_from(Addrinfo.tcp("0.0.0.0", 4649)) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}


172
173
174
175
176
# File 'lib/socket/mri.rb', line 172

def connect_from(*args, &block)
  opts = Hash === args.last ? args.pop : {}
  local_addr_args = args
  connect_internal(family_addrinfo(*local_addr_args), opts[:timeout], &block)
end

#connect_to(*args, &block) ⇒ Object

:call-seq:

addrinfo.connect_to([remote_addr_args], [opts]) {|socket| ... }
addrinfo.connect_to([remote_addr_args], [opts])

creates a socket connected to remote_addr_args and bound to self.

The optional last argument opts is options represented by a hash. opts may have following options:

:timeout

specify the timeout in seconds.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("0.0.0.0", 4649).connect_to("www.ruby-lang.org", 80) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}


220
221
222
223
224
225
# File 'lib/socket/mri.rb', line 220

def connect_to(*args, &block)
  opts = Hash === args.last ? args.pop : {}
  remote_addr_args = args
  remote_addrinfo = family_addrinfo(*remote_addr_args)
  remote_addrinfo.send(:connect_internal, self, opts[:timeout], &block)
end

#family_addrinfo(*args) ⇒ Object

creates an Addrinfo object from the arguments.

The arguments are interpreted as similar to self.

Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("www.ruby-lang.org", 80)
#=> #<Addrinfo: 221.186.184.68:80 TCP (www.ruby-lang.org:80)>

Addrinfo.unix("/tmp/sock").family_addrinfo("/tmp/sock2")
#=> #<Addrinfo: /tmp/sock2 SOCK_STREAM>


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/socket/mri.rb', line 72

def family_addrinfo(*args)
  if args.empty?
    raise ArgumentError, "no address specified"
  elsif Addrinfo === args.first
    raise ArgumentError, "too many arguments" if args.length != 1
    addrinfo = args.first
    if (self.pfamily != addrinfo.pfamily) ||
       (self.socktype != addrinfo.socktype)
      raise ArgumentError, "Addrinfo type mismatch"
    end
    addrinfo
  elsif self.ip?
    raise ArgumentError, "IP address needs host and port but #{args.length} arguments given" if args.length != 2
    host, port = args
    Addrinfo.getaddrinfo(host, port, self.pfamily, self.socktype, self.protocol)[0]
  elsif self.unix?
    raise ArgumentError, "UNIX socket needs single path argument but #{args.length} arguments given" if args.length != 1
    path, = args
    Addrinfo.unix(path)
  else
    raise ArgumentError, "unexpected family"
  end
end

#getnameinfo(flags = 0) ⇒ Object



213
214
215
# File 'lib/socket/addrinfo.rb', line 213

def getnameinfo(flags = 0)
  Socket.getnameinfo(to_sockaddr, flags)
end

#inspectObject



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/socket/addrinfo.rb', line 243

def inspect
  if socktype and socktype != 0
    if ip?
      case socktype
      when Socket::SOCK_STREAM
        suffix = 'TCP'
      when Socket::SOCK_DGRAM
        suffix = 'UDP'
      else
        suffix = RubySL::Socket.socket_type_name(socktype)
      end
    else
      suffix = RubySL::Socket.socket_type_name(socktype)
    end

    "#<Addrinfo: #{inspect_sockaddr} #{suffix}>"
  else
    "#<Addrinfo: #{inspect_sockaddr}>"
  end
end

#inspect_sockaddrObject



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/socket/addrinfo.rb', line 217

def inspect_sockaddr
  if ipv4?
    if ip_port and ip_port != 0
      "#{ip_address}:#{ip_port}"
    elsif ip_address
      ip_address.dup
    else
      'UNKNOWN'
    end
  elsif ipv6?
    if ip_port and ip_port != 0
      "[#{ip_address}]:#{ip_port}"
    else
      ip_address.dup
    end
  elsif unix?
    if unix_path.start_with?(File::SEPARATOR)
      unix_path.dup
    else
      "UNIX #{unix_path}"
    end
  else
    RubySL::Socket.address_family_name(afamily)
  end
end

#ip?Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/socket/addrinfo.rb', line 175

def ip?
  ipv4? || ipv6?
end

#ip_addressObject



179
180
181
182
183
184
185
# File 'lib/socket/addrinfo.rb', line 179

def ip_address
  unless ip?
    raise SocketError, 'An IPv4/IPv6 address is required'
  end

  @ip_address
end

#ip_portObject



187
188
189
190
191
192
193
# File 'lib/socket/addrinfo.rb', line 187

def ip_port
  unless ip?
    raise SocketError, 'An IPv4/IPv6 address is required'
  end

  @ip_port
end

#ip_unpackObject



264
265
266
267
268
269
270
# File 'lib/socket/addrinfo.rb', line 264

def ip_unpack
  unless ip?
    raise SocketError, 'An IPv4/IPv6 address is required'
  end

  [ip_address, ip_port]
end

#ipv4?Boolean

Returns:

  • (Boolean)


167
168
169
# File 'lib/socket/addrinfo.rb', line 167

def ipv4?
  @afamily == Socket::AF_INET
end

#ipv4_loopback?Boolean

Returns:

  • (Boolean)


272
273
274
275
276
# File 'lib/socket/addrinfo.rb', line 272

def ipv4_loopback?
  return false unless ipv4?

  RubySL::Socket::Foreign.inet_network(ip_address) & 0xff000000 == 0x7f000000
end

#ipv4_multicast?Boolean

Returns:

  • (Boolean)


278
279
280
281
282
# File 'lib/socket/addrinfo.rb', line 278

def ipv4_multicast?
  return false unless ipv4?

  RubySL::Socket::Foreign.inet_network(ip_address) & 0xf0000000 == 0xe0000000
end

#ipv4_private?Boolean

Returns:

  • (Boolean)


284
285
286
287
288
289
290
291
292
# File 'lib/socket/addrinfo.rb', line 284

def ipv4_private?
  return false unless ipv4?

  num = RubySL::Socket::Foreign.inet_network(ip_address)

  num & 0xff000000 == 0x0a000000 ||
    num & 0xfff00000 == 0xac100000 ||
    num & 0xffff0000 == 0xc0a80000
end

#ipv6?Boolean

Returns:

  • (Boolean)


171
172
173
# File 'lib/socket/addrinfo.rb', line 171

def ipv6?
  @afamily == Socket::AF_INET6
end

#ipv6_linklocal?Boolean

Returns:

  • (Boolean)


301
302
303
304
305
306
307
# File 'lib/socket/addrinfo.rb', line 301

def ipv6_linklocal?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xfe && bytes[1] >= 0x80
end

#ipv6_loopback?Boolean

Returns:

  • (Boolean)


294
295
296
297
298
299
# File 'lib/socket/addrinfo.rb', line 294

def ipv6_loopback?
  return false unless ipv6?

  RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address) ==
    RubySL::Socket::IPv6::LOOPBACK
end

#ipv6_mc_global?Boolean

Returns:

  • (Boolean)


325
326
327
328
329
330
331
# File 'lib/socket/addrinfo.rb', line 325

def ipv6_mc_global?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xff && bytes[1] & 0xf == 0xe
end

#ipv6_mc_linklocal?Boolean

Returns:

  • (Boolean)


333
334
335
336
337
338
339
# File 'lib/socket/addrinfo.rb', line 333

def ipv6_mc_linklocal?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xff && bytes[1] & 0xf == 0x2
end

#ipv6_mc_nodelocal?Boolean

Returns:

  • (Boolean)


341
342
343
344
345
346
347
# File 'lib/socket/addrinfo.rb', line 341

def ipv6_mc_nodelocal?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xff && bytes[1] & 0xf == 0x1
end

#ipv6_mc_orglocal?Boolean

Returns:

  • (Boolean)


349
350
351
352
353
354
355
# File 'lib/socket/addrinfo.rb', line 349

def ipv6_mc_orglocal?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xff && bytes[1] & 0xf == 0x8
end

#ipv6_mc_sitelocal?Boolean

Returns:

  • (Boolean)


357
358
359
360
361
362
363
# File 'lib/socket/addrinfo.rb', line 357

def ipv6_mc_sitelocal?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xff && bytes[1] & 0xf == 0x5
end

#ipv6_multicast?Boolean

Returns:

  • (Boolean)


309
310
311
312
313
314
315
# File 'lib/socket/addrinfo.rb', line 309

def ipv6_multicast?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xff
end

#ipv6_sitelocal?Boolean

Returns:

  • (Boolean)


317
318
319
320
321
322
323
# File 'lib/socket/addrinfo.rb', line 317

def ipv6_sitelocal?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xfe && bytes[1] >= 0xe0
end

#ipv6_to_ipv4Object



365
366
367
368
369
370
371
372
373
374
375
# File 'lib/socket/addrinfo.rb', line 365

def ipv6_to_ipv4
  return unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  if RubySL::Socket::IPv6.ipv4_embedded?(bytes)
    Addrinfo.ip(bytes.last(4).join('.'))
  else
    nil
  end
end

#ipv6_unique_local?Boolean

Returns:

  • (Boolean)


401
402
403
404
405
406
407
# File 'lib/socket/addrinfo.rb', line 401

def ipv6_unique_local?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes[0] == 0xfc || bytes[0] == 0xfd
end

#ipv6_unspecified?Boolean

Returns:

  • (Boolean)


377
378
379
380
381
382
383
# File 'lib/socket/addrinfo.rb', line 377

def ipv6_unspecified?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  bytes == RubySL::Socket::IPv6::UNSPECIFIED
end

#ipv6_v4compat?Boolean

Returns:

  • (Boolean)


385
386
387
388
389
390
391
# File 'lib/socket/addrinfo.rb', line 385

def ipv6_v4compat?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  RubySL::Socket::IPv6.ipv4_compatible?(bytes)
end

#ipv6_v4mapped?Boolean

Returns:

  • (Boolean)


393
394
395
396
397
398
399
# File 'lib/socket/addrinfo.rb', line 393

def ipv6_v4mapped?
  return false unless ipv6?

  bytes = RubySL::Socket::Foreign.ip_to_bytes(afamily, ip_address)

  RubySL::Socket::IPv6.ipv4_mapped?(bytes)
end

#listen(backlog = Socket::SOMAXCONN) ⇒ Object

creates a listening socket bound to self.



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/socket/mri.rb', line 259

def listen(backlog=Socket::SOMAXCONN)
  sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  begin
    sock.ipv6only! if self.ipv6?
    sock.setsockopt(:SOCKET, :REUSEADDR, 1)
    sock.bind(self)
    sock.listen(backlog)
  rescue Exception
    sock.close
    raise
  end
  if block_given?
    begin
      yield sock
    ensure
      sock.close if !sock.closed?
    end
  else
    sock
  end
end

#marshal_dumpObject



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/socket/addrinfo.rb', line 409

def marshal_dump
  if unix?
    address = unix_path
  else
    address = [ip_address, ip_port.to_s]
  end

  if unix?
    protocol = 0
  else
    protocol = RubySL::Socket.protocol_name(self.protocol)
  end

  [
    RubySL::Socket.address_family_name(afamily),
    address,
    RubySL::Socket.protocol_family_name(pfamily),
    RubySL::Socket.socket_type_name(socktype),
    protocol,
    canonname
  ]
end

#marshal_load(array) ⇒ Object



432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/socket/addrinfo.rb', line 432

def marshal_load(array)
  afamily, address, pfamily, socktype, protocol, canonname = array

  @afamily  = RubySL::Socket.address_family(afamily)
  @pfamily  = RubySL::Socket.protocol_family(pfamily)
  @socktype = RubySL::Socket.socket_type(socktype)

  if protocol and protocol != 0
    @protocol = ::Socket.const_get(protocol)
  else
    @protocol = protocol
  end

  if unix?
    @unix_path = address
  else
    @ip_address = address[0]
    @ip_port    = address[1].to_i
    @canonname  = canonname
  end
end

#to_sockaddrObject Also known as: to_s



203
204
205
206
207
208
209
# File 'lib/socket/addrinfo.rb', line 203

def to_sockaddr
  if unix?
    Socket.sockaddr_un(@unix_path)
  else
    Socket.sockaddr_in(@ip_port.to_i, @ip_address.to_s)
  end
end

#unix?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/socket/addrinfo.rb', line 163

def unix?
  @afamily == Socket::AF_UNIX
end

#unix_pathObject



195
196
197
198
199
200
201
# File 'lib/socket/addrinfo.rb', line 195

def unix_path
  unless unix?
    raise SocketError, 'The address family must be AF_UNIX'
  end

  @unix_path
end