cool.io 1.0.0 → 1.9.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.
- checksums.yaml +7 -0
- data/.github/workflows/test.yaml +54 -0
- data/.gitignore +30 -0
- data/.rspec +3 -0
- data/{CHANGES → CHANGES.md} +175 -79
- data/{README.markdown → README.md} +43 -49
- data/Rakefile +44 -69
- data/appveyor.yml +18 -0
- data/cool.io.gemspec +18 -131
- data/examples/callbacked_echo_server.rb +24 -0
- data/ext/cool.io/buffer.c +781 -0
- data/ext/cool.io/cool.io.h +13 -0
- data/ext/cool.io/cool.io_ext.c +1 -0
- data/ext/cool.io/ev_wrap.h +4 -2
- data/ext/cool.io/extconf.rb +27 -16
- data/ext/cool.io/iowatcher.c +17 -8
- data/ext/cool.io/loop.c +36 -84
- data/ext/cool.io/stat_watcher.c +103 -25
- data/ext/cool.io/timer_watcher.c +3 -3
- data/ext/cool.io/utils.c +5 -0
- data/ext/cool.io/watcher.h +1 -1
- data/ext/libev/Changes +152 -3
- data/ext/libev/LICENSE +2 -1
- data/ext/libev/README +8 -8
- data/ext/libev/ev.c +1719 -348
- data/ext/libev/ev.h +146 -118
- data/ext/libev/ev_epoll.c +71 -20
- data/ext/libev/ev_kqueue.c +36 -16
- data/ext/libev/ev_poll.c +14 -11
- data/ext/libev/ev_port.c +43 -18
- data/ext/libev/ev_select.c +82 -25
- data/ext/libev/ev_vars.h +28 -21
- data/ext/libev/ev_win32.c +19 -10
- data/ext/libev/ev_wrap.h +166 -152
- data/ext/libev/test_libev_win32.c +1 -1
- data/gems.rb +9 -0
- data/lib/cool.io/async_watcher.rb +1 -1
- data/lib/cool.io/custom_require.rb +9 -0
- data/lib/cool.io/dns_resolver.rb +30 -22
- data/lib/cool.io/dsl.rb +32 -28
- data/lib/cool.io/io.rb +55 -35
- data/lib/cool.io/iowatcher.rb +1 -1
- data/lib/cool.io/listener.rb +35 -17
- data/lib/cool.io/loop.rb +17 -25
- data/lib/cool.io/meta.rb +6 -5
- data/lib/cool.io/server.rb +5 -4
- data/lib/cool.io/socket.rb +41 -30
- data/lib/cool.io/timer_watcher.rb +1 -1
- data/lib/cool.io/version.rb +7 -0
- data/lib/cool.io.rb +11 -10
- data/lib/coolio.rb +1 -1
- data/libev_ruby_gil.diff +175 -0
- data/libev_win_select.diff +130 -0
- data/spec/async_watcher_spec.rb +5 -5
- data/spec/dns_spec.rb +27 -8
- data/spec/iobuffer_spec.rb +147 -0
- data/spec/spec_helper.rb +15 -1
- data/spec/stat_watcher_spec.rb +81 -0
- data/spec/tcp_server_spec.rb +225 -0
- data/spec/tcp_socket_spec.rb +185 -0
- data/spec/timer_watcher_spec.rb +23 -19
- data/spec/udp_socket_spec.rb +58 -0
- data/spec/unix_listener_spec.rb +8 -8
- data/spec/unix_server_spec.rb +10 -8
- metadata +109 -112
- data/VERSION +0 -1
- data/examples/httpclient.rb +0 -38
- data/ext/http11_client/.gitignore +0 -5
- data/ext/http11_client/LICENSE +0 -31
- data/ext/http11_client/ext_help.h +0 -14
- data/ext/http11_client/extconf.rb +0 -6
- data/ext/http11_client/http11_client.c +0 -300
- data/ext/http11_client/http11_parser.c +0 -403
- data/ext/http11_client/http11_parser.h +0 -48
- data/ext/http11_client/http11_parser.rl +0 -173
- data/lib/cool.io/eventmachine.rb +0 -234
- data/lib/cool.io/http_client.rb +0 -419
- data/lib/rev.rb +0 -4
- data/spec/possible_tests/schedules_other_threads.rb +0 -48
- data/spec/possible_tests/test_on_resolve_failed.rb +0 -9
- data/spec/possible_tests/test_resolves.rb +0 -27
- data/spec/possible_tests/test_write_during_resolve.rb +0 -27
- data/spec/possible_tests/works_straight.rb +0 -71
data/ext/libev/ev_wrap.h
CHANGED
|
@@ -1,186 +1,200 @@
|
|
|
1
1
|
/* DO NOT EDIT, automatically generated by update_ev_wrap */
|
|
2
2
|
#ifndef EV_WRAP_H
|
|
3
3
|
#define EV_WRAP_H
|
|
4
|
-
#define
|
|
5
|
-
#define mn_now ((loop)->mn_now)
|
|
6
|
-
#define rtmn_diff ((loop)->rtmn_diff)
|
|
7
|
-
#define io_blocktime ((loop)->io_blocktime)
|
|
8
|
-
#define timeout_blocktime ((loop)->timeout_blocktime)
|
|
9
|
-
#define backend ((loop)->backend)
|
|
4
|
+
#define acquire_cb ((loop)->acquire_cb)
|
|
10
5
|
#define activecnt ((loop)->activecnt)
|
|
11
|
-
#define
|
|
6
|
+
#define anfdmax ((loop)->anfdmax)
|
|
7
|
+
#define anfds ((loop)->anfds)
|
|
8
|
+
#define async_pending ((loop)->async_pending)
|
|
9
|
+
#define asynccnt ((loop)->asynccnt)
|
|
10
|
+
#define asyncmax ((loop)->asyncmax)
|
|
11
|
+
#define asyncs ((loop)->asyncs)
|
|
12
|
+
#define backend ((loop)->backend)
|
|
12
13
|
#define backend_fd ((loop)->backend_fd)
|
|
13
|
-
#define
|
|
14
|
+
#define backend_mintime ((loop)->backend_mintime)
|
|
14
15
|
#define backend_modify ((loop)->backend_modify)
|
|
15
16
|
#define backend_poll ((loop)->backend_poll)
|
|
16
|
-
#define
|
|
17
|
-
#define
|
|
18
|
-
#define
|
|
19
|
-
#define
|
|
20
|
-
#define
|
|
21
|
-
#define
|
|
22
|
-
#define rfeeds ((loop)->rfeeds)
|
|
23
|
-
#define rfeedmax ((loop)->rfeedmax)
|
|
24
|
-
#define rfeedcnt ((loop)->rfeedcnt)
|
|
25
|
-
#define evfd ((loop)->evfd)
|
|
26
|
-
#define evpipe ((loop)->evpipe)
|
|
27
|
-
#define pipe_w ((loop)->pipe_w)
|
|
17
|
+
#define checkcnt ((loop)->checkcnt)
|
|
18
|
+
#define checkmax ((loop)->checkmax)
|
|
19
|
+
#define checks ((loop)->checks)
|
|
20
|
+
#define cleanupcnt ((loop)->cleanupcnt)
|
|
21
|
+
#define cleanupmax ((loop)->cleanupmax)
|
|
22
|
+
#define cleanups ((loop)->cleanups)
|
|
28
23
|
#define curpid ((loop)->curpid)
|
|
29
|
-
#define
|
|
30
|
-
#define
|
|
31
|
-
#define
|
|
32
|
-
#define vec_wi ((loop)->vec_wi)
|
|
33
|
-
#define vec_wo ((loop)->vec_wo)
|
|
34
|
-
#define vec_eo ((loop)->vec_eo)
|
|
35
|
-
#define vec_max ((loop)->vec_max)
|
|
36
|
-
#define polls ((loop)->polls)
|
|
37
|
-
#define pollmax ((loop)->pollmax)
|
|
38
|
-
#define pollcnt ((loop)->pollcnt)
|
|
39
|
-
#define pollidxs ((loop)->pollidxs)
|
|
40
|
-
#define pollidxmax ((loop)->pollidxmax)
|
|
41
|
-
#define epoll_events ((loop)->epoll_events)
|
|
24
|
+
#define epoll_epermcnt ((loop)->epoll_epermcnt)
|
|
25
|
+
#define epoll_epermmax ((loop)->epoll_epermmax)
|
|
26
|
+
#define epoll_eperms ((loop)->epoll_eperms)
|
|
42
27
|
#define epoll_eventmax ((loop)->epoll_eventmax)
|
|
43
|
-
#define
|
|
44
|
-
#define
|
|
45
|
-
#define kqueue_changecnt ((loop)->kqueue_changecnt)
|
|
46
|
-
#define kqueue_events ((loop)->kqueue_events)
|
|
47
|
-
#define kqueue_eventmax ((loop)->kqueue_eventmax)
|
|
48
|
-
#define port_events ((loop)->port_events)
|
|
49
|
-
#define port_eventmax ((loop)->port_eventmax)
|
|
50
|
-
#define iocp ((loop)->iocp)
|
|
51
|
-
#define fdchanges ((loop)->fdchanges)
|
|
52
|
-
#define fdchangemax ((loop)->fdchangemax)
|
|
28
|
+
#define epoll_events ((loop)->epoll_events)
|
|
29
|
+
#define evpipe ((loop)->evpipe)
|
|
53
30
|
#define fdchangecnt ((loop)->fdchangecnt)
|
|
54
|
-
#define
|
|
55
|
-
#define
|
|
56
|
-
#define timercnt ((loop)->timercnt)
|
|
57
|
-
#define periodics ((loop)->periodics)
|
|
58
|
-
#define periodicmax ((loop)->periodicmax)
|
|
59
|
-
#define periodiccnt ((loop)->periodiccnt)
|
|
60
|
-
#define idles ((loop)->idles)
|
|
61
|
-
#define idlemax ((loop)->idlemax)
|
|
62
|
-
#define idlecnt ((loop)->idlecnt)
|
|
63
|
-
#define idleall ((loop)->idleall)
|
|
64
|
-
#define prepares ((loop)->prepares)
|
|
65
|
-
#define preparemax ((loop)->preparemax)
|
|
66
|
-
#define preparecnt ((loop)->preparecnt)
|
|
67
|
-
#define checks ((loop)->checks)
|
|
68
|
-
#define checkmax ((loop)->checkmax)
|
|
69
|
-
#define checkcnt ((loop)->checkcnt)
|
|
70
|
-
#define forks ((loop)->forks)
|
|
71
|
-
#define forkmax ((loop)->forkmax)
|
|
31
|
+
#define fdchangemax ((loop)->fdchangemax)
|
|
32
|
+
#define fdchanges ((loop)->fdchanges)
|
|
72
33
|
#define forkcnt ((loop)->forkcnt)
|
|
73
|
-
#define
|
|
74
|
-
#define
|
|
75
|
-
#define cleanupcnt ((loop)->cleanupcnt)
|
|
76
|
-
#define async_pending ((loop)->async_pending)
|
|
77
|
-
#define asyncs ((loop)->asyncs)
|
|
78
|
-
#define asyncmax ((loop)->asyncmax)
|
|
79
|
-
#define asynccnt ((loop)->asynccnt)
|
|
80
|
-
#define fs_fd ((loop)->fs_fd)
|
|
81
|
-
#define fs_w ((loop)->fs_w)
|
|
34
|
+
#define forkmax ((loop)->forkmax)
|
|
35
|
+
#define forks ((loop)->forks)
|
|
82
36
|
#define fs_2625 ((loop)->fs_2625)
|
|
37
|
+
#define fs_fd ((loop)->fs_fd)
|
|
83
38
|
#define fs_hash ((loop)->fs_hash)
|
|
39
|
+
#define fs_w ((loop)->fs_w)
|
|
40
|
+
#define idleall ((loop)->idleall)
|
|
41
|
+
#define idlecnt ((loop)->idlecnt)
|
|
42
|
+
#define idlemax ((loop)->idlemax)
|
|
43
|
+
#define idles ((loop)->idles)
|
|
44
|
+
#define invoke_cb ((loop)->invoke_cb)
|
|
45
|
+
#define io_blocktime ((loop)->io_blocktime)
|
|
46
|
+
#define iocp ((loop)->iocp)
|
|
47
|
+
#define kqueue_changecnt ((loop)->kqueue_changecnt)
|
|
48
|
+
#define kqueue_changemax ((loop)->kqueue_changemax)
|
|
49
|
+
#define kqueue_changes ((loop)->kqueue_changes)
|
|
50
|
+
#define kqueue_eventmax ((loop)->kqueue_eventmax)
|
|
51
|
+
#define kqueue_events ((loop)->kqueue_events)
|
|
52
|
+
#define kqueue_fd_pid ((loop)->kqueue_fd_pid)
|
|
53
|
+
#define loop_count ((loop)->loop_count)
|
|
54
|
+
#define loop_depth ((loop)->loop_depth)
|
|
55
|
+
#define loop_done ((loop)->loop_done)
|
|
56
|
+
#define mn_now ((loop)->mn_now)
|
|
57
|
+
#define now_floor ((loop)->now_floor)
|
|
58
|
+
#define origflags ((loop)->origflags)
|
|
59
|
+
#define pending_w ((loop)->pending_w)
|
|
60
|
+
#define pendingcnt ((loop)->pendingcnt)
|
|
61
|
+
#define pendingmax ((loop)->pendingmax)
|
|
62
|
+
#define pendingpri ((loop)->pendingpri)
|
|
63
|
+
#define pendings ((loop)->pendings)
|
|
64
|
+
#define periodiccnt ((loop)->periodiccnt)
|
|
65
|
+
#define periodicmax ((loop)->periodicmax)
|
|
66
|
+
#define periodics ((loop)->periodics)
|
|
67
|
+
#define pipe_w ((loop)->pipe_w)
|
|
68
|
+
#define pipe_write_skipped ((loop)->pipe_write_skipped)
|
|
69
|
+
#define pipe_write_wanted ((loop)->pipe_write_wanted)
|
|
70
|
+
#define pollcnt ((loop)->pollcnt)
|
|
71
|
+
#define pollidxmax ((loop)->pollidxmax)
|
|
72
|
+
#define pollidxs ((loop)->pollidxs)
|
|
73
|
+
#define pollmax ((loop)->pollmax)
|
|
74
|
+
#define polls ((loop)->polls)
|
|
75
|
+
#define port_eventmax ((loop)->port_eventmax)
|
|
76
|
+
#define port_events ((loop)->port_events)
|
|
77
|
+
#define postfork ((loop)->postfork)
|
|
78
|
+
#define preparecnt ((loop)->preparecnt)
|
|
79
|
+
#define preparemax ((loop)->preparemax)
|
|
80
|
+
#define prepares ((loop)->prepares)
|
|
81
|
+
#define release_cb ((loop)->release_cb)
|
|
82
|
+
#define rfeedcnt ((loop)->rfeedcnt)
|
|
83
|
+
#define rfeedmax ((loop)->rfeedmax)
|
|
84
|
+
#define rfeeds ((loop)->rfeeds)
|
|
85
|
+
#define rtmn_diff ((loop)->rtmn_diff)
|
|
84
86
|
#define sig_pending ((loop)->sig_pending)
|
|
85
87
|
#define sigfd ((loop)->sigfd)
|
|
86
|
-
#define sigfd_w ((loop)->sigfd_w)
|
|
87
88
|
#define sigfd_set ((loop)->sigfd_set)
|
|
88
|
-
#define
|
|
89
|
-
#define
|
|
89
|
+
#define sigfd_w ((loop)->sigfd_w)
|
|
90
|
+
#define timeout_blocktime ((loop)->timeout_blocktime)
|
|
91
|
+
#define timercnt ((loop)->timercnt)
|
|
92
|
+
#define timermax ((loop)->timermax)
|
|
93
|
+
#define timers ((loop)->timers)
|
|
90
94
|
#define userdata ((loop)->userdata)
|
|
91
|
-
#define
|
|
92
|
-
#define
|
|
93
|
-
#define
|
|
95
|
+
#define vec_eo ((loop)->vec_eo)
|
|
96
|
+
#define vec_max ((loop)->vec_max)
|
|
97
|
+
#define vec_ri ((loop)->vec_ri)
|
|
98
|
+
#define vec_ro ((loop)->vec_ro)
|
|
99
|
+
#define vec_wi ((loop)->vec_wi)
|
|
100
|
+
#define vec_wo ((loop)->vec_wo)
|
|
94
101
|
#else
|
|
95
102
|
#undef EV_WRAP_H
|
|
96
|
-
#undef
|
|
97
|
-
#undef mn_now
|
|
98
|
-
#undef rtmn_diff
|
|
99
|
-
#undef io_blocktime
|
|
100
|
-
#undef timeout_blocktime
|
|
101
|
-
#undef backend
|
|
103
|
+
#undef acquire_cb
|
|
102
104
|
#undef activecnt
|
|
103
|
-
#undef
|
|
105
|
+
#undef anfdmax
|
|
106
|
+
#undef anfds
|
|
107
|
+
#undef async_pending
|
|
108
|
+
#undef asynccnt
|
|
109
|
+
#undef asyncmax
|
|
110
|
+
#undef asyncs
|
|
111
|
+
#undef backend
|
|
104
112
|
#undef backend_fd
|
|
105
|
-
#undef
|
|
113
|
+
#undef backend_mintime
|
|
106
114
|
#undef backend_modify
|
|
107
115
|
#undef backend_poll
|
|
108
|
-
#undef
|
|
109
|
-
#undef
|
|
110
|
-
#undef
|
|
111
|
-
#undef
|
|
112
|
-
#undef
|
|
113
|
-
#undef
|
|
114
|
-
#undef rfeeds
|
|
115
|
-
#undef rfeedmax
|
|
116
|
-
#undef rfeedcnt
|
|
117
|
-
#undef evfd
|
|
118
|
-
#undef evpipe
|
|
119
|
-
#undef pipe_w
|
|
116
|
+
#undef checkcnt
|
|
117
|
+
#undef checkmax
|
|
118
|
+
#undef checks
|
|
119
|
+
#undef cleanupcnt
|
|
120
|
+
#undef cleanupmax
|
|
121
|
+
#undef cleanups
|
|
120
122
|
#undef curpid
|
|
121
|
-
#undef
|
|
122
|
-
#undef
|
|
123
|
-
#undef
|
|
124
|
-
#undef vec_wi
|
|
125
|
-
#undef vec_wo
|
|
126
|
-
#undef vec_eo
|
|
127
|
-
#undef vec_max
|
|
128
|
-
#undef polls
|
|
129
|
-
#undef pollmax
|
|
130
|
-
#undef pollcnt
|
|
131
|
-
#undef pollidxs
|
|
132
|
-
#undef pollidxmax
|
|
133
|
-
#undef epoll_events
|
|
123
|
+
#undef epoll_epermcnt
|
|
124
|
+
#undef epoll_epermmax
|
|
125
|
+
#undef epoll_eperms
|
|
134
126
|
#undef epoll_eventmax
|
|
135
|
-
#undef
|
|
136
|
-
#undef
|
|
137
|
-
#undef kqueue_changecnt
|
|
138
|
-
#undef kqueue_events
|
|
139
|
-
#undef kqueue_eventmax
|
|
140
|
-
#undef port_events
|
|
141
|
-
#undef port_eventmax
|
|
142
|
-
#undef iocp
|
|
143
|
-
#undef fdchanges
|
|
144
|
-
#undef fdchangemax
|
|
127
|
+
#undef epoll_events
|
|
128
|
+
#undef evpipe
|
|
145
129
|
#undef fdchangecnt
|
|
146
|
-
#undef
|
|
147
|
-
#undef
|
|
148
|
-
#undef timercnt
|
|
149
|
-
#undef periodics
|
|
150
|
-
#undef periodicmax
|
|
151
|
-
#undef periodiccnt
|
|
152
|
-
#undef idles
|
|
153
|
-
#undef idlemax
|
|
154
|
-
#undef idlecnt
|
|
155
|
-
#undef idleall
|
|
156
|
-
#undef prepares
|
|
157
|
-
#undef preparemax
|
|
158
|
-
#undef preparecnt
|
|
159
|
-
#undef checks
|
|
160
|
-
#undef checkmax
|
|
161
|
-
#undef checkcnt
|
|
162
|
-
#undef forks
|
|
163
|
-
#undef forkmax
|
|
130
|
+
#undef fdchangemax
|
|
131
|
+
#undef fdchanges
|
|
164
132
|
#undef forkcnt
|
|
165
|
-
#undef
|
|
166
|
-
#undef
|
|
167
|
-
#undef cleanupcnt
|
|
168
|
-
#undef async_pending
|
|
169
|
-
#undef asyncs
|
|
170
|
-
#undef asyncmax
|
|
171
|
-
#undef asynccnt
|
|
172
|
-
#undef fs_fd
|
|
173
|
-
#undef fs_w
|
|
133
|
+
#undef forkmax
|
|
134
|
+
#undef forks
|
|
174
135
|
#undef fs_2625
|
|
136
|
+
#undef fs_fd
|
|
175
137
|
#undef fs_hash
|
|
138
|
+
#undef fs_w
|
|
139
|
+
#undef idleall
|
|
140
|
+
#undef idlecnt
|
|
141
|
+
#undef idlemax
|
|
142
|
+
#undef idles
|
|
143
|
+
#undef invoke_cb
|
|
144
|
+
#undef io_blocktime
|
|
145
|
+
#undef iocp
|
|
146
|
+
#undef kqueue_changecnt
|
|
147
|
+
#undef kqueue_changemax
|
|
148
|
+
#undef kqueue_changes
|
|
149
|
+
#undef kqueue_eventmax
|
|
150
|
+
#undef kqueue_events
|
|
151
|
+
#undef kqueue_fd_pid
|
|
152
|
+
#undef loop_count
|
|
153
|
+
#undef loop_depth
|
|
154
|
+
#undef loop_done
|
|
155
|
+
#undef mn_now
|
|
156
|
+
#undef now_floor
|
|
157
|
+
#undef origflags
|
|
158
|
+
#undef pending_w
|
|
159
|
+
#undef pendingcnt
|
|
160
|
+
#undef pendingmax
|
|
161
|
+
#undef pendingpri
|
|
162
|
+
#undef pendings
|
|
163
|
+
#undef periodiccnt
|
|
164
|
+
#undef periodicmax
|
|
165
|
+
#undef periodics
|
|
166
|
+
#undef pipe_w
|
|
167
|
+
#undef pipe_write_skipped
|
|
168
|
+
#undef pipe_write_wanted
|
|
169
|
+
#undef pollcnt
|
|
170
|
+
#undef pollidxmax
|
|
171
|
+
#undef pollidxs
|
|
172
|
+
#undef pollmax
|
|
173
|
+
#undef polls
|
|
174
|
+
#undef port_eventmax
|
|
175
|
+
#undef port_events
|
|
176
|
+
#undef postfork
|
|
177
|
+
#undef preparecnt
|
|
178
|
+
#undef preparemax
|
|
179
|
+
#undef prepares
|
|
180
|
+
#undef release_cb
|
|
181
|
+
#undef rfeedcnt
|
|
182
|
+
#undef rfeedmax
|
|
183
|
+
#undef rfeeds
|
|
184
|
+
#undef rtmn_diff
|
|
176
185
|
#undef sig_pending
|
|
177
186
|
#undef sigfd
|
|
178
|
-
#undef sigfd_w
|
|
179
187
|
#undef sigfd_set
|
|
180
|
-
#undef
|
|
181
|
-
#undef
|
|
188
|
+
#undef sigfd_w
|
|
189
|
+
#undef timeout_blocktime
|
|
190
|
+
#undef timercnt
|
|
191
|
+
#undef timermax
|
|
192
|
+
#undef timers
|
|
182
193
|
#undef userdata
|
|
183
|
-
#undef
|
|
184
|
-
#undef
|
|
185
|
-
#undef
|
|
194
|
+
#undef vec_eo
|
|
195
|
+
#undef vec_max
|
|
196
|
+
#undef vec_ri
|
|
197
|
+
#undef vec_ro
|
|
198
|
+
#undef vec_wi
|
|
199
|
+
#undef vec_wo
|
|
186
200
|
#endif
|
data/gems.rb
ADDED
data/lib/cool.io/dns_resolver.rb
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
# as best I could with extremely limited knowledge of the DNS format. There's
|
|
10
10
|
# obviously a ton of stuff it doesn't support (like IPv6 and TCP).
|
|
11
11
|
#
|
|
12
|
-
# If you do know what you're doing with DNS, feel free to improve this!
|
|
12
|
+
# If you do know what you're doing with DNS, feel free to improve this!
|
|
13
13
|
# A good starting point my be this EventMachine Net::DNS-based asynchronous
|
|
14
14
|
# resolver:
|
|
15
15
|
#
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
#
|
|
18
18
|
#++
|
|
19
19
|
|
|
20
|
+
require 'resolv'
|
|
21
|
+
|
|
20
22
|
module Coolio
|
|
21
23
|
# A non-blocking DNS resolver. It provides interfaces for querying both
|
|
22
24
|
# /etc/hosts and nameserves listed in /etc/resolv.conf, or nameservers of
|
|
@@ -31,23 +33,30 @@ module Coolio
|
|
|
31
33
|
# again.
|
|
32
34
|
class DNSResolver < IOWatcher
|
|
33
35
|
#--
|
|
34
|
-
# TODO check if it's caching right
|
|
35
|
-
RESOLV_CONF = '/etc/resolv.conf'
|
|
36
|
-
HOSTS = '/etc/hosts'
|
|
37
36
|
DNS_PORT = 53
|
|
38
37
|
DATAGRAM_SIZE = 512
|
|
39
38
|
TIMEOUT = 3 # Retry timeout for each datagram sent
|
|
40
39
|
RETRIES = 4 # Number of retries to attempt
|
|
41
40
|
# so currently total is 12s before it will err due to timeouts
|
|
42
41
|
# if it errs due to inability to reach the DNS server [Errno::EHOSTUNREACH], same
|
|
43
|
-
|
|
44
42
|
# Query /etc/hosts (or the specified hostfile) for the given host
|
|
45
|
-
def self.hosts(host, hostfile =
|
|
43
|
+
def self.hosts(host, hostfile = Resolv::Hosts::DefaultFileName)
|
|
46
44
|
hosts = {}
|
|
47
|
-
File.open(hostfile)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
File.open(hostfile) do |f|
|
|
46
|
+
f.each_line do |host_entry|
|
|
47
|
+
entries = host_entry.gsub(/#.*$/, '').gsub(/\s+/, ' ').split(' ')
|
|
48
|
+
addr = entries.shift
|
|
49
|
+
entries.each { |e| hosts[e] ||= addr }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
unless hosts.key?("localhost")
|
|
53
|
+
# On Windows, there is a case that hosts file doesn't have entry by default
|
|
54
|
+
# and preferred IPv4/IPv6 behavior may be changed by registry key [1], so
|
|
55
|
+
# "localhost" should be resolved by getaddrinfo.
|
|
56
|
+
# (first[3] means preferred resolved IP address ::1 or 127.0.0.1)
|
|
57
|
+
# [1] https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows
|
|
58
|
+
require "socket"
|
|
59
|
+
hosts["localhost"] = ::Socket.getaddrinfo("localhost", nil).first[3]
|
|
51
60
|
end
|
|
52
61
|
|
|
53
62
|
hosts[host]
|
|
@@ -59,16 +68,16 @@ module Coolio
|
|
|
59
68
|
# use nameservers listed in /etc/resolv.conf
|
|
60
69
|
def initialize(hostname, *nameservers)
|
|
61
70
|
if nameservers.empty?
|
|
62
|
-
nameservers =
|
|
63
|
-
raise RuntimeError, "no nameservers found
|
|
71
|
+
nameservers = Resolv::DNS::Config.default_config_hash[:nameserver]
|
|
72
|
+
raise RuntimeError, "no nameservers found" if nameservers.empty? # TODO just call resolve_failed, not raise [also handle Errno::ENOENT)]
|
|
64
73
|
end
|
|
65
74
|
|
|
66
75
|
@nameservers = nameservers
|
|
67
76
|
@question = request_question hostname
|
|
68
|
-
|
|
77
|
+
|
|
69
78
|
@socket = UDPSocket.new
|
|
70
79
|
@timer = Timeout.new(self)
|
|
71
|
-
|
|
80
|
+
|
|
72
81
|
super(@socket)
|
|
73
82
|
end
|
|
74
83
|
|
|
@@ -106,11 +115,10 @@ module Coolio
|
|
|
106
115
|
def send_request
|
|
107
116
|
nameserver = @nameservers.shift
|
|
108
117
|
@nameservers << nameserver # rotate them
|
|
109
|
-
@socket.connect @nameservers.first, DNS_PORT
|
|
110
118
|
begin
|
|
111
|
-
@socket.send request_message, 0
|
|
119
|
+
@socket.send request_message, 0, @nameservers.first, DNS_PORT
|
|
112
120
|
rescue Errno::EHOSTUNREACH # TODO figure out why it has to be wrapper here, when the other wrapper should be wrapping this one!
|
|
113
|
-
end
|
|
121
|
+
end
|
|
114
122
|
end
|
|
115
123
|
|
|
116
124
|
# Called by the subclass when the DNS response is available
|
|
@@ -120,7 +128,7 @@ module Coolio
|
|
|
120
128
|
datagram = @socket.recvfrom_nonblock(DATAGRAM_SIZE).first
|
|
121
129
|
rescue Errno::ECONNREFUSED
|
|
122
130
|
end
|
|
123
|
-
|
|
131
|
+
|
|
124
132
|
address = response_address datagram rescue nil
|
|
125
133
|
address ? on_success(address) : on_failure
|
|
126
134
|
detach
|
|
@@ -128,7 +136,7 @@ module Coolio
|
|
|
128
136
|
|
|
129
137
|
def request_question(hostname)
|
|
130
138
|
raise ArgumentError, "hostname cannot be nil" if hostname.nil?
|
|
131
|
-
|
|
139
|
+
|
|
132
140
|
# Query name
|
|
133
141
|
message = hostname.split('.').map { |s| [s.size].pack('C') << s }.join + "\0"
|
|
134
142
|
|
|
@@ -149,7 +157,7 @@ module Coolio
|
|
|
149
157
|
qdcount = 1
|
|
150
158
|
|
|
151
159
|
# No answer, authority, or additional records
|
|
152
|
-
ancount = nscount = arcount = 0
|
|
160
|
+
ancount = nscount = arcount = 0
|
|
153
161
|
|
|
154
162
|
message << [qdcount, ancount, nscount, arcount].pack('nnnn')
|
|
155
163
|
message << @question
|
|
@@ -169,7 +177,7 @@ module Coolio
|
|
|
169
177
|
return unless rcode == 0
|
|
170
178
|
|
|
171
179
|
# Extract the question and answer counts
|
|
172
|
-
qdcount,
|
|
180
|
+
qdcount, _ancount = message[4..7].unpack('nn').map { |n| n.to_i }
|
|
173
181
|
|
|
174
182
|
# We only asked one question
|
|
175
183
|
return unless qdcount == 1
|
|
@@ -210,7 +218,7 @@ module Coolio
|
|
|
210
218
|
return @resolver.__send__(:send_request)
|
|
211
219
|
rescue Errno::EHOSTUNREACH # if the DNS is toast try again after the timeout occurs again
|
|
212
220
|
return nil
|
|
213
|
-
end
|
|
221
|
+
end
|
|
214
222
|
end
|
|
215
223
|
@resolver.__send__(:on_timeout)
|
|
216
224
|
@resolver.detach
|
data/lib/cool.io/dsl.rb
CHANGED
|
@@ -7,112 +7,112 @@
|
|
|
7
7
|
module Coolio
|
|
8
8
|
# A module we stash all the connections defined by the DSL under
|
|
9
9
|
module Connections; end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
# A DSL for defining Cool.io connection types and servers
|
|
12
12
|
module DSL
|
|
13
13
|
# Define all methods on the metaclass
|
|
14
14
|
module_function
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
# Run the default Cool.io event loop
|
|
17
17
|
def run
|
|
18
18
|
Cool.io::Loop.default.run
|
|
19
19
|
end
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
# Connect to the given host and port using the given connection class
|
|
22
22
|
def connect(host, port, connection_name = nil, *initializer_args, &block)
|
|
23
23
|
if block_given?
|
|
24
24
|
initializer_args.unshift connection_name if connection_name
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
klass = Class.new Cool.io::TCPSocket
|
|
27
27
|
connection_builder = ConnectionBuilder.new klass
|
|
28
|
-
connection_builder.instance_eval
|
|
28
|
+
connection_builder.instance_eval(&block)
|
|
29
29
|
else
|
|
30
30
|
raise ArgumentError, "no connection name or block given" unless connection_name
|
|
31
31
|
klass = self[connection_name]
|
|
32
32
|
end
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
client = klass.connect host, port, *initializer_args
|
|
35
35
|
client.attach Cool.io::Loop.default
|
|
36
36
|
client
|
|
37
37
|
end
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
# Create a new Cool.io::TCPServer
|
|
40
40
|
def server(host, port, connection_name = nil, *initializer_args, &block)
|
|
41
41
|
if block_given?
|
|
42
42
|
initializer_args.unshift connection_name if connection_name
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
klass = Class.new Cool.io::TCPSocket
|
|
45
45
|
connection_builder = ConnectionBuilder.new klass
|
|
46
|
-
connection_builder.instance_eval
|
|
46
|
+
connection_builder.instance_eval(&block)
|
|
47
47
|
else
|
|
48
48
|
raise ArgumentError, "no connection name or block given" unless connection_name
|
|
49
49
|
klass = self[connection_name]
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
server = Cool.io::TCPServer.new host, port, klass, *initializer_args
|
|
53
53
|
server.attach Cool.io::Loop.default
|
|
54
54
|
server
|
|
55
55
|
end
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
# Create a new Cool.io::TCPSocket class
|
|
58
58
|
def connection(name, &block)
|
|
59
59
|
# Camelize class name
|
|
60
60
|
class_name = name.to_s.split('_').map { |s| s.capitalize }.join
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
connection = Class.new Cool.io::TCPSocket
|
|
63
63
|
connection_builder = ConnectionBuilder.new connection
|
|
64
|
-
connection_builder.instance_eval
|
|
65
|
-
|
|
64
|
+
connection_builder.instance_eval(&block)
|
|
65
|
+
|
|
66
66
|
Coolio::Connections.const_set class_name, connection
|
|
67
67
|
end
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
# Look up a connection class by its name
|
|
70
70
|
def [](connection_name)
|
|
71
71
|
class_name = connection_name.to_s.split('_').map { |s| s.capitalize }.join
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
begin
|
|
74
74
|
Coolio::Connections.const_get class_name
|
|
75
75
|
rescue NameError
|
|
76
76
|
raise NameError, "No connection type registered for #{connection_name.inspect}"
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
# Builder for Cool.io::TCPSocket classes
|
|
81
81
|
class ConnectionBuilder
|
|
82
82
|
def initialize(klass)
|
|
83
83
|
@klass = klass
|
|
84
84
|
end
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
# Declare an initialize function
|
|
87
87
|
def initializer(&action)
|
|
88
88
|
@klass.send :define_method, :initialize, &action
|
|
89
89
|
end
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
# Declare the on_connect callback
|
|
92
92
|
def on_connect(&action)
|
|
93
93
|
@klass.send :define_method, :on_connect, &action
|
|
94
94
|
end
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
# Declare a callback fired if we failed to connect
|
|
97
97
|
def on_connect_failed(&action)
|
|
98
98
|
@klass.send :define_method, :on_connect_failed, &action
|
|
99
99
|
end
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
# Declare a callback fired if DNS resolution failed
|
|
102
102
|
def on_resolve_failed(&action)
|
|
103
103
|
@klass.send :define_method, :on_resolve_failed, &action
|
|
104
104
|
end
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
# Declare the on_close callback
|
|
107
107
|
def on_close(&action)
|
|
108
108
|
@klass.send :define_method, :on_close, &action
|
|
109
109
|
end
|
|
110
|
-
|
|
110
|
+
|
|
111
111
|
# Declare the on_read callback
|
|
112
112
|
def on_read(&action)
|
|
113
113
|
@klass.send :define_method, :on_read, &action
|
|
114
114
|
end
|
|
115
|
-
|
|
115
|
+
|
|
116
116
|
# Declare the on_write_complete callback
|
|
117
117
|
def on_write_complete(&action)
|
|
118
118
|
@klass.send :define_method, :on_write_complete, &action
|
|
@@ -124,12 +124,16 @@ end
|
|
|
124
124
|
# The Cool module containing all our coolness
|
|
125
125
|
module Cool
|
|
126
126
|
module Coolness
|
|
127
|
-
def cool
|
|
127
|
+
def cool
|
|
128
|
+
Cool::IOThunk
|
|
129
|
+
end
|
|
128
130
|
end
|
|
129
|
-
|
|
131
|
+
|
|
130
132
|
module IOThunk
|
|
131
|
-
def self.io
|
|
133
|
+
def self.io
|
|
134
|
+
Coolio::DSL
|
|
135
|
+
end
|
|
132
136
|
end
|
|
133
137
|
end
|
|
134
138
|
|
|
135
|
-
extend Cool::Coolness
|
|
139
|
+
extend Cool::Coolness
|