gdr / tuntox (public) (License: GPLv3) (since 2017-01-24) (hash sha1)
Tunnel TCP connections over the Tox protocol
List of commits:
Subject Hash Author Date (UTC)
builds well 3b42ed1ca1be6d1c8f14606befee8b8deae64ac8 GDR! 2014-11-10 18:05:14
makefile f877c04fdb45aebff081df4ed1b7fea9bd293fa5 GDR! 2014-11-09 16:24:12
Commit 3b42ed1ca1be6d1c8f14606befee8b8deae64ac8 - builds well
Author: GDR!
Author date (UTC): 2014-11-10 18:05
Committer name: GDR!
Committer date (UTC): 2014-11-10 18:05
Parent(s): f877c04fdb45aebff081df4ed1b7fea9bd293fa5
Signer:
Signing key:
Signing status: N
Tree: da63b91d1df005deb20818c7db12fb2bfd1aa6cf
File Lines added Lines deleted
Makefile 13 7
main.c 289 0
tox_bootstrap.h 122 0
File Makefile changed (mode: 100644) (index ef572e6..7617e07)
1 SOURCES = main.c
2 DEPS=
1 SOURCES = $(wildcard *.c)
2 DEPS=libtoxcore
3 3 CC=gcc CC=gcc
4 CFLAGS=-g
4 CFLAGS=-g #-std=c99
5 CFLAGS += $(shell pkg-config --cflags $(DEPS))
6 LDFLAGS=-g -pthread -lm -static
7 LDFLAGS += $(shell pkg-config --libs $(DEPS))
5 8 OBJECTS=$(SOURCES:.c=.o) OBJECTS=$(SOURCES:.c=.o)
9 INCLUDES = $(wildcard *.h)
6 10
7 .c.o:
11 .c.o: $(INCLUDES)
8 12 $(CC) $(CFLAGS) $< -c -o $@ $(CC) $(CFLAGS) $< -c -o $@
9 13
10 tuntox: $(OBJECTS)
11 $(CC) --static -o $@ -ltoxcore $^ $(CFLAGS) /usr/local/lib/libsodium.a
14 tuntox: $(OBJECTS) $(INCLUDES)
15 $(CC) -o $@ $(OBJECTS) -ltoxcore -lpthread $(LDFLAGS) /usr/local/lib/libsodium.a /usr/local/lib/libtoxcore.a
12 16
13 all: tuntox
17 cscope.out:
18 cscope -bv ./*.[ch]
14 19
20 all: cscope.out tuntox
File main.c added (mode: 100644) (index 0000000..2d09e2e)
1 #include <arpa/inet.h>
2 #include <errno.h>
3 #include <netdb.h>
4 #include <netinet/in.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/socket.h>
9 #include <sys/time.h>
10 #include <sys/types.h>
11 #include <tox/tox.h>
12 #include <unistd.h>
13
14 #include "main.h"
15 #include "tox_bootstrap.h"
16
17 static Tox_Options tox_options;
18 static Tox *tox;
19 int client_socket = 0;
20
21 static void writechecksum(uint8_t *address)
22 {
23 uint8_t *checksum = address + 36;
24 uint32_t i;
25
26 for (i = 0; i < 36; ++i)
27 checksum[i % 2] ^= address[i];
28 }
29
30 /* From utox/util.c */
31 static void to_hex(char_t *a, const char_t *p, int size)
32 {
33 char_t b, c, *end = p + size;
34
35 while(p != end) {
36 b = *p++;
37
38 c = (b & 0xF);
39 b = (b >> 4);
40
41 if(b < 10) {
42 *a++ = b + '0';
43 } else {
44 *a++ = b - 10 + 'A';
45 }
46
47 if(c < 10) {
48 *a++ = c + '0';
49 } else {
50 *a++ = c - 10 + 'A';
51 }
52 }
53 }
54
55 /* From utox/util.c */
56 void id_to_string(char_t *dest, const char_t *src)
57 {
58 to_hex(dest, src, TOX_FRIEND_ADDRESS_SIZE);
59 }
60
61 /* bootstrap to dht with bootstrap_nodes */
62 /* From uTox/tox.c */
63 static void do_bootstrap(Tox *tox)
64 {
65 static unsigned int j = 0;
66
67 if (j == 0)
68 j = rand();
69
70 int i = 0;
71 while(i < 4) {
72 struct bootstrap_node *d = &bootstrap_nodes[j % countof(bootstrap_nodes)];
73 tox_bootstrap_from_address(tox, d->address, d->port, d->key);
74 i++;
75 j++;
76 }
77 }
78
79 /* Set username to the machine's FQDN */
80 void set_tox_username(Tox *tox)
81 {
82 unsigned char hostname[1024];
83 struct addrinfo hints, *info, *p;
84 int gai_result;
85
86 gethostname(hostname, 1024);
87 hostname[1023] = '\0';
88 # if 0
89 memset(&hints, 0, sizeof hints);
90 hints.ai_family = AF_UNSPEC; /*either IPV4 or IPV6*/
91 hints.ai_socktype = SOCK_STREAM;
92 hints.ai_flags = AI_CANONNAME;
93
94 if ((gai_result = getaddrinfo(hostname, "ftp", &hints, &info)) != 0)
95 {
96 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_result));
97 exit(1);
98 }
99
100 for(p = info; p != NULL; p = p->ai_next)
101 {
102 printf("hostname: %s\n", p->ai_canonname);
103 }
104 # endif
105
106 tox_set_name(tox, hostname, strlen(hostname));
107
108 // freeaddrinfo(info);
109 }
110
111 void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata)
112 {
113 unsigned char tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1];
114
115 printf("Got friend request\n");
116 tox_add_friend_norequest(tox, public_key);
117 id_to_string(tox_printable_id, public_key);
118 printf("Accepted friend request from %s\n", tox_printable_id);
119 }
120
121 void cleanup(int status, void *tmp)
122 {
123 printf("kthxbye\n");
124 fflush(stdout);
125 tox_kill(tox);
126 if(client_socket)
127 {
128 close(client_socket);
129 }
130 }
131
132 // get sockaddr, IPv4 or IPv6:
133 /* From Beej */
134 void *get_in_addr(struct sockaddr *sa)
135 {
136 if (sa->sa_family == AF_INET) {
137 return &(((struct sockaddr_in*)sa)->sin_addr);
138 }
139
140 return &(((struct sockaddr_in6*)sa)->sin6_addr);
141 }
142
143 /* From Beej */
144 int get_client_socket()
145 {
146 int sockfd, numbytes;
147 char buf[READ_BUFFER_SIZE];
148 struct addrinfo hints, *servinfo, *p;
149 int rv;
150 char s[INET6_ADDRSTRLEN];
151 int port = 22;
152 char hostname[4096] = "127.0.0.1";
153 char port_str[6];
154
155 snprintf(port_str, 6, "%d", port);
156
157 memset(&hints, 0, sizeof hints);
158 hints.ai_family = AF_UNSPEC;
159 hints.ai_socktype = SOCK_STREAM;
160
161 if ((rv = getaddrinfo(hostname, port_str, &hints, &servinfo)) != 0) {
162 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
163 exit(1);
164 }
165
166 // loop through all the results and connect to the first we can
167 for(p = servinfo; p != NULL; p = p->ai_next) {
168 if ((sockfd = socket(p->ai_family, p->ai_socktype,
169 p->ai_protocol)) == -1) {
170 perror("client: socket");
171 continue;
172 }
173
174 if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
175 close(sockfd);
176 perror("client: connect");
177 continue;
178 }
179
180 break;
181 }
182
183 if (p == NULL) {
184 fprintf(stderr, "failed to connect to %s:%d\n", hostname, port);
185 exit(1);
186 }
187
188 inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
189 s, sizeof s);
190 fprintf(stderr, "connecting to %s\n", s);
191
192 freeaddrinfo(servinfo); // all done with this structure
193
194 fprintf(stderr, "Connected to %s:%d\n", hostname, port);
195
196 return sockfd;
197 }
198
199 unsigned int create_packet(unsigned char *dst, unsigned char *data, int data_len, int sockfd)
200 {
201 // assert data_len < 65536
202 dst[0] = 0xa2;
203 dst[1] = 0x6a;
204 dst[2] = sockfd >> 8;
205 dst[3] = sockfd & 0xff;
206 dst[4] = (data_len >> 8) & 0xff;
207 dst[5] = data_len & 0xff;
208 memcpy(dst+PROTOCOL_BUFFER_OFFSET, data, data_len);
209 return data_len + PROTOCOL_BUFFER_OFFSET;
210 }
211
212 int do_loop()
213 {
214 struct timeval tv;
215 fd_set fds;
216 fd_set master;
217 unsigned char read_buf[READ_BUFFER_SIZE+1];
218 unsigned char tox_packet_buf[PROTOCOL_MAX_PACKET_SIZE];
219
220 tv.tv_sec = 0;
221 tv.tv_usec = 20000;
222
223 FD_ZERO(&fds);
224 FD_SET(client_socket, &fds);
225
226 master = fds;
227
228 while(1)
229 {
230 /* Let tox do its stuff */
231 tox_do(tox);
232
233 /* Poll for data from our client connection */
234 select(client_socket+1, &fds, NULL, NULL, &tv);
235 if(FD_ISSET(client_socket, &fds))
236 {
237 int nbytes = recv(client_socket, read_buf, READ_BUFFER_SIZE, 0);
238
239 /* Check if connection closed */
240 if(nbytes == 0)
241 {
242 printf("conn closed!\n");
243 }
244 else
245 {
246 unsigned int tox_packet_length = 0;
247 read_buf[nbytes] = '\0';
248 tox_packet_length = create_packet(tox_packet_buf, read_buf, nbytes, client_socket);
249 tox_send_lossless_packet(tox, 0, tox_packet_buf, tox_packet_length);
250 printf("READ: %s\n", read_buf);
251 }
252 }
253
254 fds = master;
255 }
256 }
257
258 int main(int argc, char *argv[])
259 {
260 unsigned char tox_id[TOX_FRIEND_ADDRESS_SIZE];
261 unsigned char tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1];
262
263 on_exit(cleanup, NULL);
264
265 /* Bootstrap tox */
266 tox_options.ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
267 tox_options.udp_disabled = 0;
268 tox_options.proxy_enabled = 0;
269
270 tox = tox_new(&tox_options);
271
272 tox_callback_friend_request(tox, accept_friend_request, NULL);
273
274 set_tox_username(tox);
275
276 tox_get_address(tox, tox_id);
277 id_to_string(tox_printable_id, tox_id);
278 tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0';
279 printf("Generated Tox ID: %s\n", tox_printable_id);
280
281 do_bootstrap(tox);
282
283 /* Connect to the forwarded service */
284 client_socket = get_client_socket();
285
286 do_loop();
287
288 return 0;
289 }
File tox_bootstrap.h added (mode: 100644) (index 0000000..119a2d2)
1 struct bootstrap_node {
2 char *address;
3 uint16_t port;
4 uint8_t key[32];
5 } bootstrap_nodes[] = {
6 {
7 "37.187.46.132",
8 33445,
9 {
10 0x5E, 0xB6, 0x7C, 0x51, 0xD3, 0xFF, 0x5A, 0x9D, 0x52, 0x8D, 0x24, 0x2B, 0x66, 0x90, 0x36, 0xED,
11 0x2A, 0x30, 0xF8, 0xA6, 0x0E, 0x67, 0x4C, 0x45, 0xE7, 0xD4, 0x30, 0x10, 0xCB, 0x2E, 0x13, 0x31
12 }
13 },
14
15 {
16 "144.76.60.215",
17 33445,
18 {
19 0x04, 0x11, 0x9E, 0x83, 0x5D, 0xF3, 0xE7, 0x8B, 0xAC, 0xF0, 0xF8, 0x42, 0x35, 0xB3, 0x00, 0x54,
20 0x6A, 0xF8, 0xB9, 0x36, 0xF0, 0x35, 0x18, 0x5E, 0x2A, 0x8E, 0x9E, 0x0A, 0x67, 0xC8, 0x92, 0x4F
21 }
22 },
23
24 {
25 "23.226.230.47",
26 33445,
27 {
28 0xA0, 0x91, 0x62, 0xD6, 0x86, 0x18, 0xE7, 0x42, 0xFF, 0xBC, 0xA1, 0xC2, 0xC7, 0x03, 0x85, 0xE6,
29 0x67, 0x96, 0x04, 0xB2, 0xD8, 0x0E, 0xA6, 0xE8, 0x4A, 0xD0, 0x99, 0x6A, 0x1A, 0xC8, 0xA0, 0x74
30 }
31 },
32
33 {
34 "54.199.139.199",
35 33445,
36 {
37 0x7F, 0x9C, 0x31, 0xFE, 0x85, 0x0E, 0x97, 0xCE, 0xFD, 0x4C, 0x45, 0x91, 0xDF, 0x93, 0xFC, 0x75,
38 0x7C, 0x7C, 0x12, 0x54, 0x9D, 0xDD, 0x55, 0xF8, 0xEE, 0xAE, 0xCC, 0x34, 0xFE, 0x76, 0xC0, 0x29
39 }
40 },
41
42 {
43 "192.210.149.121",
44 33445,
45 {
46 0xF4, 0x04, 0xAB, 0xAA, 0x1C, 0x99, 0xA9, 0xD3, 0x7D, 0x61, 0xAB, 0x54, 0x89, 0x8F, 0x56, 0x79,
47 0x3E, 0x1D, 0xEF, 0x8B, 0xD4, 0x6B, 0x10, 0x38, 0xB9, 0xD8, 0x22, 0xE8, 0x46, 0x0F, 0xAB, 0x67
48 }
49 },
50
51 {
52 "192.254.75.98",
53 33445,
54 {
55 0x95, 0x1C, 0x88, 0xB7, 0xE7, 0x5C, 0x86, 0x74, 0x18, 0xAC, 0xDB, 0x5D, 0x27, 0x38, 0x21, 0x37,
56 0x2B, 0xB5, 0xBD, 0x65, 0x27, 0x40, 0xBC, 0xDF, 0x62, 0x3A, 0x4F, 0xA2, 0x93, 0xE7, 0x5D, 0x2F
57 }
58 },
59
60 {
61 "31.7.57.236",
62 443,
63 {
64 0x2A, 0x4B, 0x50, 0xD1, 0xD5, 0x25, 0xDA, 0x2E, 0x66, 0x95, 0x92, 0xA2, 0x0C, 0x32, 0x7B, 0x5F,
65 0xAD, 0x6C, 0x7E, 0x59, 0x62, 0xDC, 0x69, 0x29, 0x6F, 0x9F, 0xEC, 0x77, 0xC4, 0x43, 0x6E, 0x4E
66 }
67 },
68
69 {
70 "107.161.17.51",
71 33445,
72 {
73 0x7B, 0xE3, 0x95, 0x1B, 0x97, 0xCA, 0x4B, 0x9E, 0xCD, 0xDA, 0x76, 0x8E, 0x8C, 0x52, 0xBA, 0x19,
74 0xE9, 0xE2, 0x69, 0x0A, 0xB5, 0x84, 0x78, 0x7B, 0xF4, 0xC9, 0x0E, 0x04, 0xDB, 0xB7, 0x51, 0x11
75 }
76 },
77
78 {
79 "37.59.102.176",
80 33445,
81 {
82 0xB9, 0x8A, 0x2C, 0xEA, 0xA6, 0xC6, 0xA2, 0xFA, 0xDC, 0x2C, 0x36, 0x32, 0xD2, 0x84, 0x31, 0x8B,
83 0x60, 0xFE, 0x53, 0x75, 0xCC, 0xB4, 0x1E, 0xFA, 0x08, 0x1A, 0xB6, 0x7F, 0x50, 0x0C, 0x1B, 0x0B
84 }
85 },
86
87 {
88 "178.21.112.187",
89 33445,
90 {
91 0x4B, 0x2C, 0x19, 0xE9, 0x24, 0x97, 0x2C, 0xB9, 0xB5, 0x77, 0x32, 0xFB, 0x17, 0x2F, 0x8A, 0x86,
92 0x04, 0xDE, 0x13, 0xEE, 0xDA, 0x2A, 0x62, 0x34, 0xE3, 0x48, 0x98, 0x33, 0x44, 0xB2, 0x30, 0x57
93 }
94 },
95
96 {
97 "63.165.243.15",
98 443,
99 {
100 0x8C, 0xD0, 0x87, 0xE3, 0x1C, 0x67, 0x56, 0x81, 0x03, 0xE8, 0xC2, 0xA2, 0x86, 0x53, 0x33, 0x7E,
101 0x90, 0xE6, 0xB8, 0xED, 0xA0, 0xD7, 0x65, 0xD5, 0x7C, 0x6B, 0x51, 0x72, 0xB4, 0xF1, 0xF0, 0x4C
102 }
103 },
104
105 {
106 "195.154.119.113",
107 33445,
108 {
109 0xE3, 0x98, 0xA6, 0x96, 0x46, 0xB8, 0xCE, 0xAC, 0xA9, 0xF0, 0xB8, 0x4F, 0x55, 0x37, 0x26, 0xC1,
110 0xC4, 0x92, 0x70, 0x55, 0x8C, 0x57, 0xDF, 0x5F, 0x3C, 0x36, 0x8F, 0x05, 0xA7, 0xD7, 0x13, 0x54
111 }
112 },
113
114 {
115 "176.31.28.63",
116 465,
117 {
118 0x0B, 0x6C, 0x7A, 0x93, 0xA6, 0xD8, 0xC0, 0xEB, 0x44, 0x96, 0x5C, 0x4A, 0x85, 0xCB, 0x88, 0xBA,
119 0x75, 0x71, 0x17, 0x0F, 0xE2, 0xDB, 0x3D, 0xEA, 0x10, 0x71, 0x3E, 0x48, 0x55, 0x9A, 0x55, 0x4D
120 }
121 },
122 };
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/gdr/tuntox

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/gdr/tuntox

Clone this repository using git:
git clone git://git.rocketgit.com/user/gdr/tuntox

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main