1
/* $Id: server.c 3553 2011-05-05 06:14:19Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
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.
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.
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
23
#define THIS_FILE "server.c"
24
#define MAX_STUN_PKT 1500
25
#define TURN_NONCE "thenonce"
27
static pj_bool_t stun_on_data_recvfrom(pj_activesock_t *asock,
30
const pj_sockaddr_t *src_addr,
33
static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock,
36
const pj_sockaddr_t *src_addr,
39
static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock,
42
const pj_sockaddr_t *src_addr,
46
pj_status_t create_test_server(pj_stun_config *stun_cfg,
49
test_server **p_test_srv)
52
test_server *test_srv;
57
PJ_ASSERT_RETURN(stun_cfg && domain && p_test_srv, PJ_EINVAL);
59
status = pj_gethostip(pj_AF_INET(), &hostip);
60
if (status != PJ_SUCCESS)
63
pool = pj_pool_create(mem, THIS_FILE, 512, 512, NULL);
64
test_srv = (test_server*) PJ_POOL_ZALLOC_T(pool, test_server);
65
test_srv->pool = pool;
66
test_srv->flags = flags;
67
test_srv->stun_cfg = stun_cfg;
69
pj_strdup2(pool, &test_srv->domain, domain);
70
test_srv->username = pj_str(TURN_USERNAME);
71
test_srv->passwd = pj_str(TURN_PASSWD);
73
pj_ioqueue_op_key_init(&test_srv->send_key, sizeof(test_srv->send_key));
75
if (flags & CREATE_DNS_SERVER) {
76
status = pj_dns_server_create(mem, test_srv->stun_cfg->ioqueue,
77
pj_AF_INET(), DNS_SERVER_PORT,
78
0, &test_srv->dns_server);
79
if (status != PJ_SUCCESS) {
80
destroy_test_server(test_srv);
84
/* Add DNS A record for the domain, for fallback */
85
if (flags & CREATE_A_RECORD_FOR_DOMAIN) {
90
pj_strdup2(pool, &res_name, domain);
91
ip_addr = hostip.ipv4.sin_addr;
92
pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
93
pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
98
if (flags & CREATE_STUN_SERVER) {
99
pj_activesock_cb stun_sock_cb;
100
pj_sockaddr bound_addr;
102
pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));
103
stun_sock_cb.on_data_recvfrom = &stun_on_data_recvfrom;
105
pj_sockaddr_in_init(&bound_addr.ipv4, NULL, STUN_SERVER_PORT);
107
status = pj_activesock_create_udp(pool, &bound_addr, NULL,
108
test_srv->stun_cfg->ioqueue,
109
&stun_sock_cb, test_srv,
110
&test_srv->stun_sock, NULL);
111
if (status != PJ_SUCCESS) {
112
destroy_test_server(test_srv);
116
status = pj_activesock_start_recvfrom(test_srv->stun_sock, pool,
118
if (status != PJ_SUCCESS) {
119
destroy_test_server(test_srv);
123
if (test_srv->dns_server && (flags & CREATE_STUN_SERVER_DNS_SRV)) {
124
pj_str_t res_name, target;
129
* _stun._udp.domain 60 IN SRV 0 0 PORT stun.domain.
130
* stun.domain IN A 127.0.0.1
132
pj_ansi_snprintf(strbuf, sizeof(strbuf),
133
"_stun._udp.%s", domain);
134
pj_strdup2(pool, &res_name, strbuf);
135
pj_ansi_snprintf(strbuf, sizeof(strbuf),
137
pj_strdup2(pool, &target, strbuf);
138
pj_dns_init_srv_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 0, 0,
139
STUN_SERVER_PORT, &target);
140
pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
143
ip_addr = hostip.ipv4.sin_addr;
144
pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
145
pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
150
if (flags & CREATE_TURN_SERVER) {
151
pj_activesock_cb turn_sock_cb;
152
pj_sockaddr bound_addr;
154
pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb));
155
turn_sock_cb.on_data_recvfrom = &turn_on_data_recvfrom;
157
pj_sockaddr_in_init(&bound_addr.ipv4, NULL, TURN_SERVER_PORT);
159
status = pj_activesock_create_udp(pool, &bound_addr, NULL,
160
test_srv->stun_cfg->ioqueue,
161
&turn_sock_cb, test_srv,
162
&test_srv->turn_sock, NULL);
163
if (status != PJ_SUCCESS) {
164
destroy_test_server(test_srv);
168
status = pj_activesock_start_recvfrom(test_srv->turn_sock, pool,
170
if (status != PJ_SUCCESS) {
171
destroy_test_server(test_srv);
175
if (test_srv->dns_server && (flags & CREATE_TURN_SERVER_DNS_SRV)) {
176
pj_str_t res_name, target;
181
* _turn._udp.domain 60 IN SRV 0 0 PORT turn.domain.
182
* turn.domain IN A 127.0.0.1
184
pj_ansi_snprintf(strbuf, sizeof(strbuf),
185
"_turn._udp.%s", domain);
186
pj_strdup2(pool, &res_name, strbuf);
187
pj_ansi_snprintf(strbuf, sizeof(strbuf),
189
pj_strdup2(pool, &target, strbuf);
190
pj_dns_init_srv_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 0, 0,
191
TURN_SERVER_PORT, &target);
192
pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
195
ip_addr = hostip.ipv4.sin_addr;
196
pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
197
pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
201
*p_test_srv = test_srv;
205
void destroy_test_server(test_server *test_srv)
209
PJ_ASSERT_ON_FAIL(test_srv, return);
211
for (i=0; i<test_srv->turn_alloc_cnt; ++i) {
212
pj_activesock_close(test_srv->turn_alloc[i].sock);
213
pj_pool_release(test_srv->turn_alloc[i].pool);
215
test_srv->turn_alloc_cnt = 0;
217
if (test_srv->turn_sock) {
218
pj_activesock_close(test_srv->turn_sock);
219
test_srv->turn_sock = NULL;
222
if (test_srv->stun_sock) {
223
pj_activesock_close(test_srv->stun_sock);
224
test_srv->stun_sock = NULL;
227
if (test_srv->dns_server) {
228
pj_dns_server_destroy(test_srv->dns_server);
229
test_srv->dns_server = NULL;
232
if (test_srv->pool) {
233
pj_pool_t *pool = test_srv->pool;
234
test_srv->pool = NULL;
235
pj_pool_release(pool);
239
static pj_bool_t stun_on_data_recvfrom(pj_activesock_t *asock,
242
const pj_sockaddr_t *src_addr,
246
test_server *test_srv;
247
pj_stun_msg *req, *resp = NULL;
251
if (status != PJ_SUCCESS)
254
test_srv = (test_server*) pj_activesock_get_user_data(asock);
255
pool = pj_pool_create(test_srv->stun_cfg->pf, NULL, 512, 512, NULL);
257
status = pj_stun_msg_decode(pool, (pj_uint8_t*)data, size,
258
PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET,
260
if (status != PJ_SUCCESS)
263
if (req->hdr.type != PJ_STUN_BINDING_REQUEST) {
264
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_BAD_REQUEST,
269
status = pj_stun_msg_create_response(pool, req, 0, NULL, &resp);
270
if (status != PJ_SUCCESS)
273
pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_MAPPED_ADDR,
274
PJ_TRUE, src_addr, addr_len);
277
status = pj_stun_msg_encode(resp, (pj_uint8_t*)data, MAX_STUN_PKT,
279
if (status != PJ_SUCCESS)
283
status = pj_activesock_sendto(asock, &test_srv->send_key, data, &len,
284
0, src_addr, addr_len);
287
pj_pool_release(pool);
292
static pj_stun_msg* create_success_response(test_server *test_srv,
293
turn_allocation *alloc,
303
/* Create response */
304
status = pj_stun_msg_create_response(pool, req, 0, NULL, &resp);
305
if (status != PJ_SUCCESS) {
309
pj_stun_msg_add_string_attr(pool, resp, PJ_STUN_ATTR_NONCE, pj_cstr(&tmp, TURN_NONCE));
311
pj_stun_msg_add_uint_attr(pool, resp, PJ_STUN_ATTR_LIFETIME, lifetime);
313
/* Add XOR-RELAYED-ADDRESS */
314
pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_RELAYED_ADDR, PJ_TRUE, &alloc->alloc_addr,
315
pj_sockaddr_get_len(&alloc->alloc_addr));
316
/* Add XOR-MAPPED-ADDRESS */
317
pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, &alloc->client_addr,
318
pj_sockaddr_get_len(&alloc->client_addr));
321
/* Add blank MESSAGE-INTEGRITY */
322
pj_stun_msg_add_msgint_attr(pool, resp);
325
pj_stun_create_key(pool, auth_key, &test_srv->domain, &test_srv->username,
326
PJ_STUN_PASSWD_PLAIN, &test_srv->passwd);
332
static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock,
335
const pj_sockaddr_t *src_addr,
339
test_server *test_srv;
341
turn_allocation *alloc;
342
pj_stun_msg *req, *resp = NULL;
343
pj_str_t auth_key = { NULL, 0 };
344
char client_info[PJ_INET6_ADDRSTRLEN+10];
348
if (status != PJ_SUCCESS)
351
pj_sockaddr_print(src_addr, client_info, sizeof(client_info), 3);
353
test_srv = (test_server*) pj_activesock_get_user_data(asock);
354
pool = pj_pool_create(test_srv->stun_cfg->pf, NULL, 512, 512, NULL);
356
/* Find the client */
357
for (i=0; i<test_srv->turn_alloc_cnt; i++) {
358
if (pj_sockaddr_cmp(&test_srv->turn_alloc[i].client_addr, src_addr)==0)
363
if (pj_stun_msg_check((pj_uint8_t*)data, size, PJ_STUN_NO_FINGERPRINT_CHECK)!=PJ_SUCCESS) {
364
/* Not STUN message, this probably is a ChannelData */
365
pj_turn_channel_data cd;
366
const pj_turn_channel_data *pcd = (const pj_turn_channel_data*)data;
369
if (i==test_srv->turn_alloc_cnt) {
372
"TURN Server received strayed data"));
376
alloc = &test_srv->turn_alloc[i];
378
cd.ch_number = pj_ntohs(pcd->ch_number);
379
cd.length = pj_ntohs(pcd->length);
381
/* For UDP check the packet length */
382
if (size < cd.length+sizeof(cd)) {
384
"TURN Server: ChannelData discarded: UDP size error"));
389
for (i=0; i<alloc->perm_cnt; ++i) {
390
if (alloc->chnum[i] == cd.ch_number)
394
if (i==alloc->perm_cnt) {
396
"TURN Server: ChannelData discarded: invalid channel number"));
400
/* Relay the data to peer */
402
pj_activesock_sendto(alloc->sock, &alloc->send_key,
405
pj_sockaddr_get_len(&alloc->perm[i]));
411
status = pj_stun_msg_decode(pool, (pj_uint8_t*)data, size,
412
PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET |
413
PJ_STUN_NO_FINGERPRINT_CHECK,
415
if (status != PJ_SUCCESS) {
416
char errmsg[PJ_ERR_MSG_SIZE];
417
pj_strerror(status, errmsg, sizeof(errmsg));
418
PJ_LOG(1,("", "STUN message decode error from client %s: %s", client_info, errmsg));
422
if (i==test_srv->turn_alloc_cnt) {
425
pj_stun_username_attr *uname;
426
pj_activesock_cb alloc_sock_cb;
427
turn_allocation *alloc;
429
/* Must be Allocate request */
430
if (req->hdr.type != PJ_STUN_ALLOCATE_REQUEST) {
431
PJ_LOG(1,(THIS_FILE, "Invalid %s %s from client %s",
432
pj_stun_get_method_name(req->hdr.type),
433
pj_stun_get_class_name(req->hdr.type),
436
if (PJ_STUN_IS_REQUEST(req->hdr.type))
437
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_BAD_REQUEST, NULL, &resp);
441
test_srv->turn_stat.rx_allocate_cnt++;
443
/* Skip if we're not responding to Allocate request */
444
if (!test_srv->turn_respond_allocate)
447
/* Check if we have too many clients */
448
if (test_srv->turn_alloc_cnt == MAX_TURN_ALLOC) {
449
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_INSUFFICIENT_CAPACITY, NULL, &resp);
453
/* Get USERNAME attribute */
454
uname = (pj_stun_username_attr*)
455
pj_stun_msg_find_attr(req, PJ_STUN_ATTR_USERNAME, 0);
457
/* Reject if it doesn't have MESSAGE-INTEGRITY or USERNAME attributes or
458
* the user is incorrect
460
if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 0) == NULL ||
461
uname==NULL || pj_stricmp2(&uname->value, TURN_USERNAME) != 0)
465
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_UNAUTHORIZED, NULL, &resp);
466
pj_stun_msg_add_string_attr(pool, resp, PJ_STUN_ATTR_REALM, &test_srv->domain);
467
pj_stun_msg_add_string_attr(pool, resp, PJ_STUN_ATTR_NONCE, pj_cstr(&tmp, TURN_NONCE));
471
pj_bzero(&alloc_sock_cb, sizeof(alloc_sock_cb));
472
alloc_sock_cb.on_data_recvfrom = &alloc_on_data_recvfrom;
474
/* Create allocation */
475
alloc = &test_srv->turn_alloc[test_srv->turn_alloc_cnt];
477
alloc->test_srv = test_srv;
478
pj_memcpy(&alloc->client_addr, src_addr, addr_len);
479
pj_ioqueue_op_key_init(&alloc->send_key, sizeof(alloc->send_key));
481
alloc->pool = pj_pool_create(test_srv->stun_cfg->pf, "alloc", 512, 512, NULL);
483
/* Create relay socket */
484
pj_sockaddr_in_init(&alloc->alloc_addr.ipv4, NULL, 0);
485
pj_gethostip(pj_AF_INET(), &alloc->alloc_addr);
487
status = pj_activesock_create_udp(alloc->pool, &alloc->alloc_addr, NULL,
488
test_srv->stun_cfg->ioqueue,
489
&alloc_sock_cb, alloc,
490
&alloc->sock, &alloc->alloc_addr);
491
if (status != PJ_SUCCESS) {
492
pj_pool_release(alloc->pool);
493
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR, NULL, &resp);
496
//pj_sockaddr_set_str_addr(pj_AF_INET(), &alloc->alloc_addr, &ip_addr);
498
pj_activesock_set_user_data(alloc->sock, alloc);
500
status = pj_activesock_start_recvfrom(alloc->sock, alloc->pool, 1500, 0);
501
if (status != PJ_SUCCESS) {
502
pj_activesock_close(alloc->sock);
503
pj_pool_release(alloc->pool);
504
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR, NULL, &resp);
508
/* Create Data indication */
509
status = pj_stun_msg_create(alloc->pool, PJ_STUN_DATA_INDICATION,
510
PJ_STUN_MAGIC, NULL, &alloc->data_ind);
511
if (status != PJ_SUCCESS) {
512
pj_activesock_close(alloc->sock);
513
pj_pool_release(alloc->pool);
514
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR, NULL, &resp);
517
pj_stun_msg_add_sockaddr_attr(alloc->pool, alloc->data_ind,
518
PJ_STUN_ATTR_XOR_PEER_ADDR, PJ_TRUE,
520
pj_sockaddr_get_len(&alloc->alloc_addr));
521
pj_stun_msg_add_binary_attr(alloc->pool, alloc->data_ind,
522
PJ_STUN_ATTR_DATA, (pj_uint8_t*)"", 1);
524
/* Create response */
525
resp = create_success_response(test_srv, alloc, req, pool, 600, &auth_key);
527
pj_activesock_close(alloc->sock);
528
pj_pool_release(alloc->pool);
529
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR, NULL, &resp);
533
++test_srv->turn_alloc_cnt;
536
alloc = &test_srv->turn_alloc[i];
538
if (req->hdr.type == PJ_STUN_ALLOCATE_REQUEST) {
540
test_srv->turn_stat.rx_allocate_cnt++;
542
/* Skip if we're not responding to Allocate request */
543
if (!test_srv->turn_respond_allocate)
546
resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
548
} else if (req->hdr.type == PJ_STUN_REFRESH_REQUEST) {
549
pj_stun_lifetime_attr *lf_attr;
551
test_srv->turn_stat.rx_refresh_cnt++;
553
/* Skip if we're not responding to Refresh request */
554
if (!test_srv->turn_respond_refresh)
557
lf_attr = (pj_stun_lifetime_attr*)
558
pj_stun_msg_find_attr(req, PJ_STUN_ATTR_LIFETIME, 0);
559
if (lf_attr && lf_attr->value != 0) {
560
resp = create_success_response(test_srv, alloc, req, pool, 600, &auth_key);
561
pj_array_erase(test_srv->turn_alloc, sizeof(test_srv->turn_alloc[0]),
562
test_srv->turn_alloc_cnt, i);
563
--test_srv->turn_alloc_cnt;
565
resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
566
} else if (req->hdr.type == PJ_STUN_CREATE_PERM_REQUEST) {
567
for (i=0; i<req->attr_count; ++i) {
568
if (req->attr[i]->type == PJ_STUN_ATTR_XOR_PEER_ADDR) {
569
pj_stun_xor_peer_addr_attr *pa = (pj_stun_xor_peer_addr_attr*)req->attr[i];
572
for (j=0; j<alloc->perm_cnt; ++j) {
573
if (pj_sockaddr_cmp(&alloc->perm[j], &pa->sockaddr)==0)
577
if (j==alloc->perm_cnt && alloc->perm_cnt < MAX_TURN_PERM) {
578
char peer_info[PJ_INET6_ADDRSTRLEN];
579
pj_sockaddr_print(&pa->sockaddr, peer_info, sizeof(peer_info), 3);
581
pj_sockaddr_cp(&alloc->perm[alloc->perm_cnt], &pa->sockaddr);
584
PJ_LOG(5,("", "Permission %s added to client %s, perm_cnt=%d",
585
peer_info, client_info, alloc->perm_cnt));
590
resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
591
} else if (req->hdr.type == PJ_STUN_SEND_INDICATION) {
592
pj_stun_xor_peer_addr_attr *pa;
593
pj_stun_data_attr *da;
595
test_srv->turn_stat.rx_send_ind_cnt++;
597
pa = (pj_stun_xor_peer_addr_attr*)
598
pj_stun_msg_find_attr(req, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);
599
da = (pj_stun_data_attr*)
600
pj_stun_msg_find_attr(req, PJ_STUN_ATTR_DATA, 0);
603
char peer_info[PJ_INET6_ADDRSTRLEN];
606
pj_sockaddr_print(&pa->sockaddr, peer_info, sizeof(peer_info), 3);
608
for (j=0; j<alloc->perm_cnt; ++j) {
609
if (pj_sockaddr_cmp(&alloc->perm[j], &pa->sockaddr)==0)
613
if (j==alloc->perm_cnt) {
614
PJ_LOG(5,("", "SendIndication to %s is rejected (no permission)",
615
peer_info, client_info, alloc->perm_cnt));
617
PJ_LOG(5,(THIS_FILE, "Relaying %d bytes data from client %s to peer %s, "
619
da->length, client_info, peer_info, alloc->perm_cnt));
622
pj_activesock_sendto(alloc->sock, &alloc->send_key,
625
pj_sockaddr_get_len(&pa->sockaddr));
628
PJ_LOG(1,(THIS_FILE, "Invalid Send Indication from %s", client_info));
630
} else if (req->hdr.type == PJ_STUN_CHANNEL_BIND_REQUEST) {
631
pj_stun_xor_peer_addr_attr *pa;
632
pj_stun_channel_number_attr *cna;
635
pa = (pj_stun_xor_peer_addr_attr*)
636
pj_stun_msg_find_attr(req, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);
637
cna = (pj_stun_channel_number_attr*)
638
pj_stun_msg_find_attr(req, PJ_STUN_ATTR_CHANNEL_NUMBER, 0);
639
cn = PJ_STUN_GET_CH_NB(cna->value);
641
resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
643
for (j=0; j<alloc->perm_cnt; ++j) {
644
if (pj_sockaddr_cmp(&alloc->perm[j], &pa->sockaddr)==0)
648
if (i==alloc->perm_cnt) {
649
if (alloc->perm_cnt==MAX_TURN_PERM) {
650
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_INSUFFICIENT_CAPACITY, NULL, &resp);
653
pj_sockaddr_cp(&alloc->perm[i], &pa->sockaddr);
656
alloc->chnum[i] = cn;
658
resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key);
660
} else if (PJ_STUN_IS_REQUEST(req->hdr.type)) {
661
pj_stun_msg_create_response(pool, req, PJ_STUN_SC_BAD_REQUEST, NULL, &resp);
668
status = pj_stun_msg_encode(resp, (pj_uint8_t*)data, MAX_STUN_PKT,
669
0, &auth_key, &size);
670
if (status != PJ_SUCCESS)
674
status = pj_activesock_sendto(asock, &test_srv->send_key, data, &len,
675
0, src_addr, addr_len);
679
pj_pool_release(pool);
683
/* On received data from peer */
684
static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock,
687
const pj_sockaddr_t *src_addr,
691
turn_allocation *alloc;
692
pj_stun_xor_peer_addr_attr *pa;
693
pj_stun_data_attr *da;
694
char peer_info[PJ_INET6_ADDRSTRLEN+10];
695
char client_info[PJ_INET6_ADDRSTRLEN+10];
696
pj_uint8_t buffer[1500];
700
if (status != PJ_SUCCESS)
703
alloc = (turn_allocation*) pj_activesock_get_user_data(asock);
705
pj_sockaddr_print(&alloc->client_addr, client_info, sizeof(client_info), 3);
706
pj_sockaddr_print(src_addr, peer_info, sizeof(peer_info), 3);
708
/* Check that this peer has a permission */
709
for (i=0; i<alloc->perm_cnt; ++i) {
710
if (pj_sockaddr_get_len(&alloc->perm[i]) == (unsigned)addr_len &&
711
pj_memcmp(pj_sockaddr_get_addr(&alloc->perm[i]),
712
pj_sockaddr_get_addr(src_addr),
718
if (i==alloc->perm_cnt) {
719
PJ_LOG(5,("", "Client %s received %d bytes unauthorized data from peer %s",
720
client_info, size, peer_info));
721
if (alloc->perm_cnt == 0)
722
PJ_LOG(5,("", "Client %s has no permission", client_info));
726
/* Format a Data indication */
727
pa = (pj_stun_xor_peer_addr_attr*)
728
pj_stun_msg_find_attr(alloc->data_ind, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);
729
da = (pj_stun_data_attr*)
730
pj_stun_msg_find_attr(alloc->data_ind, PJ_STUN_ATTR_DATA, 0);
733
pj_sockaddr_cp(&pa->sockaddr, src_addr);
734
da->data = (pj_uint8_t*)data;
737
/* Encode Data indication */
738
status = pj_stun_msg_encode(alloc->data_ind, buffer, sizeof(buffer), 0,
740
if (status != PJ_SUCCESS)
745
PJ_LOG(5,("", "Forwarding %d bytes data from peer %s to client %s",
746
sent, peer_info, client_info));
748
pj_activesock_sendto(alloc->test_srv->turn_sock, &alloc->send_key, buffer,
749
&sent, 0, &alloc->client_addr,
750
pj_sockaddr_get_len(&alloc->client_addr));