eventmachine 1.0.9.1-java → 1.2.0.1-java

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +2 -2
  4. data/ext/cmain.cpp +77 -5
  5. data/ext/ed.cpp +112 -42
  6. data/ext/ed.h +27 -13
  7. data/ext/em.cpp +105 -163
  8. data/ext/em.h +10 -7
  9. data/ext/eventmachine.h +13 -1
  10. data/ext/extconf.rb +23 -14
  11. data/ext/fastfilereader/extconf.rb +1 -2
  12. data/ext/fastfilereader/rubymain.cpp +6 -6
  13. data/ext/project.h +9 -4
  14. data/ext/rubymain.cpp +155 -36
  15. data/ext/ssl.cpp +157 -13
  16. data/ext/ssl.h +7 -2
  17. data/lib/em/channel.rb +5 -0
  18. data/lib/em/completion.rb +2 -2
  19. data/lib/em/connection.rb +61 -3
  20. data/lib/em/iterator.rb +26 -5
  21. data/lib/em/pool.rb +1 -1
  22. data/lib/em/protocols/line_and_text.rb +1 -1
  23. data/lib/em/pure_ruby.rb +6 -1
  24. data/lib/em/queue.rb +16 -7
  25. data/lib/em/resolver.rb +46 -23
  26. data/lib/em/threaded_resource.rb +2 -2
  27. data/lib/em/version.rb +1 -1
  28. data/lib/eventmachine.rb +59 -42
  29. data/lib/rubyeventmachine.jar +0 -0
  30. data/rakelib/package.rake +23 -1
  31. data/tests/dhparam.pem +13 -0
  32. data/tests/em_test_helper.rb +79 -0
  33. data/tests/test_basic.rb +17 -26
  34. data/tests/test_channel.rb +14 -1
  35. data/tests/test_connection_write.rb +2 -2
  36. data/tests/test_defer.rb +17 -0
  37. data/tests/test_epoll.rb +1 -1
  38. data/tests/test_fork.rb +75 -0
  39. data/tests/test_ipv4.rb +125 -0
  40. data/tests/test_ipv6.rb +131 -0
  41. data/tests/test_iterator.rb +18 -0
  42. data/tests/test_many_fds.rb +1 -1
  43. data/tests/test_queue.rb +14 -0
  44. data/tests/test_resolver.rb +23 -0
  45. data/tests/test_set_sock_opt.rb +2 -0
  46. data/tests/test_ssl_dhparam.rb +83 -0
  47. data/tests/test_ssl_ecdh_curve.rb +79 -0
  48. data/tests/test_ssl_extensions.rb +49 -0
  49. data/tests/test_ssl_methods.rb +19 -0
  50. data/tests/test_ssl_protocols.rb +246 -0
  51. data/tests/test_ssl_verify.rb +44 -0
  52. data/tests/test_system.rb +4 -0
  53. data/tests/test_unbind_reason.rb +5 -1
  54. metadata +101 -20
  55. data/.gitignore +0 -21
  56. data/.travis.yml +0 -22
  57. data/.yardopts +0 -7
  58. data/Gemfile +0 -2
  59. data/Rakefile +0 -20
  60. data/eventmachine.gemspec +0 -38
  61. data/rakelib/cpp.rake_example +0 -77
data/ext/em.h CHANGED
@@ -37,7 +37,7 @@ See the file COPYING for complete licensing information.
37
37
  #include <ruby/io.h>
38
38
  #endif
39
39
 
40
- #if defined(HAVE_RBTRAP)
40
+ #if defined(HAVE_RB_TRAP_IMMEDIATE)
41
41
  #include <rubysig.h>
42
42
  #elif defined(HAVE_RB_ENABLE_INTERRUPT)
43
43
  extern "C" {
@@ -69,7 +69,7 @@ See the file COPYING for complete licensing information.
69
69
  #define EmSelect select
70
70
  #endif
71
71
 
72
- #if !defined(HAVE_RB_FDSET_T)
72
+ #if !defined(HAVE_TYPE_RB_FDSET_T)
73
73
  #define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n)))
74
74
  // These definitions are cribbed from include/ruby/intern.h in Ruby 1.9.3,
75
75
  // with this change: any macros that read or write the nth element of an
@@ -140,6 +140,7 @@ class EventMachine_t
140
140
  bool RunOnce();
141
141
  void Run();
142
142
  void ScheduleHalt();
143
+ bool Stopping();
143
144
  void SignalLoopBreaker();
144
145
  const uintptr_t InstallOneshotTimer (int);
145
146
  const uintptr_t ConnectToServer (const char *, int, const char *, int);
@@ -148,7 +149,7 @@ class EventMachine_t
148
149
  const uintptr_t CreateTcpServer (const char *, int);
149
150
  const uintptr_t OpenDatagramSocket (const char *, int);
150
151
  const uintptr_t CreateUnixDomainServer (const char*);
151
- const uintptr_t AttachSD (int);
152
+ const uintptr_t AttachSD (SOCKET);
152
153
  const uintptr_t OpenKeyboard();
153
154
  //const char *Popen (const char*, const char*);
154
155
  const uintptr_t Socketpair (char* const*);
@@ -157,7 +158,7 @@ class EventMachine_t
157
158
  void Modify (EventableDescriptor*);
158
159
  void Deregister (EventableDescriptor*);
159
160
 
160
- const uintptr_t AttachFD (int, bool);
161
+ const uintptr_t AttachFD (SOCKET, bool);
161
162
  int DetachFD (EventableDescriptor*);
162
163
 
163
164
  void ArmKqueueWriter (EventableDescriptor*);
@@ -200,6 +201,8 @@ class EventMachine_t
200
201
 
201
202
  Poller_t GetPoller() { return Poller; }
202
203
 
204
+ static bool name2address (const char *server, int port, struct sockaddr *addr, size_t *addr_len);
205
+
203
206
  private:
204
207
  void _RunTimers();
205
208
  void _UpdateTime();
@@ -241,8 +244,8 @@ class EventMachine_t
241
244
  vector<EventableDescriptor*> NewDescriptors;
242
245
  set<EventableDescriptor*> ModifiedDescriptors;
243
246
 
244
- int LoopBreakerReader;
245
- int LoopBreakerWriter;
247
+ SOCKET LoopBreakerReader;
248
+ SOCKET LoopBreakerWriter;
246
249
  #ifdef OS_WIN32
247
250
  struct sockaddr_in LoopBreakerTarget;
248
251
  #endif
@@ -294,7 +297,7 @@ struct SelectData_t
294
297
  int _Select();
295
298
  void _Clear();
296
299
 
297
- int maxsocket;
300
+ SOCKET maxsocket;
298
301
  rb_fdset_t fdreads;
299
302
  rb_fdset_t fdwrites;
300
303
  rb_fdset_t fderrors;
data/ext/eventmachine.h CHANGED
@@ -37,7 +37,14 @@ extern "C" {
37
37
  EM_SSL_VERIFY = 109,
38
38
  EM_PROXY_TARGET_UNBOUND = 110,
39
39
  EM_PROXY_COMPLETED = 111
40
+ };
40
41
 
42
+ enum { // SSL/TLS Protocols
43
+ EM_PROTO_SSLv2 = 2,
44
+ EM_PROTO_SSLv3 = 4,
45
+ EM_PROTO_TLSv1 = 8,
46
+ EM_PROTO_TLSv1_1 = 16,
47
+ EM_PROTO_TLSv1_2 = 32
41
48
  };
42
49
 
43
50
  void evma_initialize_library (EMCallback);
@@ -68,11 +75,15 @@ extern "C" {
68
75
  const uintptr_t evma_attach_sd (int sd);
69
76
  const uintptr_t evma_open_datagram_socket (const char *server, int port);
70
77
  const uintptr_t evma_open_keyboard();
71
- void evma_set_tls_parms (const uintptr_t binding, const char *privatekey_filename, const char *certchain_filenane, int verify_peer);
78
+ void evma_set_tls_parms (const uintptr_t binding, const char *privatekey_filename, const char *certchain_filenane, int verify_peer, int fail_if_no_peer_cert, const char *sni_hostname, const char *cipherlist, const char *ecdh_curve, const char *dhparam, int protocols);
72
79
  void evma_start_tls (const uintptr_t binding);
73
80
 
74
81
  #ifdef WITH_SSL
75
82
  X509 *evma_get_peer_cert (const uintptr_t binding);
83
+ int evma_get_cipher_bits (const uintptr_t binding);
84
+ const char *evma_get_cipher_name (const uintptr_t binding);
85
+ const char *evma_get_cipher_protocol (const uintptr_t binding);
86
+ const char *evma_get_sni_hostname (const uintptr_t binding);
76
87
  void evma_accept_ssl_peer (const uintptr_t binding);
77
88
  #endif
78
89
 
@@ -101,6 +112,7 @@ extern "C" {
101
112
  void evma_set_simultaneous_accept_count (int);
102
113
  void evma_setuid_string (const char *username);
103
114
  void evma_stop_machine();
115
+ bool evma_stopping();
104
116
  float evma_get_heartbeat_interval();
105
117
  int evma_set_heartbeat_interval(float);
106
118
 
data/ext/extconf.rb CHANGED
@@ -103,22 +103,27 @@ elsif dir_config_search('OpenSSL', 'ssl', ['/usr/local', '/opt/local', '/usr/loc
103
103
  end
104
104
 
105
105
  add_define 'BUILD_FOR_RUBY'
106
- add_define 'HAVE_RBTRAP' if have_var('rb_trap_immediate', ['ruby.h', 'rubysig.h'])
107
- add_define "HAVE_TBR" if have_func('rb_thread_blocking_region')# and have_macro('RUBY_UBF_IO', 'ruby.h')
108
- add_define "HAVE_RB_THREAD_CALL_WITHOUT_GVL" if have_header('ruby/thread.h') && have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
109
- add_define "HAVE_INOTIFY" if inotify = have_func('inotify_init', 'sys/inotify.h')
110
- add_define "HAVE_OLD_INOTIFY" if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h')
111
- add_define 'HAVE_WRITEV' if have_func('writev', 'sys/uio.h')
112
- add_define 'HAVE_RB_THREAD_FD_SELECT' if have_func('rb_thread_fd_select')
113
- add_define 'HAVE_RB_FDSET_T' if have_type('rb_fdset_t', 'ruby/intern.h')
114
- add_define 'HAVE_PIPE2' if have_func('pipe2', 'unistd.h')
115
- add_define 'HAVE_ACCEPT4' if have_func('accept4', 'sys/socket.h')
116
- add_define 'HAVE_SOCK_CLOEXEC' if have_const('SOCK_CLOEXEC', 'sys/socket.h')
117
106
 
107
+ # Ruby features:
108
+
109
+ have_var('rb_trap_immediate', ['ruby.h', 'rubysig.h'])
110
+ have_func('rb_thread_blocking_region')
111
+ have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
112
+ have_func('rb_thread_fd_select')
113
+ have_type('rb_fdset_t', 'ruby/intern.h')
118
114
  have_func('rb_wait_for_single_fd')
119
115
  have_func('rb_enable_interrupt')
120
116
  have_func('rb_time_new')
121
117
 
118
+ # System features:
119
+
120
+ add_define('HAVE_INOTIFY') if inotify = have_func('inotify_init', 'sys/inotify.h')
121
+ add_define('HAVE_OLD_INOTIFY') if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h')
122
+ have_func('writev', 'sys/uio.h')
123
+ have_func('pipe2', 'unistd.h')
124
+ have_func('accept4', 'sys/socket.h')
125
+ have_const('SOCK_CLOEXEC', 'sys/socket.h')
126
+
122
127
  # Minor platform details between *nix and Windows:
123
128
 
124
129
  if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
@@ -130,7 +135,7 @@ else
130
135
  OS_UNIX = true
131
136
  add_define 'OS_UNIX'
132
137
 
133
- add_define "HAVE_KQUEUE" if have_header("sys/event.h") and have_header("sys/queue.h")
138
+ add_define "HAVE_KQUEUE" if have_header("sys/event.h") && have_header("sys/queue.h")
134
139
  end
135
140
 
136
141
  # Adjust number of file descriptors (FD) on Windows
@@ -156,13 +161,17 @@ when /mswin32/, /mingw32/, /bccwin32/
156
161
  $defs.push "-GR"
157
162
  end
158
163
 
164
+ # Newer versions of Ruby already define _WIN32_WINNT, which is needed
165
+ # to get access to newer POSIX networking functions (e.g. getaddrinfo)
166
+ add_define '_WIN32_WINNT=0x0501' unless have_func('getaddrinfo')
167
+
159
168
  when /solaris/
160
169
  add_define 'OS_SOLARIS8'
161
170
  check_libs(%w[nsl socket], true)
162
171
 
163
172
  # If Ruby was compiled for 32-bits, then select() can only handle 1024 fds
164
173
  # There is an alternate function, select_large_fdset, that supports more.
165
- add_define 'HAVE_SELECT_LARGE_FDSET' if have_func('select_large_fdset', 'sys/select.h')
174
+ have_func('select_large_fdset', 'sys/select.h')
166
175
 
167
176
  if CONFIG['CC'] == 'cc' && (
168
177
  `cc -flags 2>&1` =~ /Sun/ || # detect SUNWspro compiler
@@ -202,7 +211,7 @@ when /linux/
202
211
  CONFIG['LDSHARED'] = "$(CXX) -shared"
203
212
 
204
213
  when /aix/
205
- CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G -Wl,-brtl"
214
+ CONFIG['LDSHARED'] = "$(CXX) -Wl,-bstatic -Wl,-bdynamic -Wl,-G -Wl,-brtl"
206
215
 
207
216
  when /cygwin/
208
217
  # For rubies built with Cygwin, CXX may be set to CC, which is just
@@ -90,8 +90,7 @@ when /linux/
90
90
  CONFIG['LDSHARED'] = "$(CXX) -shared"
91
91
 
92
92
  when /aix/
93
- # on Unix we need a g++ link, not gcc.
94
- CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G"
93
+ CONFIG['LDSHARED'] = "$(CXX) -Wl,-bstatic -Wl,-bdynamic -Wl,-G -Wl,-brtl"
95
94
 
96
95
  when /cygwin/
97
96
  # For rubies built with Cygwin, CXX may be set to CC, which is just
@@ -50,7 +50,7 @@ static VALUE mapper_new (VALUE self, VALUE filename)
50
50
  {
51
51
  Mapper_t *m = new Mapper_t (StringValueCStr (filename));
52
52
  if (!m)
53
- rb_raise (rb_eException, "No Mapper Object");
53
+ rb_raise (rb_eStandardError, "No Mapper Object");
54
54
  VALUE v = Data_Wrap_Struct (Mapper, 0, mapper_dt, (void*)m);
55
55
  return v;
56
56
  }
@@ -65,17 +65,17 @@ static VALUE mapper_get_chunk (VALUE self, VALUE start, VALUE length)
65
65
  Mapper_t *m = NULL;
66
66
  Data_Get_Struct (self, Mapper_t, m);
67
67
  if (!m)
68
- rb_raise (rb_eException, "No Mapper Object");
68
+ rb_raise (rb_eStandardError, "No Mapper Object");
69
69
 
70
70
  // TODO, what if some moron sends us a negative start value?
71
71
  unsigned _start = NUM2INT (start);
72
72
  unsigned _length = NUM2INT (length);
73
73
  if ((_start + _length) > m->GetFileSize())
74
- rb_raise (rb_eException, "Mapper Range Error");
74
+ rb_raise (rb_eStandardError, "Mapper Range Error");
75
75
 
76
76
  const char *chunk = m->GetChunk (_start);
77
77
  if (!chunk)
78
- rb_raise (rb_eException, "No Mapper Chunk");
78
+ rb_raise (rb_eStandardError, "No Mapper Chunk");
79
79
  return rb_str_new (chunk, _length);
80
80
  }
81
81
 
@@ -88,7 +88,7 @@ static VALUE mapper_close (VALUE self)
88
88
  Mapper_t *m = NULL;
89
89
  Data_Get_Struct (self, Mapper_t, m);
90
90
  if (!m)
91
- rb_raise (rb_eException, "No Mapper Object");
91
+ rb_raise (rb_eStandardError, "No Mapper Object");
92
92
  m->Close();
93
93
  return Qnil;
94
94
  }
@@ -102,7 +102,7 @@ static VALUE mapper_size (VALUE self)
102
102
  Mapper_t *m = NULL;
103
103
  Data_Get_Struct (self, Mapper_t, m);
104
104
  if (!m)
105
- rb_raise (rb_eException, "No Mapper Object");
105
+ rb_raise (rb_eStandardError, "No Mapper Object");
106
106
  return INT2NUM (m->GetFileSize());
107
107
  }
108
108
 
data/ext/project.h CHANGED
@@ -22,10 +22,6 @@ See the file COPYING for complete licensing information.
22
22
  #define __Project__H_
23
23
 
24
24
 
25
- #ifdef OS_WIN32
26
- #pragma warning(disable:4786)
27
- #endif
28
-
29
25
  #include <iostream>
30
26
  #include <map>
31
27
  #include <set>
@@ -100,6 +96,15 @@ typedef int SOCKET;
100
96
  #include <fcntl.h>
101
97
  #include <assert.h>
102
98
 
99
+ // Older versions of MinGW in the Ruby Dev Kit do not provide the getaddrinfo hint flags
100
+ #ifndef AI_ADDRCONFIG
101
+ #define AI_ADDRCONFIG 0x0400
102
+ #endif
103
+
104
+ #ifndef AI_NUMERICSERV
105
+ #define AI_NUMERICSERV 0x0008
106
+ #endif
107
+
103
108
  // Use the Win32 wrapper library that Ruby owns to be able to close sockets with the close() function
104
109
  #define RUBY_EXPORT
105
110
  #include <ruby/defines.h>
data/ext/rubymain.cpp CHANGED
@@ -30,9 +30,19 @@ See the file COPYING for complete licensing information.
30
30
  #if SIZEOF_VOIDP == SIZEOF_LONG
31
31
  # define BSIG2NUM(x) (ULONG2NUM((unsigned long)(x)))
32
32
  # define NUM2BSIG(x) (NUM2ULONG(x))
33
+ # ifdef OS_WIN32
34
+ # define PRIFBSIG "I32u"
35
+ # else
36
+ # define PRIFBSIG "lu"
37
+ # endif
33
38
  #else
34
39
  # define BSIG2NUM(x) (ULL2NUM((unsigned long long)(x)))
35
40
  # define NUM2BSIG(x) (NUM2ULL(x))
41
+ # ifdef OS_WIN32
42
+ # define PRIFBSIG "I64u"
43
+ # else
44
+ # define PRIFBSIG "llu"
45
+ # endif
36
46
  #endif
37
47
 
38
48
  /*******
@@ -57,6 +67,7 @@ static VALUE Intern_event_callback;
57
67
  static VALUE Intern_run_deferred_callbacks;
58
68
  static VALUE Intern_delete;
59
69
  static VALUE Intern_call;
70
+ static VALUE Intern_at;
60
71
  static VALUE Intern_receive_data;
61
72
  static VALUE Intern_ssl_handshake_completed;
62
73
  static VALUE Intern_ssl_verify_peer;
@@ -79,7 +90,7 @@ static inline VALUE ensure_conn(const uintptr_t signature)
79
90
  {
80
91
  VALUE conn = rb_hash_aref (EmConnsHash, BSIG2NUM (signature));
81
92
  if (conn == Qnil)
82
- rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", signature);
93
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %" PRIFBSIG, signature);
83
94
  return conn;
84
95
  }
85
96
 
@@ -100,7 +111,7 @@ static inline void event_callback (struct em_event* e)
100
111
  {
101
112
  VALUE conn = rb_hash_aref (EmConnsHash, BSIG2NUM (signature));
102
113
  if (conn == Qnil)
103
- rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", data_num, signature);
114
+ rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %" PRIFBSIG, data_num, signature);
104
115
  rb_funcall (conn, Intern_receive_data, 1, rb_str_new (data_str, data_num));
105
116
  return;
106
117
  }
@@ -330,14 +341,14 @@ static VALUE t_start_tls (VALUE self UNUSED, VALUE signature)
330
341
  t_set_tls_parms
331
342
  ***************/
332
343
 
333
- static VALUE t_set_tls_parms (VALUE self UNUSED, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer)
344
+ static VALUE t_set_tls_parms (VALUE self UNUSED, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer, VALUE fail_if_no_peer_cert, VALUE snihostname, VALUE cipherlist, VALUE ecdh_curve, VALUE dhparam, VALUE ssl_version)
334
345
  {
335
346
  /* set_tls_parms takes a series of positional arguments for specifying such things
336
347
  * as private keys and certificate chains.
337
348
  * It's expected that the parameter list will grow as we add more supported features.
338
349
  * ALL of these parameters are optional, and can be specified as empty or NULL strings.
339
350
  */
340
- evma_set_tls_parms (NUM2BSIG (signature), StringValueCStr (privkeyfile), StringValueCStr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
351
+ evma_set_tls_parms (NUM2BSIG (signature), StringValueCStr (privkeyfile), StringValueCStr (certchainfile), (verify_peer == Qtrue ? 1 : 0), (fail_if_no_peer_cert == Qtrue ? 1 : 0), StringValueCStr (snihostname), StringValueCStr (cipherlist), StringValueCStr (ecdh_curve), StringValueCStr (dhparam), NUM2INT (ssl_version));
341
352
  return Qnil;
342
353
  }
343
354
 
@@ -374,6 +385,85 @@ static VALUE t_get_peer_cert (VALUE self UNUSED, VALUE signature UNUSED)
374
385
  }
375
386
  #endif
376
387
 
388
+ /***************
389
+ t_get_cipher_bits
390
+ ***************/
391
+
392
+ #ifdef WITH_SSL
393
+ static VALUE t_get_cipher_bits (VALUE self UNUSED, VALUE signature)
394
+ {
395
+ int bits = evma_get_cipher_bits (NUM2BSIG (signature));
396
+ if (bits == -1)
397
+ return Qnil;
398
+ return INT2NUM (bits);
399
+ }
400
+ #else
401
+ static VALUE t_get_cipher_bits (VALUE self UNUSED, VALUE signature UNUSED)
402
+ {
403
+ return Qnil;
404
+ }
405
+ #endif
406
+
407
+ /***************
408
+ t_get_cipher_name
409
+ ***************/
410
+
411
+ #ifdef WITH_SSL
412
+ static VALUE t_get_cipher_name (VALUE self UNUSED, VALUE signature)
413
+ {
414
+ const char *protocol = evma_get_cipher_name (NUM2BSIG (signature));
415
+ if (protocol)
416
+ return rb_str_new2 (protocol);
417
+
418
+ return Qnil;
419
+ }
420
+ #else
421
+ static VALUE t_get_cipher_name (VALUE self UNUSED, VALUE signature UNUSED)
422
+ {
423
+ return Qnil;
424
+ }
425
+ #endif
426
+
427
+ /***************
428
+ t_get_cipher_protocol
429
+ ***************/
430
+
431
+ #ifdef WITH_SSL
432
+ static VALUE t_get_cipher_protocol (VALUE self UNUSED, VALUE signature)
433
+ {
434
+ const char *cipher = evma_get_cipher_protocol (NUM2BSIG (signature));
435
+ if (cipher)
436
+ return rb_str_new2 (cipher);
437
+
438
+ return Qnil;
439
+ }
440
+ #else
441
+ static VALUE t_get_cipher_protocol (VALUE self UNUSED, VALUE signature UNUSED)
442
+ {
443
+ return Qnil;
444
+ }
445
+ #endif
446
+
447
+ /***************
448
+ t_get_sni_hostname
449
+ ***************/
450
+
451
+ #ifdef WITH_SSL
452
+ static VALUE t_get_sni_hostname (VALUE self UNUSED, VALUE signature)
453
+ {
454
+ const char *sni_hostname = evma_get_sni_hostname (NUM2BSIG (signature));
455
+ if (sni_hostname)
456
+ return rb_str_new2 (sni_hostname);
457
+
458
+ return Qnil;
459
+ }
460
+ #else
461
+ static VALUE t_get_sni_hostname (VALUE self UNUSED, VALUE signature UNUSED)
462
+ {
463
+ return Qnil;
464
+ }
465
+ #endif
466
+
377
467
  /**************
378
468
  t_get_peername
379
469
  **************/
@@ -442,9 +532,9 @@ static VALUE t_get_subprocess_status (VALUE self UNUSED, VALUE signature)
442
532
  rb_iv_set(proc_status, "@pid", INT2FIX(pid));
443
533
  if (WIFEXITED(status)) {
444
534
  rb_iv_set(proc_status, "@status", INT2FIX(WEXITSTATUS(status)));
445
- } else if(WIFSIGNALED(status)) {
535
+ } else if (WIFSIGNALED(status)) {
446
536
  rb_iv_set(proc_status, "@termsig", INT2FIX(WTERMSIG(status)));
447
- } else if(WIFSTOPPED(status)){
537
+ } else if (WIFSTOPPED(status)){
448
538
  rb_iv_set(proc_status, "@stopsig", INT2FIX(WSTOPSIG(status)));
449
539
  }
450
540
  #endif
@@ -514,6 +604,8 @@ t_send_datagram
514
604
  static VALUE t_send_datagram (VALUE self UNUSED, VALUE signature, VALUE data, VALUE data_length, VALUE address, VALUE port)
515
605
  {
516
606
  int b = evma_send_datagram (NUM2BSIG (signature), StringValuePtr (data), FIX2INT (data_length), StringValueCStr(address), FIX2INT(port));
607
+ if (b < 0)
608
+ rb_raise (EM_eConnectionError, "%s", "error in sending datagram"); // FIXME: this could be more specific.
517
609
  return INT2NUM (b);
518
610
  }
519
611
 
@@ -870,12 +962,11 @@ t_invoke_popen
870
962
 
871
963
  static VALUE t_invoke_popen (VALUE self UNUSED, VALUE cmd)
872
964
  {
873
- // 1.8.7+
874
- #ifdef RARRAY_LEN
875
- int len = RARRAY_LEN(cmd);
876
- #else
877
- int len = RARRAY (cmd)->len;
965
+ #ifdef OS_WIN32
966
+ rb_raise (EM_eUnsupported, "popen is not available on this platform");
878
967
  #endif
968
+
969
+ int len = RARRAY_LEN(cmd);
879
970
  if (len >= 2048)
880
971
  rb_raise (rb_eRuntimeError, "%s", "too many arguments to popen");
881
972
  char *strings [2048];
@@ -890,7 +981,7 @@ static VALUE t_invoke_popen (VALUE self UNUSED, VALUE cmd)
890
981
  try {
891
982
  f = evma_popen (strings);
892
983
  } catch (std::runtime_error e) {
893
- f = 0; // raise exception below
984
+ rb_raise (rb_eRuntimeError, "%s", e.what());
894
985
  }
895
986
  if (!f) {
896
987
  char *err = strerror (errno);
@@ -1061,6 +1152,23 @@ static VALUE t__ssl_p (VALUE self UNUSED)
1061
1152
  #endif
1062
1153
  }
1063
1154
 
1155
+ /********
1156
+ t_stopping
1157
+ ********/
1158
+
1159
+ static VALUE t_stopping ()
1160
+ {
1161
+ if (evma_stopping())
1162
+ {
1163
+ return Qtrue;
1164
+ }
1165
+ else
1166
+ {
1167
+ return Qfalse;
1168
+ }
1169
+
1170
+ }
1171
+
1064
1172
 
1065
1173
  /****************
1066
1174
  t_send_file_data
@@ -1131,20 +1239,17 @@ t_get_loop_time
1131
1239
 
1132
1240
  static VALUE t_get_loop_time (VALUE self UNUSED)
1133
1241
  {
1134
- #ifndef HAVE_RB_TIME_NEW
1135
- static VALUE cTime = rb_path2class("Time");
1136
- static ID at = rb_intern("at");
1137
- #endif
1138
-
1139
1242
  uint64_t current_time = evma_get_current_loop_time();
1140
- if (current_time != 0) {
1141
- #ifndef HAVE_RB_TIME_NEW
1142
- return rb_funcall(cTime, at, 2, INT2NUM(current_time / 1000000), INT2NUM(current_time % 1000000));
1143
- #else
1243
+ if (current_time == 0) {
1244
+ return Qnil;
1245
+ }
1246
+
1247
+ // Generally the industry has moved to 64-bit time_t, this is just in case we're 32-bit time_t.
1248
+ if (sizeof(time_t) < 8 && current_time > INT_MAX) {
1249
+ return rb_funcall(rb_cTime, Intern_at, 2, INT2NUM(current_time / 1000000), INT2NUM(current_time % 1000000));
1250
+ } else {
1144
1251
  return rb_time_new(current_time / 1000000, current_time % 1000000);
1145
- #endif
1146
1252
  }
1147
- return Qnil;
1148
1253
  }
1149
1254
 
1150
1255
 
@@ -1259,6 +1364,7 @@ extern "C" void Init_rubyeventmachine()
1259
1364
  Intern_run_deferred_callbacks = rb_intern ("run_deferred_callbacks");
1260
1365
  Intern_delete = rb_intern ("delete");
1261
1366
  Intern_call = rb_intern ("call");
1367
+ Intern_at = rb_intern("at");
1262
1368
  Intern_receive_data = rb_intern ("receive_data");
1263
1369
  Intern_ssl_handshake_completed = rb_intern ("ssl_handshake_completed");
1264
1370
  Intern_ssl_verify_peer = rb_intern ("ssl_verify_peer");
@@ -1289,9 +1395,13 @@ extern "C" void Init_rubyeventmachine()
1289
1395
  rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
1290
1396
  rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
1291
1397
  rb_define_module_function (EmModule, "attach_sd", (VALUE(*)(...))t_attach_sd, 1);
1292
- rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 4);
1398
+ rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 10);
1293
1399
  rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
1294
1400
  rb_define_module_function (EmModule, "get_peer_cert", (VALUE(*)(...))t_get_peer_cert, 1);
1401
+ rb_define_module_function (EmModule, "get_cipher_bits", (VALUE(*)(...))t_get_cipher_bits, 1);
1402
+ rb_define_module_function (EmModule, "get_cipher_name", (VALUE(*)(...))t_get_cipher_name, 1);
1403
+ rb_define_module_function (EmModule, "get_cipher_protocol", (VALUE(*)(...))t_get_cipher_protocol, 1);
1404
+ rb_define_module_function (EmModule, "get_sni_hostname", (VALUE(*)(...))t_get_sni_hostname, 1);
1295
1405
  rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
1296
1406
  rb_define_module_function (EmModule, "send_datagram", (VALUE(*)(...))t_send_datagram, 5);
1297
1407
  rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2);
@@ -1365,21 +1475,30 @@ extern "C" void Init_rubyeventmachine()
1365
1475
  rb_define_module_function (EmModule, "kqueue?", (VALUE(*)(...))t__kqueue_p, 0);
1366
1476
 
1367
1477
  rb_define_module_function (EmModule, "ssl?", (VALUE(*)(...))t__ssl_p, 0);
1478
+ rb_define_module_function(EmModule, "stopping?",(VALUE(*)(...))t_stopping, 0);
1368
1479
 
1369
1480
  rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
1370
1481
  rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1);
1371
1482
 
1372
- rb_define_const (EmModule, "TimerFired", INT2NUM(100));
1373
- rb_define_const (EmModule, "ConnectionData", INT2NUM(101));
1374
- rb_define_const (EmModule, "ConnectionUnbound", INT2NUM(102));
1375
- rb_define_const (EmModule, "ConnectionAccepted", INT2NUM(103));
1376
- rb_define_const (EmModule, "ConnectionCompleted", INT2NUM(104));
1377
- rb_define_const (EmModule, "LoopbreakSignalled", INT2NUM(105));
1378
-
1379
- rb_define_const (EmModule, "ConnectionNotifyReadable", INT2NUM(106));
1380
- rb_define_const (EmModule, "ConnectionNotifyWritable", INT2NUM(107));
1381
-
1382
- rb_define_const (EmModule, "SslHandshakeCompleted", INT2NUM(108));
1383
-
1483
+ // Connection states
1484
+ rb_define_const (EmModule, "TimerFired", INT2NUM(EM_TIMER_FIRED ));
1485
+ rb_define_const (EmModule, "ConnectionData", INT2NUM(EM_CONNECTION_READ ));
1486
+ rb_define_const (EmModule, "ConnectionUnbound", INT2NUM(EM_CONNECTION_UNBOUND ));
1487
+ rb_define_const (EmModule, "ConnectionAccepted", INT2NUM(EM_CONNECTION_ACCEPTED ));
1488
+ rb_define_const (EmModule, "ConnectionCompleted", INT2NUM(EM_CONNECTION_COMPLETED ));
1489
+ rb_define_const (EmModule, "LoopbreakSignalled", INT2NUM(EM_LOOPBREAK_SIGNAL ));
1490
+ rb_define_const (EmModule, "ConnectionNotifyReadable", INT2NUM(EM_CONNECTION_NOTIFY_READABLE));
1491
+ rb_define_const (EmModule, "ConnectionNotifyWritable", INT2NUM(EM_CONNECTION_NOTIFY_WRITABLE));
1492
+ rb_define_const (EmModule, "SslHandshakeCompleted", INT2NUM(EM_SSL_HANDSHAKE_COMPLETED ));
1493
+ // EM_SSL_VERIFY = 109,
1494
+ // EM_PROXY_TARGET_UNBOUND = 110,
1495
+ // EM_PROXY_COMPLETED = 111
1496
+
1497
+ // SSL Protocols
1498
+ rb_define_const (EmModule, "EM_PROTO_SSLv2", INT2NUM(EM_PROTO_SSLv2 ));
1499
+ rb_define_const (EmModule, "EM_PROTO_SSLv3", INT2NUM(EM_PROTO_SSLv3 ));
1500
+ rb_define_const (EmModule, "EM_PROTO_TLSv1", INT2NUM(EM_PROTO_TLSv1 ));
1501
+ rb_define_const (EmModule, "EM_PROTO_TLSv1_1", INT2NUM(EM_PROTO_TLSv1_1));
1502
+ rb_define_const (EmModule, "EM_PROTO_TLSv1_2", INT2NUM(EM_PROTO_TLSv1_2));
1384
1503
  }
1385
1504