diff options
author | GDR! <gdr@go2.pl> | 2014-11-10 19:05:14 +0100 |
---|---|---|
committer | GDR! <gdr@go2.pl> | 2014-11-10 19:05:14 +0100 |
commit | 3b42ed1ca1be6d1c8f14606befee8b8deae64ac8 (patch) | |
tree | da63b91d1df005deb20818c7db12fb2bfd1aa6cf /main.c | |
parent | f877c04fdb45aebff081df4ed1b7fea9bd293fa5 (diff) |
builds well
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 289 |
1 files changed, 289 insertions, 0 deletions
@@ -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 | } | ||