raindrops 0.17.0 → 0.19.1
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.
- 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"));
|