ffi-nats-core 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/ffi-nats-core.gemspec +8 -0
  3. data/lib/ffi/nats/core/version.rb +1 -1
  4. data/vendor/cnats/CMakeLists.txt +137 -0
  5. data/vendor/cnats/adapters/libevent.h +220 -0
  6. data/vendor/cnats/adapters/libuv.h +472 -0
  7. data/vendor/cnats/examples/CMakeLists.txt +56 -0
  8. data/vendor/cnats/examples/asynctimeout.c +83 -0
  9. data/vendor/cnats/examples/examples.h +322 -0
  10. data/vendor/cnats/examples/libevent-pub.c +136 -0
  11. data/vendor/cnats/examples/libevent-sub.c +104 -0
  12. data/vendor/cnats/examples/libuv-pub.c +120 -0
  13. data/vendor/cnats/examples/libuv-sub.c +114 -0
  14. data/vendor/cnats/examples/publisher.c +62 -0
  15. data/vendor/cnats/examples/queuegroup.c +132 -0
  16. data/vendor/cnats/examples/replier.c +149 -0
  17. data/vendor/cnats/examples/requestor.c +75 -0
  18. data/vendor/cnats/examples/subscriber.c +133 -0
  19. data/vendor/cnats/src/CMakeLists.txt +31 -0
  20. data/vendor/cnats/src/asynccb.c +66 -0
  21. data/vendor/cnats/src/asynccb.h +42 -0
  22. data/vendor/cnats/src/buf.c +246 -0
  23. data/vendor/cnats/src/buf.h +116 -0
  24. data/vendor/cnats/src/comsock.c +474 -0
  25. data/vendor/cnats/src/comsock.h +81 -0
  26. data/vendor/cnats/src/conn.c +2725 -0
  27. data/vendor/cnats/src/conn.h +75 -0
  28. data/vendor/cnats/src/err.h +31 -0
  29. data/vendor/cnats/src/gc.h +27 -0
  30. data/vendor/cnats/src/hash.c +725 -0
  31. data/vendor/cnats/src/hash.h +141 -0
  32. data/vendor/cnats/src/include/n-unix.h +56 -0
  33. data/vendor/cnats/src/include/n-win.h +59 -0
  34. data/vendor/cnats/src/mem.h +20 -0
  35. data/vendor/cnats/src/msg.c +155 -0
  36. data/vendor/cnats/src/msg.h +43 -0
  37. data/vendor/cnats/src/nats.c +1734 -0
  38. data/vendor/cnats/src/nats.h +2024 -0
  39. data/vendor/cnats/src/natsp.h +518 -0
  40. data/vendor/cnats/src/natstime.c +79 -0
  41. data/vendor/cnats/src/natstime.h +27 -0
  42. data/vendor/cnats/src/nuid.c +265 -0
  43. data/vendor/cnats/src/nuid.h +21 -0
  44. data/vendor/cnats/src/opts.c +1030 -0
  45. data/vendor/cnats/src/opts.h +19 -0
  46. data/vendor/cnats/src/parser.c +869 -0
  47. data/vendor/cnats/src/parser.h +87 -0
  48. data/vendor/cnats/src/pub.c +293 -0
  49. data/vendor/cnats/src/srvpool.c +380 -0
  50. data/vendor/cnats/src/srvpool.h +71 -0
  51. data/vendor/cnats/src/stats.c +54 -0
  52. data/vendor/cnats/src/stats.h +21 -0
  53. data/vendor/cnats/src/status.c +60 -0
  54. data/vendor/cnats/src/status.h +95 -0
  55. data/vendor/cnats/src/sub.c +956 -0
  56. data/vendor/cnats/src/sub.h +34 -0
  57. data/vendor/cnats/src/timer.c +86 -0
  58. data/vendor/cnats/src/timer.h +57 -0
  59. data/vendor/cnats/src/unix/cond.c +103 -0
  60. data/vendor/cnats/src/unix/mutex.c +107 -0
  61. data/vendor/cnats/src/unix/sock.c +105 -0
  62. data/vendor/cnats/src/unix/thread.c +162 -0
  63. data/vendor/cnats/src/url.c +134 -0
  64. data/vendor/cnats/src/url.h +24 -0
  65. data/vendor/cnats/src/util.c +823 -0
  66. data/vendor/cnats/src/util.h +75 -0
  67. data/vendor/cnats/src/version.h +29 -0
  68. data/vendor/cnats/src/version.h.in +29 -0
  69. data/vendor/cnats/src/win/cond.c +86 -0
  70. data/vendor/cnats/src/win/mutex.c +54 -0
  71. data/vendor/cnats/src/win/sock.c +158 -0
  72. data/vendor/cnats/src/win/strings.c +108 -0
  73. data/vendor/cnats/src/win/thread.c +180 -0
  74. data/vendor/cnats/test/CMakeLists.txt +35 -0
  75. data/vendor/cnats/test/certs/ca.pem +38 -0
  76. data/vendor/cnats/test/certs/client-cert.pem +30 -0
  77. data/vendor/cnats/test/certs/client-key.pem +51 -0
  78. data/vendor/cnats/test/certs/server-cert.pem +31 -0
  79. data/vendor/cnats/test/certs/server-key.pem +51 -0
  80. data/vendor/cnats/test/dylib/CMakeLists.txt +10 -0
  81. data/vendor/cnats/test/dylib/nonats.c +13 -0
  82. data/vendor/cnats/test/list.txt +125 -0
  83. data/vendor/cnats/test/test.c +11655 -0
  84. data/vendor/cnats/test/tls.conf +15 -0
  85. data/vendor/cnats/test/tlsverify.conf +19 -0
  86. metadata +83 -1
@@ -0,0 +1,474 @@
1
+ // Copyright 2015 Apcera Inc. All rights reserved.
2
+
3
+ #include "natsp.h"
4
+
5
+ #include <errno.h>
6
+ #include <string.h>
7
+ #include <stdio.h>
8
+ #include <assert.h>
9
+ #include <time.h>
10
+
11
+ #include "status.h"
12
+ #include "comsock.h"
13
+ #include "mem.h"
14
+
15
+ static void
16
+ _closeFd(natsSock fd)
17
+ {
18
+ if (fd != NATS_SOCK_INVALID)
19
+ NATS_SOCK_CLOSE(fd);
20
+ }
21
+
22
+ void
23
+ natsSock_Close(natsSock fd)
24
+ {
25
+ _closeFd(fd);
26
+ }
27
+
28
+ void
29
+ natsSock_Shutdown(natsSock fd)
30
+ {
31
+ if (fd != NATS_SOCK_INVALID)
32
+ NATS_SOCK_SHUTDOWN(fd);
33
+ }
34
+
35
+ natsStatus
36
+ natsSock_SetCommonTcpOptions(natsSock fd)
37
+ {
38
+ struct linger l;
39
+ int yes = 1;
40
+
41
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char*) &yes, sizeof(yes)) == -1)
42
+ return nats_setError(NATS_SYS_ERROR, "setsockopt TCP_NO_DELAY error: %d",
43
+ NATS_SOCK_GET_ERROR);
44
+
45
+ yes = 1;
46
+
47
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*) &yes, sizeof(yes)) == -1)
48
+ return nats_setError(NATS_SYS_ERROR, "setsockopt SO_REUSEADDR error: %d",
49
+ NATS_SOCK_GET_ERROR);
50
+
51
+ l.l_onoff = 1;
52
+ l.l_linger = 0;
53
+
54
+ if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (void*)&l, sizeof(l)) == -1)
55
+ return nats_setError(NATS_SYS_ERROR, "setsockopt SO_LINGER error: %d",
56
+ NATS_SOCK_GET_ERROR);
57
+
58
+ return NATS_OK;
59
+ }
60
+
61
+ natsStatus
62
+ natsSock_CreateFDSet(fd_set **newFDSet)
63
+ {
64
+ fd_set *fdSet = NULL;
65
+
66
+ #ifdef _WIN32
67
+ #else
68
+ assert(FD_SETSIZE == 32768);
69
+ #endif
70
+
71
+ fdSet = (fd_set*) NATS_MALLOC(sizeof(fd_set));
72
+
73
+ if (fdSet == NULL)
74
+ return nats_setDefaultError(NATS_NO_MEMORY);
75
+
76
+ FD_ZERO(fdSet);
77
+
78
+ *newFDSet = fdSet;
79
+
80
+ return NATS_OK;
81
+ }
82
+
83
+ void
84
+ natsSock_DestroyFDSet(fd_set *fdSet)
85
+ {
86
+ if (fdSet == NULL)
87
+ return;
88
+
89
+ NATS_FREE(fdSet);
90
+ }
91
+
92
+ #define MAX_HOST_NAME (256)
93
+
94
+ natsStatus
95
+ natsSock_ConnectTcp(natsSockCtx *ctx, const char *phost, int port)
96
+ {
97
+ natsStatus s = NATS_OK;
98
+ int res;
99
+ char sport[6];
100
+ struct addrinfo hints;
101
+ struct addrinfo *servinfo = NULL;
102
+ struct addrinfo *p;
103
+ bool waitForConnect = false;
104
+ bool error = false;
105
+ int i;
106
+ int max = 2;
107
+ char hosta[MAX_HOST_NAME];
108
+ int hostLen;
109
+ char *host;
110
+
111
+ if (phost == NULL)
112
+ return nats_setError(NATS_ADDRESS_MISSING, "%s", "No host specified");
113
+
114
+ hostLen = (int) strlen(phost);
115
+ if ((hostLen == 0) || ((hostLen == 1) && phost[0] == '['))
116
+ return nats_setError(NATS_INVALID_ARG, "Invalid host name: %s", phost);
117
+
118
+ if (phost[0] == '[')
119
+ {
120
+ snprintf(hosta, sizeof(hosta), "%.*s", hostLen - 2, phost + 1);
121
+ host = (char*) hosta;
122
+ }
123
+ else
124
+ host = (char*) phost;
125
+
126
+ snprintf(sport, sizeof(sport), "%d", port);
127
+
128
+ if ((ctx->orderIP == 4) || (ctx->orderIP == 6))
129
+ max = 1;
130
+
131
+ for (i=0; i<max; i++)
132
+ {
133
+ memset(&hints,0,sizeof(hints));
134
+ hints.ai_socktype = SOCK_STREAM;
135
+
136
+ switch (ctx->orderIP)
137
+ {
138
+ case 4: hints.ai_family = AF_INET; break;
139
+ case 6: hints.ai_family = AF_INET6; break;
140
+ case 46: hints.ai_family = (i == 0 ? AF_INET : AF_INET6); break;
141
+ case 64: hints.ai_family = (i == 0 ? AF_INET6 : AF_INET); break;
142
+ default: hints.ai_family = AF_UNSPEC;
143
+ }
144
+
145
+ s = NATS_OK;
146
+ if ((res = getaddrinfo(host, sport, &hints, &servinfo)) != 0)
147
+ {
148
+ s = nats_setError(NATS_SYS_ERROR, "getaddrinfo error: %s",
149
+ gai_strerror(res));
150
+ }
151
+ for (p = servinfo; (s == NATS_OK) && (p != NULL); p = p->ai_next)
152
+ {
153
+ ctx->fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
154
+ if (ctx->fd == NATS_SOCK_INVALID)
155
+ continue;
156
+
157
+ error = false;
158
+
159
+ s = natsSock_SetBlocking(ctx->fd, false);
160
+ if (s != NATS_OK)
161
+ break;
162
+
163
+ res = connect(ctx->fd, p->ai_addr, (natsSockLen) p->ai_addrlen);
164
+ if ((res == NATS_SOCK_ERROR)
165
+ && (NATS_SOCK_GET_ERROR == NATS_SOCK_CONNECT_IN_PROGRESS))
166
+ {
167
+ if ((natsSock_WaitReady(WAIT_FOR_CONNECT, ctx) != NATS_OK)
168
+ || !natsSock_IsConnected(ctx->fd))
169
+ {
170
+ error = true;
171
+ }
172
+ }
173
+ else if (res == NATS_SOCK_ERROR)
174
+ {
175
+ error = true;
176
+ }
177
+
178
+ if (error)
179
+ {
180
+ _closeFd(ctx->fd);
181
+ ctx->fd = NATS_SOCK_INVALID;
182
+ continue;
183
+ }
184
+
185
+ s = natsSock_SetCommonTcpOptions(ctx->fd);
186
+ if (s == NATS_OK)
187
+ break;
188
+ }
189
+
190
+ if (s == NATS_OK)
191
+ {
192
+ if (ctx->fd == NATS_SOCK_INVALID)
193
+ s = nats_setDefaultError(NATS_NO_SERVER);
194
+ }
195
+
196
+ freeaddrinfo(servinfo);
197
+ servinfo = NULL;
198
+
199
+ if (s == NATS_OK)
200
+ {
201
+ // Clear the error stack in case we got errors in the loop until
202
+ // being able to successfully connect.
203
+ nats_clearLastError();
204
+ break;
205
+ }
206
+ else
207
+ {
208
+ _closeFd(ctx->fd);
209
+ ctx->fd = NATS_SOCK_INVALID;
210
+ }
211
+ }
212
+
213
+ return NATS_UPDATE_ERR_STACK(s);
214
+ }
215
+
216
+ natsStatus
217
+ natsSock_ReadLine(natsSockCtx *ctx, char *buffer, size_t maxBufferSize)
218
+ {
219
+ natsStatus s = NATS_OK;
220
+ int readBytes = 0;
221
+ size_t totalBytes = 0;
222
+ char *p = buffer;
223
+ char *eol;
224
+
225
+ // By contract, the caller needs to set buffer[0] to '\0' before the first
226
+ // call.
227
+ if (*p != '\0')
228
+ {
229
+ // We assume that this is not the first call with the given buffer.
230
+ // Move possible data after the first line to the beginning of the
231
+ // buffer.
232
+ char *nextLine;
233
+ size_t nextStart;
234
+ size_t len = 0;
235
+
236
+ // The start of the next line will be the length of the line at the
237
+ // start of the buffer + 2, which is the number of characters
238
+ // representing CRLF.
239
+ nextStart = strlen(buffer) + 2;
240
+ nextLine = (char*) (buffer + nextStart);
241
+
242
+ // There is some data...
243
+ if (*nextLine != '\0')
244
+ {
245
+ // The next line (even if partial) is guaranteed to be NULL
246
+ // terminated.
247
+ len = strlen(nextLine);
248
+
249
+ // Move to the beginning of the buffer (and include the NULL char)
250
+ memmove(buffer, nextLine, len + 1);
251
+
252
+ // Now, if the string contains a CRLF, we don't even need to read
253
+ // from the socket. Update the buffer and return.
254
+ if ((eol = strstr(buffer, _CRLF_)) != NULL)
255
+ {
256
+ // Replace the '\r' with '\0' to NULL terminate the string.
257
+ *eol = '\0';
258
+
259
+ // We are done!
260
+ return NATS_OK;
261
+ }
262
+
263
+ // This is a partial, we need to read more data until we get to
264
+ // the end of the line (\r\n).
265
+ p = (char*) (p + len);
266
+ }
267
+ else
268
+ {
269
+ *p = '\0';
270
+ }
271
+ }
272
+
273
+ while (1)
274
+ {
275
+ s = natsSock_Read(ctx, p, (maxBufferSize - totalBytes), &readBytes);
276
+ if (s != NATS_OK)
277
+ return NATS_UPDATE_ERR_STACK(s);
278
+
279
+ if (totalBytes + readBytes == maxBufferSize)
280
+ return nats_setDefaultError(NATS_LINE_TOO_LONG);
281
+
282
+ // We need to append a NULL character after what we have received.
283
+ *(p + readBytes) = '\0';
284
+
285
+ if ((eol = strstr(p, _CRLF_)) != NULL)
286
+ {
287
+ *eol = '\0';
288
+ return NATS_OK;
289
+ }
290
+
291
+ p += readBytes;
292
+ totalBytes += readBytes;
293
+ }
294
+ }
295
+
296
+ natsStatus
297
+ natsSock_Read(natsSockCtx *ctx, char *buffer, size_t maxBufferSize, int *n)
298
+ {
299
+ natsStatus s = NATS_OK;
300
+ int readBytes = 0;
301
+ bool needRead = true;
302
+
303
+ while (needRead)
304
+ {
305
+ #if defined(NATS_HAS_TLS)
306
+ if (ctx->ssl != NULL)
307
+ readBytes = SSL_read(ctx->ssl, buffer, (int) maxBufferSize);
308
+ else
309
+ #endif
310
+ readBytes = recv(ctx->fd, buffer, (natsRecvLen) maxBufferSize, 0);
311
+
312
+ if (readBytes == 0)
313
+ {
314
+ return NATS_CONNECTION_CLOSED;
315
+ }
316
+ else if (readBytes == NATS_SOCK_ERROR)
317
+ {
318
+ #if defined(NATS_HAS_TLS)
319
+ if (ctx->ssl != NULL)
320
+ {
321
+ int sslErr = SSL_get_error(ctx->ssl, readBytes);
322
+
323
+ if ((sslErr != SSL_ERROR_WANT_READ)
324
+ && (sslErr != SSL_ERROR_WANT_WRITE))
325
+ {
326
+ return nats_setError(NATS_IO_ERROR, "SSL_read error: %s",
327
+ NATS_SSL_ERR_REASON_STRING);
328
+ }
329
+ else
330
+ {
331
+ // SSL requires that we go back with the same buffer
332
+ // and size. We can't return until SSL_read returns
333
+ // success (bytes read) or a different error.
334
+ continue;
335
+ }
336
+ }
337
+ else
338
+ #endif
339
+ if (NATS_SOCK_GET_ERROR != NATS_SOCK_WOULD_BLOCK)
340
+ {
341
+ return nats_setError(NATS_IO_ERROR, "recv error: %d",
342
+ NATS_SOCK_GET_ERROR);
343
+ }
344
+ else if (ctx->useEventLoop)
345
+ {
346
+ // When using an external event loop, we are done. We will be
347
+ // called again...
348
+ if (n != NULL)
349
+ *n = 0;
350
+
351
+ return NATS_OK;
352
+ }
353
+
354
+ // For non-blocking sockets, if the read would block, we need to
355
+ // wait up to the deadline.
356
+ s = natsSock_WaitReady(WAIT_FOR_READ, ctx);
357
+ if (s != NATS_OK)
358
+ return NATS_UPDATE_ERR_STACK(s);
359
+
360
+ continue;
361
+ }
362
+
363
+ if (n != NULL)
364
+ *n = readBytes;
365
+
366
+ needRead = false;
367
+ }
368
+
369
+ return NATS_OK;
370
+ }
371
+
372
+ natsStatus
373
+ natsSock_Write(natsSockCtx *ctx, const char *data, int len, int *n)
374
+ {
375
+ natsStatus s = NATS_OK;
376
+ int bytes = 0;
377
+ bool needWrite = true;
378
+
379
+ while (needWrite)
380
+ {
381
+ #if defined(NATS_HAS_TLS)
382
+ if (ctx->ssl != NULL)
383
+ bytes = SSL_write(ctx->ssl, data, len);
384
+ else
385
+ #endif
386
+ bytes = send(ctx->fd, data, len, 0);
387
+
388
+ if (bytes == 0)
389
+ {
390
+ return NATS_CONNECTION_CLOSED;
391
+ }
392
+ else if (bytes == NATS_SOCK_ERROR)
393
+ {
394
+ #if defined(NATS_HAS_TLS)
395
+ if (ctx->ssl != NULL)
396
+ {
397
+ int sslErr = SSL_get_error(ctx->ssl, bytes);
398
+ if ((sslErr != SSL_ERROR_WANT_READ)
399
+ && (sslErr != SSL_ERROR_WANT_WRITE))
400
+ {
401
+ return nats_setError(NATS_IO_ERROR, "SSL_write error: %s",
402
+ NATS_SSL_ERR_REASON_STRING);
403
+ }
404
+ else
405
+ {
406
+ // SSL requires that we go back with the same buffer
407
+ // and size. We can't return until SSL_write returns
408
+ // success (bytes written) a different error.
409
+ continue;
410
+ }
411
+ }
412
+ else
413
+ #endif
414
+ if (NATS_SOCK_GET_ERROR != NATS_SOCK_WOULD_BLOCK)
415
+ {
416
+ return nats_setError(NATS_IO_ERROR, "send error: %d",
417
+ NATS_SOCK_GET_ERROR);
418
+ }
419
+ else if (ctx->useEventLoop)
420
+ {
421
+ // With external event loop, we are done now, we will be
422
+ // called later for more.
423
+ if (n != NULL)
424
+ *n = 0;
425
+
426
+ return NATS_OK;
427
+ }
428
+
429
+ // For non-blocking sockets, if the write would block, we need to
430
+ // wait up to the deadline.
431
+ s = natsSock_WaitReady(WAIT_FOR_WRITE, ctx);
432
+ if (s != NATS_OK)
433
+ return NATS_UPDATE_ERR_STACK(s);
434
+
435
+ continue;
436
+ }
437
+
438
+ if (n != NULL)
439
+ *n = bytes;
440
+
441
+ needWrite = false;
442
+ }
443
+
444
+ return NATS_OK;
445
+ }
446
+
447
+ natsStatus
448
+ natsSock_WriteFully(natsSockCtx *ctx, const char *data, int len)
449
+ {
450
+ natsStatus s = NATS_OK;
451
+ int bytes = 0;
452
+ int n = 0;
453
+
454
+ do
455
+ {
456
+ s = natsSock_Write(ctx, data, len, &n);
457
+ if (s == NATS_OK)
458
+ {
459
+ if (n > 0)
460
+ {
461
+ data += n;
462
+ len -= n;
463
+ }
464
+
465
+ // We use an external event loop and got nothing, or we have
466
+ // sent the whole buffer. Return.
467
+ if ((n == 0) || (len == 0))
468
+ return NATS_OK;
469
+ }
470
+ }
471
+ while (s == NATS_OK);
472
+
473
+ return NATS_UPDATE_ERR_STACK(s);
474
+ }