eventmachine 1.0.9.1-java → 1.2.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
/****************************
|