diff options
Diffstat (limited to 'pjlib-util/src/pjlib-util/stun_client.c')
-rw-r--r-- | pjlib-util/src/pjlib-util/stun_client.c | 130 |
1 files changed, 46 insertions, 84 deletions
diff --git a/pjlib-util/src/pjlib-util/stun_client.c b/pjlib-util/src/pjlib-util/stun_client.c index 9771145d..d8f2246f 100644 --- a/pjlib-util/src/pjlib-util/stun_client.c +++ b/pjlib-util/src/pjlib-util/stun_client.c @@ -17,16 +17,18 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <pjlib-util/stun.h> -#include <pj/pool.h> -#include <pj/log.h> -#include <pj/string.h> +#include <pjlib-util/errno.h> #include <pj/os.h> +#include <pj/pool.h> +#include <pj/rand.h> #include <pj/sock_select.h> +#include <pj/string.h> + enum { MAX_REQUEST = 3 }; static int stun_timer[] = {1600, 1600, 1600 }; -#define THIS_FILE "stunclient" +#define THIS_FILE "stun_client.c" #define LOG_ADDR(addr) pj_inet_ntoa(addr.sin_addr), pj_ntohs(addr.sin_port) @@ -37,7 +39,7 @@ PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf, pj_sockaddr_in mapped_addr[]) { pj_sockaddr_in srv_addr[2]; - int i, j, rc, send_cnt = 0; + int i, j, send_cnt = 0; pj_pool_t *pool; struct { struct { @@ -48,40 +50,38 @@ PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf, void *out_msg; pj_size_t out_msg_len; int wait_resp = 0; - int mapped_status = 0; + pj_status_t status; PJ_CHECK_STACK(); /* Create pool. */ pool = pj_pool_create(pf, "stun%p", 1024, 1024, NULL); - if (!pool) { - mapped_status = PJ_STUN_ERR_MEMORY; - return -1; - } + if (!pool) + return PJ_ENOMEM; + /* Allocate client records */ rec = pj_pool_calloc(pool, sock_cnt, sizeof(*rec)); if (!rec) { - mapped_status = PJ_STUN_ERR_MEMORY; + status = PJ_ENOMEM; goto on_error; } + /* Create the outgoing BIND REQUEST message template */ - rc = pj_stun_create_bind_req( pool, &out_msg, &out_msg_len, 0, 0); - if (rc != 0) { - mapped_status = -1; + status = pj_stun_create_bind_req( pool, &out_msg, &out_msg_len, + pj_rand(), pj_rand()); + if (status != PJ_SUCCESS) goto on_error; - } /* Resolve servers. */ - if (pj_sockaddr_in_init(&srv_addr[0], srv1, (pj_uint16_t)port1) != 0) { - mapped_status = PJ_STUN_ERR_RESOLVE; + status = pj_sockaddr_in_init(&srv_addr[0], srv1, (pj_uint16_t)port1); + if (status != PJ_SUCCESS) goto on_error; - } - if (pj_sockaddr_in_init(&srv_addr[1], srv2, (pj_uint16_t)port2) != 0) { - mapped_status = PJ_STUN_ERR_RESOLVE; + + status = pj_sockaddr_in_init(&srv_addr[1], srv2, (pj_uint16_t)port2); + if (status != PJ_SUCCESS) goto on_error; - } /* Init mapped addresses to zero */ pj_memset(mapped_addr, 0, sock_cnt * sizeof(pj_sockaddr_in)); @@ -92,14 +92,11 @@ PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf, pj_fd_set_t r; int select_rc; - PJ_LOG(4,(THIS_FILE, "STUN retransmit %d, wait_resp=%d", - send_cnt, wait_resp)); - PJ_FD_ZERO(&r); /* Send messages to servers that has not given us response. */ - for (i=0; i<sock_cnt && mapped_status==0; ++i) { - for (j=0; j<2 && mapped_status==0; ++j) { + for (i=0; i<sock_cnt && status==PJ_SUCCESS; ++i) { + for (j=0; j<2 && status==PJ_SUCCESS; ++j) { pj_stun_msg_hdr *msg_hdr = out_msg; pj_ssize_t sent_len; @@ -112,17 +109,11 @@ PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf, /* Send! */ sent_len = out_msg_len; - rc = pj_sock_sendto(sock[i], out_msg, &sent_len, 0, - (pj_sockaddr_t*)&srv_addr[j], - sizeof(pj_sockaddr_in)); - if (sent_len != (int)out_msg_len) { - PJ_LOG(4,(THIS_FILE, - "Error sending STUN request to %s:%d", - LOG_ADDR(srv_addr[j]))); - mapped_status = PJ_STUN_ERR_TRANSPORT; - } else { + status = pj_sock_sendto(sock[i], out_msg, &sent_len, 0, + (pj_sockaddr_t*)&srv_addr[j], + sizeof(pj_sockaddr_in)); + if (status == PJ_SUCCESS) ++wait_resp; - } } } @@ -139,7 +130,8 @@ PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf, pj_time_val_normalize(&next_tx); for (pj_gettimeofday(&now), select_rc=1; - mapped_status==0 && select_rc==1 && wait_resp>0 && PJ_TIME_VAL_LT(now, next_tx); + status==PJ_SUCCESS && select_rc==1 && wait_resp>0 + && PJ_TIME_VAL_LT(now, next_tx); pj_gettimeofday(&now)) { pj_time_val timeout; @@ -168,59 +160,43 @@ PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf, continue; len = sizeof(recv_buf); - pj_sock_recvfrom( sock[i], recv_buf, - &len, 0, - (pj_sockaddr_t*)&addr, - &addrlen); + status = pj_sock_recvfrom( sock[i], recv_buf, + &len, 0, + (pj_sockaddr_t*)&addr, + &addrlen); --wait_resp; - if (len < 1) { - mapped_status = PJ_STUN_ERR_TRANSPORT; + if (status != PJ_SUCCESS) continue; - } - if (pj_stun_parse_msg(recv_buf, len, &msg) != 0) { - PJ_LOG(4,(THIS_FILE, - "Error parsing STUN response from %s:%d", - LOG_ADDR(addr))); - mapped_status = PJ_STUN_ERR_INVALID_MSG; + status = pj_stun_parse_msg(recv_buf, len, &msg); + if (status != PJ_SUCCESS) { continue; } + sock_idx = pj_ntohl(msg.hdr->tsx[2]); srv_idx = pj_ntohl(msg.hdr->tsx[3]); if (sock_idx<0 || sock_idx>=sock_cnt || srv_idx<0 || srv_idx>=2) { - PJ_LOG(4,(THIS_FILE, - "Invalid transaction ID from %s:%d", - LOG_ADDR(addr))); - mapped_status = PJ_STUN_ERR_INVALID_MSG; + status = PJLIB_UTIL_ESTUNININDEX; continue; } if (pj_ntohs(msg.hdr->type) != PJ_STUN_BINDING_RESPONSE) { - PJ_LOG(4,(THIS_FILE, - "Non binding response %d from %s:%d", - pj_ntohs(msg.hdr->type), LOG_ADDR(addr))); - mapped_status = PJ_STUN_ERR_INVALID_MSG; + status = PJLIB_UTIL_ESTUNNOBINDRES; continue; } if (pj_stun_msg_find_attr(&msg, PJ_STUN_ATTR_ERROR_CODE) != NULL) { - PJ_LOG(4,(THIS_FILE, - "Got STUN error attribute from %s:%d", - LOG_ADDR(addr))); - mapped_status = PJ_STUN_ERR_INVALID_MSG; + status = PJLIB_UTIL_ESTUNRECVERRATTR; continue; } attr = (void*)pj_stun_msg_find_attr(&msg, PJ_STUN_ATTR_MAPPED_ADDR); if (!attr) { - PJ_LOG(4,(THIS_FILE, - "No mapped address in response from %s:%d", - LOG_ADDR(addr))); - mapped_status = PJ_STUN_ERR_INVALID_MSG; + status = PJLIB_UTIL_ESTUNNOMAP; continue; } @@ -236,7 +212,7 @@ PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf, break; } - for (i=0; i<sock_cnt && mapped_status==0; ++i) { + for (i=0; i<sock_cnt && status==PJ_SUCCESS; ++i) { if (rec[i].srv[0].mapped_addr == rec[i].srv[1].mapped_addr && rec[i].srv[0].mapped_port == rec[i].srv[1].mapped_port) { @@ -245,35 +221,21 @@ PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf, mapped_addr[i].sin_port = (pj_uint16_t)rec[i].srv[0].mapped_port; if (rec[i].srv[0].mapped_addr == 0 || rec[i].srv[0].mapped_port == 0) { - mapped_status = PJ_STUN_ERR_NO_RESPONSE; + status = PJLIB_UTIL_ESTUNNOTRESPOND; break; } } else { - mapped_status = PJ_STUN_ERR_SYMETRIC; + status = PJLIB_UTIL_ESTUNSYMMETRIC; break; } } pj_pool_release(pool); - return mapped_status; + return status; on_error: if (pool) pj_pool_release(pool); - return -1; + return status; } -PJ_DEF(const char*) pj_stun_get_err_msg(pj_status_t status) -{ - switch (status) { - case 0: return "No error"; - case -1: return "General error"; - case PJ_STUN_ERR_MEMORY: return "Memory allocation failed"; - case PJ_STUN_ERR_RESOLVE: return "Invalid IP or unable to resolve STUN server"; - case PJ_STUN_ERR_TRANSPORT: return "Unable to contact STUN server"; - case PJ_STUN_ERR_INVALID_MSG: return "Invalid response from STUN server"; - case PJ_STUN_ERR_NO_RESPONSE: return "No response from STUN server"; - case PJ_STUN_ERR_SYMETRIC: return "Different mappings are returned from servers"; - } - return "Unknown error"; -} |