diff options
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | main.c | 289 | ||||
-rw-r--r-- | tox_bootstrap.h | 122 |
3 files changed, 424 insertions, 7 deletions
@@ -1,14 +1,20 @@ | |||
1 | SOURCES = main.c | 1 | SOURCES = $(wildcard *.c) |
2 | DEPS= | 2 | DEPS=libtoxcore |
3 | CC=gcc | 3 | 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 | OBJECTS=$(SOURCES:.c=.o) | 8 | OBJECTS=$(SOURCES:.c=.o) |
9 | INCLUDES = $(wildcard *.h) | ||
6 | 10 | ||
7 | .c.o: | 11 | .c.o: $(INCLUDES) |
8 | $(CC) $(CFLAGS) $< -c -o $@ | 12 | $(CC) $(CFLAGS) $< -c -o $@ |
9 | 13 | ||
10 | tuntox: $(OBJECTS) | 14 | tuntox: $(OBJECTS) $(INCLUDES) |
11 | $(CC) --static -o $@ -ltoxcore $^ $(CFLAGS) /usr/local/lib/libsodium.a | 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 | ||
@@ -0,0 +1,289 @@ | |||
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 | } | ||
diff --git a/tox_bootstrap.h b/tox_bootstrap.h new file mode 100644 index 0000000..119a2d2 --- /dev/null +++ b/tox_bootstrap.h | |||
@@ -0,0 +1,122 @@ | |||
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 | }; | ||