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