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.
- checksums.yaml +7 -0
- data/ext/spiped/extconf.rb +3 -0
- data/ext/spiped/spiped-source/BUILDING +46 -0
- data/ext/spiped/spiped-source/CHANGELOG +44 -0
- data/ext/spiped/spiped-source/COPYRIGHT +33 -0
- data/ext/spiped/spiped-source/Makefile +47 -0
- data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
- data/ext/spiped/spiped-source/Makefile.inc +20 -0
- data/ext/spiped/spiped-source/Makefile.prog +23 -0
- data/ext/spiped/spiped-source/POSIX/README +10 -0
- data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
- data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
- data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
- data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
- data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
- data/ext/spiped/spiped-source/README +198 -0
- data/ext/spiped/spiped-source/STYLE +151 -0
- data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
- data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
- data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
- data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
- data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
- data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
- data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
- data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
- data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
- data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
- data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
- data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
- data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
- data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
- data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
- data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
- data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
- data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
- data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
- data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
- data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
- data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
- data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
- data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
- data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
- data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
- data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
- data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
- data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
- data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
- data/ext/spiped/spiped-source/spipe/Makefile +90 -0
- data/ext/spiped/spiped-source/spipe/README +24 -0
- data/ext/spiped/spiped-source/spipe/main.c +178 -0
- data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
- data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
- data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
- data/ext/spiped/spiped-source/spiped/Makefile +98 -0
- data/ext/spiped/spiped-source/spiped/README +62 -0
- data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
- data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
- data/ext/spiped/spiped-source/spiped/main.c +267 -0
- data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
- data/lib/spiped.rb +3 -0
- 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
|
+
}
|