summaryrefslogtreecommitdiff
path: root/pjnath/src/pjturn-srv
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-03-20 16:32:06 +0000
committerBenny Prijono <bennylp@teluu.com>2008-03-20 16:32:06 +0000
commitf5c4ac3cbadd515c83b71618e7ff2b1683c2aca2 (patch)
treef3378bd897fc58e21490005bb0000999eaa0940b /pjnath/src/pjturn-srv
parent7f5db291ab29a7396137961f69470562f5bce4a7 (diff)
More ticket #485: client and server self tested
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1879 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjnath/src/pjturn-srv')
-rw-r--r--pjnath/src/pjturn-srv/allocation.c79
-rw-r--r--pjnath/src/pjturn-srv/auth.c12
-rw-r--r--pjnath/src/pjturn-srv/auth.h10
-rw-r--r--pjnath/src/pjturn-srv/main.c98
-rw-r--r--pjnath/src/pjturn-srv/server.c26
-rw-r--r--pjnath/src/pjturn-srv/turn.h2
6 files changed, 168 insertions, 59 deletions
diff --git a/pjnath/src/pjturn-srv/allocation.c b/pjnath/src/pjturn-srv/allocation.c
index 14ed228b..339b2924 100644
--- a/pjnath/src/pjturn-srv/allocation.c
+++ b/pjnath/src/pjturn-srv/allocation.c
@@ -668,7 +668,7 @@ static pj_status_t create_relay(pj_turn_srv *srv,
if (status != PJ_SUCCESS) {
/* Unable to allocate port */
- PJ_LOG(4,(THIS_FILE, "bind() failed: err %d",
+ PJ_LOG(4,(THIS_FILE, "Unable to allocate relay, giving up: err %d",
status));
pj_sock_close(relay->tp.sock);
relay->tp.sock = PJ_INVALID_SOCKET;
@@ -688,6 +688,11 @@ static pj_status_t create_relay(pj_turn_srv *srv,
if (!pj_sockaddr_has_addr(&relay->hkey.addr)) {
pj_sockaddr_copy_addr(&relay->hkey.addr, &alloc->listener->addr);
}
+ if (!pj_sockaddr_has_addr(&relay->hkey.addr)) {
+ pj_sockaddr tmp_addr;
+ pj_gethostip(af, &tmp_addr);
+ pj_sockaddr_copy_addr(&relay->hkey.addr, &tmp_addr);
+ }
/* Init ioqueue */
pj_bzero(&icb, sizeof(icb));
@@ -751,14 +756,18 @@ static void send_reply_ok(pj_turn_allocation *alloc,
interval = 0;
}
- /* Add LIFETIME. */
- pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
- PJ_STUN_ATTR_LIFETIME, interval);
+ /* Add LIFETIME if this is not ChannelBind. */
+ if (PJ_STUN_GET_METHOD(tdata->msg->hdr.type)!=PJ_STUN_CHANNEL_BIND_METHOD){
+ pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
+ PJ_STUN_ATTR_LIFETIME, interval);
- /* Add BANDWIDTH */
- pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
- PJ_STUN_ATTR_BANDWIDTH,
- alloc->bandwidth);
+ /* Add BANDWIDTH if lifetime is not zero */
+ if (interval != 0) {
+ pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
+ PJ_STUN_ATTR_BANDWIDTH,
+ alloc->bandwidth);
+ }
+ }
status = pj_stun_session_send_msg(alloc->sess, PJ_TRUE,
&alloc->hkey.clt_addr,
@@ -773,8 +782,8 @@ static void send_reply_ok(pj_turn_allocation *alloc,
/* Create new permission */
static pj_turn_permission *create_permission(pj_turn_allocation *alloc,
- const pj_sockaddr_t *peer_addr,
- unsigned addr_len)
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len)
{
pj_turn_permission *perm;
@@ -794,6 +803,10 @@ static pj_turn_permission *create_permission(pj_turn_allocation *alloc,
pj_gettimeofday(&perm->expiry);
perm->expiry.sec += PJ_TURN_PERM_TIMEOUT;
+ /* Register to hash table */
+ pj_hash_set(alloc->pool, alloc->peer_table, &perm->hkey.peer_addr,
+ pj_sockaddr_get_len(&perm->hkey.peer_addr), 0, perm);
+
return perm;
}
@@ -804,14 +817,14 @@ static pj_turn_permission *check_permission_expiry(pj_turn_permission *perm)
pj_time_val now;
pj_gettimeofday(&now);
- if (PJ_TIME_VAL_LT(perm->expiry, now)) {
+ if (PJ_TIME_VAL_GT(perm->expiry, now)) {
/* Permission has not expired */
return perm;
}
/* Remove from permission hash table */
- pj_hash_set(NULL, alloc->peer_table, &perm->hkey, sizeof(perm->hkey),
- 0, NULL);
+ pj_hash_set(NULL, alloc->peer_table, &perm->hkey.peer_addr,
+ pj_sockaddr_get_len(&perm->hkey.peer_addr), 0, NULL);
/* Remove from channel hash table, if assigned a channel number */
if (perm->channel != PJ_TURN_INVALID_CHANNEL) {
@@ -828,16 +841,12 @@ lookup_permission_by_addr(pj_turn_allocation *alloc,
const pj_sockaddr_t *peer_addr,
unsigned addr_len)
{
- pj_turn_permission_key key;
pj_turn_permission *perm;
- pj_bzero(&key, sizeof(key));
- pj_memcpy(&key, peer_addr, addr_len);
-
/* Lookup in peer hash table */
- perm = (pj_turn_permission*) pj_hash_get(alloc->peer_table, &key,
- sizeof(key), NULL);
- return check_permission_expiry(perm);
+ perm = (pj_turn_permission*) pj_hash_get(alloc->peer_table, peer_addr,
+ addr_len, NULL);
+ return perm ? check_permission_expiry(perm) : NULL;
}
/* Lookup permission in hash table by the channel number */
@@ -849,9 +858,9 @@ lookup_permission_by_chnum(pj_turn_allocation *alloc,
pj_turn_permission *perm;
/* Lookup in peer hash table */
- perm = (pj_turn_permission*) pj_hash_get(alloc->peer_table, &chnum16,
+ perm = (pj_turn_permission*) pj_hash_get(alloc->ch_table, &chnum16,
sizeof(chnum16), NULL);
- return check_permission_expiry(perm);
+ return perm ? check_permission_expiry(perm) : NULL;
}
/* Update permission because of data from client to peer.
@@ -930,8 +939,8 @@ PJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,
if (!perm) {
/* Discard */
PJ_LOG(4,(alloc->obj_name,
- "ChannelData from %s discarded: not found",
- alloc->info));
+ "ChannelData from %s discarded: ch#0x%x not found",
+ alloc->info, pj_ntohs(cd->ch_number)));
goto on_return;
}
@@ -991,7 +1000,7 @@ static void handle_peer_pkt(pj_turn_allocation *alloc,
cd->length = pj_htons((pj_uint16_t)len);
/* Copy data */
- pj_memcpy(rel->tp.rx_pkt+sizeof(pj_turn_channel_data), pkt, len);
+ pj_memcpy(rel->tp.tx_pkt+sizeof(pj_turn_channel_data), pkt, len);
/* Send to client */
pj_turn_listener_sendto(alloc->listener, rel->tp.tx_pkt,
@@ -1009,6 +1018,18 @@ static void handle_peer_pkt(pj_turn_allocation *alloc,
alloc_err(alloc, "Error creating Data indication", status);
return;
}
+
+ pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
+ PJ_STUN_ATTR_PEER_ADDR, PJ_TRUE,
+ src_addr, pj_sockaddr_get_len(src_addr));
+ pj_stun_msg_add_binary_attr(tdata->pool, tdata->msg,
+ PJ_STUN_ATTR_DATA,
+ (const pj_uint8_t*)pkt, len);
+
+ pj_stun_session_send_msg(alloc->sess, PJ_FALSE,
+ &alloc->hkey.clt_addr,
+ pj_sockaddr_get_len(&alloc->hkey.clt_addr),
+ tdata);
}
}
@@ -1186,6 +1207,9 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
/* Refresh permission */
refresh_permission(p1);
+ /* Send response */
+ send_reply_ok(alloc, rdata);
+
/* Done */
return PJ_SUCCESS;
}
@@ -1212,6 +1236,11 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
/* Assign channel number to permission */
p2->channel = PJ_STUN_GET_CH_NB(ch_attr->value);
+ /* Register to hash table */
+ pj_assert(sizeof(p2->channel==2));
+ pj_hash_set(alloc->pool, alloc->ch_table, &p2->channel,
+ sizeof(p2->channel), 0, p2);
+
/* Update */
refresh_permission(p2);
diff --git a/pjnath/src/pjturn-srv/auth.c b/pjnath/src/pjturn-srv/auth.c
index 3071221c..8e6c9c59 100644
--- a/pjnath/src/pjturn-srv/auth.c
+++ b/pjnath/src/pjturn-srv/auth.c
@@ -113,11 +113,11 @@ PJ_DEF(pj_status_t) pj_turn_get_password(const pj_stun_msg *msg,
* in the message can be accepted. If this callback returns
* PJ_FALSE, 438 (Stale Nonce) response will be created.
*/
-PJ_DEF(pj_status_t) pj_turn_verify_nonce(const pj_stun_msg *msg,
- void *user_data,
- const pj_str_t *realm,
- const pj_str_t *username,
- const pj_str_t *nonce)
+PJ_DEF(pj_bool_t) pj_turn_verify_nonce(const pj_stun_msg *msg,
+ void *user_data,
+ const pj_str_t *realm,
+ const pj_str_t *username,
+ const pj_str_t *nonce)
{
PJ_UNUSED_ARG(msg);
PJ_UNUSED_ARG(user_data);
@@ -127,6 +127,6 @@ PJ_DEF(pj_status_t) pj_turn_verify_nonce(const pj_stun_msg *msg,
if (pj_stricmp2(nonce, THE_NONCE))
return PJ_FALSE;
- return PJ_SUCCESS;
+ return PJ_TRUE;
}
diff --git a/pjnath/src/pjturn-srv/auth.h b/pjnath/src/pjturn-srv/auth.h
index db928051..2e342a73 100644
--- a/pjnath/src/pjturn-srv/auth.h
+++ b/pjnath/src/pjturn-srv/auth.h
@@ -105,11 +105,11 @@ PJ_DECL(pj_status_t) pj_turn_get_password(const pj_stun_msg *msg,
* @return The callback MUST return non-zero if the
* NONCE can be accepted.
*/
-PJ_DECL(pj_status_t) pj_turn_verify_nonce(const pj_stun_msg *msg,
- void *user_data,
- const pj_str_t *realm,
- const pj_str_t *username,
- const pj_str_t *nonce);
+PJ_DECL(pj_bool_t) pj_turn_verify_nonce(const pj_stun_msg *msg,
+ void *user_data,
+ const pj_str_t *realm,
+ const pj_str_t *username,
+ const pj_str_t *nonce);
#endif /* __PJ_TURN_SRV_AUTH_H__ */
diff --git a/pjnath/src/pjturn-srv/main.c b/pjnath/src/pjturn-srv/main.c
index 60c420b2..164b3c25 100644
--- a/pjnath/src/pjturn-srv/main.c
+++ b/pjnath/src/pjturn-srv/main.c
@@ -21,6 +21,8 @@
#define REALM "pjsip.org"
+static pj_caching_pool g_cp;
+
int err(const char *title, pj_status_t status)
{
char errmsg[PJ_ERR_MSG_SIZE];
@@ -30,9 +32,91 @@ int err(const char *title, pj_status_t status)
return 1;
}
+static void dump_status(pj_turn_srv *srv)
+{
+ char addr[80];
+ pj_hash_iterator_t itbuf, *it;
+ pj_time_val now;
+ unsigned i;
+
+ for (i=0; i<srv->core.lis_cnt; ++i) {
+ pj_turn_listener *lis = srv->core.listener[i];
+ printf("Server address : %s\n", lis->info);
+ }
+
+ printf("Worker threads : %d\n", srv->core.thread_cnt);
+ printf("Total mem usage: %d.%03dMB\n", g_cp.used_size / 1000000,
+ (g_cp.used_size % 1000000)/1000);
+ printf("UDP port range : %u %u %u (next/min/max)\n", srv->ports.next_udp,
+ srv->ports.min_udp, srv->ports.max_udp);
+ printf("TCP port range : %u %u %u (next/min/max)\n", srv->ports.next_tcp,
+ srv->ports.min_tcp, srv->ports.max_tcp);
+ printf("Clients # : %u\n", pj_hash_count(srv->tables.alloc));
+
+ puts("");
+
+ if (pj_hash_count(srv->tables.alloc)==0) {
+ return;
+ }
+
+ puts("# Client addr. Alloc addr. Username Lftm Expy #prm #chl");
+ puts("------------------------------------------------------------------------------");
+
+ pj_gettimeofday(&now);
+
+ it = pj_hash_first(srv->tables.alloc, &itbuf);
+ i=1;
+ while (it) {
+ pj_turn_allocation *alloc = (pj_turn_allocation*)
+ pj_hash_this(srv->tables.alloc, it);
+ printf("%-3d %-22s %-22s %-8.*s %-4d %-4d %-4d %-4d\n",
+ i,
+ alloc->info,
+ pj_sockaddr_print(&alloc->relay.hkey.addr, addr, sizeof(addr), 3),
+ (int)alloc->cred.data.static_cred.username.slen,
+ (int)alloc->cred.data.static_cred.username.ptr,
+ alloc->relay.lifetime,
+ alloc->relay.expiry.sec - now.sec,
+ pj_hash_count(alloc->peer_table),
+ pj_hash_count(alloc->ch_table));
+ it = pj_hash_next(srv->tables.alloc, it);
+ ++i;
+ }
+}
+
+static void menu(void)
+{
+ puts("");
+ puts("Menu:");
+ puts(" d Dump status");
+ puts(" q Quit");
+ printf(">> ");
+}
+
+static void console_main(pj_turn_srv *srv)
+{
+ pj_bool_t quit = PJ_FALSE;
+
+ while (!quit) {
+ char line[10];
+
+ menu();
+
+ fgets(line, sizeof(line), stdin);
+
+ switch (line[0]) {
+ case 'd':
+ dump_status(srv);
+ break;
+ case 'q':
+ quit = PJ_TRUE;
+ break;
+ }
+ }
+}
+
int main()
{
- pj_caching_pool cp;
pj_turn_srv *srv;
pj_turn_listener *listener;
pj_status_t status;
@@ -44,11 +128,11 @@ int main()
pjlib_util_init();
pjnath_init();
- pj_caching_pool_init(&cp, NULL, 0);
+ pj_caching_pool_init(&g_cp, NULL, 0);
pj_turn_auth_init(REALM);
- status = pj_turn_srv_create(&cp.factory, &srv);
+ status = pj_turn_srv_create(&g_cp.factory, &srv);
if (status != PJ_SUCCESS)
return err("Error creating server", status);
@@ -62,15 +146,11 @@ int main()
return err("Error adding listener", status);
puts("Server is running");
- puts("Press <ENTER> to quit");
- {
- char line[10];
- fgets(line, sizeof(line), stdin);
- }
+ console_main(srv);
pj_turn_srv_destroy(srv);
- pj_caching_pool_destroy(&cp);
+ pj_caching_pool_destroy(&g_cp);
pj_shutdown();
return 0;
diff --git a/pjnath/src/pjturn-srv/server.c b/pjnath/src/pjturn-srv/server.c
index b22cc53b..66f1c6a7 100644
--- a/pjnath/src/pjturn-srv/server.c
+++ b/pjnath/src/pjturn-srv/server.c
@@ -135,7 +135,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
/* Init ports settings */
srv->ports.min_udp = srv->ports.next_udp = MIN_PORT;
- srv->ports.max_tcp = MAX_PORT;
+ srv->ports.max_udp = MAX_PORT;
srv->ports.min_tcp = srv->ports.next_tcp = MIN_PORT;
srv->ports.max_tcp = MAX_PORT;
@@ -265,6 +265,18 @@ PJ_DEF(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv)
}
}
+ /* Destroy all allocations FIRST */
+ if (srv->tables.alloc) {
+ it = pj_hash_first(srv->tables.alloc, &itbuf);
+ while (it != NULL) {
+ pj_turn_allocation *alloc = (pj_turn_allocation*)
+ pj_hash_this(srv->tables.alloc, it);
+ pj_hash_iterator_t *next = pj_hash_next(srv->tables.alloc, it);
+ pj_turn_allocation_destroy(alloc);
+ it = next;
+ }
+ }
+
/* Destroy all listeners and STUN sessions associated with them. */
for (i=0; i<srv->core.lis_cnt; ++i) {
if (srv->core.listener[i]) {
@@ -277,18 +289,6 @@ PJ_DEF(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv)
}
}
- /* Destroy all allocations */
- if (srv->tables.alloc) {
- it = pj_hash_first(srv->tables.alloc, &itbuf);
- while (it != NULL) {
- pj_turn_allocation *alloc = (pj_turn_allocation*)
- pj_hash_this(srv->tables.alloc, it);
- pj_turn_allocation_destroy(alloc);
- it = pj_hash_next(srv->tables.alloc, it);
- }
- }
-
-
/* Destroy hash tables (well, sort of) */
if (srv->tables.alloc) {
srv->tables.alloc = NULL;
diff --git a/pjnath/src/pjturn-srv/turn.h b/pjnath/src/pjturn-srv/turn.h
index 2eb99254..337e8746 100644
--- a/pjnath/src/pjturn-srv/turn.h
+++ b/pjnath/src/pjturn-srv/turn.h
@@ -190,7 +190,7 @@ struct pj_turn_permission
pj_turn_allocation *allocation;
/** Optional channel number, or PJ_TURN_INVALID_CHANNEL if channel number
- * is not requested for this permission.
+ * is not requested for this permission.
*/
pj_uint16_t channel;