annotate main.c @ 0:17cb7cdbb8be draft default tip

Working prototype
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 07 Feb 2014 23:28:39 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 /* Copyright 2014 Ivo Smits <Ivo@UCIS.nl>. All rights reserved.
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 Redistribution and use in source and binary forms, with or without modification, are
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
3 permitted provided that the following conditions are met:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 1. Redistributions of source code must retain the above copyright notice, this list of
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6 conditions and the following disclaimer.
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 2. Redistributions in binary form must reproduce the above copyright notice, this list
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 of conditions and the following disclaimer in the documentation and/or other materials
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 provided with the distribution.
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
17 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
18 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
19 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
20 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
21
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
22 The views and conclusions contained in the software and documentation are those of the
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
23 authors and should not be interpreted as representing official policies, either expressed
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 or implied, of Ivo Smits.*/
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26 #include <stdlib.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27 #include <stdio.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
28 #include <stdbool.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
29 #include <fcntl.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
30 #include <string.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
31 #include <sys/types.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
32 #include <poll.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
33 #include <sys/socket.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
34 #ifndef HAVE_NETINET_IN_H
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
35 #include <netinet/in.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
36 #endif
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
37 #include <arpa/inet.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
38 #include <netdb.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
39 #include "include.h"
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
41 char* (*getconf)(const char*) = getenv;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43 static void hex2bin(unsigned char* dest, const char* src, const int count) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44 int i;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45 for (i = 0; i < count; i++) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
46 if (*src >= '0' && *src <= '9') *dest = *src - '0';
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
47 else if (*src >= 'a' && * src <='f') *dest = *src - 'a' + 10;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
48 else if (*src >= 'A' && * src <='F') *dest = *src - 'A' + 10;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49 src++; *dest = *dest << 4;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 if (*src >= '0' && *src <= '9') *dest += *src - '0';
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51 else if (*src >= 'a' && *src <= 'f') *dest += *src - 'a' + 10;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 else if (*src >= 'A' && *src <= 'F') *dest += *src - 'A' + 10;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
53 src++; dest++;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
54 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
55 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
56
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
57 static bool crypto_init(connection_context* context, bool* keyupdate) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
58 unsigned char cpublickey[32], csecretkey[32];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
59 bool hpublickey = false, hsecretkey = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60 char* envval;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61 *keyupdate = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62 if ((envval = getconf("PUBLIC_KEY"))) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 if (strlen(envval) != 64) return errorexit("PUBLIC_KEY length");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64 hex2bin(cpublickey, envval, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65 hpublickey = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
66 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
67 if ((envval = getconf("PRIVATE_KEY"))) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
68 if (strlen(envval) != 64) return errorexit("PRIVATE_KEY length");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
69 hex2bin(csecretkey, envval, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
70 hsecretkey = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
71 } else if ((envval = getconf("PRIVATE_KEY_FILE"))) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
72 FILE* pkfile = fopen(envval, "rb");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
73 if (!pkfile) return errorexitp("Could not open PRIVATE_KEY_FILE");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
74 char pktextbuf[64];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75 const size_t pktextsize = fread(pktextbuf, 1, sizeof(pktextbuf), pkfile);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
76 if (pktextsize == 32) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
77 memcpy(csecretkey, pktextbuf, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
78 } else if (pktextsize == 64) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
79 hex2bin(csecretkey, pktextbuf, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80 } else {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
81 return errorexit("PRIVATE_KEY length");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
83 fclose(pkfile);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
84 hsecretkey = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
85 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
86 if (hpublickey || hsecretkey || ((envval = getconf("ENCRYPT")) && atoi(envval))) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
87 if (!hpublickey) fprintf(stderr, "Warning: encryption enabled but remote key not set, cryptographic authentication disabled.\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
88 if (!connection_init_encryption(context, hsecretkey ? csecretkey : NULL, hpublickey ? cpublickey : NULL)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
89 *keyupdate = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
90 } else {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
91 fprintf(stderr, "Warning: encryption disabled.\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
92 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
93 if ((envval = getconf("PASSWORD"))) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
94 if (!connection_init_passwordauth(context, strdup(envval))) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
95 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
96 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
97 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
98
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
99 typedef union {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
100 struct sockaddr any;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
101 struct sockaddr_in ip4;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
102 struct sockaddr_in6 ip6;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
103 } sockaddr_any;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
104
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
105 static int sockaddr_set_port(sockaddr_any* sa, int port) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
106 port = htons(port);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
107 int af = sa->any.sa_family;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
108 if (af == AF_INET) sa->ip4.sin_port = port;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
109 else if (af == AF_INET6) sa->ip6.sin6_port = port;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
110 else return errorexit("Unknown address family");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
111 return 0;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
112 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
113
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
114 static bool socket_init(connection_context* context) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
115 char* envval;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
116 fprintf(stderr, "Initializing socket...\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
117 struct addrinfo *ai_local = NULL, *ai_remote = NULL;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
118 unsigned short af = 0;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
119 int ret;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
120 if ((envval = getconf("LOCAL_ADDRESS"))) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
121 if ((ret = getaddrinfo(envval, NULL, NULL, &ai_local))) return errorexitf("getaddrinfo(LOCAL_ADDRESS)", gai_strerror(ret));
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
122 if (!ai_local) return errorexit("LOCAL_ADDRESS lookup failed");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
123 if (ai_local->ai_addrlen > sizeof(sockaddr_any)) return errorexit("Resolved LOCAL_ADDRESS is too big");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
124 af = ai_local->ai_family;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
125 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
126 if ((envval = getconf("REMOTE_ADDRESS"))) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
127 if ((ret = getaddrinfo(envval, NULL, NULL, &ai_remote))) return errorexitf("getaddrinfo(REMOTE_ADDRESS)", gai_strerror(ret));
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
128 if (!ai_remote) return errorexit("REMOTE_ADDRESS lookup failed");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
129 if (ai_remote->ai_addrlen > sizeof(sockaddr_any)) return errorexit("Resolved REMOTE_ADDRESS is too big");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
130 if (af && af != ai_remote->ai_family) return errorexit("Address families do not match");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
131 af = ai_remote->ai_family;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
132 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
133 if (!af) return connection_init_socket(context, 0, 1);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
134 int sa_size = sizeof(sockaddr_any);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
135 if (af == AF_INET) sa_size = sizeof(struct sockaddr_in);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
136 else if (af == AF_INET6) sa_size = sizeof(struct sockaddr_in6);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
137 int sfd = socket(af, SOCK_STREAM, IPPROTO_TCP);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
138 if (sfd < 0) return errorexitp("Could not create socket");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
139 sockaddr_any udpaddr;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
140 if (ai_local) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
141 memset(&udpaddr, 0, sizeof(udpaddr));
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
142 udpaddr.any.sa_family = af;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
143 memcpy(&udpaddr, ai_local->ai_addr, ai_local->ai_addrlen);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
144 int port = 2998;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
145 if ((envval = getconf("LOCAL_PORT"))) port = atoi(envval);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
146 if (sockaddr_set_port(&udpaddr, port)) return -1;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 if (bind(sfd, &udpaddr.any, sa_size)) return errorexitp("Could not bind socket");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
148 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
149 if (ai_remote) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
150 memset(&udpaddr, 0, sizeof(udpaddr));
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
151 udpaddr.any.sa_family = af;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
152 memcpy(&udpaddr, ai_remote->ai_addr, ai_remote->ai_addrlen);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
153 int port = 2998;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
154 if ((envval = getconf("REMOTE_PORT"))) port = atoi(envval);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
155 if (sockaddr_set_port(&udpaddr, port)) return -1;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
156 if (connect(sfd, &udpaddr.any, sa_size)) return errorexitp("Could not connect socket");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
157 } else {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
158 return errorexit("REMOTE_ADDRESS not specified and server mode is currently not supported :-(. Please use (x)inetd or similar.");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
159 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
160 if (ai_local) freeaddrinfo(ai_local);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
161 if (ai_remote) freeaddrinfo(ai_remote);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
162 return connection_init_socket(context, sfd, sfd);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
163 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
164
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
165 static bool mainA() {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
166 connection_context context;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
167 tunnel_context tunnel;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
168 bool keyupdate = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
169 if (!connection_init(&context)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
170 if (!socket_init(&context)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
171 if (!crypto_init(&context, &keyupdate)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
172 if (!connection_init_done(&context)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
173 while (!context.local_tunnelready) if (!connection_read(&context)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
174 if (keyupdate) connection_update_key(&context);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
175
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
176 if (!tunnel_init(&tunnel)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
177 context.tunnel = &tunnel;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
178 tunnel.connection = &context;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
179
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
180 struct pollfd fds[2];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
181 fds[0].fd = context.recv_socket;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
182 fds[0].events = POLLIN;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
183 fds[1].fd = tunnel.fd;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
184 fds[1].events = POLLIN;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
185
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
186 while (true) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
187 int len = poll(fds, 2, 10000);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
188 if (len < 0) return errorexitp("poll failed");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
189 else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) return errorexit("poll error on socket");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
190 else if (fds[1].revents & (POLLHUP | POLLNVAL)) return errorexit("poll error on tap device");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
191 if (len == 0) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
192 if (keyupdate) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
193 if (!context.key_updated) return errorexit("key update timed out");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
194 if (!connection_update_key(&context)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
195 } else {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
196 if (!connection_ping(&context)) return errorexit("ping timed out");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
197 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
198 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
199 if (fds[0].revents & POLLERR) return errorexitp("poll error on socket");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
200 if (fds[0].revents & POLLIN) if (!connection_read(&context)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
201 if (fds[1].revents & POLLIN) if (!tunnel_read(&tunnel)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
202 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
203 return -1;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
204 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
205
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
206 int main() {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
207 return mainA() ? 0 : -1;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
208 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
209
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
210 int errorexit(const char* text) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
211 fprintf(stderr, "%s\n", text);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
212 return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
213 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
214 int errorexitf(const char* text, const char* error) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
215 fprintf(stderr, "%s: %s\n", text, error);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
216 return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
217 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
218 bool errorexitp(const char* text) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
219 perror(text);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
220 return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
221 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
222