summaryrefslogtreecommitdiff
path: root/pjnath
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-03-14 17:56:11 +0000
committerBenny Prijono <bennylp@teluu.com>2008-03-14 17:56:11 +0000
commit685aef52bcf830cb591798cd0814dd4a10605497 (patch)
tree3c25f3b536fdec539edc3b640c4b8594b77ebe9f /pjnath
parente2b198a3e133146b85c7a7c6b12af02e5735fe8b (diff)
More ticket #485: initial test on TURN client/server
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1869 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjnath')
-rw-r--r--pjnath/include/pjnath/stun_auth.h4
-rw-r--r--pjnath/src/pjnath-test/stun.c2
-rw-r--r--pjnath/src/pjnath/stun_auth.c5
-rw-r--r--pjnath/src/pjnath/stun_session.c5
-rw-r--r--pjnath/src/pjnath/turn_session.c3
-rw-r--r--pjnath/src/pjnath/turn_udp.c25
-rw-r--r--pjnath/src/pjturn-client/client_main.c13
-rw-r--r--pjnath/src/pjturn-srv/auth.c23
-rw-r--r--pjnath/src/pjturn-srv/auth.h12
-rw-r--r--pjnath/src/pjturn-srv/main.c11
-rw-r--r--pjnath/src/pjturn-srv/server.c2
11 files changed, 92 insertions, 13 deletions
diff --git a/pjnath/include/pjnath/stun_auth.h b/pjnath/include/pjnath/stun_auth.h
index 849d2e0a..840e473d 100644
--- a/pjnath/include/pjnath/stun_auth.h
+++ b/pjnath/include/pjnath/stun_auth.h
@@ -277,6 +277,9 @@ PJ_DECL(void) pj_stun_auth_cred_dup(pj_pool_t *pool,
* the message.
* @param pool If response is to be created, then memory will
* be allocated from this pool.
+ * @param auth_key Optional pointer to receive authentication key to
+ * calculate MESSAGE-INTEGRITY of the response, if
+ * the response needs to be authenticated.
* @param p_response Optional pointer to receive the response message
* then the credential in the request fails to
* authenticate.
@@ -291,6 +294,7 @@ PJ_DECL(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
const pj_stun_msg *msg,
pj_stun_auth_cred *cred,
pj_pool_t *pool,
+ pj_str_t *auth_key,
pj_stun_msg **p_response);
diff --git a/pjnath/src/pjnath-test/stun.c b/pjnath/src/pjnath-test/stun.c
index 32a31719..c0d74380 100644
--- a/pjnath/src/pjnath-test/stun.c
+++ b/pjnath/src/pjnath-test/stun.c
@@ -655,7 +655,7 @@ static int fingerprint_test_vector()
cred.data.static_cred.data = pj_str(v->password);
status = pj_stun_authenticate_request(buf, len, msg,
- &cred, pool, NULL);
+ &cred, pool, NULL, NULL);
if (status != PJ_SUCCESS) {
char errmsg[PJ_ERR_MSG_SIZE];
pj_strerror(status, errmsg, sizeof(errmsg));
diff --git a/pjnath/src/pjnath/stun_auth.c b/pjnath/src/pjnath/stun_auth.c
index b809c072..4a6024f0 100644
--- a/pjnath/src/pjnath/stun_auth.c
+++ b/pjnath/src/pjnath/stun_auth.c
@@ -121,6 +121,7 @@ PJ_DEF(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
const pj_stun_msg *msg,
pj_stun_auth_cred *cred,
pj_pool_t *pool,
+ pj_str_t *auth_key,
pj_stun_msg **p_response)
{
pj_str_t realm, nonce, password;
@@ -332,6 +333,10 @@ PJ_DEF(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_STALE_NONCE,
NULL, &realm, &nonce, p_response);
}
+ if (auth_key) {
+ pj_stun_create_key(pool, auth_key, &realm,
+ &auser->value, &password);
+ }
return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_STALE_NONCE);
}
}
diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c
index d9ae3b75..29dc3e57 100644
--- a/pjnath/src/pjnath/stun_session.c
+++ b/pjnath/src/pjnath/stun_session.c
@@ -859,16 +859,17 @@ static pj_status_t authenticate_req(pj_stun_session *sess,
unsigned src_addr_len)
{
pj_stun_msg *response;
+ pj_str_t auth_key;
pj_status_t status;
if (PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type) || sess->cred == NULL)
return PJ_SUCCESS;
status = pj_stun_authenticate_request(pkt, pkt_len, msg, sess->cred,
- tmp_pool, &response);
+ tmp_pool, &auth_key, &response);
if (status != PJ_SUCCESS && response != NULL) {
PJ_LOG(5,(SNAME(sess), "Message authentication failed"));
- send_response(sess, tmp_pool, response, NULL, PJ_FALSE,
+ send_response(sess, tmp_pool, response, &auth_key, PJ_FALSE,
src_addr, src_addr_len);
}
diff --git a/pjnath/src/pjnath/turn_session.c b/pjnath/src/pjnath/turn_session.c
index 05abc436..7b772dcf 100644
--- a/pjnath/src/pjnath/turn_session.c
+++ b/pjnath/src/pjnath/turn_session.c
@@ -218,6 +218,9 @@ PJ_DEF(pj_status_t) pj_turn_session_create( pj_stun_config *cfg,
return status;
}
+ /* Attach ourself to STUN session */
+ pj_stun_session_set_user_data(sess->stun, sess);
+
/* Replace mutex in STUN session with a NULL mutex, since access to
* STUN session is serialized.
*/
diff --git a/pjnath/src/pjnath/turn_udp.c b/pjnath/src/pjnath/turn_udp.c
index a5d34b60..8d5ff9d4 100644
--- a/pjnath/src/pjnath/turn_udp.c
+++ b/pjnath/src/pjnath/turn_udp.c
@@ -19,6 +19,7 @@
#include <pjnath/turn_udp.h>
#include <pj/assert.h>
#include <pj/errno.h>
+#include <pj/log.h>
#include <pj/pool.h>
#include <pj/ioqueue.h>
@@ -112,6 +113,15 @@ PJ_DEF(pj_status_t) pj_turn_udp_create( pj_stun_config *cfg,
return status;
}
+ /* Bind to any */
+ pj_sockaddr_init(af, &udp_rel->src_addr, NULL, 0);
+ status = pj_sock_bind(udp_rel->sock, &udp_rel->src_addr,
+ pj_sockaddr_get_len(&udp_rel->src_addr));
+ if (status != PJ_SUCCESS) {
+ pj_turn_udp_destroy(udp_rel);
+ return status;
+ }
+
/* Register to ioqeuue */
pj_bzero(&ioq_cb, sizeof(ioq_cb));
ioq_cb.on_read_complete = &on_read_complete;
@@ -255,7 +265,9 @@ static void on_read_complete(pj_ioqueue_key_t *key,
pj_ioqueue_op_key_t *op_key,
pj_ssize_t bytes_read)
{
+ enum { MAX_RETRY = 10 };
pj_turn_udp *udp_rel;
+ int retry = 0;
pj_status_t status;
udp_rel = (pj_turn_udp*) pj_ioqueue_get_user_data(key);
@@ -270,16 +282,23 @@ static void on_read_complete(pj_ioqueue_key_t *key,
/* Read next packet */
bytes_read = sizeof(udp_rel->pkt);
udp_rel->src_addr_len = sizeof(udp_rel->src_addr);
-
status = pj_ioqueue_recvfrom(udp_rel->key, op_key,
udp_rel->pkt, &bytes_read, 0,
&udp_rel->src_addr,
&udp_rel->src_addr_len);
- if (status != PJ_EPENDING && status != PJ_SUCCESS)
+ if (status != PJ_EPENDING && status != PJ_SUCCESS) {
+ char errmsg[PJ_ERR_MSG_SIZE];
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(4,(udp_rel->pool->obj_name,
+ "ioqueue recvfrom error: %s", errmsg));
+
bytes_read = -status;
+ }
- } while (status != PJ_EPENDING && status != PJ_ECANCELLED);
+ } while (status != PJ_EPENDING && status != PJ_ECANCELLED &&
+ ++retry < MAX_RETRY);
}
diff --git a/pjnath/src/pjturn-client/client_main.c b/pjnath/src/pjturn-client/client_main.c
index a9123319..114f47c8 100644
--- a/pjnath/src/pjturn-client/client_main.c
+++ b/pjnath/src/pjturn-client/client_main.c
@@ -132,7 +132,7 @@ static int init()
len = sizeof(addr);
CHECK( pj_sock_getsockname(g.peer[i].sock, &addr, &len) );
- port = pj_sockaddr_get_port(&g.peer[i].addr);
+ port = pj_sockaddr_get_port(&addr);
CHECK( pj_gethostip(pj_AF_INET(), &g.peer[i].addr) );
pj_sockaddr_set_port(&g.peer[0].addr, port);
@@ -357,7 +357,10 @@ static void menu(void)
if (g.udp_rel) {
pj_turn_udp_get_info(g.udp_rel, &info);
strcpy(client_state, pj_turn_state_name(info.state));
- pj_sockaddr_print(&info.relay_addr, relay_addr, sizeof(relay_addr), 3);
+ if (info.state >= PJ_TURN_STATE_READY)
+ pj_sockaddr_print(&info.relay_addr, relay_addr, sizeof(relay_addr), 3);
+ else
+ strcpy(relay_addr, "0.0.0.0:0");
} else {
strcpy(client_state, "NULL");
strcpy(relay_addr, "0.0.0.0:0");
@@ -371,15 +374,15 @@ static void menu(void)
puts("+====================================================================+");
puts("| CLIENT | PEER-0 |");
puts("| | |");
- printf("| State : %12s | Address: %21s |\n",
+ printf("| State : %-12s | Address: %-21s |\n",
client_state, peer0_addr);
- printf("| Relay addr: %21s | |\n",
+ printf("| Relay addr: %-21s | |\n",
relay_addr);
puts("| | 0 Send data to relay address |");
puts("| A Allocate relay +--------------------------------+ ");
puts("| S[01] Send data to peer 0/1 | PEER-1 |");
puts("| B[01] BindChannel to peer 0/1 | |");
- printf("| X Delete allocation | Address: %21s |\n",
+ printf("| X Delete allocation | Address: %-21s |\n",
peer1_addr);
puts("+-----------------------------------+ |");
puts("| q Quit | 1 Send data to relay adderss |");
diff --git a/pjnath/src/pjturn-srv/auth.c b/pjnath/src/pjturn-srv/auth.c
index 3071221c..ad930251 100644
--- a/pjnath/src/pjturn-srv/auth.c
+++ b/pjnath/src/pjturn-srv/auth.c
@@ -58,6 +58,29 @@ PJ_DEF(void) pj_turn_auth_dinit(void)
}
+PJ_DEF(pj_status_t) pj_turn_get_cred( const pj_stun_msg *msg,
+ void *user_data,
+ pj_pool_t *pool,
+ pj_str_t *realm,
+ pj_str_t *username,
+ pj_str_t *nonce,
+ int *data_type,
+ pj_str_t *data)
+{
+ PJ_UNUSED_ARG(msg);
+ PJ_UNUSED_ARG(pool);
+ PJ_UNUSED_ARG(user_data);
+
+ *realm = pj_str(g_realm);
+ *username = pj_str(g_cred[0].username);
+ *nonce = pj_str(THE_NONCE);
+ *data_type = 0;
+ *data = pj_str(g_cred[0].passwd);
+
+ return PJ_SUCCESS;
+}
+
+
/*
* This function is called by pj_stun_verify_credential() when
* server needs to challenge the request with 401 response.
diff --git a/pjnath/src/pjturn-srv/auth.h b/pjnath/src/pjturn-srv/auth.h
index db928051..d0b5a0ec 100644
--- a/pjnath/src/pjturn-srv/auth.h
+++ b/pjnath/src/pjturn-srv/auth.h
@@ -61,6 +61,18 @@ PJ_DECL(pj_status_t) pj_turn_get_auth(void *user_data,
pj_str_t *nonce);
/**
+ * Get credential.
+ */
+PJ_DECL(pj_status_t) pj_turn_get_cred(const pj_stun_msg *msg,
+ void *user_data,
+ pj_pool_t *pool,
+ pj_str_t *realm,
+ pj_str_t *username,
+ pj_str_t *nonce,
+ int *data_type,
+ pj_str_t *data);
+
+/**
* This function is called to get the password for the specified username.
* This function is also used to check whether the username is valid.
*
diff --git a/pjnath/src/pjturn-srv/main.c b/pjnath/src/pjturn-srv/main.c
index 3cddafc1..60c420b2 100644
--- a/pjnath/src/pjturn-srv/main.c
+++ b/pjnath/src/pjturn-srv/main.c
@@ -17,6 +17,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "turn.h"
+#include "auth.h"
+
+#define REALM "pjsip.org"
int err(const char *title, pj_status_t status)
{
@@ -38,13 +41,19 @@ int main()
if (status != PJ_SUCCESS)
return err("pj_init() error", status);
+ pjlib_util_init();
+ pjnath_init();
+
pj_caching_pool_init(&cp, NULL, 0);
+ pj_turn_auth_init(REALM);
+
status = pj_turn_srv_create(&cp.factory, &srv);
if (status != PJ_SUCCESS)
return err("Error creating server", status);
- status = pj_turn_listener_create_udp(srv, pj_AF_INET(), NULL, 3478, 1, 0, &listener);
+ status = pj_turn_listener_create_udp(srv, pj_AF_INET(), NULL,
+ PJ_STUN_PORT, 1, 0, &listener);
if (status != PJ_SUCCESS)
return err("Error creating listener", status);
diff --git a/pjnath/src/pjturn-srv/server.c b/pjnath/src/pjturn-srv/server.c
index 6765b3ca..11180dbf 100644
--- a/pjnath/src/pjturn-srv/server.c
+++ b/pjnath/src/pjturn-srv/server.c
@@ -147,7 +147,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
srv->core.cred.type = PJ_STUN_AUTH_CRED_DYNAMIC;
srv->core.cred.data.dyn_cred.user_data = srv;
srv->core.cred.data.dyn_cred.get_auth = &pj_turn_get_auth;
- srv->core.cred.data.dyn_cred.get_cred = &pj_turn_srv_get_cred;
+ srv->core.cred.data.dyn_cred.get_cred = &pj_turn_get_cred;
srv->core.cred.data.dyn_cred.get_password = &pj_turn_get_password;
srv->core.cred.data.dyn_cred.verify_nonce = &pj_turn_verify_nonce;