From cf9f0e279d1adeceefb3acb075cbbc8118b171e5 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Tue, 12 May 2009 10:14:52 +0000 Subject: Ticket #840: Update in pjnath-test to support updated TURN draft git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2693 74dad513-b988-da41-8d7b-12977e46ad98 --- pjnath/src/pjnath-test/server.c | 143 ++++++++++++++++++++++++++++++++++------ pjnath/src/pjnath-test/server.h | 1 + 2 files changed, 123 insertions(+), 21 deletions(-) diff --git a/pjnath/src/pjnath-test/server.c b/pjnath/src/pjnath-test/server.c index a5218a94..6224a599 100644 --- a/pjnath/src/pjnath-test/server.c +++ b/pjnath/src/pjnath-test/server.c @@ -353,6 +353,61 @@ static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock, test_srv = (test_server*) pj_activesock_get_user_data(asock); pool = pj_pool_create(test_srv->stun_cfg->pf, NULL, 512, 512, NULL); + /* Find the client */ + for (i=0; iturn_alloc_cnt; i++) { + if (pj_sockaddr_cmp(&test_srv->turn_alloc[i].client_addr, src_addr)==0) + break; + } + + + if (pj_stun_msg_check((pj_uint8_t*)data, size, PJ_STUN_NO_FINGERPRINT_CHECK)!=PJ_SUCCESS) { + /* Not STUN message, this probably is a ChannelData */ + pj_turn_channel_data cd; + const pj_turn_channel_data *pcd = (const pj_turn_channel_data*)data; + pj_ssize_t sent; + + if (i==test_srv->turn_alloc_cnt) { + /* Invalid data */ + PJ_LOG(1,(THIS_FILE, + "TURN Server received strayed data")); + goto on_return; + } + + alloc = &test_srv->turn_alloc[i]; + + cd.ch_number = pj_ntohs(pcd->ch_number); + cd.length = pj_ntohs(pcd->length); + + /* For UDP check the packet length */ + if (size < cd.length+sizeof(cd)) { + PJ_LOG(1,(THIS_FILE, + "TURN Server: ChannelData discarded: UDP size error")); + goto on_return; + } + + /* Lookup peer */ + for (i=0; iperm_cnt; ++i) { + if (alloc->chnum[i] == cd.ch_number) + break; + } + + if (i==alloc->perm_cnt) { + PJ_LOG(1,(THIS_FILE, + "TURN Server: ChannelData discarded: invalid channel number")); + goto on_return; + } + + /* Relay the data to peer */ + sent = cd.length; + pj_activesock_sendto(alloc->sock, &alloc->send_key, + pcd+1, &sent, 0, + &alloc->perm[i], + pj_sockaddr_get_len(&alloc->perm[i])); + + /* Done */ + goto on_return; + } + status = pj_stun_msg_decode(pool, (pj_uint8_t*)data, size, PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK, @@ -364,12 +419,6 @@ static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock, goto on_return; } - /* Find the client */ - for (i=0; iturn_alloc_cnt; i++) { - if (pj_sockaddr_cmp(&test_srv->turn_alloc[i].client_addr, src_addr)==0) - break; - } - if (i==test_srv->turn_alloc_cnt) { /* New client */ //pj_str_t ip_addr; @@ -514,6 +563,31 @@ static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock, --test_srv->turn_alloc_cnt; } else resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key); + } else if (req->hdr.type == PJ_STUN_CREATE_PERM_REQUEST) { + for (i=0; iattr_count; ++i) { + if (req->attr[i]->type == PJ_STUN_ATTR_XOR_PEER_ADDR) { + pj_stun_xor_peer_addr_attr *pa = (pj_stun_xor_peer_addr_attr*)req->attr[i]; + unsigned j; + + for (j=0; jperm_cnt; ++j) { + if (pj_sockaddr_cmp(&alloc->perm[j], &pa->sockaddr)==0) + break; + } + + if (j==alloc->perm_cnt && alloc->perm_cnt < MAX_TURN_PERM) { + char peer_info[PJ_INET6_ADDRSTRLEN]; + pj_sockaddr_print(&pa->sockaddr, peer_info, sizeof(peer_info), 3); + + pj_sockaddr_cp(&alloc->perm[alloc->perm_cnt], &pa->sockaddr); + ++alloc->perm_cnt; + + PJ_LOG(5,("", "Permission %s added to client %s, perm_cnt=%d", + peer_info, client_info, alloc->perm_cnt)); + } + + } + } + resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key); } else if (req->hdr.type == PJ_STUN_SEND_INDICATION) { pj_stun_xor_peer_addr_attr *pa; pj_stun_data_attr *da; @@ -536,26 +610,53 @@ static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock, break; } - if (j==alloc->perm_cnt && alloc->perm_cnt < MAX_TURN_PERM) { - pj_sockaddr_cp(&alloc->perm[alloc->perm_cnt], &pa->sockaddr); - ++alloc->perm_cnt; - - PJ_LOG(5,("", "Permission %s added to client %s, perm_cnt=%d", + if (j==alloc->perm_cnt) { + PJ_LOG(5,("", "SendIndication to %s is rejected (no permission)", peer_info, client_info, alloc->perm_cnt)); + } else { + PJ_LOG(5,(THIS_FILE, "Relaying %d bytes data from client %s to peer %s, " + "perm_cnt=%d", + da->length, client_info, peer_info, alloc->perm_cnt)); + + sent = da->length; + pj_activesock_sendto(alloc->sock, &alloc->send_key, + da->data, &sent, 0, + &pa->sockaddr, + pj_sockaddr_get_len(&pa->sockaddr)); } - - PJ_LOG(5,(THIS_FILE, "Relaying %d bytes data from client %s to peer %s, " - "perm_cnt=%d", - da->length, client_info, peer_info, alloc->perm_cnt)); - - sent = da->length; - pj_activesock_sendto(alloc->sock, &alloc->send_key, - da->data, &sent, 0, - &pa->sockaddr, - pj_sockaddr_get_len(&pa->sockaddr)); } else { PJ_LOG(1,(THIS_FILE, "Invalid Send Indication from %s", client_info)); } + } else if (req->hdr.type == PJ_STUN_CHANNEL_BIND_REQUEST) { + pj_stun_xor_peer_addr_attr *pa; + pj_stun_channel_number_attr *cna; + unsigned j, cn; + + pa = (pj_stun_xor_peer_addr_attr*) + pj_stun_msg_find_attr(req, PJ_STUN_ATTR_XOR_PEER_ADDR, 0); + cna = (pj_stun_channel_number_attr*) + pj_stun_msg_find_attr(req, PJ_STUN_ATTR_CHANNEL_NUMBER, 0); + cn = PJ_STUN_GET_CH_NB(cna->value); + + resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key); + + for (j=0; jperm_cnt; ++j) { + if (pj_sockaddr_cmp(&alloc->perm[j], &pa->sockaddr)==0) + break; + } + + if (i==alloc->perm_cnt) { + if (alloc->perm_cnt==MAX_TURN_PERM) { + pj_stun_msg_create_response(pool, req, PJ_STUN_SC_INSUFFICIENT_CAPACITY, NULL, &resp); + goto send_pkt; + } + pj_sockaddr_cp(&alloc->perm[i], &pa->sockaddr); + ++alloc->perm_cnt; + } + alloc->chnum[i] = cn; + + resp = create_success_response(test_srv, alloc, req, pool, 0, &auth_key); + } else if (PJ_STUN_IS_REQUEST(req->hdr.type)) { pj_stun_msg_create_response(pool, req, PJ_STUN_SC_BAD_REQUEST, NULL, &resp); } diff --git a/pjnath/src/pjnath-test/server.h b/pjnath/src/pjnath-test/server.h index 074a4178..0d178151 100644 --- a/pjnath/src/pjnath-test/server.h +++ b/pjnath/src/pjnath-test/server.h @@ -60,6 +60,7 @@ typedef struct turn_allocation pj_sockaddr alloc_addr; unsigned perm_cnt; pj_sockaddr perm[MAX_TURN_PERM]; + unsigned chnum[MAX_TURN_PERM]; pj_stun_msg *data_ind; } turn_allocation; -- cgit v1.2.3