eventmachine 1.0.9.1 → 1.2.0.dev.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/cmain.cpp +77 -5
  4. data/ext/ed.cpp +100 -39
  5. data/ext/ed.h +27 -13
  6. data/ext/em.cpp +105 -163
  7. data/ext/em.h +10 -7
  8. data/ext/eventmachine.h +13 -1
  9. data/ext/extconf.rb +22 -13
  10. data/ext/fastfilereader/rubymain.cpp +6 -6
  11. data/ext/project.h +9 -4
  12. data/ext/rubymain.cpp +155 -36
  13. data/ext/ssl.cpp +157 -13
  14. data/ext/ssl.h +7 -2
  15. data/lib/em/channel.rb +5 -0
  16. data/lib/em/completion.rb +2 -2
  17. data/lib/em/connection.rb +61 -3
  18. data/lib/em/iterator.rb +26 -5
  19. data/lib/em/pool.rb +1 -1
  20. data/lib/em/protocols/line_and_text.rb +1 -1
  21. data/lib/em/pure_ruby.rb +6 -1
  22. data/lib/em/queue.rb +16 -7
  23. data/lib/em/resolver.rb +46 -23
  24. data/lib/em/threaded_resource.rb +2 -2
  25. data/lib/em/version.rb +1 -1
  26. data/lib/eventmachine.rb +59 -42
  27. data/rakelib/package.rake +23 -1
  28. data/tests/dhparam.pem +13 -0
  29. data/tests/em_test_helper.rb +79 -0
  30. data/tests/test_basic.rb +17 -26
  31. data/tests/test_channel.rb +14 -1
  32. data/tests/test_connection_write.rb +2 -2
  33. data/tests/test_defer.rb +17 -0
  34. data/tests/test_epoll.rb +1 -1
  35. data/tests/test_fork.rb +75 -0
  36. data/tests/test_ipv4.rb +125 -0
  37. data/tests/test_ipv6.rb +131 -0
  38. data/tests/test_iterator.rb +18 -0
  39. data/tests/test_many_fds.rb +1 -1
  40. data/tests/test_queue.rb +14 -0
  41. data/tests/test_resolver.rb +23 -0
  42. data/tests/test_set_sock_opt.rb +2 -0
  43. data/tests/test_ssl_dhparam.rb +83 -0
  44. data/tests/test_ssl_ecdh_curve.rb +79 -0
  45. data/tests/test_ssl_extensions.rb +49 -0
  46. data/tests/test_ssl_methods.rb +19 -0
  47. data/tests/test_ssl_protocols.rb +246 -0
  48. data/tests/test_ssl_verify.rb +44 -0
  49. data/tests/test_system.rb +4 -0
  50. data/tests/test_unbind_reason.rb +5 -1
  51. metadata +116 -49
  52. data/.gitignore +0 -21
  53. data/.travis.yml +0 -22
  54. data/.yardopts +0 -7
  55. data/Gemfile +0 -2
  56. data/Rakefile +0 -20
  57. data/eventmachine.gemspec +0 -38
  58. 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;
@@ -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
 
@@ -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
@@ -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
 
@@ -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>
@@ -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