summaryrefslogtreecommitdiff
path: root/pjnath
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-05-12 10:14:52 +0000
committerBenny Prijono <bennylp@teluu.com>2009-05-12 10:14:52 +0000
commitcf9f0e279d1adeceefb3acb075cbbc8118b171e5 (patch)
tree475d0da79162673bc133b8e9fc4ee3a2bdd1e7bb /pjnath
parent658c5af6fff20c7cb0dc1e2663e6059e3cc6fd74 (diff)
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
Diffstat (limited to 'pjnath')
-rw-r--r--pjnath/src/pjnath-test/server.c143
-rw-r--r--pjnath/src/pjnath-test/server.h1
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; i<test_srv->turn_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; i<alloc->perm_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; i<test_srv->turn_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; i<req->attr_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; j<alloc->perm_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; j<alloc->perm_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;