eventmachine-eventmachine 0.12.7 → 0.12.8
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.
- data/{docs/README → README} +21 -13
- data/Rakefile +14 -4
- data/docs/DEFERRABLES +0 -5
- data/docs/INSTALL +2 -4
- data/docs/LEGAL +1 -1
- data/docs/LIGHTWEIGHT_CONCURRENCY +0 -2
- data/docs/PURE_RUBY +0 -2
- data/docs/RELEASE_NOTES +0 -2
- data/docs/SMTP +0 -7
- data/docs/SPAWNED_PROCESSES +0 -4
- data/docs/TODO +0 -2
- data/eventmachine.gemspec +17 -8
- data/examples/ex_channel.rb +43 -0
- data/examples/ex_queue.rb +2 -0
- data/examples/helper.rb +2 -0
- data/ext/cmain.cpp +119 -20
- data/ext/cplusplus.cpp +15 -6
- data/ext/ed.cpp +303 -93
- data/ext/ed.h +49 -22
- data/ext/em.cpp +368 -42
- data/ext/em.h +43 -6
- data/ext/eventmachine.h +21 -8
- data/ext/eventmachine_cpp.h +1 -0
- data/ext/extconf.rb +4 -0
- data/ext/kb.cpp +1 -2
- data/ext/pipe.cpp +1 -3
- data/ext/project.h +21 -0
- data/ext/rubymain.cpp +232 -32
- data/ext/ssl.cpp +38 -1
- data/ext/ssl.h +5 -1
- data/java/src/com/rubyeventmachine/Application.java +7 -3
- data/java/src/com/rubyeventmachine/EmReactor.java +16 -1
- data/java/src/com/rubyeventmachine/tests/ConnectTest.java +25 -3
- data/lib/{protocols → em}/buftok.rb +16 -5
- data/lib/em/callback.rb +26 -0
- data/lib/em/channel.rb +57 -0
- data/lib/em/connection.rb +505 -0
- data/lib/em/deferrable.rb +144 -165
- data/lib/em/file_watch.rb +54 -0
- data/lib/em/future.rb +24 -25
- data/lib/em/messages.rb +1 -1
- data/lib/em/process_watch.rb +44 -0
- data/lib/em/processes.rb +58 -52
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +263 -0
- data/lib/em/protocols/httpclient2.rb +582 -0
- data/lib/{protocols → em/protocols}/line_and_text.rb +2 -2
- data/lib/em/protocols/linetext2.rb +160 -0
- data/lib/{protocols → em/protocols}/memcache.rb +37 -7
- data/lib/em/protocols/object_protocol.rb +39 -0
- data/lib/em/protocols/postgres3.rb +247 -0
- data/lib/em/protocols/saslauth.rb +175 -0
- data/lib/em/protocols/smtpclient.rb +331 -0
- data/lib/em/protocols/smtpserver.rb +547 -0
- data/lib/em/protocols/stomp.rb +200 -0
- data/lib/{protocols → em/protocols}/tcptest.rb +21 -25
- data/lib/em/protocols.rb +35 -0
- data/lib/em/queue.rb +61 -0
- data/lib/em/spawnable.rb +53 -56
- data/lib/em/streamer.rb +92 -74
- data/lib/em/timers.rb +55 -0
- data/lib/em/version.rb +3 -0
- data/lib/eventmachine.rb +1008 -1298
- data/lib/evma.rb +1 -1
- data/lib/jeventmachine.rb +106 -101
- data/lib/pr_eventmachine.rb +47 -36
- data/tasks/project.rake +2 -1
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/test_attach.rb +18 -0
- data/tests/test_basic.rb +108 -54
- data/tests/test_channel.rb +63 -0
- data/tests/test_connection_count.rb +2 -2
- data/tests/test_epoll.rb +109 -110
- data/tests/test_errors.rb +36 -36
- data/tests/test_exc.rb +22 -25
- data/tests/test_file_watch.rb +49 -0
- data/tests/test_futures.rb +77 -93
- data/tests/test_hc.rb +2 -2
- data/tests/test_httpclient.rb +55 -52
- data/tests/test_httpclient2.rb +110 -112
- data/tests/test_inactivity_timeout.rb +30 -0
- data/tests/test_kb.rb +8 -9
- data/tests/test_ltp2.rb +274 -277
- data/tests/test_next_tick.rb +91 -65
- data/tests/test_object_protocol.rb +37 -0
- data/tests/test_process_watch.rb +48 -0
- data/tests/test_processes.rb +56 -23
- data/tests/test_proxy_connection.rb +92 -0
- data/tests/test_pure.rb +1 -5
- data/tests/test_queue.rb +44 -0
- data/tests/test_running.rb +9 -14
- data/tests/test_sasl.rb +32 -34
- data/tests/test_send_file.rb +175 -176
- data/tests/test_servers.rb +37 -41
- data/tests/test_smtpserver.rb +47 -55
- data/tests/test_spawn.rb +284 -291
- data/tests/test_ssl_args.rb +1 -1
- data/tests/test_ssl_methods.rb +1 -1
- data/tests/test_ssl_verify.rb +82 -0
- data/tests/test_timers.rb +81 -88
- data/tests/test_ud.rb +0 -7
- data/tests/testem.rb +1 -1
- metadata +53 -37
- data/lib/em/eventable.rb +0 -39
- data/lib/eventmachine_version.rb +0 -31
- data/lib/protocols/header_and_content.rb +0 -129
- data/lib/protocols/httpcli2.rb +0 -803
- data/lib/protocols/httpclient.rb +0 -270
- data/lib/protocols/linetext2.rb +0 -161
- data/lib/protocols/postgres.rb +0 -261
- data/lib/protocols/saslauth.rb +0 -179
- data/lib/protocols/smtpclient.rb +0 -308
- data/lib/protocols/smtpserver.rb +0 -556
- data/lib/protocols/stomp.rb +0 -153
- data/tests/test_eventables.rb +0 -77
data/ext/eventmachine.h
CHANGED
|
@@ -33,7 +33,9 @@ extern "C" {
|
|
|
33
33
|
EM_LOOPBREAK_SIGNAL = 105,
|
|
34
34
|
EM_CONNECTION_NOTIFY_READABLE = 106,
|
|
35
35
|
EM_CONNECTION_NOTIFY_WRITABLE = 107,
|
|
36
|
-
EM_SSL_HANDSHAKE_COMPLETED = 108
|
|
36
|
+
EM_SSL_HANDSHAKE_COMPLETED = 108,
|
|
37
|
+
EM_SSL_VERIFY = 109,
|
|
38
|
+
EM_PROXY_TARGET_UNBOUND = 110
|
|
37
39
|
|
|
38
40
|
};
|
|
39
41
|
|
|
@@ -41,7 +43,7 @@ extern "C" {
|
|
|
41
43
|
void evma_run_machine();
|
|
42
44
|
void evma_release_library();
|
|
43
45
|
const char *evma_install_oneshot_timer (int seconds);
|
|
44
|
-
const char *evma_connect_to_server (const char *server, int port);
|
|
46
|
+
const char *evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port);
|
|
45
47
|
const char *evma_connect_to_unix_server (const char *server);
|
|
46
48
|
|
|
47
49
|
const char *evma_attach_fd (int file_descriptor, int read_mode, int write_mode);
|
|
@@ -52,11 +54,12 @@ extern "C" {
|
|
|
52
54
|
const char *evma_create_unix_domain_server (const char *filename);
|
|
53
55
|
const char *evma_open_datagram_socket (const char *server, int port);
|
|
54
56
|
const char *evma_open_keyboard();
|
|
55
|
-
void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filenane);
|
|
57
|
+
void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filenane, int verify_peer);
|
|
56
58
|
void evma_start_tls (const char *binding);
|
|
57
59
|
|
|
58
60
|
#ifdef WITH_SSL
|
|
59
61
|
X509 *evma_get_peer_cert (const char *binding);
|
|
62
|
+
void evma_accept_ssl_peer (const char *binding);
|
|
60
63
|
#endif
|
|
61
64
|
|
|
62
65
|
int evma_get_peername (const char *binding, struct sockaddr*);
|
|
@@ -66,8 +69,8 @@ extern "C" {
|
|
|
66
69
|
int evma_get_connection_count();
|
|
67
70
|
int evma_send_data_to_connection (const char *binding, const char *data, int data_length);
|
|
68
71
|
int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port);
|
|
69
|
-
|
|
70
|
-
int evma_set_comm_inactivity_timeout (const char *binding,
|
|
72
|
+
float evma_get_comm_inactivity_timeout (const char *binding);
|
|
73
|
+
int evma_set_comm_inactivity_timeout (const char *binding, float value);
|
|
71
74
|
int evma_get_outbound_data_size (const char *binding);
|
|
72
75
|
int evma_send_file_data_to_connection (const char *binding, const char *filename);
|
|
73
76
|
|
|
@@ -79,15 +82,25 @@ extern "C" {
|
|
|
79
82
|
void evma_set_max_timer_count (int);
|
|
80
83
|
void evma_setuid_string (const char *username);
|
|
81
84
|
void evma_stop_machine();
|
|
85
|
+
float evma_get_heartbeat_interval();
|
|
86
|
+
int evma_set_heartbeat_interval(float);
|
|
82
87
|
|
|
83
88
|
const char *evma__write_file (const char *filename);
|
|
84
89
|
const char *evma_popen (char * const*cmd_strings);
|
|
85
90
|
|
|
91
|
+
const char *evma_watch_filename (const char *fname);
|
|
92
|
+
void evma_unwatch_filename (const char *sig);
|
|
93
|
+
|
|
94
|
+
const char *evma_watch_pid (int);
|
|
95
|
+
void evma_unwatch_pid (const char *sig);
|
|
96
|
+
|
|
97
|
+
void evma_start_proxy(const char*, const char*);
|
|
98
|
+
void evma_stop_proxy(const char*);
|
|
99
|
+
|
|
86
100
|
int evma_set_rlimit_nofile (int n_files);
|
|
87
101
|
|
|
88
|
-
|
|
89
|
-
void
|
|
90
|
-
void evma__kqueue();
|
|
102
|
+
void evma_set_epoll (int use);
|
|
103
|
+
void evma_set_kqueue (int use);
|
|
91
104
|
|
|
92
105
|
#if __cplusplus
|
|
93
106
|
}
|
data/ext/eventmachine_cpp.h
CHANGED
data/ext/extconf.rb
CHANGED
|
@@ -15,6 +15,9 @@ end
|
|
|
15
15
|
add_define 'BUILD_FOR_RUBY'
|
|
16
16
|
add_define 'HAVE_RBTRAP' if have_var('rb_trap_immediate', ['ruby.h', 'rubysig.h'])
|
|
17
17
|
add_define "HAVE_TBR" if have_func('rb_thread_blocking_region')# and have_macro('RUBY_UBF_IO', 'ruby.h')
|
|
18
|
+
add_define "HAVE_INOTIFY" if inotify = have_func('inotify_init', 'sys/inotify.h')
|
|
19
|
+
add_define "HAVE_OLD_INOTIFY" if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h')
|
|
20
|
+
add_define 'HAVE_WRITEV' if have_func('writev', 'sys/uio.h')
|
|
18
21
|
|
|
19
22
|
# Minor platform details between *nix and Windows:
|
|
20
23
|
|
|
@@ -59,6 +62,7 @@ when /solaris/
|
|
|
59
62
|
# on Unix we need a g++ link, not gcc.
|
|
60
63
|
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
|
61
64
|
end
|
|
65
|
+
|
|
62
66
|
when /openbsd/
|
|
63
67
|
# OpenBSD branch contributed by Guillaume Sellier.
|
|
64
68
|
|
data/ext/kb.cpp
CHANGED
data/ext/pipe.cpp
CHANGED
|
@@ -164,7 +164,6 @@ void PipeDescriptor::Read()
|
|
|
164
164
|
|
|
165
165
|
if (r > 0) {
|
|
166
166
|
total_bytes_read += r;
|
|
167
|
-
LastRead = gCurrentLoopTime;
|
|
168
167
|
|
|
169
168
|
// Add a null-terminator at the the end of the buffer
|
|
170
169
|
// that we will send to the callback.
|
|
@@ -173,8 +172,7 @@ void PipeDescriptor::Read()
|
|
|
173
172
|
// the option to do some things faster. Additionally it's
|
|
174
173
|
// a security guard against buffer overflows.
|
|
175
174
|
readbuffer [r] = 0;
|
|
176
|
-
|
|
177
|
-
(*EventCallback)(GetBinding().c_str(), EM_CONNECTION_READ, readbuffer, r);
|
|
175
|
+
_GenericInboundDispatch(readbuffer, r);
|
|
178
176
|
}
|
|
179
177
|
else if (r == 0) {
|
|
180
178
|
break;
|
data/ext/project.h
CHANGED
|
@@ -102,6 +102,27 @@ using namespace std;
|
|
|
102
102
|
#include <sys/queue.h>
|
|
103
103
|
#endif
|
|
104
104
|
|
|
105
|
+
#ifdef HAVE_INOTIFY
|
|
106
|
+
#include <sys/inotify.h>
|
|
107
|
+
#endif
|
|
108
|
+
|
|
109
|
+
#ifdef HAVE_OLD_INOTIFY
|
|
110
|
+
#include <sys/syscall.h>
|
|
111
|
+
#include <linux/inotify.h>
|
|
112
|
+
static inline int inotify_init (void) { return syscall (__NR_inotify_init); }
|
|
113
|
+
static inline int inotify_add_watch (int fd, const char *name, __u32 mask) { return syscall (__NR_inotify_add_watch, fd, name, mask); }
|
|
114
|
+
static inline int inotify_rm_watch (int fd, __u32 wd) { return syscall (__NR_inotify_rm_watch, fd, wd); }
|
|
115
|
+
#define HAVE_INOTIFY 1
|
|
116
|
+
#endif
|
|
117
|
+
|
|
118
|
+
#ifdef HAVE_INOTIFY
|
|
119
|
+
#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
|
|
120
|
+
#endif
|
|
121
|
+
|
|
122
|
+
#ifdef HAVE_WRITEV
|
|
123
|
+
#include <sys/uio.h>
|
|
124
|
+
#endif
|
|
125
|
+
|
|
105
126
|
#include "binder.h"
|
|
106
127
|
#include "em.h"
|
|
107
128
|
#include "epoll.h"
|
data/ext/rubymain.cpp
CHANGED
|
@@ -21,7 +21,9 @@ See the file COPYING for complete licensing information.
|
|
|
21
21
|
#include "eventmachine.h"
|
|
22
22
|
#include <ruby.h>
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
#ifndef RFLOAT_VALUE
|
|
25
|
+
#define RFLOAT_VALUE(arg) RFLOAT(arg)->value
|
|
26
|
+
#endif
|
|
25
27
|
|
|
26
28
|
/*******
|
|
27
29
|
Statics
|
|
@@ -43,8 +45,10 @@ static VALUE Intern_delete;
|
|
|
43
45
|
static VALUE Intern_call;
|
|
44
46
|
static VALUE Intern_receive_data;
|
|
45
47
|
static VALUE Intern_ssl_handshake_completed;
|
|
48
|
+
static VALUE Intern_ssl_verify_peer;
|
|
46
49
|
static VALUE Intern_notify_readable;
|
|
47
50
|
static VALUE Intern_notify_writable;
|
|
51
|
+
static VALUE Intern_proxy_target_unbound;
|
|
48
52
|
|
|
49
53
|
static VALUE rb_cProcStatus;
|
|
50
54
|
|
|
@@ -93,10 +97,15 @@ static void event_callback (struct em_event* e)
|
|
|
93
97
|
else if (a2 == EM_TIMER_FIRED) {
|
|
94
98
|
VALUE t = rb_ivar_get (EmModule, Intern_at_timers);
|
|
95
99
|
VALUE q = rb_funcall (t, Intern_delete, 1, rb_str_new(a3, a4));
|
|
96
|
-
if (q == Qnil)
|
|
100
|
+
if (q == Qnil) {
|
|
97
101
|
rb_raise (EM_eUnknownTimerFired, "no such timer: %s", a1);
|
|
98
|
-
|
|
102
|
+
} else if (q == Qfalse) {
|
|
103
|
+
/* Timer Canceled */
|
|
104
|
+
} else {
|
|
105
|
+
rb_funcall (q, Intern_call, 0);
|
|
106
|
+
}
|
|
99
107
|
}
|
|
108
|
+
#ifdef WITH_SSL
|
|
100
109
|
else if (a2 == EM_SSL_HANDSHAKE_COMPLETED) {
|
|
101
110
|
VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
|
|
102
111
|
VALUE q = rb_hash_aref (t, rb_str_new2(a1));
|
|
@@ -104,6 +113,23 @@ static void event_callback (struct em_event* e)
|
|
|
104
113
|
rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
|
|
105
114
|
rb_funcall (q, Intern_ssl_handshake_completed, 0);
|
|
106
115
|
}
|
|
116
|
+
else if (a2 == EM_SSL_VERIFY) {
|
|
117
|
+
VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
|
|
118
|
+
VALUE q = rb_hash_aref (t, rb_str_new2(a1));
|
|
119
|
+
if (q == Qnil)
|
|
120
|
+
rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
|
|
121
|
+
VALUE r = rb_funcall (q, Intern_ssl_verify_peer, 1, rb_str_new(a3, a4));
|
|
122
|
+
if (RTEST(r))
|
|
123
|
+
evma_accept_ssl_peer (a1);
|
|
124
|
+
}
|
|
125
|
+
#endif
|
|
126
|
+
else if (a2 == EM_PROXY_TARGET_UNBOUND) {
|
|
127
|
+
VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
|
|
128
|
+
VALUE q = rb_hash_aref (t, rb_str_new2(a1));
|
|
129
|
+
if (q == Qnil)
|
|
130
|
+
rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
|
|
131
|
+
rb_funcall (q, Intern_proxy_target_unbound, 0);
|
|
132
|
+
}
|
|
107
133
|
else
|
|
108
134
|
rb_funcall (EmModule, Intern_event_callback, 3, rb_str_new2(a1), (a2 << 1) | 1, rb_str_new(a3,a4));
|
|
109
135
|
}
|
|
@@ -234,20 +260,20 @@ static VALUE t_start_tls (VALUE self, VALUE signature)
|
|
|
234
260
|
t_set_tls_parms
|
|
235
261
|
***************/
|
|
236
262
|
|
|
237
|
-
static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile)
|
|
263
|
+
static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer)
|
|
238
264
|
{
|
|
239
265
|
/* set_tls_parms takes a series of positional arguments for specifying such things
|
|
240
266
|
* as private keys and certificate chains.
|
|
241
267
|
* It's expected that the parameter list will grow as we add more supported features.
|
|
242
268
|
* ALL of these parameters are optional, and can be specified as empty or NULL strings.
|
|
243
269
|
*/
|
|
244
|
-
evma_set_tls_parms (StringValuePtr (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile) );
|
|
270
|
+
evma_set_tls_parms (StringValuePtr (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
|
|
245
271
|
return Qnil;
|
|
246
272
|
}
|
|
247
273
|
|
|
248
|
-
|
|
274
|
+
/***************
|
|
249
275
|
t_get_peer_cert
|
|
250
|
-
|
|
276
|
+
***************/
|
|
251
277
|
|
|
252
278
|
static VALUE t_get_peer_cert (VALUE self, VALUE signature)
|
|
253
279
|
{
|
|
@@ -352,10 +378,7 @@ t_get_comm_inactivity_timeout
|
|
|
352
378
|
|
|
353
379
|
static VALUE t_get_comm_inactivity_timeout (VALUE self, VALUE signature)
|
|
354
380
|
{
|
|
355
|
-
|
|
356
|
-
if (evma_get_comm_inactivity_timeout (StringValuePtr (signature), &timeout))
|
|
357
|
-
return INT2FIX (timeout);
|
|
358
|
-
return Qnil;
|
|
381
|
+
return rb_float_new(evma_get_comm_inactivity_timeout(StringValuePtr(signature)));
|
|
359
382
|
}
|
|
360
383
|
|
|
361
384
|
/*****************************
|
|
@@ -364,10 +387,10 @@ t_set_comm_inactivity_timeout
|
|
|
364
387
|
|
|
365
388
|
static VALUE t_set_comm_inactivity_timeout (VALUE self, VALUE signature, VALUE timeout)
|
|
366
389
|
{
|
|
367
|
-
|
|
368
|
-
if (evma_set_comm_inactivity_timeout (StringValuePtr (signature),
|
|
390
|
+
float ti = RFLOAT_VALUE(timeout);
|
|
391
|
+
if (evma_set_comm_inactivity_timeout (StringValuePtr (signature), ti));
|
|
369
392
|
return Qtrue;
|
|
370
|
-
return
|
|
393
|
+
return Qfalse;
|
|
371
394
|
}
|
|
372
395
|
|
|
373
396
|
|
|
@@ -414,12 +437,33 @@ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
|
|
|
414
437
|
// Specifically, if the value of port comes in as a string rather than an integer,
|
|
415
438
|
// NUM2INT will throw a type error, but FIX2INT will generate garbage.
|
|
416
439
|
|
|
417
|
-
const char *f = evma_connect_to_server (StringValuePtr(server), NUM2INT(port));
|
|
440
|
+
const char *f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
|
|
418
441
|
if (!f || !*f)
|
|
419
442
|
rb_raise (rb_eRuntimeError, "no connection");
|
|
420
443
|
return rb_str_new2 (f);
|
|
421
444
|
}
|
|
422
445
|
|
|
446
|
+
/*********************
|
|
447
|
+
t_bind_connect_server
|
|
448
|
+
*********************/
|
|
449
|
+
|
|
450
|
+
static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port, VALUE server, VALUE port)
|
|
451
|
+
{
|
|
452
|
+
// Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
|
|
453
|
+
// Specifically, if the value of port comes in as a string rather than an integer,
|
|
454
|
+
// NUM2INT will throw a type error, but FIX2INT will generate garbage.
|
|
455
|
+
|
|
456
|
+
const char *f;
|
|
457
|
+
try {
|
|
458
|
+
f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
|
|
459
|
+
if (!f || !*f)
|
|
460
|
+
rb_raise (rb_eRuntimeError, "no connection");
|
|
461
|
+
} catch (std::runtime_error e) {
|
|
462
|
+
rb_sys_fail(e.what());
|
|
463
|
+
}
|
|
464
|
+
return rb_str_new2 (f);
|
|
465
|
+
}
|
|
466
|
+
|
|
423
467
|
/*********************
|
|
424
468
|
t_connect_unix_server
|
|
425
469
|
*********************/
|
|
@@ -609,17 +653,56 @@ static VALUE t_read_keyboard (VALUE self)
|
|
|
609
653
|
}
|
|
610
654
|
|
|
611
655
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
656
|
+
/****************
|
|
657
|
+
t_watch_filename
|
|
658
|
+
****************/
|
|
615
659
|
|
|
616
|
-
static VALUE
|
|
660
|
+
static VALUE t_watch_filename (VALUE self, VALUE fname)
|
|
661
|
+
{
|
|
662
|
+
try {
|
|
663
|
+
return rb_str_new2(evma_watch_filename(StringValuePtr(fname)));
|
|
664
|
+
} catch (std::runtime_error e) {
|
|
665
|
+
rb_sys_fail(e.what());
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
/******************
|
|
671
|
+
t_unwatch_filename
|
|
672
|
+
******************/
|
|
673
|
+
|
|
674
|
+
static VALUE t_unwatch_filename (VALUE self, VALUE sig)
|
|
617
675
|
{
|
|
618
|
-
|
|
619
|
-
evma__epoll();
|
|
676
|
+
evma_unwatch_filename(StringValuePtr(sig));
|
|
620
677
|
return Qnil;
|
|
621
678
|
}
|
|
622
679
|
|
|
680
|
+
|
|
681
|
+
/***********
|
|
682
|
+
t_watch_pid
|
|
683
|
+
***********/
|
|
684
|
+
|
|
685
|
+
static VALUE t_watch_pid (VALUE self, VALUE pid)
|
|
686
|
+
{
|
|
687
|
+
try {
|
|
688
|
+
return rb_str_new2(evma_watch_pid(NUM2INT(pid)));
|
|
689
|
+
} catch (std::runtime_error e) {
|
|
690
|
+
rb_sys_fail(e.what());
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
/*************
|
|
696
|
+
t_unwatch_pid
|
|
697
|
+
*************/
|
|
698
|
+
|
|
699
|
+
static VALUE t_unwatch_pid (VALUE self, VALUE sig)
|
|
700
|
+
{
|
|
701
|
+
evma_unwatch_pid(StringValuePtr(sig));
|
|
702
|
+
return Qnil;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
|
|
623
706
|
/**********
|
|
624
707
|
t__epoll_p
|
|
625
708
|
**********/
|
|
@@ -633,18 +716,33 @@ static VALUE t__epoll_p (VALUE self)
|
|
|
633
716
|
#endif
|
|
634
717
|
}
|
|
635
718
|
|
|
719
|
+
/********
|
|
720
|
+
t__epoll
|
|
721
|
+
********/
|
|
636
722
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
723
|
+
static VALUE t__epoll (VALUE self)
|
|
724
|
+
{
|
|
725
|
+
if (t__epoll_p(self) == Qfalse)
|
|
726
|
+
return Qfalse;
|
|
640
727
|
|
|
641
|
-
|
|
728
|
+
evma_set_epoll (1);
|
|
729
|
+
return Qtrue;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/***********
|
|
733
|
+
t__epoll_set
|
|
734
|
+
***********/
|
|
735
|
+
|
|
736
|
+
static VALUE t__epoll_set (VALUE self, VALUE val)
|
|
642
737
|
{
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
738
|
+
if (t__epoll_p(self) == Qfalse)
|
|
739
|
+
return Qfalse;
|
|
740
|
+
|
|
741
|
+
evma_set_epoll (val == Qtrue ? 1 : 0);
|
|
742
|
+
return val;
|
|
646
743
|
}
|
|
647
744
|
|
|
745
|
+
|
|
648
746
|
/***********
|
|
649
747
|
t__kqueue_p
|
|
650
748
|
***********/
|
|
@@ -658,6 +756,46 @@ static VALUE t__kqueue_p (VALUE self)
|
|
|
658
756
|
#endif
|
|
659
757
|
}
|
|
660
758
|
|
|
759
|
+
/*********
|
|
760
|
+
t__kqueue
|
|
761
|
+
*********/
|
|
762
|
+
|
|
763
|
+
static VALUE t__kqueue (VALUE self)
|
|
764
|
+
{
|
|
765
|
+
if (t__kqueue_p(self) == Qfalse)
|
|
766
|
+
return Qfalse;
|
|
767
|
+
|
|
768
|
+
evma_set_kqueue (1);
|
|
769
|
+
return Qtrue;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/*************
|
|
773
|
+
t__kqueue_set
|
|
774
|
+
*************/
|
|
775
|
+
|
|
776
|
+
static VALUE t__kqueue_set (VALUE self, VALUE val)
|
|
777
|
+
{
|
|
778
|
+
if (t__kqueue_p(self) == Qfalse)
|
|
779
|
+
return Qfalse;
|
|
780
|
+
|
|
781
|
+
evma_set_kqueue (val == Qtrue ? 1 : 0);
|
|
782
|
+
return val;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
/********
|
|
787
|
+
t__ssl_p
|
|
788
|
+
********/
|
|
789
|
+
|
|
790
|
+
static VALUE t__ssl_p (VALUE self)
|
|
791
|
+
{
|
|
792
|
+
#ifdef WITH_SSL
|
|
793
|
+
return Qtrue;
|
|
794
|
+
#else
|
|
795
|
+
return Qfalse;
|
|
796
|
+
#endif
|
|
797
|
+
}
|
|
798
|
+
|
|
661
799
|
|
|
662
800
|
/****************
|
|
663
801
|
t_send_file_data
|
|
@@ -739,6 +877,51 @@ static VALUE t_get_loop_time (VALUE self)
|
|
|
739
877
|
}
|
|
740
878
|
|
|
741
879
|
|
|
880
|
+
/*************
|
|
881
|
+
t_start_proxy
|
|
882
|
+
**************/
|
|
883
|
+
|
|
884
|
+
static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to)
|
|
885
|
+
{
|
|
886
|
+
evma_start_proxy(StringValuePtr(from), StringValuePtr(to));
|
|
887
|
+
return Qnil;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
/************
|
|
892
|
+
t_stop_proxy
|
|
893
|
+
*************/
|
|
894
|
+
|
|
895
|
+
static VALUE t_stop_proxy (VALUE self, VALUE from)
|
|
896
|
+
{
|
|
897
|
+
evma_stop_proxy(StringValuePtr(from));
|
|
898
|
+
return Qnil;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
/************************
|
|
903
|
+
t_get_heartbeat_interval
|
|
904
|
+
*************************/
|
|
905
|
+
|
|
906
|
+
static VALUE t_get_heartbeat_interval (VALUE self)
|
|
907
|
+
{
|
|
908
|
+
return rb_float_new(evma_get_heartbeat_interval());
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
/************************
|
|
913
|
+
t_set_heartbeat_interval
|
|
914
|
+
*************************/
|
|
915
|
+
|
|
916
|
+
static VALUE t_set_heartbeat_interval (VALUE self, VALUE interval)
|
|
917
|
+
{
|
|
918
|
+
float iv = RFLOAT_VALUE(interval);
|
|
919
|
+
if (evma_set_heartbeat_interval(iv))
|
|
920
|
+
return Qtrue;
|
|
921
|
+
return Qfalse;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
|
|
742
925
|
/*********************
|
|
743
926
|
Init_rubyeventmachine
|
|
744
927
|
*********************/
|
|
@@ -761,8 +944,10 @@ extern "C" void Init_rubyeventmachine()
|
|
|
761
944
|
Intern_call = rb_intern ("call");
|
|
762
945
|
Intern_receive_data = rb_intern ("receive_data");
|
|
763
946
|
Intern_ssl_handshake_completed = rb_intern ("ssl_handshake_completed");
|
|
947
|
+
Intern_ssl_verify_peer = rb_intern ("ssl_verify_peer");
|
|
764
948
|
Intern_notify_readable = rb_intern ("notify_readable");
|
|
765
949
|
Intern_notify_writable = rb_intern ("notify_writable");
|
|
950
|
+
Intern_proxy_target_unbound = rb_intern ("proxy_target_unbound");
|
|
766
951
|
|
|
767
952
|
// INCOMPLETE, we need to define class Connections inside module EventMachine
|
|
768
953
|
// run_machine and run_machine_without_threads are now identical.
|
|
@@ -781,7 +966,7 @@ extern "C" void Init_rubyeventmachine()
|
|
|
781
966
|
rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
|
|
782
967
|
rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
|
|
783
968
|
rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
|
|
784
|
-
rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms,
|
|
969
|
+
rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 4);
|
|
785
970
|
rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
|
|
786
971
|
rb_define_module_function (EmModule, "get_peer_cert", (VALUE(*)(...))t_get_peer_cert, 1);
|
|
787
972
|
rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
|
|
@@ -789,11 +974,21 @@ extern "C" void Init_rubyeventmachine()
|
|
|
789
974
|
rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2);
|
|
790
975
|
rb_define_module_function (EmModule, "report_connection_error_status", (VALUE(*)(...))t_report_connection_error_status, 1);
|
|
791
976
|
rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2);
|
|
977
|
+
rb_define_module_function (EmModule, "bind_connect_server", (VALUE(*)(...))t_bind_connect_server, 4);
|
|
792
978
|
rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1);
|
|
793
979
|
|
|
794
980
|
rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 3);
|
|
795
981
|
rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
|
|
796
982
|
|
|
983
|
+
rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 2);
|
|
984
|
+
rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
|
|
985
|
+
|
|
986
|
+
rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
|
|
987
|
+
rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1);
|
|
988
|
+
|
|
989
|
+
rb_define_module_function (EmModule, "watch_pid", (VALUE (*)(...))t_watch_pid, 1);
|
|
990
|
+
rb_define_module_function (EmModule, "unwatch_pid", (VALUE (*)(...))t_unwatch_pid, 1);
|
|
991
|
+
|
|
797
992
|
rb_define_module_function (EmModule, "current_time", (VALUE(*)(...))t_get_loop_time, 0);
|
|
798
993
|
|
|
799
994
|
rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2);
|
|
@@ -808,6 +1003,8 @@ extern "C" void Init_rubyeventmachine()
|
|
|
808
1003
|
rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
|
|
809
1004
|
rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
|
|
810
1005
|
rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
|
|
1006
|
+
rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
|
|
1007
|
+
rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
|
|
811
1008
|
|
|
812
1009
|
// Provisional:
|
|
813
1010
|
rb_define_module_function (EmModule, "_write_file", (VALUE(*)(...))t__write_file, 1);
|
|
@@ -821,13 +1018,16 @@ extern "C" void Init_rubyeventmachine()
|
|
|
821
1018
|
rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
|
|
822
1019
|
rb_define_module_function (EmModule, "get_connection_count", (VALUE(*)(...))t_get_connection_count, 0);
|
|
823
1020
|
|
|
824
|
-
// Temporary:
|
|
825
1021
|
rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0);
|
|
826
|
-
rb_define_module_function (EmModule, "
|
|
827
|
-
|
|
1022
|
+
rb_define_module_function (EmModule, "epoll=", (VALUE(*)(...))t__epoll_set, 1);
|
|
828
1023
|
rb_define_module_function (EmModule, "epoll?", (VALUE(*)(...))t__epoll_p, 0);
|
|
1024
|
+
|
|
1025
|
+
rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
|
|
1026
|
+
rb_define_module_function (EmModule, "kqueue=", (VALUE(*)(...))t__kqueue_set, 1);
|
|
829
1027
|
rb_define_module_function (EmModule, "kqueue?", (VALUE(*)(...))t__kqueue_p, 0);
|
|
830
1028
|
|
|
1029
|
+
rb_define_module_function (EmModule, "ssl?", (VALUE(*)(...))t__ssl_p, 0);
|
|
1030
|
+
|
|
831
1031
|
rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
|
|
832
1032
|
rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1);
|
|
833
1033
|
|
data/ext/ssl.cpp
CHANGED
|
@@ -208,9 +208,10 @@ SslContext_t::~SslContext_t()
|
|
|
208
208
|
SslBox_t::SslBox_t
|
|
209
209
|
******************/
|
|
210
210
|
|
|
211
|
-
SslBox_t::SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile):
|
|
211
|
+
SslBox_t::SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer, const char *binding):
|
|
212
212
|
bIsServer (is_server),
|
|
213
213
|
bHandshakeCompleted (false),
|
|
214
|
+
bVerifyPeer (verify_peer),
|
|
214
215
|
pSSL (NULL),
|
|
215
216
|
pbioRead (NULL),
|
|
216
217
|
pbioWrite (NULL)
|
|
@@ -232,6 +233,12 @@ SslBox_t::SslBox_t (bool is_server, const string &privkeyfile, const string &cer
|
|
|
232
233
|
assert (pSSL);
|
|
233
234
|
SSL_set_bio (pSSL, pbioRead, pbioWrite);
|
|
234
235
|
|
|
236
|
+
// Store a pointer to the binding signature in the SSL object so we can retrieve it later
|
|
237
|
+
SSL_set_ex_data(pSSL, 0, (void*) binding);
|
|
238
|
+
|
|
239
|
+
if (bVerifyPeer)
|
|
240
|
+
SSL_set_verify(pSSL, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, ssl_verify_wrapper);
|
|
241
|
+
|
|
235
242
|
if (!bIsServer)
|
|
236
243
|
SSL_connect (pSSL);
|
|
237
244
|
}
|
|
@@ -419,5 +426,35 @@ X509 *SslBox_t::GetPeerCert()
|
|
|
419
426
|
return cert;
|
|
420
427
|
}
|
|
421
428
|
|
|
429
|
+
|
|
430
|
+
/******************
|
|
431
|
+
ssl_verify_wrapper
|
|
432
|
+
*******************/
|
|
433
|
+
|
|
434
|
+
extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx)
|
|
435
|
+
{
|
|
436
|
+
const char *binding;
|
|
437
|
+
X509 *cert;
|
|
438
|
+
SSL *ssl;
|
|
439
|
+
BUF_MEM *buf;
|
|
440
|
+
BIO *out;
|
|
441
|
+
int result;
|
|
442
|
+
|
|
443
|
+
cert = X509_STORE_CTX_get_current_cert(ctx);
|
|
444
|
+
ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
|
|
445
|
+
binding = (const char*) SSL_get_ex_data(ssl, 0);
|
|
446
|
+
|
|
447
|
+
out = BIO_new(BIO_s_mem());
|
|
448
|
+
PEM_write_bio_X509(out, cert);
|
|
449
|
+
BIO_write(out, "\0", 1);
|
|
450
|
+
BIO_get_mem_ptr(out, &buf);
|
|
451
|
+
|
|
452
|
+
ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject(binding));
|
|
453
|
+
result = (cd->VerifySslPeer(buf->data) == true ? 1 : 0);
|
|
454
|
+
BUF_MEM_free(buf);
|
|
455
|
+
|
|
456
|
+
return result;
|
|
457
|
+
}
|
|
458
|
+
|
|
422
459
|
#endif // WITH_SSL
|
|
423
460
|
|
data/ext/ssl.h
CHANGED
|
@@ -57,7 +57,7 @@ class SslBox_t
|
|
|
57
57
|
class SslBox_t
|
|
58
58
|
{
|
|
59
59
|
public:
|
|
60
|
-
SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile);
|
|
60
|
+
SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer, const char *binding);
|
|
61
61
|
virtual ~SslBox_t();
|
|
62
62
|
|
|
63
63
|
int PutPlaintext (const char*, int);
|
|
@@ -75,6 +75,7 @@ class SslBox_t
|
|
|
75
75
|
protected:
|
|
76
76
|
SslContext_t *Context;
|
|
77
77
|
|
|
78
|
+
bool bVerifyPeer;
|
|
78
79
|
bool bIsServer;
|
|
79
80
|
bool bHandshakeCompleted;
|
|
80
81
|
SSL *pSSL;
|
|
@@ -83,6 +84,9 @@ class SslBox_t
|
|
|
83
84
|
|
|
84
85
|
PageList OutboundQ;
|
|
85
86
|
};
|
|
87
|
+
|
|
88
|
+
extern "C" int ssl_verify_wrapper(int, X509_STORE_CTX*);
|
|
89
|
+
|
|
86
90
|
#endif // WITH_SSL
|
|
87
91
|
|
|
88
92
|
|
|
@@ -128,16 +128,20 @@ public class Application {
|
|
|
128
128
|
reactor.timers.put(s, t);
|
|
129
129
|
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
public void
|
|
131
|
+
|
|
132
|
+
public void bindConnect (String bindAddr, int bindPort, String host, int port, Connection c) {
|
|
133
133
|
try {
|
|
134
|
-
String s = reactor.connectTcpServer(host, port);
|
|
134
|
+
String s = reactor.connectTcpServer(bindAddr, bindPort, host, port);
|
|
135
135
|
c.application = this;
|
|
136
136
|
c.signature = s;
|
|
137
137
|
reactor.connections.put(s, c);
|
|
138
138
|
c.postInit();
|
|
139
139
|
} catch (ClosedChannelException e) {}
|
|
140
140
|
}
|
|
141
|
+
|
|
142
|
+
public void connect (String host, int port, Connection c) {
|
|
143
|
+
bindConnect(null, 0, host, port, c);
|
|
144
|
+
}
|
|
141
145
|
|
|
142
146
|
public void startServer (SocketAddress sa, ConnectionFactory f) throws EmReactorException {
|
|
143
147
|
String s = reactor.startTcpServer(sa);
|