spiped 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,76 @@
1
+ #include <errno.h>
2
+ #include <stdarg.h>
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+
7
+ #include "warnp.h"
8
+
9
+ static int initialized = 0;
10
+ static char * name = NULL;
11
+
12
+ /* Free the name string. */
13
+ static void
14
+ done(void)
15
+ {
16
+
17
+ free(name);
18
+ name = NULL;
19
+ }
20
+
21
+ /**
22
+ * warnp_setprogname(progname):
23
+ * Set the program name to be used by warn() and warnx() to ${progname}.
24
+ */
25
+ void
26
+ warnp_setprogname(const char * progname)
27
+ {
28
+ const char * p;
29
+
30
+ /* Free the name if we already have one. */
31
+ free(name);
32
+
33
+ /* Find the last segment of the program name. */
34
+ for (p = progname; progname[0] != '\0'; progname++)
35
+ if (progname[0] == '/')
36
+ p = progname + 1;
37
+
38
+ /* Copy the name string. */
39
+ name = strdup(p);
40
+
41
+ /* If we haven't already done so, register our exit handler. */
42
+ if (initialized == 0) {
43
+ atexit(done);
44
+ initialized = 1;
45
+ }
46
+ }
47
+
48
+ void
49
+ warn(const char * fmt, ...)
50
+ {
51
+ va_list ap;
52
+
53
+ va_start(ap, fmt);
54
+ fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
55
+ if (fmt != NULL) {
56
+ fprintf(stderr, ": ");
57
+ vfprintf(stderr, fmt, ap);
58
+ }
59
+ fprintf(stderr, ": %s\n", strerror(errno));
60
+ va_end(ap);
61
+ }
62
+
63
+ void
64
+ warnx(const char * fmt, ...)
65
+ {
66
+ va_list ap;
67
+
68
+ va_start(ap, fmt);
69
+ fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
70
+ if (fmt != NULL) {
71
+ fprintf(stderr, ": ");
72
+ vfprintf(stderr, fmt, ap);
73
+ }
74
+ fprintf(stderr, "\n");
75
+ va_end(ap);
76
+ }
@@ -0,0 +1,59 @@
1
+ #ifndef _WARNP_H_
2
+ #define _WARNP_H_
3
+
4
+ #include <errno.h>
5
+
6
+ /* Avoid namespace collisions with BSD <err.h>. */
7
+ #define warn libcperciva_warn
8
+ #define warnx libcperciva_warnx
9
+
10
+ /**
11
+ * warnp_setprogname(progname):
12
+ * Set the program name to be used by warn() and warnx() to ${progname}.
13
+ */
14
+ void warnp_setprogname(const char *);
15
+ #define WARNP_INIT do { \
16
+ if (argv[0] != NULL) \
17
+ warnp_setprogname(argv[0]); \
18
+ } while (0)
19
+
20
+ /* As in BSD <err.h>. */
21
+ void warn(const char *, ...);
22
+ void warnx(const char *, ...);
23
+
24
+ /*
25
+ * If compiled with DEBUG defined, print __FILE__ and __LINE__.
26
+ */
27
+ #ifdef DEBUG
28
+ #define warnline do { \
29
+ warnx("%s, %d", __FILE__, __LINE__); \
30
+ } while (0)
31
+ #else
32
+ #define warnline
33
+ #endif
34
+
35
+ /*
36
+ * Call warn(3) or warnx(3) depending upon whether errno == 0; and clear
37
+ * errno (so that the standard error message isn't repeated later).
38
+ */
39
+ #define warnp(...) do { \
40
+ warnline; \
41
+ if (errno != 0) { \
42
+ warn(__VA_ARGS__); \
43
+ errno = 0; \
44
+ } else \
45
+ warnx(__VA_ARGS__); \
46
+ } while (0)
47
+
48
+ /*
49
+ * Call warnx(3) and set errno == 0. Unlike warnp, this should be used
50
+ * in cases where we're reporting a problem which we discover ourselves
51
+ * rather than one which is reported to us from a library or the kernel.
52
+ */
53
+ #define warn0(...) do { \
54
+ warnline; \
55
+ warnx(__VA_ARGS__); \
56
+ errno = 0; \
57
+ } while (0)
58
+
59
+ #endif /* !_WARNP_H_ */
@@ -0,0 +1,362 @@
1
+ #include <sys/socket.h>
2
+
3
+ #include <assert.h>
4
+ #include <stdint.h>
5
+ #include <stdlib.h>
6
+
7
+ #include "events.h"
8
+ #include "network.h"
9
+ #include "sock.h"
10
+
11
+ #include "proto_handshake.h"
12
+ #include "proto_pipe.h"
13
+ #include "proto_crypt.h"
14
+
15
+ #include "proto_conn.h"
16
+
17
+ struct conn_state {
18
+ int (* callback_dead)(void *);
19
+ void * cookie;
20
+ struct sock_addr ** sas;
21
+ int decr;
22
+ int nofps;
23
+ int requirefps;
24
+ int nokeepalive;
25
+ const struct proto_secret * K;
26
+ double timeo;
27
+ int s;
28
+ int t;
29
+ void * connect_cookie;
30
+ void * connect_timeout_cookie;
31
+ void * handshake_cookie;
32
+ void * handshake_timeout_cookie;
33
+ struct proto_keys * k_f;
34
+ struct proto_keys * k_r;
35
+ void * pipe_f;
36
+ void * pipe_r;
37
+ int stat_f;
38
+ int stat_r;
39
+ };
40
+
41
+ static int callback_connect_done(void *, int);
42
+ static int callback_connect_timeout(void *);
43
+ static int callback_handshake_done(void *, struct proto_keys *,
44
+ struct proto_keys *);
45
+ static int callback_handshake_timeout(void *);
46
+ static int callback_pipestatus(void *);
47
+
48
+ /* Start a handshake. */
49
+ static int
50
+ starthandshake(struct conn_state * C, int s, int decr)
51
+ {
52
+
53
+ /* Start the handshake timer. */
54
+ if ((C->handshake_timeout_cookie = events_timer_register_double(
55
+ callback_handshake_timeout, C, C->timeo)) == NULL)
56
+ goto err0;
57
+
58
+ /* Start the handshake. */
59
+ if ((C->handshake_cookie = proto_handshake(s, decr, C->nofps,
60
+ C->requirefps, C->K, callback_handshake_done, C)) == NULL)
61
+ goto err1;
62
+
63
+ /* Success! */
64
+ return (0);
65
+
66
+ err1:
67
+ events_timer_cancel(C->handshake_timeout_cookie);
68
+ C->handshake_timeout_cookie = NULL;
69
+ err0:
70
+ /* Failure! */
71
+ return (-1);
72
+ }
73
+
74
+ /* Launch the two pipes. */
75
+ static int
76
+ launchpipes(struct conn_state * C)
77
+ {
78
+ int on = C->nokeepalive ? 0 : 1;
79
+
80
+ /*
81
+ * Attempt to turn keepalives on or off as requested. We ignore
82
+ * failures here since the sockets might not be of a type for which
83
+ * SO_KEEPALIVE is valid -- it is a socket level option, but protocol
84
+ * specific. In particular, it has no sensible meaning for UNIX
85
+ * sockets.
86
+ */
87
+ (void)setsockopt(C->s, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
88
+ (void)setsockopt(C->t, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
89
+
90
+ /* Create two pipes. */
91
+ if ((C->pipe_f = proto_pipe(C->s, C->t, C->decr, C->k_f,
92
+ &C->stat_f, callback_pipestatus, C)) == NULL)
93
+ goto err0;
94
+ if ((C->pipe_r = proto_pipe(C->t, C->s, !C->decr, C->k_r,
95
+ &C->stat_r, callback_pipestatus, C)) == NULL)
96
+ goto err0;
97
+
98
+ /* Success! */
99
+ return (0);
100
+
101
+ err0:
102
+ /* Failure! */
103
+ return (-1);
104
+ }
105
+
106
+ /* Drop a connection. */
107
+ static int
108
+ dropconn(struct conn_state * C)
109
+ {
110
+ int rc;
111
+
112
+ /* Close the incoming connection. */
113
+ close(C->s);
114
+
115
+ /* Close the outgoing connection if it is open. */
116
+ if (C->t != -1)
117
+ close(C->t);
118
+
119
+ /* Stop connecting if a connection is in progress. */
120
+ if (C->connect_cookie != NULL)
121
+ network_connect_cancel(C->connect_cookie);
122
+
123
+ /* Free the target addresses if we haven't already done so. */
124
+ sock_addr_freelist(C->sas);
125
+
126
+ /* Stop handshaking if a handshake is in progress. */
127
+ if (C->handshake_cookie != NULL)
128
+ proto_handshake_cancel(C->handshake_cookie);
129
+
130
+ /* Kill timeouts if they are pending. */
131
+ if (C->connect_timeout_cookie != NULL)
132
+ events_timer_cancel(C->connect_timeout_cookie);
133
+ if (C->handshake_timeout_cookie != NULL)
134
+ events_timer_cancel(C->handshake_timeout_cookie);
135
+
136
+ /* Free protocol keys. */
137
+ proto_crypt_free(C->k_f);
138
+ proto_crypt_free(C->k_r);
139
+
140
+ /* Shut down pipes. */
141
+ if (C->pipe_f != NULL)
142
+ proto_pipe_cancel(C->pipe_f);
143
+ if (C->pipe_r != NULL)
144
+ proto_pipe_cancel(C->pipe_r);
145
+
146
+ /* Notify the upstream that we've dropped a connection. */
147
+ rc = (C->callback_dead)(C->cookie);
148
+
149
+ /* Free the connection cookie. */
150
+ free(C);
151
+
152
+ /* Return success/fail status. */
153
+ return (rc);
154
+ }
155
+
156
+ /**
157
+ * proto_conn_create(s, sas, decr, nofps, requirefps, nokeepalive, K, timeo,
158
+ * callback_dead, cookie):
159
+ * Create a connection with one end at ${s} and the other end connecting to
160
+ * the target addresses ${sas}. If ${decr} is 0, encrypt the outgoing data;
161
+ * if ${decr} is nonzero, decrypt the outgoing data. If ${nofps} is non-zero,
162
+ * don't use perfect forward secrecy. If ${requirefps} is non-zero, drop
163
+ * the connection if the other end tries to disable perfect forward secrecy.
164
+ * Enable transport layer keep-alives (if applicable) on both sockets if and
165
+ * only if ${nokeepalive} is zero. Drop the connection if the handshake or
166
+ * connecting to the target takes more than ${timeo} seconds. When the
167
+ * connection is dropped, invoke ${callback_dead}(${cookie}). Free ${sas}
168
+ * once it is no longer needed.
169
+ */
170
+ int
171
+ proto_conn_create(int s, struct sock_addr ** sas, int decr, int nofps,
172
+ int requirefps, int nokeepalive, const struct proto_secret * K,
173
+ double timeo, int (* callback_dead)(void *), void * cookie)
174
+ {
175
+ struct conn_state * C;
176
+
177
+ /* Bake a cookie for this connection. */
178
+ if ((C = malloc(sizeof(struct conn_state))) == NULL)
179
+ goto err0;
180
+ C->callback_dead = callback_dead;
181
+ C->cookie = cookie;
182
+ C->sas = sas;
183
+ C->decr = decr;
184
+ C->nofps = nofps;
185
+ C->requirefps = requirefps;
186
+ C->nokeepalive = nokeepalive;
187
+ C->K = K;
188
+ C->timeo = timeo;
189
+ C->s = s;
190
+ C->t = -1;
191
+ C->connect_cookie = NULL;
192
+ C->connect_timeout_cookie = NULL;
193
+ C->handshake_cookie = NULL;
194
+ C->handshake_timeout_cookie = NULL;
195
+ C->k_f = C->k_r = NULL;
196
+ C->pipe_f = C->pipe_r = NULL;
197
+ C->stat_f = C->stat_r = 1;
198
+
199
+ /* Start the connect timer. */
200
+ if ((C->connect_timeout_cookie = events_timer_register_double(
201
+ callback_connect_timeout, C, C->timeo)) == NULL)
202
+ goto err1;
203
+
204
+ /* Connect to target. */
205
+ if ((C->connect_cookie =
206
+ network_connect(C->sas, callback_connect_done, C)) == NULL)
207
+ goto err2;
208
+
209
+ /* If we're decrypting, start the handshake. */
210
+ if (C->decr) {
211
+ if (starthandshake(C, C->s, C->decr))
212
+ goto err3;
213
+ }
214
+
215
+ /* Success! */
216
+ return (0);
217
+
218
+ err3:
219
+ network_connect_cancel(C->connect_cookie);
220
+ err2:
221
+ events_timer_cancel(C->connect_timeout_cookie);
222
+ err1:
223
+ free(C);
224
+ err0:
225
+ /* Failure! */
226
+ return (-1);
227
+ }
228
+
229
+ /* We have connected to the target. */
230
+ static int
231
+ callback_connect_done(void * cookie, int t)
232
+ {
233
+ struct conn_state * C = cookie;
234
+
235
+ /* This connection attempt is no longer pending. */
236
+ C->connect_cookie = NULL;
237
+
238
+ /* Don't need the target address any more. */
239
+ sock_addr_freelist(C->sas);
240
+ C->sas = NULL;
241
+
242
+ /* We beat the clock. */
243
+ events_timer_cancel(C->connect_timeout_cookie);
244
+ C->connect_timeout_cookie = NULL;
245
+
246
+ /* Did we manage to connect? */
247
+ if ((C->t = t) == -1)
248
+ return (dropconn(C));
249
+
250
+ /* If we're encrypting, start the handshake. */
251
+ if (!C->decr) {
252
+ if (starthandshake(C, C->t, C->decr))
253
+ goto err1;
254
+ }
255
+
256
+ /* If we have connections and keys, start shuttling data. */
257
+ if ((C->t != -1) && (C->k_f != NULL) && (C->k_r != NULL)) {
258
+ if (launchpipes(C))
259
+ goto err1;
260
+ }
261
+
262
+ /* Success! */
263
+ return (0);
264
+
265
+ err1:
266
+ dropconn(C);
267
+
268
+ /* Failure! */
269
+ return (-1);
270
+ }
271
+
272
+ /* Connecting to the target took too long. */
273
+ static int
274
+ callback_connect_timeout(void * cookie)
275
+ {
276
+ struct conn_state * C = cookie;
277
+
278
+ /* This timeout is no longer pending. */
279
+ C->connect_timeout_cookie = NULL;
280
+
281
+ /*
282
+ * We could free C->sas here, but from a semantic point of view it
283
+ * could still be in use by the not-yet-cancelled connect operation.
284
+ * Instead, we free it in dropconn, after cancelling the connect.
285
+ */
286
+
287
+ /* Drop the connection. */
288
+ return (dropconn(C));
289
+ }
290
+
291
+ /* We have performed the protocol handshake. */
292
+ static int
293
+ callback_handshake_done(void * cookie, struct proto_keys * f,
294
+ struct proto_keys * r)
295
+ {
296
+ struct conn_state * C = cookie;
297
+
298
+ /* The handshake is no longer in progress. */
299
+ C->handshake_cookie = NULL;
300
+
301
+ /* We beat the clock. */
302
+ events_timer_cancel(C->handshake_timeout_cookie);
303
+ C->handshake_timeout_cookie = NULL;
304
+
305
+ /* If the protocol handshake failed, drop the connection. */
306
+ if ((f == NULL) && (r == NULL))
307
+ return (dropconn(C));
308
+
309
+ /* We should have two keys. */
310
+ assert(f != NULL);
311
+ assert(r != NULL);
312
+
313
+ /* Record the keys so we can free them later. */
314
+ C->k_f = f;
315
+ C->k_r = r;
316
+
317
+ /* If we have connections and keys, start shuttling data. */
318
+ if ((C->t != -1) && (C->k_f != NULL) && (C->k_r != NULL)) {
319
+ if (launchpipes(C))
320
+ goto err1;
321
+ }
322
+
323
+ /* Success! */
324
+ return (0);
325
+
326
+ err1:
327
+ dropconn(C);
328
+
329
+ /* Failure! */
330
+ return (-1);
331
+ }
332
+
333
+ /* The protocol handshake took too long. */
334
+ static int
335
+ callback_handshake_timeout(void * cookie)
336
+ {
337
+ struct conn_state * C = cookie;
338
+
339
+ /* This timeout is no longer pending. */
340
+ C->handshake_timeout_cookie = NULL;
341
+
342
+ /* Drop the connection. */
343
+ return (dropconn(C));
344
+ }
345
+
346
+ /* The status of one of the directions has changed. */
347
+ static int
348
+ callback_pipestatus(void * cookie)
349
+ {
350
+ struct conn_state * C = cookie;
351
+
352
+ /* If we have an error in either direction, kill the connection. */
353
+ if ((C->stat_f == -1) || (C->stat_r == -1))
354
+ return (dropconn(C));
355
+
356
+ /* If both directions have been shut down, kill the connection. */
357
+ if ((C->stat_f == 0) && (C->stat_r == 0))
358
+ return (dropconn(C));
359
+
360
+ /* Nothing to do. */
361
+ return (0);
362
+ }