eventmachine 0.12.6-java → 0.12.8-java
Sign up to get free protection for your applications and to get access to all the features.
- data/{docs/README → README} +21 -13
- data/Rakefile +5 -3
- 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.rb +35 -0
- 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/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 +52 -36
- 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/cplusplus.cpp
CHANGED
@@ -33,7 +33,7 @@ EM::Run
|
|
33
33
|
|
34
34
|
void EM::Run (void (*start_func)())
|
35
35
|
{
|
36
|
-
|
36
|
+
evma_set_epoll (1);
|
37
37
|
evma_initialize_library (EM::Callback);
|
38
38
|
if (start_func)
|
39
39
|
AddTimer (0, start_func);
|
@@ -115,13 +115,13 @@ void EM::Connection::Close (bool afterWriting)
|
|
115
115
|
}
|
116
116
|
|
117
117
|
|
118
|
-
|
119
|
-
EM::Connection::
|
120
|
-
|
118
|
+
/***************************
|
119
|
+
EM::Connection::BindConnect
|
120
|
+
***************************/
|
121
121
|
|
122
|
-
void EM::Connection::
|
122
|
+
void EM::Connection::BindConnect (const char *bind_addr, int bind_port, const char *host, int port)
|
123
123
|
{
|
124
|
-
Signature = evma_connect_to_server (host, port);
|
124
|
+
Signature = evma_connect_to_server (bind_addr, bind_port, host, port);
|
125
125
|
#ifdef OS_SOLARIS8
|
126
126
|
Eventables.insert( std::map<std::string,EM::Eventable*>::value_type (Signature, this));
|
127
127
|
#else
|
@@ -129,6 +129,15 @@ void EM::Connection::Connect (const char *host, int port)
|
|
129
129
|
#endif
|
130
130
|
}
|
131
131
|
|
132
|
+
/***********************
|
133
|
+
EM::Connection::Connect
|
134
|
+
***********************/
|
135
|
+
|
136
|
+
void EM::Connection::Connect (const char *host, int port)
|
137
|
+
{
|
138
|
+
this->BindConnect(NULL, 0, host, port);
|
139
|
+
}
|
140
|
+
|
132
141
|
/*******************
|
133
142
|
EM::Acceptor::Start
|
134
143
|
*******************/
|
data/ext/ed.cpp
CHANGED
@@ -48,10 +48,9 @@ EventableDescriptor::EventableDescriptor (int sd, EventMachine_t *em):
|
|
48
48
|
bCloseAfterWriting (false),
|
49
49
|
MySocket (sd),
|
50
50
|
EventCallback (NULL),
|
51
|
-
LastRead (0),
|
52
|
-
LastWritten (0),
|
53
51
|
bCallbackUnbind (true),
|
54
52
|
UnbindReasonCode (0),
|
53
|
+
ProxyTarget(NULL),
|
55
54
|
MyEventMachine (em)
|
56
55
|
{
|
57
56
|
/* There are three ways to close a socket, all of which should
|
@@ -95,6 +94,7 @@ EventableDescriptor::~EventableDescriptor()
|
|
95
94
|
{
|
96
95
|
if (EventCallback && bCallbackUnbind)
|
97
96
|
(*EventCallback)(GetBinding().c_str(), EM_CONNECTION_UNBOUND, NULL, UnbindReasonCode);
|
97
|
+
StopProxy();
|
98
98
|
Close();
|
99
99
|
}
|
100
100
|
|
@@ -168,6 +168,52 @@ bool EventableDescriptor::IsCloseScheduled()
|
|
168
168
|
}
|
169
169
|
|
170
170
|
|
171
|
+
/*******************************
|
172
|
+
EventableDescriptor::StartProxy
|
173
|
+
*******************************/
|
174
|
+
|
175
|
+
void EventableDescriptor::StartProxy(const char *to)
|
176
|
+
{
|
177
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (to));
|
178
|
+
if (ed) {
|
179
|
+
StopProxy();
|
180
|
+
ProxyTarget = strdup(to);
|
181
|
+
return;
|
182
|
+
}
|
183
|
+
throw std::runtime_error ("Tried to proxy to an invalid descriptor");
|
184
|
+
}
|
185
|
+
|
186
|
+
|
187
|
+
/******************************
|
188
|
+
EventableDescriptor::StopProxy
|
189
|
+
******************************/
|
190
|
+
|
191
|
+
void EventableDescriptor::StopProxy()
|
192
|
+
{
|
193
|
+
if (ProxyTarget) {
|
194
|
+
free(ProxyTarget);
|
195
|
+
ProxyTarget = NULL;
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
|
200
|
+
/********************************************
|
201
|
+
EventableDescriptor::_GenericInboundDispatch
|
202
|
+
********************************************/
|
203
|
+
|
204
|
+
void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
|
205
|
+
{
|
206
|
+
assert(EventCallback);
|
207
|
+
|
208
|
+
if (!ProxyTarget)
|
209
|
+
(*EventCallback)(GetBinding().c_str(), EM_CONNECTION_READ, buf, size);
|
210
|
+
else if (ConnectionDescriptor::SendDataToConnection(ProxyTarget, buf, size) == -1) {
|
211
|
+
(*EventCallback)(GetBinding().c_str(), EM_PROXY_TARGET_UNBOUND, NULL, 0);
|
212
|
+
StopProxy();
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
|
171
217
|
/******************************************
|
172
218
|
ConnectionDescriptor::ConnectionDescriptor
|
173
219
|
******************************************/
|
@@ -183,15 +229,18 @@ ConnectionDescriptor::ConnectionDescriptor (int sd, EventMachine_t *em):
|
|
183
229
|
#ifdef WITH_SSL
|
184
230
|
SslBox (NULL),
|
185
231
|
bHandshakeSignaled (false),
|
232
|
+
bSslVerifyPeer (false),
|
233
|
+
bSslPeerAccepted(false),
|
234
|
+
#endif
|
235
|
+
#ifdef HAVE_KQUEUE
|
236
|
+
bGotExtraKqueueEvent(false),
|
186
237
|
#endif
|
187
238
|
bIsServer (false),
|
188
239
|
LastIo (gCurrentLoopTime),
|
189
240
|
InactivityTimeout (0)
|
190
241
|
{
|
191
|
-
#ifdef HAVE_EPOLL
|
192
|
-
EpollEvent.events = EPOLLOUT;
|
193
|
-
#endif
|
194
242
|
// 22Jan09: Moved ArmKqueueWriter into SetConnectPending() to fix assertion failure in _WriteOutboundData()
|
243
|
+
// 5May09: Moved EPOLLOUT into SetConnectPending() so it doesn't happen for attached read pipes
|
195
244
|
}
|
196
245
|
|
197
246
|
|
@@ -270,9 +319,60 @@ ConnectionDescriptor::SetConnectPending
|
|
270
319
|
void ConnectionDescriptor::SetConnectPending(bool f)
|
271
320
|
{
|
272
321
|
bConnectPending = f;
|
273
|
-
|
274
|
-
|
275
|
-
|
322
|
+
|
323
|
+
if (bConnectPending) { // not yet connected, select for writability
|
324
|
+
#ifdef HAVE_EPOLL
|
325
|
+
EpollEvent.events = EPOLLOUT;
|
326
|
+
#endif
|
327
|
+
#ifdef HAVE_KQUEUE
|
328
|
+
MyEventMachine->ArmKqueueWriter (this);
|
329
|
+
#endif
|
330
|
+
} else { // connected, wait for incoming data and write out any pending outgoing data
|
331
|
+
#ifdef HAVE_EPOLL
|
332
|
+
EpollEvent.events = EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0);
|
333
|
+
#endif
|
334
|
+
#ifdef HAVE_KQUEUE
|
335
|
+
MyEventMachine->ArmKqueueReader (this);
|
336
|
+
if (SelectForWrite())
|
337
|
+
MyEventMachine->ArmKqueueWriter (this);
|
338
|
+
#endif
|
339
|
+
}
|
340
|
+
}
|
341
|
+
|
342
|
+
|
343
|
+
/***************************************
|
344
|
+
ConnectionDescriptor::SetNotifyReadable
|
345
|
+
****************************************/
|
346
|
+
|
347
|
+
void ConnectionDescriptor::SetNotifyReadable(bool readable)
|
348
|
+
{
|
349
|
+
bNotifyReadable = readable;
|
350
|
+
if (bNotifyReadable) {
|
351
|
+
#ifdef HAVE_EPOLL
|
352
|
+
EpollEvent.events |= EPOLLIN;
|
353
|
+
#endif
|
354
|
+
#ifdef HAVE_KQUEUE
|
355
|
+
MyEventMachine->ArmKqueueReader (this);
|
356
|
+
#endif
|
357
|
+
}
|
358
|
+
}
|
359
|
+
|
360
|
+
|
361
|
+
/***************************************
|
362
|
+
ConnectionDescriptor::SetNotifyWritable
|
363
|
+
****************************************/
|
364
|
+
|
365
|
+
void ConnectionDescriptor::SetNotifyWritable(bool writable)
|
366
|
+
{
|
367
|
+
bNotifyWritable = writable;
|
368
|
+
if (bNotifyWritable) {
|
369
|
+
#ifdef HAVE_EPOLL
|
370
|
+
EpollEvent.events |= EPOLLOUT;
|
371
|
+
#endif
|
372
|
+
#ifdef HAVE_KQUEUE
|
373
|
+
MyEventMachine->ArmKqueueWriter (this);
|
374
|
+
#endif
|
375
|
+
}
|
276
376
|
}
|
277
377
|
|
278
378
|
|
@@ -328,10 +428,12 @@ int ConnectionDescriptor::_SendRawOutboundData (const char *data, int length)
|
|
328
428
|
char *buffer = (char *) malloc (length + 1);
|
329
429
|
if (!buffer)
|
330
430
|
throw std::runtime_error ("no allocation for outbound data");
|
431
|
+
|
331
432
|
memcpy (buffer, data, length);
|
332
433
|
buffer [length] = 0;
|
333
434
|
OutboundPages.push_back (OutboundPage (buffer, length));
|
334
435
|
OutboundDataSize += length;
|
436
|
+
|
335
437
|
#ifdef HAVE_EPOLL
|
336
438
|
EpollEvent.events = (EPOLLIN | EPOLLOUT);
|
337
439
|
assert (MyEventMachine);
|
@@ -340,6 +442,7 @@ int ConnectionDescriptor::_SendRawOutboundData (const char *data, int length)
|
|
340
442
|
#ifdef HAVE_KQUEUE
|
341
443
|
MyEventMachine->ArmKqueueWriter (this);
|
342
444
|
#endif
|
445
|
+
|
343
446
|
return length;
|
344
447
|
}
|
345
448
|
|
@@ -446,12 +549,11 @@ void ConnectionDescriptor::Read()
|
|
446
549
|
// to user code.
|
447
550
|
|
448
551
|
|
449
|
-
int r =
|
552
|
+
int r = read (sd, readbuffer, sizeof(readbuffer) - 1);
|
450
553
|
//cerr << "<R:" << r << ">";
|
451
554
|
|
452
555
|
if (r > 0) {
|
453
556
|
total_bytes_read += r;
|
454
|
-
LastRead = gCurrentLoopTime;
|
455
557
|
|
456
558
|
// Add a null-terminator at the the end of the buffer
|
457
559
|
// that we will send to the callback.
|
@@ -499,22 +601,25 @@ void ConnectionDescriptor::_DispatchInboundData (const char *buffer, int size)
|
|
499
601
|
while ((s = SslBox->GetPlaintext (B, sizeof(B) - 1)) > 0) {
|
500
602
|
_CheckHandshakeStatus();
|
501
603
|
B [s] = 0;
|
502
|
-
|
503
|
-
|
604
|
+
_GenericInboundDispatch(B, s);
|
605
|
+
}
|
606
|
+
|
607
|
+
// If our SSL handshake had a problem, shut down the connection.
|
608
|
+
if (s == -2) {
|
609
|
+
ScheduleClose(false);
|
610
|
+
return;
|
504
611
|
}
|
612
|
+
|
505
613
|
_CheckHandshakeStatus();
|
506
|
-
// INCOMPLETE, s may indicate an SSL error that would force the connection down.
|
507
614
|
_DispatchCiphertext();
|
508
615
|
}
|
509
616
|
else {
|
510
|
-
|
511
|
-
(*EventCallback)(GetBinding().c_str(), EM_CONNECTION_READ, buffer, size);
|
617
|
+
_GenericInboundDispatch(buffer, size);
|
512
618
|
}
|
513
619
|
#endif
|
514
620
|
|
515
621
|
#ifdef WITHOUT_SSL
|
516
|
-
|
517
|
-
(*EventCallback)(GetBinding().c_str(), EM_CONNECTION_READ, buffer, size);
|
622
|
+
_GenericInboundDispatch(buffer, size);
|
518
623
|
#endif
|
519
624
|
}
|
520
625
|
|
@@ -568,17 +673,10 @@ void ConnectionDescriptor::Write()
|
|
568
673
|
if ((o == 0) && (error == 0)) {
|
569
674
|
if (EventCallback)
|
570
675
|
(*EventCallback)(GetBinding().c_str(), EM_CONNECTION_COMPLETED, "", 0);
|
571
|
-
|
572
|
-
|
573
|
-
//
|
574
|
-
|
575
|
-
#endif
|
576
|
-
#ifdef HAVE_KQUEUE
|
577
|
-
MyEventMachine->ArmKqueueReader (this);
|
578
|
-
// The callback may have scheduled outbound data.
|
579
|
-
if (SelectForWrite())
|
580
|
-
MyEventMachine->ArmKqueueWriter (this);
|
581
|
-
#endif
|
676
|
+
|
677
|
+
// 5May09: Moved epoll/kqueue read/write arming into SetConnectPending, so it can be called
|
678
|
+
// from EventMachine_t::AttachFD as well.
|
679
|
+
SetConnectPending (false);
|
582
680
|
}
|
583
681
|
else
|
584
682
|
ScheduleClose (false);
|
@@ -592,6 +690,22 @@ void ConnectionDescriptor::Write()
|
|
592
690
|
return;
|
593
691
|
}
|
594
692
|
|
693
|
+
/* 5May09: Kqueue bugs on OSX cause one extra writable event to fire even though we're using
|
694
|
+
EV_ONESHOT. We ignore this extra event once, but only the first time. If it happens again,
|
695
|
+
we should fall through to the assert(nbytes>0) failure to catch any EM bugs which might cause
|
696
|
+
::Write to be called in a busy-loop.
|
697
|
+
*/
|
698
|
+
#ifdef HAVE_KQUEUE
|
699
|
+
if (MyEventMachine->UsingKqueue()) {
|
700
|
+
if (OutboundDataSize == 0 && !bGotExtraKqueueEvent) {
|
701
|
+
bGotExtraKqueueEvent = true;
|
702
|
+
return;
|
703
|
+
} else if (OutboundDataSize > 0) {
|
704
|
+
bGotExtraKqueueEvent = false;
|
705
|
+
}
|
706
|
+
}
|
707
|
+
#endif
|
708
|
+
|
595
709
|
_WriteOutboundData();
|
596
710
|
}
|
597
711
|
}
|
@@ -624,9 +738,25 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
624
738
|
}
|
625
739
|
|
626
740
|
LastIo = gCurrentLoopTime;
|
627
|
-
char output_buffer [16 * 1024];
|
628
741
|
size_t nbytes = 0;
|
629
742
|
|
743
|
+
#ifdef HAVE_WRITEV
|
744
|
+
int iovcnt = OutboundPages.size();
|
745
|
+
// Max of 16 outbound pages at a time
|
746
|
+
if (iovcnt > 16) iovcnt = 16;
|
747
|
+
|
748
|
+
struct iovec iov[ iovcnt ];
|
749
|
+
|
750
|
+
for(int i = 0; i < iovcnt; i++){
|
751
|
+
OutboundPage *op = &(OutboundPages[i]);
|
752
|
+
iov[i].iov_base = (void *)(op->Buffer + op->Offset);
|
753
|
+
iov[i].iov_len = op->Length - op->Offset;
|
754
|
+
|
755
|
+
nbytes += iov[i].iov_len;
|
756
|
+
}
|
757
|
+
#else
|
758
|
+
char output_buffer [16 * 1024];
|
759
|
+
|
630
760
|
while ((OutboundPages.size() > 0) && (nbytes < sizeof(output_buffer))) {
|
631
761
|
OutboundPage *op = &(OutboundPages[0]);
|
632
762
|
if ((nbytes + op->Length - op->Offset) < sizeof (output_buffer)) {
|
@@ -642,6 +772,7 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
642
772
|
nbytes += len;
|
643
773
|
}
|
644
774
|
}
|
775
|
+
#endif
|
645
776
|
|
646
777
|
// We should never have gotten here if there were no data to write,
|
647
778
|
// so assert that as a sanity check.
|
@@ -650,7 +781,11 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
650
781
|
assert (nbytes > 0);
|
651
782
|
|
652
783
|
assert (GetSocket() != INVALID_SOCKET);
|
653
|
-
|
784
|
+
#ifdef HAVE_WRITEV
|
785
|
+
int bytes_written = writev (GetSocket(), iov, iovcnt);
|
786
|
+
#else
|
787
|
+
int bytes_written = write (GetSocket(), output_buffer, nbytes);
|
788
|
+
#endif
|
654
789
|
|
655
790
|
bool err = false;
|
656
791
|
if (bytes_written < 0) {
|
@@ -660,6 +795,31 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
660
795
|
|
661
796
|
assert (bytes_written >= 0);
|
662
797
|
OutboundDataSize -= bytes_written;
|
798
|
+
|
799
|
+
#ifdef HAVE_WRITEV
|
800
|
+
if (!err) {
|
801
|
+
int sent = bytes_written;
|
802
|
+
deque<OutboundPage>::iterator op = OutboundPages.begin();
|
803
|
+
|
804
|
+
for (int i = 0; i < iovcnt; i++) {
|
805
|
+
if (iov[i].iov_len <= sent) {
|
806
|
+
// Sent this page in full, free it.
|
807
|
+
op->Free();
|
808
|
+
OutboundPages.pop_front();
|
809
|
+
|
810
|
+
sent -= iov[i].iov_len;
|
811
|
+
} else {
|
812
|
+
// Sent part (or none) of this page, increment offset to send the remainder
|
813
|
+
op->Offset += sent;
|
814
|
+
break;
|
815
|
+
}
|
816
|
+
|
817
|
+
// Shouldn't be possible run out of pages before the loop ends
|
818
|
+
assert(op != OutboundPages.end());
|
819
|
+
*op++;
|
820
|
+
}
|
821
|
+
}
|
822
|
+
#else
|
663
823
|
if ((size_t)bytes_written < nbytes) {
|
664
824
|
int len = nbytes - bytes_written;
|
665
825
|
char *buffer = (char*) malloc (len + 1);
|
@@ -669,6 +829,7 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
669
829
|
buffer [len] = 0;
|
670
830
|
OutboundPages.push_front (OutboundPage (buffer, len));
|
671
831
|
}
|
832
|
+
#endif
|
672
833
|
|
673
834
|
#ifdef HAVE_EPOLL
|
674
835
|
EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0));
|
@@ -725,7 +886,7 @@ void ConnectionDescriptor::StartTls()
|
|
725
886
|
if (SslBox)
|
726
887
|
throw std::runtime_error ("SSL/TLS already running on connection");
|
727
888
|
|
728
|
-
SslBox = new SslBox_t (bIsServer, PrivateKeyFilename, CertChainFilename);
|
889
|
+
SslBox = new SslBox_t (bIsServer, PrivateKeyFilename, CertChainFilename, bSslVerifyPeer, GetBinding().c_str());
|
729
890
|
_DispatchCiphertext();
|
730
891
|
#endif
|
731
892
|
|
@@ -739,7 +900,7 @@ void ConnectionDescriptor::StartTls()
|
|
739
900
|
ConnectionDescriptor::SetTlsParms
|
740
901
|
*********************************/
|
741
902
|
|
742
|
-
void ConnectionDescriptor::SetTlsParms (const char *privkey_filename, const char *certchain_filename)
|
903
|
+
void ConnectionDescriptor::SetTlsParms (const char *privkey_filename, const char *certchain_filename, bool verify_peer)
|
743
904
|
{
|
744
905
|
#ifdef WITH_SSL
|
745
906
|
if (SslBox)
|
@@ -748,6 +909,7 @@ void ConnectionDescriptor::SetTlsParms (const char *privkey_filename, const char
|
|
748
909
|
PrivateKeyFilename = privkey_filename;
|
749
910
|
if (certchain_filename && *certchain_filename)
|
750
911
|
CertChainFilename = certchain_filename;
|
912
|
+
bSslVerifyPeer = verify_peer;
|
751
913
|
#endif
|
752
914
|
|
753
915
|
#ifdef WITHOUT_SSL
|
@@ -770,6 +932,35 @@ X509 *ConnectionDescriptor::GetPeerCert()
|
|
770
932
|
#endif
|
771
933
|
|
772
934
|
|
935
|
+
/***********************************
|
936
|
+
ConnectionDescriptor::VerifySslPeer
|
937
|
+
***********************************/
|
938
|
+
|
939
|
+
#ifdef WITH_SSL
|
940
|
+
bool ConnectionDescriptor::VerifySslPeer(const char *cert)
|
941
|
+
{
|
942
|
+
bSslPeerAccepted = false;
|
943
|
+
|
944
|
+
if (EventCallback)
|
945
|
+
(*EventCallback)(GetBinding().c_str(), EM_SSL_VERIFY, cert, strlen(cert));
|
946
|
+
|
947
|
+
return bSslPeerAccepted;
|
948
|
+
}
|
949
|
+
#endif
|
950
|
+
|
951
|
+
|
952
|
+
/***********************************
|
953
|
+
ConnectionDescriptor::AcceptSslPeer
|
954
|
+
***********************************/
|
955
|
+
|
956
|
+
#ifdef WITH_SSL
|
957
|
+
void ConnectionDescriptor::AcceptSslPeer()
|
958
|
+
{
|
959
|
+
bSslPeerAccepted = true;
|
960
|
+
}
|
961
|
+
#endif
|
962
|
+
|
963
|
+
|
773
964
|
/*****************************************
|
774
965
|
ConnectionDescriptor::_DispatchCiphertext
|
775
966
|
*****************************************/
|
@@ -1156,7 +1347,6 @@ void DatagramDescriptor::Read()
|
|
1156
1347
|
|
1157
1348
|
// In UDP, a zero-length packet is perfectly legal.
|
1158
1349
|
if (r >= 0) {
|
1159
|
-
LastRead = gCurrentLoopTime;
|
1160
1350
|
|
1161
1351
|
// Add a null-terminator at the the end of the buffer
|
1162
1352
|
// that we will send to the callback.
|
@@ -1178,8 +1368,7 @@ void DatagramDescriptor::Read()
|
|
1178
1368
|
memset (&ReturnAddress, 0, sizeof(ReturnAddress));
|
1179
1369
|
memcpy (&ReturnAddress, &sin, slen);
|
1180
1370
|
|
1181
|
-
|
1182
|
-
(*EventCallback)(GetBinding().c_str(), EM_CONNECTION_READ, readbuffer, r);
|
1371
|
+
_GenericInboundDispatch(readbuffer, r);
|
1183
1372
|
|
1184
1373
|
}
|
1185
1374
|
else {
|
@@ -1290,11 +1479,13 @@ int DatagramDescriptor::SendOutboundData (const char *data, int length)
|
|
1290
1479
|
buffer [length] = 0;
|
1291
1480
|
OutboundPages.push_back (OutboundPage (buffer, length, ReturnAddress));
|
1292
1481
|
OutboundDataSize += length;
|
1482
|
+
|
1293
1483
|
#ifdef HAVE_EPOLL
|
1294
1484
|
EpollEvent.events = (EPOLLIN | EPOLLOUT);
|
1295
1485
|
assert (MyEventMachine);
|
1296
1486
|
MyEventMachine->Modify (this);
|
1297
1487
|
#endif
|
1488
|
+
|
1298
1489
|
return length;
|
1299
1490
|
}
|
1300
1491
|
|
@@ -1334,7 +1525,6 @@ int DatagramDescriptor::SendOutboundDatagram (const char *data, int length, cons
|
|
1334
1525
|
pin.sin_port = htons (port);
|
1335
1526
|
|
1336
1527
|
|
1337
|
-
|
1338
1528
|
if (!data && (length > 0))
|
1339
1529
|
throw std::runtime_error ("bad outbound data");
|
1340
1530
|
char *buffer = (char *) malloc (length + 1);
|
@@ -1344,11 +1534,13 @@ int DatagramDescriptor::SendOutboundDatagram (const char *data, int length, cons
|
|
1344
1534
|
buffer [length] = 0;
|
1345
1535
|
OutboundPages.push_back (OutboundPage (buffer, length, pin));
|
1346
1536
|
OutboundDataSize += length;
|
1537
|
+
|
1347
1538
|
#ifdef HAVE_EPOLL
|
1348
1539
|
EpollEvent.events = (EPOLLIN | EPOLLOUT);
|
1349
1540
|
assert (MyEventMachine);
|
1350
1541
|
MyEventMachine->Modify (this);
|
1351
1542
|
#endif
|
1543
|
+
|
1352
1544
|
return length;
|
1353
1545
|
}
|
1354
1546
|
|
@@ -1404,16 +1596,9 @@ bool ConnectionDescriptor::GetSockname (struct sockaddr *s)
|
|
1404
1596
|
ConnectionDescriptor::GetCommInactivityTimeout
|
1405
1597
|
**********************************************/
|
1406
1598
|
|
1407
|
-
|
1599
|
+
float ConnectionDescriptor::GetCommInactivityTimeout()
|
1408
1600
|
{
|
1409
|
-
|
1410
|
-
*value = InactivityTimeout;
|
1411
|
-
return 1;
|
1412
|
-
}
|
1413
|
-
else {
|
1414
|
-
// TODO, extended logging, got bad parameter.
|
1415
|
-
return 0;
|
1416
|
-
}
|
1601
|
+
return ((float)InactivityTimeout / 1000000);
|
1417
1602
|
}
|
1418
1603
|
|
1419
1604
|
|
@@ -1421,27 +1606,13 @@ int ConnectionDescriptor::GetCommInactivityTimeout (int *value)
|
|
1421
1606
|
ConnectionDescriptor::SetCommInactivityTimeout
|
1422
1607
|
**********************************************/
|
1423
1608
|
|
1424
|
-
int ConnectionDescriptor::SetCommInactivityTimeout (
|
1609
|
+
int ConnectionDescriptor::SetCommInactivityTimeout (float value)
|
1425
1610
|
{
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
if ((*value==0) || (*value >= 2)) {
|
1430
|
-
// Replace the value and send the old one back to the caller.
|
1431
|
-
int v = *value;
|
1432
|
-
*value = InactivityTimeout;
|
1433
|
-
InactivityTimeout = v;
|
1434
|
-
out = 1;
|
1435
|
-
}
|
1436
|
-
else {
|
1437
|
-
// TODO, extended logging, got bad value.
|
1438
|
-
}
|
1439
|
-
}
|
1440
|
-
else {
|
1441
|
-
// TODO, extended logging, got bad parameter.
|
1611
|
+
if (value > 0) {
|
1612
|
+
InactivityTimeout = (Int64)(value * 1000000);
|
1613
|
+
return 1;
|
1442
1614
|
}
|
1443
|
-
|
1444
|
-
return out;
|
1615
|
+
return 0;
|
1445
1616
|
}
|
1446
1617
|
|
1447
1618
|
/*******************************
|
@@ -1481,42 +1652,81 @@ bool DatagramDescriptor::GetSockname (struct sockaddr *s)
|
|
1481
1652
|
DatagramDescriptor::GetCommInactivityTimeout
|
1482
1653
|
********************************************/
|
1483
1654
|
|
1484
|
-
|
1655
|
+
float DatagramDescriptor::GetCommInactivityTimeout()
|
1485
1656
|
{
|
1486
|
-
|
1487
|
-
*value = InactivityTimeout;
|
1488
|
-
return 1;
|
1489
|
-
}
|
1490
|
-
else {
|
1491
|
-
// TODO, extended logging, got bad parameter.
|
1492
|
-
return 0;
|
1493
|
-
}
|
1657
|
+
return ((float)InactivityTimeout / 1000000);
|
1494
1658
|
}
|
1495
1659
|
|
1496
1660
|
/********************************************
|
1497
1661
|
DatagramDescriptor::SetCommInactivityTimeout
|
1498
1662
|
********************************************/
|
1499
1663
|
|
1500
|
-
int DatagramDescriptor::SetCommInactivityTimeout (
|
1501
|
-
{
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1664
|
+
int DatagramDescriptor::SetCommInactivityTimeout (float value)
|
1665
|
+
{
|
1666
|
+
if (value > 0) {
|
1667
|
+
InactivityTimeout = (Int64)(value * 1000000);
|
1668
|
+
return 1;
|
1669
|
+
}
|
1670
|
+
return 0;
|
1671
|
+
}
|
1672
|
+
|
1673
|
+
|
1674
|
+
/************************************
|
1675
|
+
InotifyDescriptor::InotifyDescriptor
|
1676
|
+
*************************************/
|
1677
|
+
|
1678
|
+
InotifyDescriptor::InotifyDescriptor (EventMachine_t *em):
|
1679
|
+
EventableDescriptor(0, em)
|
1680
|
+
{
|
1681
|
+
bCallbackUnbind = false;
|
1682
|
+
|
1683
|
+
#ifndef HAVE_INOTIFY
|
1684
|
+
throw std::runtime_error("no inotify support on this system");
|
1685
|
+
#else
|
1519
1686
|
|
1520
|
-
|
1687
|
+
int fd = inotify_init();
|
1688
|
+
if (fd == -1) {
|
1689
|
+
char buf[200];
|
1690
|
+
snprintf (buf, sizeof(buf)-1, "unable to create inotify descriptor: %s", strerror(errno));
|
1691
|
+
throw std::runtime_error (buf);
|
1692
|
+
}
|
1693
|
+
|
1694
|
+
MySocket = fd;
|
1695
|
+
SetSocketNonblocking(MySocket);
|
1696
|
+
#ifdef HAVE_EPOLL
|
1697
|
+
EpollEvent.events = EPOLLIN;
|
1698
|
+
#endif
|
1699
|
+
|
1700
|
+
#endif
|
1701
|
+
}
|
1702
|
+
|
1703
|
+
|
1704
|
+
/*************************************
|
1705
|
+
InotifyDescriptor::~InotifyDescriptor
|
1706
|
+
**************************************/
|
1707
|
+
|
1708
|
+
InotifyDescriptor::~InotifyDescriptor()
|
1709
|
+
{
|
1710
|
+
close(MySocket);
|
1711
|
+
MySocket = INVALID_SOCKET;
|
1521
1712
|
}
|
1522
1713
|
|
1714
|
+
/***********************
|
1715
|
+
InotifyDescriptor::Read
|
1716
|
+
************************/
|
1717
|
+
|
1718
|
+
void InotifyDescriptor::Read()
|
1719
|
+
{
|
1720
|
+
assert (MyEventMachine);
|
1721
|
+
MyEventMachine->_ReadInotifyEvents();
|
1722
|
+
}
|
1723
|
+
|
1724
|
+
|
1725
|
+
/************************
|
1726
|
+
InotifyDescriptor::Write
|
1727
|
+
*************************/
|
1728
|
+
|
1729
|
+
void InotifyDescriptor::Write()
|
1730
|
+
{
|
1731
|
+
throw std::runtime_error("bad code path in inotify");
|
1732
|
+
}
|