1 # -*- encoding: binary -*-
3 # For reporting TCP ListenStats, users of older \Linux kernels need to ensure
4 # that the the "inet_diag" and "tcp_diag" kernel modules are loaded as they do
5 # not autoload correctly
6 module Raindrops::Linux
8 # The standard proc path for active UNIX domain sockets, feel free to call
9 # String#replace on this if your /proc is mounted in a non-standard location
11 PROC_NET_UNIX_ARGS = %w(/proc/net/unix)
12 defined?(::Encoding) and PROC_NET_UNIX_ARGS.push({ :encoding => "binary" })
14 # Get ListenStats from an array of +paths+
16 # Socket state mapping from integer => symbol, based on socket_state
17 # enum from include/linux/net.h in the \Linux kernel:
19 # SS_FREE = 0, /* not allocated */
20 # SS_UNCONNECTED, /* unconnected to any socket */
21 # SS_CONNECTING, /* in process of connecting */
22 # SS_CONNECTED, /* connected to socket */
23 # SS_DISCONNECTING /* in process of disconnecting */
25 # * SS_CONNECTING maps to ListenStats#active
26 # * SS_CONNECTED maps to ListenStats#queued
28 # This method may be significantly slower than its tcp_listener_stats
29 # counterpart due to the latter being able to use inet_diag via netlink.
30 # This parses /proc/net/unix as there is no other (known) way
31 # to expose Unix domain socket statistics over netlink.
32 def unix_listener_stats(paths)
33 rv = Hash.new { |h,k| h[k.freeze] = Raindrops::ListenStats.new(0, 0) }
34 paths = paths.map do |path|
36 path.force_encoding(Encoding::BINARY) if defined?(Encoding)
40 paths = / 00000000 \d+ (\d+)\s+\d+ (#{paths.join('|')})$/n
42 # no point in pread since we can't stat for size on this file
43 File.read(*PROC_NET_UNIX_ARGS).scan(paths) do |s|
46 when 2 then rv[path].queued += 1
47 when 3 then rv[path].active += 1
53 module_function :unix_listener_stats
55 end # Raindrops::Linux