spiped 0.0.0

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.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/ext/spiped/extconf.rb +3 -0
  3. data/ext/spiped/spiped-source/BUILDING +46 -0
  4. data/ext/spiped/spiped-source/CHANGELOG +44 -0
  5. data/ext/spiped/spiped-source/COPYRIGHT +33 -0
  6. data/ext/spiped/spiped-source/Makefile +47 -0
  7. data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
  8. data/ext/spiped/spiped-source/Makefile.inc +20 -0
  9. data/ext/spiped/spiped-source/Makefile.prog +23 -0
  10. data/ext/spiped/spiped-source/POSIX/README +10 -0
  11. data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
  12. data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
  13. data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
  14. data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
  15. data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
  16. data/ext/spiped/spiped-source/README +198 -0
  17. data/ext/spiped/spiped-source/STYLE +151 -0
  18. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
  19. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
  20. data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
  21. data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
  22. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
  23. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
  24. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
  25. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
  26. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
  27. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
  28. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
  29. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
  30. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
  31. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
  32. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
  33. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
  34. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
  35. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
  36. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
  37. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
  38. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
  39. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
  40. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
  41. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
  42. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
  43. data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
  44. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
  45. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
  46. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
  47. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
  48. data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
  49. data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
  50. data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
  51. data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
  52. data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
  53. data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
  54. data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
  55. data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
  56. data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
  57. data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
  58. data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
  59. data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
  60. data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
  61. data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
  62. data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
  63. data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
  64. data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
  65. data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
  66. data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
  67. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
  68. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
  69. data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
  70. data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
  71. data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
  72. data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
  73. data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
  74. data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
  75. data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
  76. data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
  77. data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
  78. data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
  79. data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
  80. data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
  81. data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
  82. data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
  83. data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
  84. data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
  85. data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
  86. data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
  87. data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
  88. data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
  89. data/ext/spiped/spiped-source/spipe/Makefile +90 -0
  90. data/ext/spiped/spiped-source/spipe/README +24 -0
  91. data/ext/spiped/spiped-source/spipe/main.c +178 -0
  92. data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
  93. data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
  94. data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
  95. data/ext/spiped/spiped-source/spiped/Makefile +98 -0
  96. data/ext/spiped/spiped-source/spiped/README +62 -0
  97. data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
  98. data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
  99. data/ext/spiped/spiped-source/spiped/main.c +267 -0
  100. data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
  101. data/lib/spiped.rb +3 -0
  102. metadata +143 -0
@@ -0,0 +1,103 @@
1
+ #include <sys/types.h>
2
+ #include <sys/socket.h>
3
+
4
+ #include <errno.h>
5
+ #include <stdlib.h>
6
+
7
+ #include "events.h"
8
+
9
+ #include "network.h"
10
+
11
+ struct accept_cookie {
12
+ int (* callback)(void *, int);
13
+ void * cookie;
14
+ int fd;
15
+ };
16
+
17
+ /* Accept the connection and invoke the callback. */
18
+ static int
19
+ callback_accept(void * cookie)
20
+ {
21
+ struct accept_cookie * C = cookie;
22
+ int s;
23
+ int rc;
24
+
25
+ /* Attempt to accept a new connection. */
26
+ if ((s = accept(C->fd, NULL, NULL)) == -1) {
27
+ /* If a connection isn't available, reset the callback. */
28
+ if ((errno == EAGAIN) ||
29
+ (errno == EWOULDBLOCK) ||
30
+ (errno == ECONNABORTED) ||
31
+ (errno == EINTR))
32
+ goto tryagain;
33
+ }
34
+
35
+ /* Call the upstream callback. */
36
+ rc = (C->callback)(C->cookie, s);
37
+
38
+ /* Free the cookie. */
39
+ free(C);
40
+
41
+ /* Return status from upstream callback. */
42
+ return (rc);
43
+
44
+ tryagain:
45
+ /* Reset the callback. */
46
+ return (events_network_register(callback_accept, C, C->fd,
47
+ EVENTS_NETWORK_OP_READ));
48
+ }
49
+
50
+ /**
51
+ * network_accept(fd, callback, cookie):
52
+ * Asynchronously accept a connection on the socket ${fd}, which must be
53
+ * already marked as listening and non-blocking. When a connection has been
54
+ * accepted or an error occurs, invoke ${callback}(${cookie}, s) where s is
55
+ * the accepted connection or -1 on error. Return a cookie which can be
56
+ * passed to network_accept_cancel in order to cancel the accept.
57
+ */
58
+ void *
59
+ network_accept(int fd, int (* callback)(void *, int), void * cookie)
60
+ {
61
+ struct accept_cookie * C;
62
+
63
+ /* Bake a cookie. */
64
+ if ((C = malloc(sizeof(struct accept_cookie))) == NULL)
65
+ goto err0;
66
+ C->callback = callback;
67
+ C->cookie = cookie;
68
+ C->fd = fd;
69
+
70
+ /*
71
+ * Register a network event. A connection arriving on a listening
72
+ * socket is treated by select(2) as the socket becoming readable.
73
+ */
74
+ if (events_network_register(callback_accept, C, C->fd,
75
+ EVENTS_NETWORK_OP_READ))
76
+ goto err1;
77
+
78
+ /* Success! */
79
+ return (C);
80
+
81
+ err1:
82
+ free(C);
83
+ err0:
84
+ /* Failure! */
85
+ return (NULL);
86
+ }
87
+
88
+ /**
89
+ * network_accept_cancel(cookie);
90
+ * Cancel the connection accept for which the cookie ${cookie} was returned
91
+ * by network_accept. Do not invoke the callback associated with the accept.
92
+ */
93
+ void
94
+ network_accept_cancel(void * cookie)
95
+ {
96
+ struct accept_cookie * C = cookie;
97
+
98
+ /* Cancel the network event. */
99
+ events_network_cancel(C->fd, EVENTS_NETWORK_OP_READ);
100
+
101
+ /* Free the cookie. */
102
+ free(C);
103
+ }
@@ -0,0 +1,258 @@
1
+ #include <sys/types.h>
2
+ #include <sys/select.h>
3
+ #include <sys/socket.h>
4
+
5
+ #include <assert.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <unistd.h>
9
+
10
+ #include "events.h"
11
+ #include "sock.h"
12
+
13
+ #include "network.h"
14
+
15
+ struct connect_cookie {
16
+ int (* callback)(void *, int);
17
+ void * cookie;
18
+ struct sock_addr * const * sas;
19
+ struct timeval timeo;
20
+ void * cookie_immediate;
21
+ int s;
22
+ int timeo_enabled;
23
+ void * cookie_timeo;
24
+ };
25
+
26
+ static int tryconnect(struct connect_cookie *);
27
+
28
+ /* Invoke the upstream callback and clean up. */
29
+ static int
30
+ docallback(void * cookie)
31
+ {
32
+ struct connect_cookie * C = cookie;
33
+ int rc;
34
+
35
+ /* Invoke the upstream callback. */
36
+ rc = (C->callback)(C->cookie, C->s);
37
+
38
+ /* Free the cookie. */
39
+ free(C);
40
+
41
+ /* Return status from upstream callback. */
42
+ return (rc);
43
+ }
44
+
45
+ /* An address failed to connect. */
46
+ static int
47
+ dofailed(struct connect_cookie * C)
48
+ {
49
+
50
+ /* Close the socket which failed to connect. */
51
+ close(C->s);
52
+
53
+ /* We don't have an open socket any more. */
54
+ C->s = -1;
55
+
56
+ /* This address didn't work. */
57
+ C->sas++;
58
+
59
+ /* Try other addresses until we run out of options. */
60
+ return (tryconnect(C));
61
+ }
62
+
63
+ /* Callback when connect(2) succeeds or fails. */
64
+ static int
65
+ callback_connect(void * cookie)
66
+ {
67
+ struct connect_cookie * C = cookie;
68
+ int sockerr;
69
+ socklen_t sockerrlen = sizeof(int);
70
+
71
+ /* Stop waiting for the timer callback. */
72
+ if (C->cookie_timeo != NULL) {
73
+ events_timer_cancel(C->cookie_timeo);
74
+ C->cookie_timeo = NULL;
75
+ }
76
+
77
+ /* Did we succeed? */
78
+ if (getsockopt(C->s, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen))
79
+ goto err1;
80
+ if (sockerr != 0)
81
+ return (dofailed(C));
82
+
83
+ /*
84
+ * Perform the callback (this can be done here rather than being
85
+ * scheduled as an immediate callback, as we're already running from
86
+ * callback context).
87
+ */
88
+ return (docallback(C));
89
+
90
+ err1:
91
+ close(C->s);
92
+ free(C);
93
+
94
+ /* Fatal error! */
95
+ return (-1);
96
+ }
97
+
98
+ /* Callback when a timer expires. */
99
+ static int
100
+ callback_timeo(void * cookie)
101
+ {
102
+ struct connect_cookie * C = cookie;
103
+
104
+ /* We're not waiting for a timer callback any more. */
105
+ C->cookie_timeo = NULL;
106
+
107
+ /* Stop listening for this socket. */
108
+ events_network_cancel(C->s, EVENTS_NETWORK_OP_WRITE);
109
+
110
+ /* This connect attempt failed. */
111
+ return (dofailed(C));
112
+ }
113
+
114
+ /* Try to launch a connection. Free the cookie on fatal errors. */
115
+ static int
116
+ tryconnect(struct connect_cookie * C)
117
+ {
118
+
119
+ /* Try addresses until we find one which doesn't fail immediately. */
120
+ for (; C->sas[0] != NULL; C->sas++) {
121
+ /* Can we try to connect to this address? */
122
+ if ((C->s = sock_connect_nb(C->sas[0])) != -1)
123
+ break;
124
+ }
125
+
126
+ /* Did we run out of addresses to try? */
127
+ if (C->sas[0] == NULL)
128
+ goto failed;
129
+
130
+ /* If we've been asked to have a timeout, set one. */
131
+ if (C->timeo_enabled) {
132
+ if ((C->cookie_timeo = events_timer_register(callback_timeo,
133
+ C, &C->timeo)) == NULL)
134
+ goto err1;
135
+ } else {
136
+ C->cookie_timeo = NULL;
137
+ }
138
+
139
+ /* Wait until this socket connects or fails to do so. */
140
+ if (events_network_register(callback_connect, C, C->s,
141
+ EVENTS_NETWORK_OP_WRITE))
142
+ goto err2;
143
+
144
+ /* Success! */
145
+ return (0);
146
+
147
+ failed:
148
+ /* Schedule a callback. */
149
+ if ((C->cookie_immediate =
150
+ events_immediate_register(docallback, C, 0)) == NULL)
151
+ goto err1;
152
+
153
+ /* Failure successfully handled. */
154
+ return (0);
155
+
156
+ err2:
157
+ if (C->cookie_timeo != NULL)
158
+ events_timer_cancel(C->cookie_timeo);
159
+ err1:
160
+ if (C->s != -1)
161
+ close(C->s);
162
+ free(C);
163
+
164
+ /* Fatal error. */
165
+ return (-1);
166
+ }
167
+
168
+ /**
169
+ * network_connect(sas, callback, cookie):
170
+ * Iterate through the addresses in ${sas}, attempting to create and connect
171
+ * a non-blocking socket. Once connected, invoke ${callback}(${cookie}, s)
172
+ * where s is the connected socket; upon fatal error or if there are no
173
+ * addresses remaining to attempt, invoke ${callback}(${cookie}, -1). Return
174
+ * a cookie which can be passed to network_connect_cancel in order to cancel
175
+ * the connection attempt.
176
+ */
177
+ void *
178
+ network_connect(struct sock_addr * const * sas,
179
+ int (* callback)(void *, int), void * cookie)
180
+ {
181
+
182
+ /* Let network_connect_timeo handle this. */
183
+ return (network_connect_timeo(sas, NULL, callback, cookie));
184
+ }
185
+
186
+ /**
187
+ * network_connect_timeo(sas, timeo, callback, cookie):
188
+ * Behave as network_connect, but wait a duration of at most ${timeo} for
189
+ * each address which is being attempted.
190
+ */
191
+ void *
192
+ network_connect_timeo(struct sock_addr * const * sas,
193
+ const struct timeval * timeo,
194
+ int (* callback)(void *, int), void * cookie)
195
+ {
196
+ struct connect_cookie * C;
197
+
198
+ /* Bake a cookie. */
199
+ if ((C = malloc(sizeof(struct connect_cookie))) == NULL)
200
+ goto err0;
201
+ C->callback = callback;
202
+ C->cookie = cookie;
203
+ C->sas = sas;
204
+ C->cookie_immediate = NULL;
205
+ C->cookie_timeo = NULL;
206
+ C->s = -1;
207
+
208
+ /* Do we have a timeout? */
209
+ if (timeo != NULL) {
210
+ memcpy(&C->timeo, timeo, sizeof(struct timeval));
211
+ C->timeo_enabled = 1;
212
+ } else {
213
+ C->timeo_enabled = 0;
214
+ }
215
+
216
+ /* Try to connect to the first address. */
217
+ if (tryconnect(C))
218
+ goto err0;
219
+
220
+ /* Success! */
221
+ return (C);
222
+
223
+ err0:
224
+ /* Failure! */
225
+ return (NULL);
226
+ }
227
+
228
+ /**
229
+ * network_connect_cancel(cookie):
230
+ * Cancel the connection attempt for which ${cookie} was returned by
231
+ * network_connect. Do not invoke the associated callback.
232
+ */
233
+ void
234
+ network_connect_cancel(void * cookie)
235
+ {
236
+ struct connect_cookie * C = cookie;
237
+
238
+ /* We should have either an immediate callback or a socket. */
239
+ assert((C->cookie_immediate != NULL) || (C->s != -1));
240
+ assert((C->cookie_immediate == NULL) || (C->s == -1));
241
+
242
+ /* Cancel any timer. */
243
+ if (C->cookie_timeo != NULL)
244
+ events_timer_cancel(C->cookie_timeo);
245
+
246
+ /* Cancel any immediate callback. */
247
+ if (C->cookie_immediate != NULL)
248
+ events_immediate_cancel(C->cookie_immediate);
249
+
250
+ /* Close any socket. */
251
+ if (C->s != -1) {
252
+ events_network_cancel(C->s, EVENTS_NETWORK_OP_WRITE);
253
+ close(C->s);
254
+ }
255
+
256
+ /* Free the cookie. */
257
+ free(C);
258
+ }
@@ -0,0 +1,155 @@
1
+ #include <sys/socket.h>
2
+
3
+ #include <assert.h>
4
+ #include <errno.h>
5
+ #include <limits.h>
6
+ #include <stdint.h>
7
+ #include <stdlib.h>
8
+ #include <unistd.h>
9
+
10
+ #include "events.h"
11
+ #include "warnp.h"
12
+
13
+ #include "network.h"
14
+
15
+ struct network_read_cookie {
16
+ int (*callback)(void *, ssize_t);
17
+ void * cookie;
18
+ int fd;
19
+ uint8_t * buf;
20
+ size_t buflen;
21
+ size_t minlen;
22
+ size_t bufpos;
23
+ };
24
+
25
+ /* Invoke the callback, clean up, and return the callback's status. */
26
+ static int
27
+ docallback(struct network_read_cookie * C, ssize_t nbytes)
28
+ {
29
+ int rc;
30
+
31
+ /* Invoke the callback. */
32
+ rc = (C->callback)(C->cookie, nbytes);
33
+
34
+ /* Clean up. */
35
+ free(C);
36
+
37
+ /* Return the callback's status. */
38
+ return (rc);
39
+ }
40
+
41
+ /* The socket is ready for reading/writing. */
42
+ static int
43
+ callback_buf(void * cookie)
44
+ {
45
+ struct network_read_cookie * C = cookie;
46
+ size_t oplen;
47
+ ssize_t len;
48
+
49
+ /* Attempt to read/write data to/from the buffer. */
50
+ oplen = C->buflen - C->bufpos;
51
+ len = recv(C->fd, C->buf + C->bufpos, oplen, 0);
52
+
53
+ /* Failure? */
54
+ if (len == -1) {
55
+ /* Was it really an error, or just a try-again? */
56
+ if ((errno == EAGAIN) ||
57
+ (errno == EWOULDBLOCK) ||
58
+ (errno == EINTR))
59
+ goto tryagain;
60
+
61
+ /* Something went wrong. */
62
+ goto failed;
63
+ } else if (len == 0) {
64
+ /* The socket was shut down by the remote host. */
65
+ goto eof;
66
+ }
67
+
68
+ /* We processed some data. Do we need to keep going? */
69
+ if ((C->bufpos += len) < C->minlen)
70
+ goto tryagain;
71
+
72
+ /* Invoke the callback and return. */
73
+ return (docallback(C, C->bufpos));
74
+
75
+ tryagain:
76
+ /* Reset the event. */
77
+ if (events_network_register(callback_buf, C, C->fd,
78
+ EVENTS_NETWORK_OP_READ))
79
+ goto failed;
80
+
81
+ /* Callback was reset. */
82
+ return (0);
83
+
84
+ eof:
85
+ /* Invoke the callback with an EOF status and return. */
86
+ return (docallback(C, 0));
87
+
88
+ failed:
89
+ /* Invoke the callback with a failure status and return. */
90
+ return (docallback(C, -1));
91
+ }
92
+
93
+ /**
94
+ * network_read(fd, buf, buflen, minread, callback, cookie):
95
+ * Asynchronously read up to ${buflen} bytes of data from ${fd} into ${buf}.
96
+ * When at least ${minread} bytes have been read or on error, invoke
97
+ * ${callback}(${cookie}, lenread), where lenread is 0 on EOF or -1 on error,
98
+ * and the number of bytes read (between ${minread} and ${buflen} inclusive)
99
+ * otherwise. Return a cookie which can be passed to network_read_cancel in
100
+ * order to cancel the read.
101
+ */
102
+ void *
103
+ network_read(int fd, uint8_t * buf, size_t buflen, size_t minread,
104
+ int (* callback)(void *, ssize_t), void * cookie)
105
+ {
106
+ struct network_read_cookie * C;
107
+
108
+ /* Make sure buflen is non-zero. */
109
+ assert(buflen != 0);
110
+
111
+ /* Sanity-check: # bytes must fit into a ssize_t. */
112
+ assert(buflen <= SSIZE_MAX);
113
+
114
+ /* Bake a cookie. */
115
+ if ((C = malloc(sizeof(struct network_read_cookie))) == NULL)
116
+ goto err0;
117
+ C->callback = callback;
118
+ C->cookie = cookie;
119
+ C->fd = fd;
120
+ C->buf = buf;
121
+ C->buflen = buflen;
122
+ C->minlen = minread;
123
+ C->bufpos = 0;
124
+
125
+ /* Register a callback for network readiness. */
126
+ if (events_network_register(callback_buf, C, C->fd,
127
+ EVENTS_NETWORK_OP_READ))
128
+ goto err1;
129
+
130
+ /* Success! */
131
+ return (C);
132
+
133
+ err1:
134
+ free(C);
135
+ err0:
136
+ /* Failure! */
137
+ return (NULL);
138
+ }
139
+
140
+ /**
141
+ * network_read_cancel(cookie):
142
+ * Cancel the buffer read for which the cookie ${cookie} was returned by
143
+ * network_read. Do not invoke the callback associated with the read.
144
+ */
145
+ void
146
+ network_read_cancel(void * cookie)
147
+ {
148
+ struct network_read_cookie * C = cookie;
149
+
150
+ /* Kill the network event. */
151
+ events_network_cancel(C->fd, EVENTS_NETWORK_OP_READ);
152
+
153
+ /* Free the cookie. */
154
+ free(C);
155
+ }