1 /* $Id$ */
2 /*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include "server.h"
21 #include "test.h"
22
23 #define THIS_FILE "server.c"
24 #define MAX_STUN_PKT 1500
25 #define TURN_NONCE "thenonce"
26 #define CERT_DIR "../../pjlib/build/"
27 #define CERT_CA_FILE CERT_DIR "cacert.pem"
28 #define CERT_FILE CERT_DIR "cacert.pem"
29 #define CERT_PRIVKEY_FILE CERT_DIR "privkey.pem"
30 #define CERT_PRIVKEY_PASS "privkeypass"
31
32 #define RETURN_ERROR(rc) {app_perror("", rc);return rc;}
33
34 static pj_bool_t stun_on_data_recvfrom(pj_activesock_t *asock,
35 void *data,
36 pj_size_t size,
37 const pj_sockaddr_t *src_addr,
38 int addr_len,
39 pj_status_t status);
40 static pj_bool_t turn_tcp_on_data_read(pj_activesock_t *asock,
41 void *data,
42 pj_size_t size,
43 pj_status_t status,
44 pj_size_t *remainder);
45 #if USE_TLS
46 static pj_bool_t turn_tls_on_data_read(pj_ssl_sock_t *ssock,
47 void *data,
48 pj_size_t size,
49 pj_status_t status,
50 pj_size_t *remainder);
51 #endif
52 static pj_bool_t turn_udp_on_data_recvfrom(pj_activesock_t *asock,
53 void *data,
54 pj_size_t size,
55 const pj_sockaddr_t *src_addr,
56 int addr_len,
57 pj_status_t status);
58 static pj_bool_t turn_on_data_read(test_server *asock,
59 void *data,
60 pj_size_t size,
61 const pj_sockaddr_t *src_addr,
62 int addr_len,
63 pj_status_t status);
64 static pj_bool_t turn_tcp_on_accept_complete(pj_activesock_t *asock,
65 pj_sock_t newsock,
66 const pj_sockaddr_t *src_addr,
67 int src_addr_len,
68 pj_status_t status);
69 #if USE_TLS
70 static pj_bool_t turn_tls_on_accept_complete2(pj_ssl_sock_t *ssock,
71 pj_ssl_sock_t *newsock,
72 const pj_sockaddr_t *src_addr,
73 int src_addr_len,
74 pj_status_t status);
75 #endif
76 static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock,
77 void *data,
78 pj_size_t size,
79 const pj_sockaddr_t *src_addr,
80 int addr_len,
81 pj_status_t status);
82
create_test_server(pj_stun_config * stun_cfg,pj_uint32_t flags,const char * domain,test_server ** p_test_srv)83 pj_status_t create_test_server(pj_stun_config *stun_cfg,
84 pj_uint32_t flags,
85 const char *domain,
86 test_server **p_test_srv)
87 {
88 pj_pool_t *pool;
89 test_server *test_srv;
90 pj_sockaddr hostip;
91 char strbuf[100];
92 pj_status_t status = PJ_EINVAL;
93 pj_bool_t use_ipv6 = flags & SERVER_IPV6;
94
95 PJ_ASSERT_RETURN(stun_cfg && domain && p_test_srv, PJ_EINVAL);
96
97 if (use_ipv6) {
98 /* pj_gethostip() may return IPv6 link-local and will cause EINVAL
99 * error, so let's just hardcode it.
100 */
101 pj_sockaddr_init(pj_AF_INET6(), &hostip, NULL, 0);
102 hostip.ipv6.sin6_addr.s6_addr[15] = 1;
103 } else {
104 status = pj_gethostip(GET_AF(use_ipv6), &hostip);
105 if (status != PJ_SUCCESS)
106 RETURN_ERROR(status);
107 }
108
109 pool = pj_pool_create(mem, THIS_FILE, 512, 512, NULL);
110 test_srv = (test_server*) PJ_POOL_ZALLOC_T(pool, test_server);
111 test_srv->pool = pool;
112 test_srv->flags = flags;
113 test_srv->stun_cfg = stun_cfg;
114
115 pj_strdup2(pool, &test_srv->domain, domain);
116 test_srv->username = pj_str(TURN_USERNAME);
117 test_srv->passwd = pj_str(TURN_PASSWD);
118
119 pj_ioqueue_op_key_init(&test_srv->send_key, sizeof(test_srv->send_key));
120
121 if (flags & CREATE_DNS_SERVER) {
122 status = pj_dns_server_create(mem, test_srv->stun_cfg->ioqueue,
123 GET_AF(use_ipv6), DNS_SERVER_PORT,
124 0, &test_srv->dns_server);
125 if (status != PJ_SUCCESS) {
126 destroy_test_server(test_srv);
127 RETURN_ERROR(status);
128 }
129
130 /* Add DNS A record for the domain, for fallback */
131 if (flags & CREATE_A_RECORD_FOR_DOMAIN) {
132 pj_dns_parsed_rr rr;
133 pj_str_t res_name;
134
135 pj_strdup2(pool, &res_name, domain);
136
137 if (use_ipv6) {
138 pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60,
139 &hostip.ipv6.sin6_addr);
140 } else {
141 pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60,
142 &hostip.ipv4.sin_addr);
143 }
144
145 pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
146 }
147
148 }
149
150 if (flags & CREATE_STUN_SERVER) {
151 pj_activesock_cb stun_sock_cb;
152 pj_sockaddr bound_addr;
153
154 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));
155 stun_sock_cb.on_data_recvfrom = &stun_on_data_recvfrom;
156
157 pj_sockaddr_init(GET_AF(use_ipv6), &bound_addr,
158 NULL, STUN_SERVER_PORT);
159
160 status = pj_activesock_create_udp(pool, &bound_addr, NULL,
161 test_srv->stun_cfg->ioqueue,
162 &stun_sock_cb, test_srv,
163 &test_srv->stun_sock, NULL);
164 if (status != PJ_SUCCESS) {
165 destroy_test_server(test_srv);
166 RETURN_ERROR(status);
167 }
168
169 status = pj_activesock_start_recvfrom(test_srv->stun_sock, pool,
170 MAX_STUN_PKT, 0);
171 if (status != PJ_SUCCESS) {
172 destroy_test_server(test_srv);
173 RETURN_ERROR(status);
174 }
175
176 if (test_srv->dns_server && (flags & CREATE_STUN_SERVER_DNS_SRV)) {
177 pj_str_t res_name, target;
178 pj_dns_parsed_rr rr;
179
180 /* Add DNS entries:
181 * _stun._udp.domain 60 IN SRV 0 0 PORT stun.domain.
182 * stun.domain IN A 127.0.0.1
183 */
184 pj_ansi_snprintf(strbuf, sizeof(strbuf),
185 "_stun._udp.%s", domain);
186 pj_strdup2(pool, &res_name, strbuf);
187 pj_ansi_snprintf(strbuf, sizeof(strbuf),
188 "stun.%s", domain);
189 pj_strdup2(pool, &target, strbuf);
190 pj_dns_init_srv_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 0, 0,
191 STUN_SERVER_PORT, &target);
192 pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
193
194 res_name = target;
195 if (use_ipv6) {
196 pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60,
197 &hostip.ipv6.sin6_addr);
198 } else {
199 pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60,
200 &hostip.ipv4.sin_addr);
201 }
202 pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
203 }
204
205 }
206
207 if (flags & CREATE_TURN_SERVER) {
208
209 pj_sockaddr bound_addr;
210 pj_turn_tp_type tp_type = get_turn_tp_type(flags);
211
212 pj_sockaddr_init(GET_AF(use_ipv6), &bound_addr, NULL, TURN_SERVER_PORT);
213
214 if (tp_type == PJ_TURN_TP_UDP) {
215 pj_activesock_cb turn_sock_cb;
216
217 pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb));
218 turn_sock_cb.on_data_recvfrom = &turn_udp_on_data_recvfrom;
219
220 status = pj_activesock_create_udp(pool, &bound_addr, NULL,
221 test_srv->stun_cfg->ioqueue,
222 &turn_sock_cb, test_srv,
223 &test_srv->turn_sock, NULL);
224
225 if (status != PJ_SUCCESS) {
226 destroy_test_server(test_srv);
227 RETURN_ERROR(status);
228 }
229
230 status = pj_activesock_start_recvfrom(test_srv->turn_sock, pool,
231 MAX_STUN_PKT, 0);
232 } else if (tp_type == PJ_TURN_TP_TCP) {
233 pj_sock_t sock_fd;
234 pj_activesock_cb turn_sock_cb;
235
236 pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb));
237 turn_sock_cb.on_accept_complete2 = &turn_tcp_on_accept_complete;
238 status = pj_sock_socket(GET_AF(use_ipv6), pj_SOCK_STREAM(), 0,
239 &sock_fd);
240 if (status != PJ_SUCCESS) {
241 RETURN_ERROR(status);
242 }
243
244 {
245 int val = 1;
246 pj_sock_setsockopt(sock_fd, pj_SOL_SOCKET(), pj_SO_REUSEADDR(),
247 &val, sizeof(val));
248 }
249
250 status = pj_sock_bind(sock_fd, &bound_addr,
251 pj_sockaddr_get_len(&bound_addr));
252 if (status != PJ_SUCCESS) {
253 pj_sock_close(sock_fd);
254 RETURN_ERROR(status);
255 }
256
257 status = pj_sock_listen(sock_fd, 4);
258 if (status != PJ_SUCCESS) {
259 pj_sock_close(sock_fd);
260 RETURN_ERROR(status);
261 }
262
263 status = pj_activesock_create(pool, sock_fd, pj_SOCK_STREAM(),
264 NULL,
265 test_srv->stun_cfg->ioqueue,
266 &turn_sock_cb, test_srv,
267 &test_srv->turn_sock);
268 if (status != PJ_SUCCESS) {
269 pj_sock_close(sock_fd);
270 RETURN_ERROR(status);
271 }
272
273 status = pj_activesock_start_accept(test_srv->turn_sock,
274 pool);
275 }
276 #if USE_TLS
277 else if (tp_type == PJ_TURN_TP_TLS) {
278 pj_ssl_sock_t *ssock_serv = NULL;
279 pj_ssl_sock_param ssl_param;
280 pj_ssl_cert_t *cert = NULL;
281 pj_str_t ca_file = pj_str(CERT_CA_FILE);
282 pj_str_t cert_file = pj_str(CERT_FILE);
283 pj_str_t privkey_file = pj_str(CERT_PRIVKEY_FILE);
284 pj_str_t privkey_pass = pj_str(CERT_PRIVKEY_PASS);
285
286 pj_ssl_sock_param_default(&ssl_param);
287 ssl_param.cb.on_accept_complete2 = &turn_tls_on_accept_complete2;
288 ssl_param.cb.on_data_read = &turn_tls_on_data_read;
289 ssl_param.ioqueue = test_srv->stun_cfg->ioqueue;
290 ssl_param.timer_heap = test_srv->stun_cfg->timer_heap;
291 ssl_param.user_data = test_srv;
292 ssl_param.sock_af = GET_AF(use_ipv6);
293
294 status = pj_ssl_sock_create(pool, &ssl_param, &ssock_serv);
295 if (status != PJ_SUCCESS) {
296 if (ssock_serv)
297 pj_ssl_sock_close(ssock_serv);
298 }
299
300 status = pj_ssl_cert_load_from_files(pool, &ca_file, &cert_file,
301 &privkey_file, &privkey_pass,
302 &cert);
303 if (status != PJ_SUCCESS) {
304 if (ssock_serv)
305 pj_ssl_sock_close(ssock_serv);
306 }
307
308 status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
309 if (status != PJ_SUCCESS) {
310 if (ssock_serv)
311 pj_ssl_sock_close(ssock_serv);
312 }
313 test_srv->ssl_srv_sock = ssock_serv;
314 status = pj_ssl_sock_start_accept(ssock_serv, pool, &bound_addr,
315 pj_sockaddr_get_len(&bound_addr));
316 }
317 #endif
318 if (status != PJ_SUCCESS) {
319 destroy_test_server(test_srv);
320 RETURN_ERROR(status);
321 }
322
323 if (test_srv->dns_server && (flags & CREATE_TURN_SERVER_DNS_SRV)) {
324 pj_str_t res_name, target;
325 pj_dns_parsed_rr rr;
326
327 /* Add DNS entries:
328 * _turn._udp.domain 60 IN SRV 0 0 PORT turn.domain.
329 * turn.domain IN A 127.0.0.1
330 */
331 switch (tp_type) {
332 case PJ_TURN_TP_TCP:
333 pj_ansi_snprintf(strbuf, sizeof(strbuf),
334 "_turn._tcp.%s", domain);
335 break;
336 case PJ_TURN_TP_TLS:
337 pj_ansi_snprintf(strbuf, sizeof(strbuf),
338 "_turns._tcp.%s", domain);
339 break;
340 default:
341 pj_ansi_snprintf(strbuf, sizeof(strbuf),
342 "_turn._udp.%s", domain);
343
344 }
345 pj_strdup2(pool, &res_name, strbuf);
346 pj_ansi_snprintf(strbuf, sizeof(strbuf),
347 "turn.%s", domain);
348 pj_strdup2(pool, &target, strbuf);
349 pj_dns_init_srv_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 0, 0,
350 TURN_SERVER_PORT, &target);
351 pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
352
353 res_name = target;
354
355 if (use_ipv6) {
356 pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60,
357 &hostip.ipv6.sin6_addr);
358 } else {
359 pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60,
360 &hostip.ipv4.sin_addr);
361 }
362 pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
363 }
364 }
365
366 *p_test_srv = test_srv;
367 return PJ_SUCCESS;
368 }
369
destroy_test_server(test_server * test_srv)370 void destroy_test_server(test_server *test_srv)
371 {
372 unsigned i;
373
374 PJ_ASSERT_ON_FAIL(test_srv, return);
375
376 for (i=0; i<test_srv->turn_alloc_cnt; ++i) {
377 pj_activesock_close(test_srv->turn_alloc[i].sock);
378 pj_pool_release(test_srv->turn_alloc[i].pool);
379 }
380 test_srv->turn_alloc_cnt = 0;
381
382 if (test_srv->turn_sock) {
383 pj_activesock_close(test_srv->turn_sock);
384 test_srv->turn_sock = NULL;
385 }
386
387 if (test_srv->cl_turn_sock) {
388 pj_activesock_close(test_srv->cl_turn_sock);
389 test_srv->cl_turn_sock = NULL;
390 }
391
392 #if USE_TLS
393 if (test_srv->ssl_srv_sock) {
394 pj_ssl_sock_close(test_srv->ssl_srv_sock);
395 test_srv->ssl_srv_sock = NULL;
396 }
397 if (test_srv->ssl_cl_sock) {
398 pj_ssl_sock_close(test_srv->ssl_cl_sock);
399 test_srv->ssl_cl_sock = NULL;
400 }
401 #endif
402
403 if (test_srv->stun_sock) {
404 pj_activesock_close(test_srv->stun_sock);
405 test_srv->stun_sock = NULL;
406 }
407
408 if (test_srv->dns_server) {
409 pj_dns_server_destroy(test_srv->dns_server);
410 test_srv->dns_server = NULL;
411 }
412
413 pj_pool_safe_release(&test_srv->pool);
414 }
415
stun_on_data_recvfrom(pj_activesock_t * asock,void * data,pj_size_t size,const pj_sockaddr_t * src_addr,int addr_len,pj_status_t status)416 static pj_bool_t stun_on_data_recvfrom(pj_activesock_t *asock,
417 void *data,
418 pj_size_t size,
419 const pj_sockaddr_t *src_addr,
420 int addr_len,
421 pj_status_t status)
422 {
423 test_server *test_srv;
424 pj_stun_msg *req, *resp = NULL;
425 pj_pool_t *pool;
426 pj_ssize_t len;
427
428 if (status != PJ_SUCCESS)
429 return PJ_TRUE;
430
431 test_srv = (test_server*) pj_activesock_get_user_data(asock);
432 pool = pj_pool_create(test_srv->stun_cfg->pf, NULL, 512, 512, NULL);
433
434 status = pj_stun_msg_decode(pool, (pj_uint8_t*)data, size,
435 PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET,
436 &req, NULL, NULL);
437 if (status != PJ_SUCCESS)
438 goto on_return;
439
440 if (req->hdr.type != PJ_STUN_BINDING_REQUEST) {
441 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_BAD_REQUEST,
442 NULL, &resp);
443 goto send_pkt;
444 }
445
446 status = pj_stun_msg_create_response(pool, req, 0, NULL, &resp);
447 if (status != PJ_SUCCESS)
448 goto on_return;
449
450 pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_MAPPED_ADDR,
451 PJ_TRUE, src_addr, addr_len);
452
453 send_pkt:
454 status = pj_stun_msg_encode(resp, (pj_uint8_t*)data, MAX_STUN_PKT,
455 0, NULL, &size);
456 if (status != PJ_SUCCESS)
457 goto on_return;
458
459 len = size;
460 status = pj_activesock_sendto(asock, &test_srv->send_key, data, &len,
461 0, src_addr, addr_len);
462
463 on_return:
464 pj_pool_release(pool);
465 return PJ_TRUE;
466 }
467
468
create_success_response(test_server * test_srv,turn_allocation * alloc,pj_stun_msg * req,pj_pool_t * pool,unsigned lifetime,pj_str_t * auth_key)469 static pj_stun_msg* create_success_response(test_server *test_srv,
470 turn_allocation *alloc,
471 pj_stun_msg *req,
472 pj_pool_t *pool,
473 unsigned lifetime,
474 pj_str_t *auth_key)
475 {
476 pj_stun_msg *resp;
477 pj_str_t tmp;
478 pj_status_t status;
479
480 /* Create response */
481 status = pj_stun_msg_create_response(pool, req, 0, NULL, &resp);
482 if (status != PJ_SUCCESS) {
483 return NULL;
484 }
485 /* Add TURN_NONCE */
486 pj_stun_msg_add_string_attr(pool, resp, PJ_STUN_ATTR_NONCE, pj_cstr(&tmp, TURN_NONCE));
487 /* Add LIFETIME */
488 pj_stun_msg_add_uint_attr(pool, resp, PJ_STUN_ATTR_LIFETIME, lifetime);
489 if (lifetime != 0) {
490 /* Add XOR-RELAYED-ADDRESS */
491 pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_RELAYED_ADDR, PJ_TRUE, &alloc->alloc_addr,
492 pj_sockaddr_get_len(&alloc->alloc_addr));
493 /* Add XOR-MAPPED-ADDRESS */
494 pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, &alloc->client_addr,
495 pj_sockaddr_get_len(&alloc->client_addr));
496 }
497
498 /* Add blank MESSAGE-INTEGRITY */
499 pj_stun_msg_add_msgint_attr(pool, resp);
500
501 /* Set auth key */
502 pj_stun_create_key(pool, auth_key, &test_srv->domain, &test_srv->username,
503 PJ_STUN_PASSWD_PLAIN, &test_srv->passwd);
504
505 return resp;
506 }
507
turn_tcp_on_data_read(pj_activesock_t * asock,void * data,pj_size_t size,pj_status_t status,pj_size_t * remainder)508 static pj_bool_t turn_tcp_on_data_read(pj_activesock_t *asock,
509 void *data,
510 pj_size_t size,
511 pj_status_t status,
512 pj_size_t *remainder)
513 {
514 test_server *test_srv = (test_server *)pj_activesock_get_user_data(asock);
515
516 PJ_UNUSED_ARG(remainder);
517 return turn_on_data_read(test_srv, data, size, &test_srv->remote_addr,
518 sizeof(test_srv->remote_addr), status);
519 }
520
521 #if USE_TLS
turn_tls_on_data_read(pj_ssl_sock_t * ssl_sock,void * data,pj_size_t size,pj_status_t status,pj_size_t * remainder)522 static pj_bool_t turn_tls_on_data_read(pj_ssl_sock_t *ssl_sock,
523 void *data,
524 pj_size_t size,
525 pj_status_t status,
526 pj_size_t *remainder)
527 {
528 test_server *test_srv = (test_server *)pj_ssl_sock_get_user_data(ssl_sock);
529
530 PJ_UNUSED_ARG(remainder);
531 return turn_on_data_read(test_srv, data, size,
532 &test_srv->remote_addr,
533 sizeof(test_srv->remote_addr),
534 status);
535 }
536 #endif
537
turn_udp_on_data_recvfrom(pj_activesock_t * asock,void * data,pj_size_t size,const pj_sockaddr_t * src_addr,int addr_len,pj_status_t status)538 static pj_bool_t turn_udp_on_data_recvfrom(pj_activesock_t *asock,
539 void *data,
540 pj_size_t size,
541 const pj_sockaddr_t *src_addr,
542 int addr_len,
543 pj_status_t status)
544 {
545 test_server *test_srv;
546 test_srv = (test_server*) pj_activesock_get_user_data(asock);
547 return turn_on_data_read(test_srv, data, size, src_addr, addr_len, status);
548 }
549
turn_on_data_read(test_server * test_srv,void * data,pj_size_t size,const pj_sockaddr_t * src_addr,int addr_len,pj_status_t status)550 static pj_bool_t turn_on_data_read(test_server *test_srv,
551 void *data,
552 pj_size_t size,
553 const pj_sockaddr_t *src_addr,
554 int addr_len,
555 pj_status_t status)
556 {
557
558 pj_pool_t *pool;
559 turn_allocation *alloc;
560 pj_stun_msg *req, *resp = NULL;
561 pj_str_t auth_key = { NULL, 0 };
562 char client_info[PJ_INET6_ADDRSTRLEN+10];
563 unsigned i;
564 pj_ssize_t len;
565 pj_bool_t use_ipv6 = PJ_FALSE;
566
567 if (status != PJ_SUCCESS)
568 return PJ_TRUE;
569
570 pj_sockaddr_print(src_addr, client_info, sizeof(client_info), 3);
571
572 use_ipv6 = test_srv->flags & SERVER_IPV6;
573 pool = pj_pool_create(test_srv->stun_cfg->pf, NULL, 512, 512, NULL);
574
575 /* Find the client */
576 for (i=0; i<test_srv->turn_alloc_cnt; i++) {
577 if (pj_sockaddr_cmp(&test_srv->turn_alloc[i].client_addr, src_addr)==0)
578 break;
579 }
580
581 if (pj_stun_msg_check((pj_uint8_t*)data, size,
582 PJ_STUN_NO_FINGERPRINT_CHECK)!=PJ_SUCCESS)
583 {
584 /* Not STUN message, this probably is a ChannelData */
585 pj_turn_channel_data cd;
586 const pj_turn_channel_data *pcd = (const pj_turn_channel_data*)data;
587 char peer_info[PJ_INET6_ADDRSTRLEN];
588 pj_ssize_t sent;
589 unsigned j;
590
591 if (i==test_srv->turn_alloc_cnt) {
592 /* Invalid data */
593 PJ_LOG(1,(THIS_FILE,
594 "TURN Server received strayed data"));
595 goto on_return;
596 }
597
598 alloc = &test_srv->turn_alloc[i];
599
600 cd.ch_number = pj_ntohs(pcd->ch_number);
601 cd.length = pj_ntohs(pcd->length);
602
603 /* For UDP check the packet length */
604 if (size < cd.length+sizeof(cd)) {
605 PJ_LOG(1,(THIS_FILE,
606 "TURN Server: ChannelData discarded: UDP size error"));
607 goto on_return;
608 }
609
610 /* Lookup peer */
611 for (j=0; j<alloc->perm_cnt; ++j) {
612 if (alloc->chnum[j] == cd.ch_number)
613 break;
614 }
615
616 if (j==alloc->perm_cnt) {
617 PJ_LOG(1,(THIS_FILE,
618 "TURN Server: ChannelData discarded: invalid channel number"));
619 goto on_return;
620 }
621
622 /* Relay the data to peer */
623 pj_sockaddr_print(&alloc->perm[j], peer_info, sizeof(peer_info), 3);
624 PJ_LOG(5,(THIS_FILE, "Relaying %d bytes data from client %s to peer %s",
625 cd.length, client_info, peer_info));
626 sent = cd.length;
627 pj_activesock_sendto(alloc->sock, &alloc->send_key,
628 pcd+1, &sent, 0,
629 &alloc->perm[j],
630 pj_sockaddr_get_len(&alloc->perm[j]));
631
632 /* Done */
633 goto on_return;
634 }
635
636 status = pj_stun_msg_decode(pool, (pj_uint8_t*)data, size,
637 PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET |
638 PJ_STUN_NO_FINGERPRINT_CHECK,
639 &req, NULL, NULL);
640 if (status != PJ_SUCCESS) {
641 char errmsg[PJ_ERR_MSG_SIZE];
642 pj_strerror(status, errmsg, sizeof(errmsg));
643 PJ_LOG(1,("", "STUN message decode error from client %s: %s", client_info, errmsg));
644 goto on_return;
645 }
646
647 if (i==test_srv->turn_alloc_cnt) {
648 /* New client */
649 //pj_str_t ip_addr;
650 pj_stun_username_attr *uname;
651 pj_activesock_cb alloc_sock_cb;
652 ///turn_allocation *alloc;
653
654 /* Must be Allocate request */
655 if (req->hdr.type != PJ_STUN_ALLOCATE_REQUEST) {
656 PJ_LOG(1,(THIS_FILE, "Invalid %s %s from client %s",
657 pj_stun_get_method_name(req->hdr.type),
658 pj_stun_get_class_name(req->hdr.type),
659 client_info));
660
661 if (PJ_STUN_IS_REQUEST(req->hdr.type))
662 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_BAD_REQUEST, NULL, &resp);
663 goto send_pkt;
664 }
665
666 test_srv->turn_stat.rx_allocate_cnt++;
667
668 /* Skip if we're not responding to Allocate request */
669 if (!test_srv->turn_respond_allocate)
670 return PJ_TRUE;
671
672 /* Check if we have too many clients */
673 if (test_srv->turn_alloc_cnt == MAX_TURN_ALLOC) {
674 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_INSUFFICIENT_CAPACITY, NULL, &resp);
675 goto send_pkt;
676 }
677
678 /* Get USERNAME attribute */
679 uname = (pj_stun_username_attr*)
680 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_USERNAME, 0);
681
682 /* Reject if it doesn't have MESSAGE-INTEGRITY or USERNAME attributes or
683 * the user is incorrect
684 */
685 if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 0) == NULL ||
686 uname==NULL || pj_stricmp2(&uname->value, TURN_USERNAME) != 0)
687 {
688 pj_str_t tmp;
689
690 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_UNAUTHORIZED, NULL, &resp);
691 pj_stun_msg_add_string_attr(pool, resp, PJ_STUN_ATTR_REALM, &test_srv->domain);
692 pj_stun_msg_add_string_attr(pool, resp, PJ_STUN_ATTR_NONCE, pj_cstr(&tmp, TURN_NONCE));
693 goto send_pkt;
694 }
695
696 pj_bzero(&alloc_sock_cb, sizeof(alloc_sock_cb));
697 alloc_sock_cb.on_data_recvfrom = &alloc_on_data_recvfrom;
698
699 /* Create allocation */
700 alloc = &test_srv->turn_alloc[test_srv->turn_alloc_cnt];
701 alloc->perm_cnt = 0;
702 alloc->test_srv = test_srv;
703 pj_memcpy(&alloc->client_addr, src_addr, addr_len);
704 pj_ioqueue_op_key_init(&alloc->send_key, sizeof(alloc->send_key));
705
706 alloc->pool = pj_pool_create(test_srv->stun_cfg->pf, "alloc", 512, 512, NULL);
707
708 /* Create relay socket */
709 pj_sockaddr_init(GET_AF(use_ipv6), &alloc->alloc_addr, NULL, 0);
710 if (use_ipv6) {
711 /* pj_gethostip() may return IPv6 link-local and will cause EINVAL
712 * error, so let's just hardcode it.
713 */
714 pj_sockaddr_init(pj_AF_INET6(), &alloc->alloc_addr, NULL, 0);
715 alloc->alloc_addr.ipv6.sin6_addr.s6_addr[15] = 1;
716 } else {
717 status = pj_gethostip(GET_AF(use_ipv6), &alloc->alloc_addr);
718 if (status != PJ_SUCCESS) {
719 pj_pool_release(alloc->pool);
720 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR,
721 NULL, &resp);
722 goto send_pkt;
723 }
724 }
725
726 status = pj_activesock_create_udp(alloc->pool, &alloc->alloc_addr, NULL,
727 test_srv->stun_cfg->ioqueue,
728 &alloc_sock_cb, alloc,
729 &alloc->sock, &alloc->alloc_addr);
730 if (status != PJ_SUCCESS) {
731 pj_pool_release(alloc->pool);
732 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR, NULL, &resp);
733 goto send_pkt;
734 }
735 //pj_sockaddr_set_str_addr(pj_AF_INET(), &alloc->alloc_addr, &ip_addr);
736
737 pj_activesock_set_user_data(alloc->sock, alloc);
738
739 status = pj_activesock_start_recvfrom(alloc->sock, alloc->pool, 1500, 0);
740 if (status != PJ_SUCCESS) {
741 pj_activesock_close(alloc->sock);
742 pj_pool_release(alloc->pool);
743 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR, NULL, &resp);
744 goto send_pkt;
745 }
746
747 /* Create Data indication */
748 status = pj_stun_msg_create(alloc->pool, PJ_STUN_DATA_INDICATION,
749 PJ_STUN_MAGIC, NULL, &alloc->data_ind);
750 if (status != PJ_SUCCESS) {
751 pj_activesock_close(alloc->sock);
752 pj_pool_release(alloc->pool);
753 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR, NULL, &resp);
754 goto send_pkt;
755 }
756 pj_stun_msg_add_sockaddr_attr(alloc->pool, alloc->data_ind,
757 PJ_STUN_ATTR_XOR_PEER_ADDR, PJ_TRUE,
758 &alloc->alloc_addr,
759 pj_sockaddr_get_len(&alloc->alloc_addr));
760 pj_stun_msg_add_binary_attr(alloc->pool, alloc->data_ind,
761 PJ_STUN_ATTR_DATA, (pj_uint8_t*)"", 1);
762
763 /* Create response */
764 resp = create_success_response(test_srv, alloc, req, pool, 600, &auth_key);
765 if (resp == NULL) {
766 pj_activesock_close(alloc->sock);
767 pj_pool_release(alloc->pool);
768 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR, NULL, &resp);
769 goto send_pkt;
770 }
771
772 ++test_srv->turn_alloc_cnt;
773
774 } else {
775 alloc = &test_srv->turn_alloc[i];
776
777 if (req->hdr.type == PJ_STUN_ALLOCATE_REQUEST) {
778
779 test_srv->turn_stat.rx_allocate_cnt++;
780
781 /* Skip if we're not responding to Allocate request */
782 if (!test_srv->turn_respond_allocate)
783 return PJ_TRUE;
784
785 resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
786
787 } else if (req->hdr.type == PJ_STUN_REFRESH_REQUEST) {
788 pj_stun_lifetime_attr *lf_attr;
789
790 test_srv->turn_stat.rx_refresh_cnt++;
791
792 /* Skip if we're not responding to Refresh request */
793 if (!test_srv->turn_respond_refresh)
794 return PJ_TRUE;
795
796 lf_attr = (pj_stun_lifetime_attr*)
797 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_LIFETIME, 0);
798 if (lf_attr && lf_attr->value != 0) {
799 resp = create_success_response(test_srv, alloc, req, pool, 600, &auth_key);
800 pj_array_erase(test_srv->turn_alloc, sizeof(test_srv->turn_alloc[0]),
801 test_srv->turn_alloc_cnt, i);
802 --test_srv->turn_alloc_cnt;
803 } else
804 resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
805 } else if (req->hdr.type == PJ_STUN_CREATE_PERM_REQUEST) {
806 for (i=0; i<req->attr_count; ++i) {
807 if (req->attr[i]->type == PJ_STUN_ATTR_XOR_PEER_ADDR) {
808 pj_stun_xor_peer_addr_attr *pa = (pj_stun_xor_peer_addr_attr*)req->attr[i];
809 unsigned j;
810
811 for (j=0; j<alloc->perm_cnt; ++j) {
812 if (pj_sockaddr_cmp(&alloc->perm[j], &pa->sockaddr)==0)
813 break;
814 }
815
816 if (j==alloc->perm_cnt && alloc->perm_cnt < MAX_TURN_PERM) {
817 char peer_info[PJ_INET6_ADDRSTRLEN];
818 pj_sockaddr_print(&pa->sockaddr, peer_info, sizeof(peer_info), 3);
819
820 pj_sockaddr_cp(&alloc->perm[alloc->perm_cnt], &pa->sockaddr);
821 ++alloc->perm_cnt;
822
823 PJ_LOG(5,("", "Permission %s added to client %s, perm_cnt=%d",
824 peer_info, client_info, alloc->perm_cnt));
825 }
826
827 }
828 }
829 resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
830 } else if (req->hdr.type == PJ_STUN_SEND_INDICATION) {
831 pj_stun_xor_peer_addr_attr *pa;
832 pj_stun_data_attr *da;
833
834 test_srv->turn_stat.rx_send_ind_cnt++;
835
836 pa = (pj_stun_xor_peer_addr_attr*)
837 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);
838 da = (pj_stun_data_attr*)
839 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_DATA, 0);
840 if (pa && da) {
841 unsigned j;
842 char peer_info[PJ_INET6_ADDRSTRLEN];
843 pj_ssize_t sent;
844
845 pj_sockaddr_print(&pa->sockaddr, peer_info, sizeof(peer_info), 3);
846
847 for (j=0; j<alloc->perm_cnt; ++j) {
848 if (pj_sockaddr_cmp(&alloc->perm[j], &pa->sockaddr)==0)
849 break;
850 }
851
852 if (j==alloc->perm_cnt) {
853 PJ_LOG(5,("", "SendIndication to %s is rejected (no permission)",
854 peer_info, client_info, alloc->perm_cnt));
855 } else {
856 PJ_LOG(5,(THIS_FILE, "Relaying %d bytes data from client %s to peer %s, "
857 "perm_cnt=%d",
858 da->length, client_info, peer_info, alloc->perm_cnt));
859
860 sent = da->length;
861 pj_activesock_sendto(alloc->sock, &alloc->send_key,
862 da->data, &sent, 0,
863 &pa->sockaddr,
864 pj_sockaddr_get_len(&pa->sockaddr));
865 }
866 } else {
867 PJ_LOG(1,(THIS_FILE, "Invalid Send Indication from %s", client_info));
868 }
869 } else if (req->hdr.type == PJ_STUN_CHANNEL_BIND_REQUEST) {
870 pj_stun_xor_peer_addr_attr *pa;
871 pj_stun_channel_number_attr *cna;
872 unsigned j, cn;
873
874 pa = (pj_stun_xor_peer_addr_attr*)
875 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);
876 cna = (pj_stun_channel_number_attr*)
877 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_CHANNEL_NUMBER, 0);
878 cn = PJ_STUN_GET_CH_NB(cna->value);
879
880 resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
881
882 for (j=0; j<alloc->perm_cnt; ++j) {
883 if (pj_sockaddr_cmp(&alloc->perm[j], &pa->sockaddr)==0)
884 break;
885 }
886
887 if (j==alloc->perm_cnt) {
888 if (alloc->perm_cnt==MAX_TURN_PERM) {
889 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_INSUFFICIENT_CAPACITY, NULL, &resp);
890 goto send_pkt;
891 }
892 pj_sockaddr_cp(&alloc->perm[j], &pa->sockaddr);
893 ++alloc->perm_cnt;
894 }
895 alloc->chnum[j] = cn;
896
897 resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
898
899 } else if (PJ_STUN_IS_REQUEST(req->hdr.type)) {
900 pj_stun_msg_create_response(pool, req, PJ_STUN_SC_BAD_REQUEST, NULL, &resp);
901 }
902 }
903
904
905 send_pkt:
906 if (resp) {
907 pj_turn_tp_type tp_type = get_turn_tp_type(test_srv->flags);
908
909 status = pj_stun_msg_encode(resp, (pj_uint8_t*)data, MAX_STUN_PKT,
910 0, &auth_key, &size);
911 if (status != PJ_SUCCESS)
912 goto on_return;
913
914 len = size;
915 switch (tp_type) {
916 case PJ_TURN_TP_TCP:
917 status = pj_activesock_send(test_srv->cl_turn_sock,
918 &test_srv->send_key, data, &len, 0);
919 break;
920 #if USE_TLS
921 case PJ_TURN_TP_TLS:
922 status = pj_ssl_sock_send(test_srv->ssl_cl_sock,
923 &test_srv->send_key, data, &len, 0);
924 break;
925 #endif
926 default:
927 status = pj_activesock_sendto(test_srv->turn_sock,
928 &test_srv->send_key, data,
929 &len, 0, src_addr, addr_len);
930 }
931 }
932
933 on_return:
934 pj_pool_release(pool);
935 return PJ_TRUE;
936 }
937
turn_tcp_on_accept_complete(pj_activesock_t * asock,pj_sock_t newsock,const pj_sockaddr_t * src_addr,int src_addr_len,pj_status_t status)938 static pj_bool_t turn_tcp_on_accept_complete(pj_activesock_t *asock,
939 pj_sock_t newsock,
940 const pj_sockaddr_t *src_addr,
941 int src_addr_len,
942 pj_status_t status)
943 {
944 pj_status_t sstatus;
945 pj_activesock_cb asock_cb;
946 test_server *test_srv = (test_server *) pj_activesock_get_user_data(asock);
947
948 PJ_UNUSED_ARG(src_addr_len);
949
950 if (status != PJ_SUCCESS && status != PJ_EPENDING) {
951 return PJ_FALSE;
952 }
953
954 pj_sockaddr_cp(&test_srv->remote_addr, src_addr);
955 pj_bzero(&asock_cb, sizeof(asock_cb));
956 asock_cb.on_data_read = &turn_tcp_on_data_read;
957
958 sstatus = pj_activesock_create(test_srv->pool, newsock, pj_SOCK_STREAM(),
959 NULL, test_srv->stun_cfg->ioqueue,
960 &asock_cb, test_srv,
961 &test_srv->cl_turn_sock);
962 if (sstatus != PJ_SUCCESS) {
963 goto on_exit;
964 }
965
966 sstatus = pj_activesock_start_read(test_srv->cl_turn_sock,
967 test_srv->pool, MAX_STUN_PKT, 0);
968 if (sstatus != PJ_SUCCESS) {
969 goto on_exit;
970 }
971
972 pj_ioqueue_op_key_init(&test_srv->send_key, sizeof(test_srv->send_key));
973
974 return PJ_TRUE;
975
976 on_exit:
977 if (test_srv->cl_turn_sock)
978 pj_activesock_close(test_srv->turn_sock);
979 else
980 pj_sock_close(newsock);
981
982 return PJ_FALSE;
983
984 }
985
986 #if USE_TLS
turn_tls_on_accept_complete2(pj_ssl_sock_t * ssock,pj_ssl_sock_t * newsock,const pj_sockaddr_t * src_addr,int src_addr_len,pj_status_t status)987 static pj_bool_t turn_tls_on_accept_complete2(pj_ssl_sock_t *ssock,
988 pj_ssl_sock_t *newsock,
989 const pj_sockaddr_t *src_addr,
990 int src_addr_len,
991 pj_status_t status)
992 {
993 pj_status_t sstatus;
994 test_server *test_srv = (test_server *) pj_ssl_sock_get_user_data(ssock);
995
996 PJ_UNUSED_ARG(src_addr_len);
997
998 if (status != PJ_SUCCESS && status != PJ_EPENDING) {
999 return PJ_FALSE;
1000 }
1001
1002 pj_ssl_sock_set_user_data(newsock, test_srv);
1003 pj_sockaddr_cp(&test_srv->remote_addr, src_addr);
1004 test_srv->ssl_cl_sock = newsock;
1005
1006 sstatus = pj_ssl_sock_start_read(newsock, test_srv->pool, MAX_STUN_PKT, 0);
1007 if (sstatus != PJ_SUCCESS) {
1008 pj_ssl_sock_close(newsock);
1009 test_srv->ssl_cl_sock = NULL;
1010
1011 }
1012 return PJ_TRUE;
1013 }
1014 #endif
1015
1016 /* On received data from peer */
alloc_on_data_recvfrom(pj_activesock_t * asock,void * data,pj_size_t size,const pj_sockaddr_t * src_addr,int addr_len,pj_status_t status)1017 static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock,
1018 void *data,
1019 pj_size_t size,
1020 const pj_sockaddr_t *src_addr,
1021 int addr_len,
1022 pj_status_t status)
1023 {
1024 turn_allocation *alloc;
1025 pj_stun_xor_peer_addr_attr *pa;
1026 pj_stun_data_attr *da;
1027 char peer_info[PJ_INET6_ADDRSTRLEN+10];
1028 char client_info[PJ_INET6_ADDRSTRLEN+10];
1029 pj_uint8_t buffer[1500];
1030 pj_ssize_t sent;
1031 unsigned i;
1032
1033 PJ_UNUSED_ARG(addr_len);
1034
1035 if (status != PJ_SUCCESS)
1036 return PJ_TRUE;
1037
1038 alloc = (turn_allocation*) pj_activesock_get_user_data(asock);
1039
1040 pj_sockaddr_print(&alloc->client_addr, client_info, sizeof(client_info), 3);
1041 pj_sockaddr_print(src_addr, peer_info, sizeof(peer_info), 3);
1042
1043 /* Check that this peer has a permission */
1044 for (i=0; i<alloc->perm_cnt; ++i) {
1045 if (pj_sockaddr_cmp(&alloc->perm[i], src_addr) == 0)
1046 {
1047 break;
1048 }
1049 }
1050 if (i==alloc->perm_cnt) {
1051 PJ_LOG(5,("", "Client %s received %d bytes unauthorized data from peer %s",
1052 client_info, size, peer_info));
1053 if (alloc->perm_cnt == 0)
1054 PJ_LOG(5,("", "Client %s has no permission", client_info));
1055 return PJ_TRUE;
1056 }
1057
1058 /* Format a Data indication */
1059 pa = (pj_stun_xor_peer_addr_attr*)
1060 pj_stun_msg_find_attr(alloc->data_ind, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);
1061 da = (pj_stun_data_attr*)
1062 pj_stun_msg_find_attr(alloc->data_ind, PJ_STUN_ATTR_DATA, 0);
1063 pj_assert(pa && da);
1064
1065 pj_sockaddr_cp(&pa->sockaddr, src_addr);
1066 da->data = (pj_uint8_t*)data;
1067 da->length = (unsigned)size;
1068
1069 /* Encode Data indication */
1070 status = pj_stun_msg_encode(alloc->data_ind, buffer, sizeof(buffer), 0,
1071 NULL, &size);
1072 if (status != PJ_SUCCESS)
1073 return PJ_TRUE;
1074
1075 /* Send */
1076 sent = size;
1077 PJ_LOG(5,("", "Forwarding %d bytes data from peer %s to client %s",
1078 sent, peer_info, client_info));
1079
1080 pj_activesock_sendto(alloc->test_srv->turn_sock, &alloc->send_key, buffer,
1081 &sent, 0, &alloc->client_addr,
1082 pj_sockaddr_get_len(&alloc->client_addr));
1083
1084 return PJ_TRUE;
1085 }
1086
1087