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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +2 -2
- data/ext/cmain.cpp +77 -5
- data/ext/ed.cpp +112 -42
- data/ext/ed.h +27 -13
- data/ext/em.cpp +105 -163
- data/ext/em.h +10 -7
- data/ext/eventmachine.h +13 -1
- data/ext/extconf.rb +23 -14
- data/ext/fastfilereader/extconf.rb +1 -2
- data/ext/fastfilereader/rubymain.cpp +6 -6
- data/ext/project.h +9 -4
- data/ext/rubymain.cpp +155 -36
- data/ext/ssl.cpp +157 -13
- data/ext/ssl.h +7 -2
- data/lib/em/channel.rb +5 -0
- data/lib/em/completion.rb +2 -2
- data/lib/em/connection.rb +61 -3
- data/lib/em/iterator.rb +26 -5
- data/lib/em/pool.rb +1 -1
- data/lib/em/protocols/line_and_text.rb +1 -1
- data/lib/em/pure_ruby.rb +6 -1
- data/lib/em/queue.rb +16 -7
- data/lib/em/resolver.rb +46 -23
- data/lib/em/threaded_resource.rb +2 -2
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +59 -42
- data/lib/rubyeventmachine.jar +0 -0
- data/rakelib/package.rake +23 -1
- data/tests/dhparam.pem +13 -0
- data/tests/em_test_helper.rb +79 -0
- data/tests/test_basic.rb +17 -26
- data/tests/test_channel.rb +14 -1
- data/tests/test_connection_write.rb +2 -2
- data/tests/test_defer.rb +17 -0
- data/tests/test_epoll.rb +1 -1
- data/tests/test_fork.rb +75 -0
- data/tests/test_ipv4.rb +125 -0
- data/tests/test_ipv6.rb +131 -0
- data/tests/test_iterator.rb +18 -0
- data/tests/test_many_fds.rb +1 -1
- data/tests/test_queue.rb +14 -0
- data/tests/test_resolver.rb +23 -0
- data/tests/test_set_sock_opt.rb +2 -0
- data/tests/test_ssl_dhparam.rb +83 -0
- data/tests/test_ssl_ecdh_curve.rb +79 -0
- data/tests/test_ssl_extensions.rb +49 -0
- data/tests/test_ssl_methods.rb +19 -0
- data/tests/test_ssl_protocols.rb +246 -0
- data/tests/test_ssl_verify.rb +44 -0
- data/tests/test_system.rb +4 -0
- data/tests/test_unbind_reason.rb +5 -1
- metadata +101 -20
- data/.gitignore +0 -21
- data/.travis.yml +0 -22
- data/.yardopts +0 -7
- data/Gemfile +0 -2
- data/Rakefile +0 -20
- data/eventmachine.gemspec +0 -38
- data/rakelib/cpp.rake_example +0 -77
data/ext/ed.h
CHANGED
@@ -36,10 +36,10 @@ class EventableDescriptor
|
|
36
36
|
class EventableDescriptor: public Bindable_t
|
37
37
|
{
|
38
38
|
public:
|
39
|
-
EventableDescriptor (
|
39
|
+
EventableDescriptor (SOCKET, EventMachine_t*);
|
40
40
|
virtual ~EventableDescriptor();
|
41
41
|
|
42
|
-
|
42
|
+
SOCKET GetSocket() {return MySocket;}
|
43
43
|
void SetSocketInvalid() { MySocket = INVALID_SOCKET; }
|
44
44
|
void Close();
|
45
45
|
|
@@ -69,10 +69,14 @@ class EventableDescriptor: public Bindable_t
|
|
69
69
|
virtual bool GetSubprocessPid (pid_t*) {return false;}
|
70
70
|
|
71
71
|
virtual void StartTls() {}
|
72
|
-
virtual void SetTlsParms (const char *, const char *, bool) {}
|
72
|
+
virtual void SetTlsParms (const char *, const char *, bool, bool, const char *, const char *, const char *, const char *, int) {}
|
73
73
|
|
74
74
|
#ifdef WITH_SSL
|
75
75
|
virtual X509 *GetPeerCert() {return NULL;}
|
76
|
+
virtual int GetCipherBits() {return -1;}
|
77
|
+
virtual const char *GetCipherName() {return NULL;}
|
78
|
+
virtual const char *GetCipherProtocol() {return NULL;}
|
79
|
+
virtual const char *GetSNIHostname() {return NULL;}
|
76
80
|
#endif
|
77
81
|
|
78
82
|
virtual uint64_t GetCommInactivityTimeout() {return 0;}
|
@@ -108,7 +112,7 @@ class EventableDescriptor: public Bindable_t
|
|
108
112
|
bool bCloseAfterWriting;
|
109
113
|
|
110
114
|
protected:
|
111
|
-
|
115
|
+
SOCKET MySocket;
|
112
116
|
bool bAttached;
|
113
117
|
bool bWatchOnly;
|
114
118
|
|
@@ -151,7 +155,7 @@ class LoopbreakDescriptor
|
|
151
155
|
class LoopbreakDescriptor: public EventableDescriptor
|
152
156
|
{
|
153
157
|
public:
|
154
|
-
LoopbreakDescriptor (
|
158
|
+
LoopbreakDescriptor (SOCKET, EventMachine_t*);
|
155
159
|
virtual ~LoopbreakDescriptor() {}
|
156
160
|
|
157
161
|
virtual void Read();
|
@@ -170,7 +174,7 @@ class ConnectionDescriptor
|
|
170
174
|
class ConnectionDescriptor: public EventableDescriptor
|
171
175
|
{
|
172
176
|
public:
|
173
|
-
ConnectionDescriptor (
|
177
|
+
ConnectionDescriptor (SOCKET, EventMachine_t*);
|
174
178
|
virtual ~ConnectionDescriptor();
|
175
179
|
|
176
180
|
int SendOutboundData (const char*, unsigned long);
|
@@ -201,10 +205,14 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
201
205
|
virtual int GetOutboundDataSize() {return OutboundDataSize;}
|
202
206
|
|
203
207
|
virtual void StartTls();
|
204
|
-
virtual void SetTlsParms (const char
|
208
|
+
virtual void SetTlsParms (const char *, const char *, bool, bool, const char *, const char *, const char *, const char *, int);
|
205
209
|
|
206
210
|
#ifdef WITH_SSL
|
207
211
|
virtual X509 *GetPeerCert();
|
212
|
+
virtual int GetCipherBits();
|
213
|
+
virtual const char *GetCipherName();
|
214
|
+
virtual const char *GetCipherProtocol();
|
215
|
+
virtual const char *GetSNIHostname();
|
208
216
|
virtual bool VerifySslPeer(const char*);
|
209
217
|
virtual void AcceptSslPeer();
|
210
218
|
#endif
|
@@ -245,8 +253,14 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
245
253
|
SslBox_t *SslBox;
|
246
254
|
std::string CertChainFilename;
|
247
255
|
std::string PrivateKeyFilename;
|
256
|
+
std::string CipherList;
|
257
|
+
std::string EcdhCurve;
|
258
|
+
std::string DhParam;
|
259
|
+
int Protocols;
|
248
260
|
bool bHandshakeSignaled;
|
249
261
|
bool bSslVerifyPeer;
|
262
|
+
bool bSslFailIfNoPeerCert;
|
263
|
+
std::string SniHostName;
|
250
264
|
bool bSslPeerAccepted;
|
251
265
|
#endif
|
252
266
|
|
@@ -275,7 +289,7 @@ class DatagramDescriptor
|
|
275
289
|
class DatagramDescriptor: public EventableDescriptor
|
276
290
|
{
|
277
291
|
public:
|
278
|
-
DatagramDescriptor (
|
292
|
+
DatagramDescriptor (SOCKET, EventMachine_t*);
|
279
293
|
virtual ~DatagramDescriptor();
|
280
294
|
|
281
295
|
virtual void Read();
|
@@ -299,18 +313,18 @@ class DatagramDescriptor: public EventableDescriptor
|
|
299
313
|
|
300
314
|
protected:
|
301
315
|
struct OutboundPage {
|
302
|
-
OutboundPage (const char *b, int l, struct
|
316
|
+
OutboundPage (const char *b, int l, struct sockaddr_in6 f, int o=0): Buffer(b), Length(l), Offset(o), From(f) {}
|
303
317
|
void Free() {if (Buffer) free (const_cast<char*>(Buffer)); }
|
304
318
|
const char *Buffer;
|
305
319
|
int Length;
|
306
320
|
int Offset;
|
307
|
-
struct
|
321
|
+
struct sockaddr_in6 From;
|
308
322
|
};
|
309
323
|
|
310
324
|
deque<OutboundPage> OutboundPages;
|
311
325
|
int OutboundDataSize;
|
312
326
|
|
313
|
-
struct
|
327
|
+
struct sockaddr_in6 ReturnAddress;
|
314
328
|
};
|
315
329
|
|
316
330
|
|
@@ -321,7 +335,7 @@ class AcceptorDescriptor
|
|
321
335
|
class AcceptorDescriptor: public EventableDescriptor
|
322
336
|
{
|
323
337
|
public:
|
324
|
-
AcceptorDescriptor (
|
338
|
+
AcceptorDescriptor (SOCKET, EventMachine_t*);
|
325
339
|
virtual ~AcceptorDescriptor();
|
326
340
|
|
327
341
|
virtual void Read();
|
@@ -344,7 +358,7 @@ class PipeDescriptor
|
|
344
358
|
class PipeDescriptor: public EventableDescriptor
|
345
359
|
{
|
346
360
|
public:
|
347
|
-
PipeDescriptor (
|
361
|
+
PipeDescriptor (SOCKET, pid_t, EventMachine_t*);
|
348
362
|
virtual ~PipeDescriptor();
|
349
363
|
|
350
364
|
virtual void Read();
|
data/ext/em.cpp
CHANGED
@@ -32,22 +32,15 @@ static unsigned int MaxOutstandingTimers = 100000;
|
|
32
32
|
*/
|
33
33
|
static unsigned int SimultaneousAcceptCount = 10;
|
34
34
|
|
35
|
-
|
36
|
-
/* Internal helper to convert strings to internet addresses. IPv6-aware.
|
37
|
-
* Not reentrant or threadsafe, optimized for speed.
|
38
|
-
*/
|
39
|
-
static struct sockaddr *name2address (const char *server, int port, int *family, int *bind_size);
|
40
|
-
|
41
35
|
/* Internal helper to create a socket with SOCK_CLOEXEC set, and fall
|
42
36
|
* back to fcntl'ing it if the headers/runtime don't support it.
|
43
37
|
*/
|
44
|
-
|
45
|
-
int EmSocket (int domain, int type, int protocol)
|
38
|
+
SOCKET EmSocket (int domain, int type, int protocol)
|
46
39
|
{
|
47
|
-
|
40
|
+
SOCKET sd;
|
48
41
|
#ifdef HAVE_SOCKET_CLOEXEC
|
49
42
|
sd = socket (domain, type | SOCK_CLOEXEC, protocol);
|
50
|
-
if (sd
|
43
|
+
if (sd == INVALID_SOCKET) {
|
51
44
|
sd = socket (domain, type, protocol);
|
52
45
|
if (sd < 0) {
|
53
46
|
return sd;
|
@@ -56,7 +49,7 @@ int EmSocket (int domain, int type, int protocol)
|
|
56
49
|
}
|
57
50
|
#else
|
58
51
|
sd = socket (domain, type, protocol);
|
59
|
-
if (sd
|
52
|
+
if (sd == INVALID_SOCKET) {
|
60
53
|
return sd;
|
61
54
|
}
|
62
55
|
SetFdCloexec(sd);
|
@@ -114,8 +107,8 @@ EventMachine_t::EventMachine_t (EMCallback event_callback, Poller_t poller):
|
|
114
107
|
NumCloseScheduled (0),
|
115
108
|
HeartbeatInterval(2000000),
|
116
109
|
EventCallback (event_callback),
|
117
|
-
LoopBreakerReader (
|
118
|
-
LoopBreakerWriter (
|
110
|
+
LoopBreakerReader (INVALID_SOCKET),
|
111
|
+
LoopBreakerWriter (INVALID_SOCKET),
|
119
112
|
bTerminateSignalReceived (false),
|
120
113
|
Poller (poller),
|
121
114
|
epfd (-1),
|
@@ -138,6 +131,11 @@ EventMachine_t::EventMachine_t (EMCallback event_callback, Poller_t poller):
|
|
138
131
|
(void) mach_timebase_info(&mach_timebase);
|
139
132
|
#endif
|
140
133
|
|
134
|
+
#ifdef OS_WIN32
|
135
|
+
TickCountTickover = 0;
|
136
|
+
LastTickCount = 0;
|
137
|
+
#endif
|
138
|
+
|
141
139
|
// Make sure the current loop time is sane, in case we do any initializations of
|
142
140
|
// objects before we start running.
|
143
141
|
_UpdateTime();
|
@@ -217,7 +215,10 @@ void EventMachine_t::ScheduleHalt()
|
|
217
215
|
SignalLoopBreaker();
|
218
216
|
}
|
219
217
|
|
220
|
-
|
218
|
+
bool EventMachine_t::Stopping()
|
219
|
+
{
|
220
|
+
return bTerminateSignalReceived;
|
221
|
+
}
|
221
222
|
|
222
223
|
/*******************************
|
223
224
|
EventMachine_t::SetTimerQuantum
|
@@ -240,6 +241,7 @@ void EventMachine_t::SetTimerQuantum (int interval)
|
|
240
241
|
(STATIC) EventMachine_t::SetuidString
|
241
242
|
*************************************/
|
242
243
|
|
244
|
+
#ifdef OS_UNIX
|
243
245
|
void EventMachine_t::SetuidString (const char *username)
|
244
246
|
{
|
245
247
|
/* This method takes a caller-supplied username and tries to setuid
|
@@ -256,7 +258,6 @@ void EventMachine_t::SetuidString (const char *username)
|
|
256
258
|
* A setuid failure here would be in the latter category.
|
257
259
|
*/
|
258
260
|
|
259
|
-
#ifdef OS_UNIX
|
260
261
|
if (!username || !*username)
|
261
262
|
throw std::runtime_error ("setuid_string failed: no username specified");
|
262
263
|
|
@@ -276,17 +277,18 @@ void EventMachine_t::SetuidString (const char *username)
|
|
276
277
|
throw std::runtime_error ("setuid_string failed: no setuid");
|
277
278
|
|
278
279
|
// Success.
|
279
|
-
#endif
|
280
280
|
}
|
281
|
-
|
281
|
+
#else
|
282
|
+
void EventMachine_t::SetuidString (const char *username UNUSED) { }
|
283
|
+
#endif
|
282
284
|
|
283
285
|
/****************************************
|
284
286
|
(STATIC) EventMachine_t::SetRlimitNofile
|
285
287
|
****************************************/
|
286
288
|
|
289
|
+
#ifdef OS_UNIX
|
287
290
|
int EventMachine_t::SetRlimitNofile (int nofiles)
|
288
291
|
{
|
289
|
-
#ifdef OS_UNIX
|
290
292
|
struct rlimit rlim;
|
291
293
|
getrlimit (RLIMIT_NOFILE, &rlim);
|
292
294
|
if (nofiles >= 0) {
|
@@ -299,14 +301,10 @@ int EventMachine_t::SetRlimitNofile (int nofiles)
|
|
299
301
|
}
|
300
302
|
getrlimit (RLIMIT_NOFILE, &rlim);
|
301
303
|
return rlim.rlim_cur;
|
302
|
-
#endif
|
303
|
-
|
304
|
-
#ifdef OS_WIN32
|
305
|
-
// No meaningful implementation on Windows.
|
306
|
-
return 0;
|
307
|
-
#endif
|
308
304
|
}
|
309
|
-
|
305
|
+
#else
|
306
|
+
int EventMachine_t::SetRlimitNofile (int nofiles UNUSED) { return 0; }
|
307
|
+
#endif
|
310
308
|
|
311
309
|
/*********************************
|
312
310
|
EventMachine_t::SignalLoopBreaker
|
@@ -361,7 +359,7 @@ void EventMachine_t::_InitializeLoopBreaker()
|
|
361
359
|
#endif
|
362
360
|
|
363
361
|
#ifdef OS_WIN32
|
364
|
-
|
362
|
+
SOCKET sd = EmSocket (AF_INET, SOCK_DGRAM, 0);
|
365
363
|
if (sd == INVALID_SOCKET)
|
366
364
|
throw std::runtime_error ("no loop breaker socket");
|
367
365
|
SetSocketNonblocking (sd);
|
@@ -914,7 +912,7 @@ SelectData_t::~SelectData_t()
|
|
914
912
|
_SelectDataSelect
|
915
913
|
*****************/
|
916
914
|
|
917
|
-
#if defined(
|
915
|
+
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
918
916
|
static VALUE _SelectDataSelect (void *v)
|
919
917
|
{
|
920
918
|
SelectData_t *sd = (SelectData_t*)v;
|
@@ -983,7 +981,7 @@ void EventMachine_t::_RunSelectOnce()
|
|
983
981
|
for (i = 0; i < Descriptors.size(); i++) {
|
984
982
|
EventableDescriptor *ed = Descriptors[i];
|
985
983
|
assert (ed);
|
986
|
-
|
984
|
+
SOCKET sd = ed->GetSocket();
|
987
985
|
if (ed->IsWatchOnly() && sd == INVALID_SOCKET)
|
988
986
|
continue;
|
989
987
|
assert (sd != INVALID_SOCKET);
|
@@ -1028,7 +1026,7 @@ void EventMachine_t::_RunSelectOnce()
|
|
1028
1026
|
for (i=0; i < Descriptors.size(); i++) {
|
1029
1027
|
EventableDescriptor *ed = Descriptors[i];
|
1030
1028
|
assert (ed);
|
1031
|
-
|
1029
|
+
SOCKET sd = ed->GetSocket();
|
1032
1030
|
if (ed->IsWatchOnly() && sd == INVALID_SOCKET)
|
1033
1031
|
continue;
|
1034
1032
|
assert (sd != INVALID_SOCKET);
|
@@ -1077,7 +1075,7 @@ void EventMachine_t::_CleanBadDescriptors()
|
|
1077
1075
|
if (ed->ShouldDelete())
|
1078
1076
|
continue;
|
1079
1077
|
|
1080
|
-
|
1078
|
+
SOCKET sd = ed->GetSocket();
|
1081
1079
|
|
1082
1080
|
struct timeval tv;
|
1083
1081
|
tv.tv_sec = 0;
|
@@ -1194,16 +1192,15 @@ const uintptr_t EventMachine_t::ConnectToServer (const char *bind_addr, int bind
|
|
1194
1192
|
if (!server || !*server || !port)
|
1195
1193
|
throw std::runtime_error ("invalid server or port");
|
1196
1194
|
|
1197
|
-
|
1198
|
-
|
1199
|
-
if (!
|
1195
|
+
struct sockaddr_storage bind_as;
|
1196
|
+
size_t bind_as_len = sizeof bind_as;
|
1197
|
+
if (!name2address (server, port, (struct sockaddr *)&bind_as, &bind_as_len)) {
|
1200
1198
|
char buf [200];
|
1201
1199
|
snprintf (buf, sizeof(buf)-1, "unable to resolve server address: %s", strerror(errno));
|
1202
1200
|
throw std::runtime_error (buf);
|
1203
1201
|
}
|
1204
|
-
bind_as = *bind_as_ptr; // copy because name2address points to a static
|
1205
1202
|
|
1206
|
-
|
1203
|
+
SOCKET sd = EmSocket (bind_as.ss_family, SOCK_STREAM, 0);
|
1207
1204
|
if (sd == INVALID_SOCKET) {
|
1208
1205
|
char buf [200];
|
1209
1206
|
snprintf (buf, sizeof(buf)-1, "unable to create new socket: %s", strerror(errno));
|
@@ -1223,23 +1220,23 @@ const uintptr_t EventMachine_t::ConnectToServer (const char *bind_addr, int bind
|
|
1223
1220
|
setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, (char*) &one, sizeof(one));
|
1224
1221
|
|
1225
1222
|
if (bind_addr) {
|
1226
|
-
|
1227
|
-
|
1228
|
-
if (!bind_to) {
|
1223
|
+
struct sockaddr_storage bind_to;
|
1224
|
+
size_t bind_to_len = sizeof bind_to;
|
1225
|
+
if (!name2address (bind_addr, bind_port, (struct sockaddr *)&bind_to, &bind_to_len)) {
|
1229
1226
|
close (sd);
|
1230
1227
|
throw std::runtime_error ("invalid bind address");
|
1231
1228
|
}
|
1232
|
-
if (bind (sd, bind_to,
|
1229
|
+
if (bind (sd, (struct sockaddr *)&bind_to, bind_to_len) < 0) {
|
1233
1230
|
close (sd);
|
1234
1231
|
throw std::runtime_error ("couldn't bind to address");
|
1235
1232
|
}
|
1236
1233
|
}
|
1237
1234
|
|
1238
1235
|
uintptr_t out = 0;
|
1239
|
-
int e = 0;
|
1240
1236
|
|
1241
1237
|
#ifdef OS_UNIX
|
1242
|
-
|
1238
|
+
int e_reason = 0;
|
1239
|
+
if (connect (sd, (struct sockaddr *)&bind_as, bind_as_len) == 0) {
|
1243
1240
|
// This is a connect success, which Linux appears
|
1244
1241
|
// never to give when the socket is nonblocking,
|
1245
1242
|
// even if the connection is intramachine or to
|
@@ -1285,13 +1282,13 @@ const uintptr_t EventMachine_t::ConnectToServer (const char *bind_addr, int bind
|
|
1285
1282
|
out = cd->GetBinding();
|
1286
1283
|
} else {
|
1287
1284
|
// Fall through to the !out case below.
|
1288
|
-
|
1285
|
+
e_reason = error;
|
1289
1286
|
}
|
1290
1287
|
}
|
1291
1288
|
else {
|
1292
1289
|
// The error from connect was something other then EINPROGRESS (EHOSTDOWN, etc).
|
1293
1290
|
// Fall through to the !out case below
|
1294
|
-
|
1291
|
+
e_reason = errno;
|
1295
1292
|
}
|
1296
1293
|
|
1297
1294
|
if (!out) {
|
@@ -1310,7 +1307,7 @@ const uintptr_t EventMachine_t::ConnectToServer (const char *bind_addr, int bind
|
|
1310
1307
|
ConnectionDescriptor *cd = new ConnectionDescriptor (sd, this);
|
1311
1308
|
if (!cd)
|
1312
1309
|
throw std::runtime_error ("no connection allocated");
|
1313
|
-
cd->SetUnbindReasonCode(
|
1310
|
+
cd->SetUnbindReasonCode (e_reason);
|
1314
1311
|
cd->ScheduleClose (false);
|
1315
1312
|
Add (cd);
|
1316
1313
|
out = cd->GetBinding();
|
@@ -1318,7 +1315,7 @@ const uintptr_t EventMachine_t::ConnectToServer (const char *bind_addr, int bind
|
|
1318
1315
|
#endif
|
1319
1316
|
|
1320
1317
|
#ifdef OS_WIN32
|
1321
|
-
if (connect (sd, (struct sockaddr*)&bind_as,
|
1318
|
+
if (connect (sd, (struct sockaddr *)&bind_as, bind_as_len) == 0) {
|
1322
1319
|
// This is a connect success, which Windows appears
|
1323
1320
|
// never to give when the socket is nonblocking,
|
1324
1321
|
// even if the connection is intramachine or to
|
@@ -1353,6 +1350,7 @@ const uintptr_t EventMachine_t::ConnectToServer (const char *bind_addr, int bind
|
|
1353
1350
|
EventMachine_t::ConnectToUnixServer
|
1354
1351
|
***********************************/
|
1355
1352
|
|
1353
|
+
#ifdef OS_UNIX
|
1356
1354
|
const uintptr_t EventMachine_t::ConnectToUnixServer (const char *server)
|
1357
1355
|
{
|
1358
1356
|
/* Connect to a Unix-domain server, which by definition is running
|
@@ -1362,14 +1360,6 @@ const uintptr_t EventMachine_t::ConnectToUnixServer (const char *server)
|
|
1362
1360
|
* is always local and can always be fulfilled immediately.
|
1363
1361
|
*/
|
1364
1362
|
|
1365
|
-
#ifdef OS_WIN32
|
1366
|
-
throw std::runtime_error ("unix-domain connection unavailable on this platform");
|
1367
|
-
return 0;
|
1368
|
-
#endif
|
1369
|
-
|
1370
|
-
// The whole rest of this function is only compiled on Unix systems.
|
1371
|
-
#ifdef OS_UNIX
|
1372
|
-
|
1373
1363
|
uintptr_t out = 0;
|
1374
1364
|
|
1375
1365
|
if (!server || !*server)
|
@@ -1387,7 +1377,7 @@ const uintptr_t EventMachine_t::ConnectToUnixServer (const char *server)
|
|
1387
1377
|
|
1388
1378
|
strcpy (pun.sun_path, server);
|
1389
1379
|
|
1390
|
-
|
1380
|
+
SOCKET fd = EmSocket (AF_LOCAL, SOCK_STREAM, 0);
|
1391
1381
|
if (fd == INVALID_SOCKET)
|
1392
1382
|
return 0;
|
1393
1383
|
|
@@ -1419,14 +1409,19 @@ const uintptr_t EventMachine_t::ConnectToUnixServer (const char *server)
|
|
1419
1409
|
close (fd);
|
1420
1410
|
|
1421
1411
|
return out;
|
1422
|
-
#endif
|
1423
1412
|
}
|
1413
|
+
#else
|
1414
|
+
const uintptr_t EventMachine_t::ConnectToUnixServer (const char *server UNUSED)
|
1415
|
+
{
|
1416
|
+
throw std::runtime_error ("unix-domain connection unavailable on this platform");
|
1417
|
+
}
|
1418
|
+
#endif
|
1424
1419
|
|
1425
1420
|
/************************
|
1426
1421
|
EventMachine_t::AttachFD
|
1427
1422
|
************************/
|
1428
1423
|
|
1429
|
-
const uintptr_t EventMachine_t::AttachFD (
|
1424
|
+
const uintptr_t EventMachine_t::AttachFD (SOCKET fd, bool watch_mode)
|
1430
1425
|
{
|
1431
1426
|
#ifdef OS_UNIX
|
1432
1427
|
if (fcntl(fd, F_GETFL, 0) < 0) {
|
@@ -1487,7 +1482,7 @@ int EventMachine_t::DetachFD (EventableDescriptor *ed)
|
|
1487
1482
|
if (!ed)
|
1488
1483
|
throw std::runtime_error ("detaching bad descriptor");
|
1489
1484
|
|
1490
|
-
|
1485
|
+
SOCKET fd = ed->GetSocket();
|
1491
1486
|
|
1492
1487
|
#ifdef HAVE_EPOLL
|
1493
1488
|
if (Poller == Poller_Epoll) {
|
@@ -1544,66 +1539,30 @@ int EventMachine_t::DetachFD (EventableDescriptor *ed)
|
|
1544
1539
|
name2address
|
1545
1540
|
************/
|
1546
1541
|
|
1547
|
-
|
1542
|
+
bool EventMachine_t::name2address (const char *server, int port, struct sockaddr *addr, size_t *addr_len)
|
1548
1543
|
{
|
1549
|
-
// THIS IS NOT RE-ENTRANT OR THREADSAFE. Optimize for speed.
|
1550
|
-
// Check the more-common cases first.
|
1551
|
-
// Return NULL if no resolution.
|
1552
|
-
|
1553
|
-
static struct sockaddr_in in4;
|
1554
|
-
#ifndef __CYGWIN__
|
1555
|
-
static struct sockaddr_in6 in6;
|
1556
|
-
#endif
|
1557
|
-
struct hostent *hp;
|
1558
|
-
|
1559
1544
|
if (!server || !*server)
|
1560
1545
|
server = "0.0.0.0";
|
1561
1546
|
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
*bind_size = sizeof(in4);
|
1568
|
-
in4.sin_family = AF_INET;
|
1569
|
-
in4.sin_port = htons (port);
|
1570
|
-
return (struct sockaddr*)&in4;
|
1571
|
-
}
|
1572
|
-
|
1573
|
-
#if defined(OS_UNIX) && !defined(__CYGWIN__)
|
1574
|
-
memset (&in6, 0, sizeof(in6));
|
1575
|
-
if (inet_pton (AF_INET6, server, in6.sin6_addr.s6_addr) > 0) {
|
1576
|
-
if (family)
|
1577
|
-
*family = AF_INET6;
|
1578
|
-
if (bind_size)
|
1579
|
-
*bind_size = sizeof(in6);
|
1580
|
-
in6.sin6_family = AF_INET6;
|
1581
|
-
in6.sin6_port = htons (port);
|
1582
|
-
return (struct sockaddr*)&in6;
|
1583
|
-
}
|
1584
|
-
#endif
|
1547
|
+
struct addrinfo *ai;
|
1548
|
+
struct addrinfo hints;
|
1549
|
+
memset (&hints, 0, sizeof(hints));
|
1550
|
+
hints.ai_family = AF_UNSPEC;
|
1551
|
+
hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG;
|
1585
1552
|
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1553
|
+
char portstr[12];
|
1554
|
+
snprintf(portstr, sizeof(portstr), "%u", port);
|
1555
|
+
|
1556
|
+
if (getaddrinfo (server, portstr, &hints, &ai) == 0) {
|
1557
|
+
assert (ai->ai_addrlen <= *addr_len);
|
1558
|
+
memcpy (addr, ai->ai_addr, ai->ai_addrlen);
|
1559
|
+
*addr_len = ai->ai_addrlen;
|
1593
1560
|
|
1594
|
-
|
1595
|
-
|
1596
|
-
in4.sin_addr.s_addr = ((in_addr*)(hp->h_addr))->s_addr;
|
1597
|
-
if (family)
|
1598
|
-
*family = AF_INET;
|
1599
|
-
if (bind_size)
|
1600
|
-
*bind_size = sizeof(in4);
|
1601
|
-
in4.sin_family = AF_INET;
|
1602
|
-
in4.sin_port = htons (port);
|
1603
|
-
return (struct sockaddr*)&in4;
|
1561
|
+
freeaddrinfo(ai);
|
1562
|
+
return true;
|
1604
1563
|
}
|
1605
1564
|
|
1606
|
-
return
|
1565
|
+
return false;
|
1607
1566
|
}
|
1608
1567
|
|
1609
1568
|
|
@@ -1620,14 +1579,12 @@ const uintptr_t EventMachine_t::CreateTcpServer (const char *server, int port)
|
|
1620
1579
|
*/
|
1621
1580
|
|
1622
1581
|
|
1623
|
-
|
1624
|
-
|
1625
|
-
if (!bind_here)
|
1582
|
+
struct sockaddr_storage bind_here;
|
1583
|
+
size_t bind_here_len = sizeof bind_here;
|
1584
|
+
if (!name2address (server, port, (struct sockaddr *)&bind_here, &bind_here_len))
|
1626
1585
|
return 0;
|
1627
1586
|
|
1628
|
-
|
1629
|
-
|
1630
|
-
int sd_accept = EmSocket (family, SOCK_STREAM, 0);
|
1587
|
+
SOCKET sd_accept = EmSocket (bind_here.ss_family, SOCK_STREAM, 0);
|
1631
1588
|
if (sd_accept == INVALID_SOCKET) {
|
1632
1589
|
goto fail;
|
1633
1590
|
}
|
@@ -1650,8 +1607,7 @@ const uintptr_t EventMachine_t::CreateTcpServer (const char *server, int port)
|
|
1650
1607
|
}
|
1651
1608
|
|
1652
1609
|
|
1653
|
-
|
1654
|
-
if (bind (sd_accept, bind_here, bind_size)) {
|
1610
|
+
if (bind (sd_accept, (struct sockaddr *)&bind_here, bind_here_len)) {
|
1655
1611
|
//__warning ("binding failed");
|
1656
1612
|
goto fail;
|
1657
1613
|
}
|
@@ -1678,40 +1634,27 @@ const uintptr_t EventMachine_t::OpenDatagramSocket (const char *address, int por
|
|
1678
1634
|
{
|
1679
1635
|
uintptr_t output_binding = 0;
|
1680
1636
|
|
1681
|
-
|
1637
|
+
struct sockaddr_storage bind_here;
|
1638
|
+
size_t bind_here_len = sizeof bind_here;
|
1639
|
+
if (!name2address (address, port, (struct sockaddr *)&bind_here, &bind_here_len))
|
1640
|
+
return 0;
|
1641
|
+
|
1642
|
+
// from here on, early returns must close the socket!
|
1643
|
+
SOCKET sd = EmSocket (bind_here.ss_family, SOCK_DGRAM, 0);
|
1682
1644
|
if (sd == INVALID_SOCKET)
|
1683
1645
|
goto fail;
|
1684
|
-
// from here on, early returns must close the socket!
|
1685
|
-
|
1686
|
-
|
1687
|
-
struct sockaddr_in sin;
|
1688
|
-
memset (&sin, 0, sizeof(sin));
|
1689
|
-
sin.sin_family = AF_INET;
|
1690
|
-
sin.sin_port = htons (port);
|
1691
|
-
|
1692
1646
|
|
1693
|
-
|
1694
|
-
|
1695
|
-
if (
|
1696
|
-
|
1697
|
-
if (hp == NULL)
|
1698
|
-
goto fail;
|
1699
|
-
sin.sin_addr.s_addr = ((in_addr*)(hp->h_addr))->s_addr;
|
1700
|
-
}
|
1647
|
+
{ // set the SO_REUSEADDR on the socket before we bind, otherwise it won't work for a second one
|
1648
|
+
int oval = 1;
|
1649
|
+
if (setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, (char*)&oval, sizeof(oval)) < 0)
|
1650
|
+
goto fail;
|
1701
1651
|
}
|
1702
|
-
else
|
1703
|
-
sin.sin_addr.s_addr = htonl (INADDR_ANY);
|
1704
|
-
|
1705
1652
|
|
1706
1653
|
// Set the new socket nonblocking.
|
1707
|
-
|
1708
|
-
|
1709
|
-
//int val = fcntl (sd, F_GETFL, 0);
|
1710
|
-
//if (fcntl (sd, F_SETFL, val | O_NONBLOCK) == -1)
|
1711
|
-
goto fail;
|
1712
|
-
}
|
1654
|
+
if (!SetSocketNonblocking (sd))
|
1655
|
+
goto fail;
|
1713
1656
|
|
1714
|
-
if (bind (sd, (struct sockaddr*)&
|
1657
|
+
if (bind (sd, (struct sockaddr *)&bind_here, bind_here_len) != 0)
|
1715
1658
|
goto fail;
|
1716
1659
|
|
1717
1660
|
{ // Looking good.
|
@@ -1953,6 +1896,7 @@ void EventMachine_t::Deregister (EventableDescriptor *ed)
|
|
1953
1896
|
EventMachine_t::CreateUnixDomainServer
|
1954
1897
|
**************************************/
|
1955
1898
|
|
1899
|
+
#ifdef OS_UNIX
|
1956
1900
|
const uintptr_t EventMachine_t::CreateUnixDomainServer (const char *filename)
|
1957
1901
|
{
|
1958
1902
|
/* Create a UNIX-domain acceptor (server) socket and add it to the event machine.
|
@@ -1962,16 +1906,9 @@ const uintptr_t EventMachine_t::CreateUnixDomainServer (const char *filename)
|
|
1962
1906
|
* THERE IS NO MEANINGFUL IMPLEMENTATION ON WINDOWS.
|
1963
1907
|
*/
|
1964
1908
|
|
1965
|
-
#ifdef OS_WIN32
|
1966
|
-
throw std::runtime_error ("unix-domain server unavailable on this platform");
|
1967
|
-
#endif
|
1968
|
-
|
1969
|
-
// The whole rest of this function is only compiled on Unix systems.
|
1970
|
-
#ifdef OS_UNIX
|
1971
|
-
|
1972
1909
|
struct sockaddr_un s_sun;
|
1973
1910
|
|
1974
|
-
|
1911
|
+
SOCKET sd_accept = EmSocket (AF_LOCAL, SOCK_STREAM, 0);
|
1975
1912
|
if (sd_accept == INVALID_SOCKET) {
|
1976
1913
|
goto fail;
|
1977
1914
|
}
|
@@ -2011,15 +1948,20 @@ const uintptr_t EventMachine_t::CreateUnixDomainServer (const char *filename)
|
|
2011
1948
|
if (sd_accept != INVALID_SOCKET)
|
2012
1949
|
close (sd_accept);
|
2013
1950
|
return 0;
|
2014
|
-
#endif // OS_UNIX
|
2015
1951
|
}
|
1952
|
+
#else
|
1953
|
+
const uintptr_t EventMachine_t::CreateUnixDomainServer (const char *filename UNUSED)
|
1954
|
+
{
|
1955
|
+
throw std::runtime_error ("unix-domain server unavailable on this platform");
|
1956
|
+
}
|
1957
|
+
#endif
|
2016
1958
|
|
2017
1959
|
|
2018
1960
|
/**************************************
|
2019
1961
|
EventMachine_t::AttachSD
|
2020
1962
|
**************************************/
|
2021
1963
|
|
2022
|
-
const uintptr_t EventMachine_t::AttachSD (
|
1964
|
+
const uintptr_t EventMachine_t::AttachSD (SOCKET sd_accept)
|
2023
1965
|
{
|
2024
1966
|
uintptr_t output_binding = 0;
|
2025
1967
|
|
@@ -2054,15 +1996,9 @@ const uintptr_t EventMachine_t::AttachSD (int sd_accept)
|
|
2054
1996
|
EventMachine_t::Socketpair
|
2055
1997
|
**************************/
|
2056
1998
|
|
2057
|
-
|
1999
|
+
#ifdef OS_UNIX
|
2000
|
+
const uintptr_t EventMachine_t::Socketpair (char * const * cmd_strings)
|
2058
2001
|
{
|
2059
|
-
#ifdef OS_WIN32
|
2060
|
-
throw std::runtime_error ("socketpair is currently unavailable on this platform");
|
2061
|
-
#endif
|
2062
|
-
|
2063
|
-
// The whole rest of this function is only compiled on Unix systems.
|
2064
|
-
// Eventually we need this functionality (or a full-duplex equivalent) on Windows.
|
2065
|
-
#ifdef OS_UNIX
|
2066
2002
|
// Make sure the incoming array of command strings is sane.
|
2067
2003
|
if (!cmd_strings)
|
2068
2004
|
return 0;
|
@@ -2110,8 +2046,14 @@ const uintptr_t EventMachine_t::Socketpair (char * const*cmd_strings)
|
|
2110
2046
|
throw std::runtime_error ("no fork");
|
2111
2047
|
|
2112
2048
|
return output_binding;
|
2113
|
-
#endif
|
2114
2049
|
}
|
2050
|
+
#else
|
2051
|
+
const uintptr_t EventMachine_t::Socketpair (char * const * cmd_strings UNUSED)
|
2052
|
+
{
|
2053
|
+
throw std::runtime_error ("socketpair is currently unavailable on this platform");
|
2054
|
+
}
|
2055
|
+
#endif
|
2056
|
+
|
2115
2057
|
|
2116
2058
|
|
2117
2059
|
/****************************
|