raindrops 0.17.0 → 0.19.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.document +1 -1
- data/.olddoc.yml +6 -8
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +1 -1
- data/README +11 -5
- data/TODO +1 -0
- data/examples/linux-listener-stats.rb +1 -2
- data/examples/watcher_demo.ru +1 -1
- data/ext/raindrops/extconf.rb +106 -2
- data/ext/raindrops/linux_inet_diag.c +55 -85
- data/ext/raindrops/raindrops.c +28 -7
- data/ext/raindrops/tcp_info.c +245 -0
- data/lib/raindrops.rb +1 -1
- data/lib/raindrops/aggregate/pmq.rb +23 -17
- data/lib/raindrops/linux.rb +4 -5
- data/lib/raindrops/middleware.rb +2 -2
- data/lib/raindrops/middleware/proxy.rb +2 -2
- data/lib/raindrops/watcher.rb +7 -7
- data/pkg.mk +1 -1
- data/raindrops.gemspec +11 -15
- data/test/ipv6_enabled.rb +4 -4
- data/test/test_aggregate_pmq.rb +1 -1
- data/test/test_inet_diag_socket.rb +1 -1
- data/test/test_last_data_recv_unicorn.rb +1 -1
- data/test/test_linux.rb +3 -2
- data/test/test_linux_all_tcp_listen_stats_leak.rb +2 -2
- data/test/test_raindrops.rb +1 -1
- data/test/{test_linux_tcp_info.rb → test_tcp_info.rb} +34 -14
- data/test/test_watcher.rb +15 -10
- metadata +10 -55
- data/ext/raindrops/linux_tcp_info.c +0 -173
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0c5318918bfd5808ecc840404c67ed59f80019c6a705ef434b10ae92da78ba06
|
4
|
+
data.tar.gz: 1f25061c601aab07e3eb041cc9c2fd005438a1527994e0696b5eafc8dc148650
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df8be08761d8444a8599da3a5885efc806df935820753f5b000f27ab408171438b0f6ff4650810b5096e648904f5993bbc2a1303b9571df213201919b4b7f565
|
7
|
+
data.tar.gz: 250b7236881f06fdd684b22f4844cacb7a0d2ca43703220fe3f0f4ebc49e51faf2015864ef6776edc0d66c7dfd2762e08145548a5dd06b55c2193e989f21a3fd
|
data/.document
CHANGED
data/.olddoc.yml
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
---
|
2
|
-
cgit_url: https://
|
3
|
-
|
4
|
-
|
5
|
-
public_email: raindrops-public@bogomips.org
|
6
|
-
private_email: raindrops@bogomips.org
|
2
|
+
cgit_url: https://yhbt.net/raindrops.git/
|
3
|
+
rdoc_url: https://yhbt.net/raindrops/
|
4
|
+
public_email: raindrops-public@yhbt.net
|
7
5
|
ml_url:
|
8
|
-
- https://
|
6
|
+
- https://yhbt.net/raindrops-public/
|
9
7
|
- http://ou63pmih66umazou.onion/raindrops-public
|
10
8
|
nntp_url:
|
11
9
|
- nntp://news.public-inbox.org/inbox.comp.lang.ruby.raindrops
|
12
10
|
- nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.raindrops
|
13
11
|
source_code:
|
14
|
-
- git clone
|
15
|
-
- git clone
|
12
|
+
- git clone https://yhbt.net/raindrops.git
|
13
|
+
- torsocks git clone http://ou63pmih66umazou.onion/raindrops.git
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
data/README
CHANGED
@@ -58,20 +58,21 @@ If you use RubyGems:
|
|
58
58
|
|
59
59
|
See Raindrops::Middleware and Raindrops::LastDataRecv documentation for
|
60
60
|
use Rack servers. The entire library is fully-documented and we are
|
61
|
-
responsive on the mailing list
|
61
|
+
responsive on the publically archived mailing list
|
62
|
+
(mailto:raindrops-public@yhbt.net) if
|
62
63
|
you have any questions or comments.
|
63
64
|
|
64
65
|
== Development
|
65
66
|
|
66
67
|
You can get the latest source via git from the following locations:
|
67
68
|
|
68
|
-
git://
|
69
|
+
git://yhbt.net/raindrops.git
|
69
70
|
git://repo.or.cz/raindrops.git (mirror)
|
70
71
|
|
71
72
|
You may browse the code from the web and download the latest snapshot
|
72
73
|
tarballs here:
|
73
74
|
|
74
|
-
* https://
|
75
|
+
* https://yhbt.net/raindrops.git
|
75
76
|
* http://repo.or.cz/w/raindrops.git (gitweb)
|
76
77
|
|
77
78
|
Inline patches (from "git format-patch") to the mailing list are
|
@@ -88,9 +89,14 @@ raindrops is licensed under the LGPL-2.1+
|
|
88
89
|
== Contact
|
89
90
|
|
90
91
|
All feedback (bug reports, user/development discussion, patches, pull
|
91
|
-
requests) go to the mailing list:
|
92
|
+
requests) go to the publically archived mailing list:
|
93
|
+
mailto:raindrops-public@yhbt.net
|
92
94
|
|
93
95
|
Mailing list archives are available over HTTPS and NNTP:
|
94
96
|
|
95
|
-
* https://
|
97
|
+
* https://yhbt.net/raindrops-public/
|
98
|
+
* http://ou63pmih66umazou.onion/raindrops-public/
|
96
99
|
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.raindrops
|
100
|
+
|
101
|
+
Since archives are public, scrub sensitive information and
|
102
|
+
use anonymity tools such as Tor or Mixmaster if you deem necessary.
|
data/TODO
CHANGED
@@ -15,7 +15,6 @@
|
|
15
15
|
usage = "Usage: #$0 [-d DELAY] [-t QUEUED_THRESHOLD] ADDR..."
|
16
16
|
ARGV.size > 0 or abort usage
|
17
17
|
delay = false
|
18
|
-
all = false
|
19
18
|
queued_thresh = -1
|
20
19
|
# "normal" exits when driven on the command-line
|
21
20
|
trap(:INT) { exit 130 }
|
@@ -25,7 +24,7 @@
|
|
25
24
|
opts.banner = usage
|
26
25
|
opts.on('-d', '--delay=DELAY', Float) { |n| delay = n }
|
27
26
|
opts.on('-t', '--queued-threshold=INT', Integer) { |n| queued_thresh = n }
|
28
|
-
opts.on('-a', '--all') {
|
27
|
+
opts.on('-a', '--all') { } # noop
|
29
28
|
opts.parse! ARGV
|
30
29
|
end
|
31
30
|
|
data/examples/watcher_demo.ru
CHANGED
data/ext/raindrops/extconf.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mkmf'
|
2
|
+
require 'shellwords'
|
2
3
|
|
3
4
|
dir_config('atomic_ops')
|
4
5
|
have_func('mmap', 'sys/mman.h') or abort 'mmap() not found'
|
@@ -6,10 +7,112 @@
|
|
6
7
|
|
7
8
|
$CPPFLAGS += " -D_GNU_SOURCE "
|
8
9
|
have_func('mremap', 'sys/mman.h')
|
9
|
-
|
10
|
+
headers = %w(sys/types.h netdb.h string.h sys/socket.h netinet/in.h)
|
11
|
+
if have_header('linux/tcp.h')
|
12
|
+
headers << 'linux/tcp.h'
|
13
|
+
else
|
14
|
+
%w(netinet/tcp.h netinet/tcp_fsm.h).each { |h|
|
15
|
+
have_header(h, headers) and headers << h
|
16
|
+
}
|
17
|
+
end
|
10
18
|
|
11
19
|
$CPPFLAGS += " -D_BSD_SOURCE "
|
20
|
+
|
21
|
+
if have_type("struct tcp_info", headers)
|
22
|
+
%w(
|
23
|
+
tcpi_state
|
24
|
+
tcpi_ca_state
|
25
|
+
tcpi_retransmits
|
26
|
+
tcpi_probes
|
27
|
+
tcpi_backoff
|
28
|
+
tcpi_options
|
29
|
+
tcpi_snd_wscale
|
30
|
+
tcpi_rcv_wscale
|
31
|
+
tcpi_rto
|
32
|
+
tcpi_ato
|
33
|
+
tcpi_snd_mss
|
34
|
+
tcpi_rcv_mss
|
35
|
+
tcpi_unacked
|
36
|
+
tcpi_sacked
|
37
|
+
tcpi_lost
|
38
|
+
tcpi_retrans
|
39
|
+
tcpi_fackets
|
40
|
+
tcpi_last_data_sent
|
41
|
+
tcpi_last_ack_sent
|
42
|
+
tcpi_last_data_recv
|
43
|
+
tcpi_last_ack_recv
|
44
|
+
tcpi_pmtu
|
45
|
+
tcpi_rcv_ssthresh
|
46
|
+
tcpi_rtt
|
47
|
+
tcpi_rttvar
|
48
|
+
tcpi_snd_ssthresh
|
49
|
+
tcpi_snd_cwnd
|
50
|
+
tcpi_advmss
|
51
|
+
tcpi_reordering
|
52
|
+
tcpi_rcv_rtt
|
53
|
+
tcpi_rcv_space
|
54
|
+
tcpi_total_retrans
|
55
|
+
tcpi_snd_wnd
|
56
|
+
tcpi_snd_bwnd
|
57
|
+
tcpi_snd_nxt
|
58
|
+
tcpi_rcv_nxt
|
59
|
+
tcpi_toe_tid
|
60
|
+
tcpi_snd_rexmitpack
|
61
|
+
tcpi_rcv_ooopack
|
62
|
+
tcpi_snd_zerowin
|
63
|
+
).each do |field|
|
64
|
+
cfunc = "tcp_info_#{field}"
|
65
|
+
if have_struct_member('struct tcp_info', field, headers)
|
66
|
+
func_body = <<EOF
|
67
|
+
static VALUE #{cfunc}(VALUE self)
|
68
|
+
{
|
69
|
+
struct tcp_info *info = DATA_PTR(self);
|
70
|
+
return UINT2NUM((uint32_t)info->#{field});
|
71
|
+
}
|
72
|
+
EOF
|
73
|
+
func_body.delete!("\n")
|
74
|
+
$defs << "-DCFUNC_#{cfunc}=#{Shellwords.shellescape(func_body)}"
|
75
|
+
else
|
76
|
+
func_body = "static inline void #{cfunc}(void) {}"
|
77
|
+
$defs << "-DCFUNC_#{cfunc}=#{Shellwords.shellescape(func_body)}"
|
78
|
+
cfunc = 'rb_f_notimplement'.freeze
|
79
|
+
end
|
80
|
+
rbmethod = %Q("#{field.sub(/\Atcpi_/, ''.freeze)}")
|
81
|
+
$defs << "-DDEFINE_METHOD_tcp_info_#{field}=" \
|
82
|
+
"#{Shellwords.shellescape(
|
83
|
+
%Q[rb_define_method(cTCP_Info,#{rbmethod},#{cfunc},0)])}"
|
84
|
+
end
|
85
|
+
tcp_state_map = {
|
86
|
+
ESTABLISHED: %w(TCP_ESTABLISHED TCPS_ESTABLISHED),
|
87
|
+
SYN_SENT: %w(TCP_SYN_SENT TCPS_SYN_SENT),
|
88
|
+
SYN_RECV: %w(TCP_SYN_RECV TCPS_SYN_RECEIVED),
|
89
|
+
FIN_WAIT1: %w(TCP_FIN_WAIT1 TCPS_FIN_WAIT_1),
|
90
|
+
FIN_WAIT2: %w(TCP_FIN_WAIT2 TCPS_FIN_WAIT_2),
|
91
|
+
TIME_WAIT: %w(TCP_TIME_WAIT TCPS_TIME_WAIT),
|
92
|
+
CLOSE: %w(TCP_CLOSE TCPS_CLOSED),
|
93
|
+
CLOSE_WAIT: %w(TCP_CLOSE_WAIT TCPS_CLOSE_WAIT),
|
94
|
+
LAST_ACK: %w(TCP_LAST_ACK TCPS_LAST_ACK),
|
95
|
+
LISTEN: %w(TCP_LISTEN TCPS_LISTEN),
|
96
|
+
CLOSING: %w(TCP_CLOSING TCPS_CLOSING),
|
97
|
+
}
|
98
|
+
nstate = 0
|
99
|
+
tcp_state_map.each do |state, try|
|
100
|
+
try.each do |os_name|
|
101
|
+
have_const(os_name, headers) or next
|
102
|
+
tcp_state_map[state] = os_name
|
103
|
+
nstate += 1
|
104
|
+
end
|
105
|
+
end
|
106
|
+
if nstate == tcp_state_map.size
|
107
|
+
$defs << '-DRAINDROPS_TCP_STATES_ALL_KNOWN=1'
|
108
|
+
tcp_state_map.each do |state, name|
|
109
|
+
$defs << "-DRAINDROPS_TCP_#{state}=#{name}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
12
114
|
have_func("getpagesize", "unistd.h")
|
115
|
+
have_func('rb_thread_call_without_gvl')
|
13
116
|
have_func('rb_thread_blocking_region')
|
14
117
|
have_func('rb_thread_io_blocking_region')
|
15
118
|
|
@@ -40,7 +143,7 @@
|
|
40
143
|
$defs.push(format("-DHAVE_GCC_ATOMIC_BUILTINS"))
|
41
144
|
true
|
42
145
|
else
|
43
|
-
|
146
|
+
$CFLAGS = prev_cflags
|
44
147
|
false
|
45
148
|
end
|
46
149
|
end
|
@@ -53,4 +156,5 @@
|
|
53
156
|
|
54
157
|
apt-get install libatomic-ops-dev
|
55
158
|
SRC
|
159
|
+
create_header # generate extconf.h to avoid excessively long command-line
|
56
160
|
create_makefile('raindrops_ext')
|
@@ -1,46 +1,24 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <stdarg.h>
|
3
|
-
#
|
4
|
-
# include <ruby/st.h>
|
5
|
-
#else
|
6
|
-
# include <st.h>
|
7
|
-
#endif
|
3
|
+
#include <ruby/st.h>
|
8
4
|
#include "my_fileno.h"
|
9
5
|
#ifdef __linux__
|
10
6
|
|
11
|
-
/* Ruby 1.8.6+ macros (for compatibility with Ruby 1.9) */
|
12
|
-
#ifndef RSTRING_LEN
|
13
|
-
# define RSTRING_LEN(s) (RSTRING(s)->len)
|
14
|
-
#endif
|
15
|
-
|
16
|
-
/* partial emulation of the 1.9 rb_thread_blocking_region under 1.8 */
|
17
|
-
#if !defined(HAVE_RB_THREAD_BLOCKING_REGION) && \
|
18
|
-
!defined(HAVE_RB_THREAD_IO_BLOCKING_REGION)
|
19
|
-
# include <rubysig.h>
|
20
|
-
# define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
|
21
|
-
typedef void rb_unblock_function_t(void *);
|
22
|
-
typedef VALUE rb_blocking_function_t(void *);
|
23
|
-
static VALUE
|
24
|
-
rb_thread_blocking_region(
|
25
|
-
rb_blocking_function_t *func, void *data1,
|
26
|
-
rb_unblock_function_t *ubf, void *data2)
|
27
|
-
{
|
28
|
-
VALUE rv;
|
29
|
-
|
30
|
-
TRAP_BEG;
|
31
|
-
rv = func(data1);
|
32
|
-
TRAP_END;
|
33
|
-
|
34
|
-
return rv;
|
35
|
-
}
|
36
|
-
#endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
|
37
|
-
|
38
7
|
#ifdef HAVE_RB_THREAD_IO_BLOCKING_REGION
|
8
|
+
/* Ruby 1.9.3 and 2.0.0 */
|
39
9
|
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *, void *, int);
|
10
|
+
# define rd_fd_region(fn,data,fd) \
|
11
|
+
rb_thread_io_blocking_region((fn),(data),(fd))
|
12
|
+
#elif defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && \
|
13
|
+
defined(HAVE_RUBY_THREAD_H) && HAVE_RUBY_THREAD_H
|
14
|
+
/* in case Ruby 2.0+ ever drops rb_thread_io_blocking_region: */
|
15
|
+
# include <ruby/thread.h>
|
16
|
+
# define COMPAT_FN (void *(*)(void *))
|
17
|
+
# define rd_fd_region(fn,data,fd) \
|
18
|
+
rb_thread_call_without_gvl(COMPAT_FN(fn),(data),RUBY_UBF_IO,NULL)
|
40
19
|
#else
|
41
|
-
#
|
42
|
-
|
43
|
-
#endif /* HAVE_RB_THREAD_IO_BLOCKING_REGION */
|
20
|
+
# error Ruby <= 1.8 not supported
|
21
|
+
#endif
|
44
22
|
|
45
23
|
#include <assert.h>
|
46
24
|
#include <errno.h>
|
@@ -227,86 +205,76 @@ static void bug_warn_nogvl(const char *fmt, ...)
|
|
227
205
|
va_end(ap);
|
228
206
|
|
229
207
|
fprintf(stderr, "Please report how you produced this at "\
|
230
|
-
"raindrops-public@
|
208
|
+
"raindrops-public@yhbt.net\n");
|
231
209
|
fflush(stderr);
|
232
210
|
}
|
233
211
|
|
234
212
|
static struct listen_stats *stats_for(st_table *table, struct inet_diag_msg *r)
|
235
213
|
{
|
236
|
-
char *key, *port, *old_key;
|
214
|
+
char *host, *key, *port, *old_key;
|
237
215
|
size_t alloca_len;
|
238
216
|
struct listen_stats *stats;
|
239
|
-
socklen_t
|
217
|
+
socklen_t hostlen;
|
240
218
|
socklen_t portlen = (socklen_t)sizeof("65535");
|
241
|
-
|
242
|
-
|
243
|
-
int rc;
|
244
|
-
int flags = NI_NUMERICHOST | NI_NUMERICSERV;
|
219
|
+
int n;
|
220
|
+
const void *src = r->id.idiag_src;
|
245
221
|
|
246
|
-
switch (
|
222
|
+
switch (r->idiag_family) {
|
247
223
|
case AF_INET: {
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
alloca_len = keylen + 1 + portlen;
|
252
|
-
key = alloca(alloca_len);
|
253
|
-
key[keylen] = 0; /* will be ':' later */
|
254
|
-
port = key + keylen + 1;
|
255
|
-
rc = getnameinfo(&sa.sa, len,
|
256
|
-
key, keylen, port, portlen, flags);
|
224
|
+
hostlen = INET_ADDRSTRLEN;
|
225
|
+
alloca_len = hostlen + portlen;
|
226
|
+
host = key = alloca(alloca_len);
|
257
227
|
break;
|
258
228
|
}
|
259
229
|
case AF_INET6: {
|
260
|
-
|
261
|
-
|
262
|
-
keylen = INET6_ADDRSTRLEN;
|
263
|
-
/* [ ] */
|
264
|
-
alloca_len = 1 + keylen + 1 + 1 + portlen;
|
230
|
+
hostlen = INET6_ADDRSTRLEN;
|
231
|
+
alloca_len = 1 + hostlen + 1 + portlen;
|
265
232
|
key = alloca(alloca_len);
|
266
|
-
|
267
|
-
key[1 + keylen + 1] = 0; /* will be ':' later */
|
268
|
-
port = 1 + key + keylen + 1 + 1;
|
269
|
-
rc = getnameinfo(&sa.sa, len,
|
270
|
-
key + 1, keylen, port, portlen, flags);
|
233
|
+
host = key + 1;
|
271
234
|
break;
|
272
235
|
}
|
273
236
|
default:
|
274
237
|
assert(0 && "unsupported address family, could that be IPv7?!");
|
275
238
|
}
|
276
|
-
if (
|
277
|
-
bug_warn_nogvl("BUG:
|
278
|
-
*key = 0;
|
239
|
+
if (!inet_ntop(r->idiag_family, src, host, hostlen)) {
|
240
|
+
bug_warn_nogvl("BUG: inet_ntop: %s\n", strerror(errno));
|
241
|
+
*key = '\0';
|
242
|
+
*host = '\0';
|
279
243
|
}
|
280
|
-
|
281
|
-
|
282
|
-
portlen = (socklen_t)strlen(port);
|
283
|
-
|
284
|
-
switch (sa.ss.ss_family) {
|
244
|
+
hostlen = (socklen_t)strlen(host);
|
245
|
+
switch (r->idiag_family) {
|
285
246
|
case AF_INET:
|
286
|
-
|
287
|
-
|
247
|
+
host[hostlen] = ':';
|
248
|
+
port = host + hostlen + 1;
|
288
249
|
break;
|
289
250
|
case AF_INET6:
|
290
|
-
key[
|
291
|
-
|
292
|
-
|
293
|
-
|
251
|
+
key[0] = '[';
|
252
|
+
host[hostlen] = ']';
|
253
|
+
host[hostlen + 1] = ':';
|
254
|
+
port = host + hostlen + 2;
|
294
255
|
break;
|
295
256
|
default:
|
296
257
|
assert(0 && "unsupported address family, could that be IPv7?!");
|
297
258
|
}
|
298
259
|
|
260
|
+
n = snprintf(port, portlen, "%u", ntohs(r->id.idiag_sport));
|
261
|
+
if (n <= 0) {
|
262
|
+
bug_warn_nogvl("BUG: snprintf port: %d\n", n);
|
263
|
+
*key = '\0';
|
264
|
+
}
|
265
|
+
|
299
266
|
if (st_lookup(table, (st_data_t)key, (st_data_t *)&stats))
|
300
267
|
return stats;
|
301
268
|
|
302
269
|
old_key = key;
|
303
270
|
|
304
271
|
if (r->idiag_state == TCP_ESTABLISHED) {
|
305
|
-
|
306
|
-
addr_any(
|
272
|
+
n = snprintf(key, alloca_len, "%s:%u",
|
273
|
+
addr_any(r->idiag_family),
|
307
274
|
ntohs(r->id.idiag_sport));
|
308
275
|
if (n <= 0) {
|
309
276
|
bug_warn_nogvl("BUG: snprintf: %d\n", n);
|
277
|
+
*key = '\0';
|
310
278
|
}
|
311
279
|
if (st_lookup(table, (st_data_t)key, (st_data_t *)&stats))
|
312
280
|
return stats;
|
@@ -319,8 +287,9 @@ static struct listen_stats *stats_for(st_table *table, struct inet_diag_msg *r)
|
|
319
287
|
memcpy(key, old_key, n + 1);
|
320
288
|
}
|
321
289
|
} else {
|
322
|
-
|
323
|
-
|
290
|
+
size_t old_len = strlen(old_key) + 1;
|
291
|
+
key = xmalloc(old_len);
|
292
|
+
memcpy(key, old_key, old_len);
|
324
293
|
}
|
325
294
|
stats = xcalloc(1, sizeof(struct listen_stats));
|
326
295
|
st_insert(table, (st_data_t)key, (st_data_t)stats);
|
@@ -617,7 +586,7 @@ static VALUE tcp_stats(struct nogvl_args *args, VALUE addr)
|
|
617
586
|
gen_bytecode(&args->iov[2], &query_addr);
|
618
587
|
|
619
588
|
memset(&args->stats, 0, sizeof(struct listen_stats));
|
620
|
-
nl_errcheck(
|
589
|
+
nl_errcheck(rd_fd_region(diag, args, args->fd));
|
621
590
|
|
622
591
|
return rb_listen_stats(&args->stats);
|
623
592
|
}
|
@@ -694,7 +663,7 @@ static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self)
|
|
694
663
|
"addr must be an array of strings, a string, or nil");
|
695
664
|
}
|
696
665
|
|
697
|
-
nl_errcheck(
|
666
|
+
nl_errcheck(rd_fd_region(diag, &args, args.fd));
|
698
667
|
|
699
668
|
st_foreach(args.table, NIL_P(addrs) ? st_to_hash : st_AND_hash, rv);
|
700
669
|
st_free_table(args.table);
|
@@ -709,11 +678,12 @@ static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self)
|
|
709
678
|
|
710
679
|
void Init_raindrops_linux_inet_diag(void)
|
711
680
|
{
|
712
|
-
VALUE cRaindrops =
|
681
|
+
VALUE cRaindrops = rb_define_class("Raindrops", rb_cObject);
|
713
682
|
VALUE mLinux = rb_define_module_under(cRaindrops, "Linux");
|
683
|
+
VALUE Socket;
|
714
684
|
|
715
685
|
rb_require("socket");
|
716
|
-
|
686
|
+
Socket = rb_const_get(rb_cObject, rb_intern("Socket"));
|
717
687
|
id_new = rb_intern("new");
|
718
688
|
|
719
689
|
/*
|
@@ -722,7 +692,7 @@ void Init_raindrops_linux_inet_diag(void)
|
|
722
692
|
* This is a subclass of +Socket+ specifically for talking
|
723
693
|
* to the inet_diag facility of Netlink.
|
724
694
|
*/
|
725
|
-
cIDSock = rb_define_class_under(cRaindrops, "InetDiagSocket",
|
695
|
+
cIDSock = rb_define_class_under(cRaindrops, "InetDiagSocket", Socket);
|
726
696
|
rb_define_singleton_method(cIDSock, "new", ids_s_new, 0);
|
727
697
|
|
728
698
|
cListenStats = rb_const_get(cRaindrops, rb_intern("ListenStats"));
|