summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorGDR! <gdr@go2.pl>2014-11-10 19:05:14 +0100
committerGDR! <gdr@go2.pl>2014-11-10 19:05:14 +0100
commit3b42ed1ca1be6d1c8f14606befee8b8deae64ac8 (patch)
treeda63b91d1df005deb20818c7db12fb2bfd1aa6cf /main.c
parentf877c04fdb45aebff081df4ed1b7fea9bd293fa5 (diff)
builds well
Diffstat (limited to 'main.c')
-rw-r--r--main.c289
1 files changed, 289 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..2d09e2e
--- /dev/null
+++ b/main.c
@@ -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
17static Tox_Options tox_options;
18static Tox *tox;
19int client_socket = 0;
20
21static 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 */
31static 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 */
56void 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 */
63static 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 */
80void 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
111void 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
121void 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 */
134void *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 */
144int 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
199unsigned 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
212int 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
258int 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}