diff options
Diffstat (limited to 'pjlib-util/src')
-rw-r--r-- | pjlib-util/src/pjlib-util/stun_msg.c | 6 | ||||
-rw-r--r-- | pjlib-util/src/pjstun-client/client_main.c | 158 | ||||
-rw-r--r-- | pjlib-util/src/pjstun-srv-test/turn_usage.c | 64 |
3 files changed, 190 insertions, 38 deletions
diff --git a/pjlib-util/src/pjlib-util/stun_msg.c b/pjlib-util/src/pjlib-util/stun_msg.c index 1887b009..e34655f8 100644 --- a/pjlib-util/src/pjlib-util/stun_msg.c +++ b/pjlib-util/src/pjlib-util/stun_msg.c @@ -405,19 +405,19 @@ static struct attr_desc extended_attr_desc[] = &encode_uint_attr }, { - /* Unassigned, 0x8025 */ + /* ID 0x8025 is not assigned*/ NULL, NULL, NULL }, { - /* Padding, 0x8026 */ + /* PADDING, 0x8026 */ NULL, NULL, NULL }, { - /* Padding, 0x8027 */ + /* CACHE-TIMEOUT, 0x8027 */ NULL, NULL, NULL diff --git a/pjlib-util/src/pjstun-client/client_main.c b/pjlib-util/src/pjstun-client/client_main.c index f412a4ce..c5c73441 100644 --- a/pjlib-util/src/pjstun-client/client_main.c +++ b/pjlib-util/src/pjstun-client/client_main.c @@ -21,6 +21,12 @@ #define THIS_FILE "client_main.c" +#define BANDWIDTH 64 /* -1 to disable */ +#define LIFETIME 30 /* -1 to disable */ +#define REQ_TRANSPORT -1 /* 0: udp, 1: tcp, -1: disable */ +#define REQ_PORT_PROPS -1 /* -1 to disable */ +#define REQ_IP NULL /* IP address string */ + static struct global { @@ -32,15 +38,15 @@ static struct global pj_sock_t sock; pj_thread_t *thread; pj_bool_t quit; - - pj_sockaddr_in dst_addr; /**< destination addr */ + pj_sockaddr_in peer_addr; + pj_sockaddr_in srv_addr; /**< server addr */ } g; static struct options { - char *dst_addr; - char *dst_port; + char *srv_addr; + char *srv_port; char *realm; char *user_name; char *password; @@ -60,14 +66,14 @@ static my_perror(const char *title, pj_status_t status) static pj_status_t on_send_msg(pj_stun_session *sess, const void *pkt, pj_size_t pkt_size, - const pj_sockaddr_t *dst_addr, + const pj_sockaddr_t *srv_addr, unsigned addr_len) { pj_ssize_t len; pj_status_t status; len = pkt_size; - status = pj_sock_sendto(g.sock, pkt, &len, 0, dst_addr, addr_len); + status = pj_sock_sendto(g.sock, pkt, &len, 0, srv_addr, addr_len); if (status != PJ_SUCCESS) my_perror("Error sending packet", status); @@ -141,22 +147,22 @@ static int init() pj_caching_pool_init(&g.cp, &pj_pool_factory_default_policy, 0); - if (o.dst_addr) { + if (o.srv_addr) { pj_str_t s; pj_uint16_t port; - if (o.dst_port) - port = (pj_uint16_t) atoi(o.dst_port); + if (o.srv_port) + port = (pj_uint16_t) atoi(o.srv_port); else port = PJ_STUN_PORT; - status = pj_sockaddr_in_init(&g.dst_addr, pj_cstr(&s, o.dst_addr), port); + status = pj_sockaddr_in_init(&g.srv_addr, pj_cstr(&s, o.srv_addr), port); if (status != PJ_SUCCESS) { my_perror("Invalid address", status); return status; } - printf("Destination address set to %s:%d\n", o.dst_addr, (int)port); + printf("Destination address set to %s:%d\n", o.srv_addr, (int)port); } else { printf("Error: address must be specified\n"); return PJ_EINVAL; @@ -245,18 +251,88 @@ static void send_bind_request(void) pj_assert(rc == PJ_SUCCESS); rc = pj_stun_session_send_msg(g.sess, PJ_FALSE, - &g.dst_addr, sizeof(g.dst_addr), + &g.srv_addr, sizeof(g.srv_addr), tdata); if (rc != PJ_SUCCESS) my_perror("Error sending STUN request", rc); } -static void send_allocate_request(void) +static void send_allocate_request(pj_bool_t allocate) { + pj_stun_tx_data *tdata; + pj_status_t rc; + + rc = pj_stun_session_create_req(g.sess, PJ_STUN_ALLOCATE_REQUEST, &tdata); + pj_assert(rc == PJ_SUCCESS); + + + if (BANDWIDTH != -1) { + pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_BANDWIDTH, BANDWIDTH); + } + + if (!allocate) { + pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_LIFETIME, 0); + + } else { + if (LIFETIME != -1) { + pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_LIFETIME, LIFETIME); + } + + if (REQ_TRANSPORT != -1) { + pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_REQ_TRANSPORT, REQ_TRANSPORT); + } + + if (REQ_PORT_PROPS != -1) { + pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_REQ_PORT_PROPS, REQ_PORT_PROPS); + } + + if (REQ_IP != NULL) { + pj_sockaddr_in addr; + pj_str_t tmp; + + pj_sockaddr_in_init(&addr, pj_cstr(&tmp, REQ_IP), 0); + pj_stun_msg_add_ip_addr_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_REQ_IP, PJ_FALSE, + &addr, sizeof(addr)); + } + } + + rc = pj_stun_session_send_msg(g.sess, PJ_FALSE, + &g.srv_addr, sizeof(g.srv_addr), + tdata); + pj_assert(rc == PJ_SUCCESS); } -static void send_sad_request(void) +static void send_sad_request(pj_bool_t set) { + pj_stun_tx_data *tdata; + pj_status_t rc; + + if (g.peer_addr.sin_addr.s_addr == 0 || + g.peer_addr.sin_port == 0) + { + puts("Error: peer address is not set"); + return; + } + + rc = pj_stun_session_create_req(g.sess, PJ_STUN_ALLOCATE_REQUEST, &tdata); + pj_assert(rc == PJ_SUCCESS); + + if (set) { + pj_stun_msg_add_ip_addr_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_REMOTE_ADDR, PJ_FALSE, + &g.peer_addr, sizeof(g.peer_addr)); + } + + rc = pj_stun_session_send_msg(g.sess, PJ_FALSE, + &g.srv_addr, sizeof(g.srv_addr), + tdata); + pj_assert(rc == PJ_SUCCESS); } static void send_send_ind(void) @@ -267,19 +343,52 @@ static void send_raw_data(void) { } +static void set_peer_addr(void) +{ + char ip_addr[64]; + pj_str_t tmp; + pj_sockaddr_in addr; + int port; + + printf("Current peer address: %s:%d\n", + pj_inet_ntoa(g.peer_addr.sin_addr), + pj_ntohs(g.peer_addr.sin_port)); + + printf("Input peer address in IP:PORT format: "); + fflush(stdout); + + if (scanf("%s:%d", ip_addr, &port) != 2) { + puts("Error."); + return; + } + + if (pj_sockaddr_in_init(&addr, pj_cstr(&tmp,ip_addr), (pj_uint16_t)port) != PJ_SUCCESS) { + puts("Error: invalid address"); + return; + } + + g.peer_addr = addr; +} + static void menu(void) { puts("Menu:"); + printf(" pr Set peer address (currently %s:%d)\n", + pj_inet_ntoa(g.peer_addr.sin_addr), pj_ntohs(g.peer_addr.sin_port)); + puts(""); puts(" br Send Bind request"); puts(" ar Send Allocate request"); + puts(" dr Send de-Allocate request"); puts(" sr Send Set Active Indication request"); - puts(" si Send Send Indication"); + puts(" cr Send clear Active Indication request"); + puts(" si Send data with Send Indication"); puts(" rw Send raw data"); puts(" q Quit"); puts(""); printf("Choice: "); } + static void console_main(void) { while (!g.quit) { @@ -293,10 +402,16 @@ static void console_main(void) send_bind_request(); } else if (input[0]=='a' && input[1]=='r') { - send_allocate_request(); + send_allocate_request(PJ_TRUE); + + } else if (input[0]=='d' && input[1]=='r') { + send_allocate_request(PJ_FALSE); } else if (input[0]=='s' && input[1]=='r') { - send_sad_request(); + send_sad_request(PJ_TRUE); + + } else if (input[0]=='c' && input[1]=='r') { + send_sad_request(PJ_FALSE); } else if (input[0]=='s' && input[1]=='i') { send_send_ind(); @@ -304,6 +419,9 @@ static void console_main(void) } else if (input[0]=='r' && input[1]=='w') { send_raw_data(); + } else if (input[0]=='p' && input[1]=='r') { + set_peer_addr(); + } else if (input[0]=='q') { g.quit = 1; } @@ -373,11 +491,11 @@ int main(int argc, char *argv[]) } if ((pos=pj_ansi_strchr(argv[pj_optind], ':')) != NULL) { - o.dst_addr = argv[pj_optind]; + o.srv_addr = argv[pj_optind]; *pos = '\0'; - o.dst_port = pos+1; + o.srv_port = pos+1; } else { - o.dst_addr = argv[pj_optind]; + o.srv_addr = argv[pj_optind]; } status = init(); diff --git a/pjlib-util/src/pjstun-srv-test/turn_usage.c b/pjlib-util/src/pjstun-srv-test/turn_usage.c index a9f2fdc7..f82d5149 100644 --- a/pjlib-util/src/pjstun-srv-test/turn_usage.c +++ b/pjlib-util/src/pjstun-srv-test/turn_usage.c @@ -89,9 +89,9 @@ struct turn_client pj_pool_t *pool; pj_stun_session *session; pj_mutex_t *mutex; - int sock_type; /* Socket and socket address of the allocated port */ + int sock_type; pj_sock_t sock; pj_ioqueue_key_t *key; pj_sockaddr_in client_addr; @@ -503,6 +503,16 @@ static struct peer* client_add_peer(struct turn_client *client, const pj_sockaddr_in *peer_addr, pj_uint32_t hval); +static const char *get_tp_type(int type) +{ + if (type==0) + return "udp"; + else if (type==1) + return "tcp"; + else + return "???"; +} + /* * This callback is called when incoming STUN message is received @@ -575,7 +585,8 @@ static pj_status_t client_create(struct turn_usage *tu, if (src_addr) { const pj_sockaddr_in *a4 = (const pj_sockaddr_in *)src_addr; pj_ansi_snprintf(client->obj_name, sizeof(client->obj_name), - "%s:%d", + "%s:%s:%d", + get_tp_type(tu->type), pj_inet_ntoa(a4->sin_addr), (int)pj_ntohs(a4->sin_port)); client->obj_name[sizeof(client->obj_name)-1] = '\0'; @@ -585,7 +596,8 @@ static pj_status_t client_create(struct turn_usage *tu, pj_bzero(&sess_cb, sizeof(sess_cb)); sess_cb.on_send_msg = &client_sess_on_send_msg; sess_cb.on_rx_request = &client_sess_on_rx_request; - status = pj_stun_session_create(tu->endpt, "turnc%p", &sess_cb, PJ_FALSE, + status = pj_stun_session_create(tu->endpt, client->obj_name, + &sess_cb, PJ_FALSE, &client->session); if (status != PJ_SUCCESS) { pj_pool_release(pool); @@ -598,7 +610,7 @@ static pj_status_t client_create(struct turn_usage *tu, pj_stun_session_set_user_data(client->session, sd); /* Mutex */ - status = pj_mutex_create_recursive(client->pool, pool->obj_name, + status = pj_mutex_create_recursive(client->pool, pool->obj_name, &client->mutex); if (status != PJ_SUCCESS) { client_destroy(client, status); @@ -692,8 +704,19 @@ static pj_status_t client_destroy(struct turn_client *client, static pj_status_t client_create_relay(struct turn_client *client) { pj_ioqueue_callback client_ioq_cb; + int addrlen; pj_status_t status; + /* Update address */ + addrlen = sizeof(pj_sockaddr_in); + status = pj_sock_getsockname(client->sock, &client->client_addr, + &addrlen); + if (status != PJ_SUCCESS) { + pj_sock_close(client->sock); + client->sock = PJ_INVALID_SOCKET; + return status; + } + /* Register to ioqueue */ pj_bzero(&client_ioq_cb, sizeof(client_ioq_cb)); client_ioq_cb.on_read_complete = &client_on_read_complete; @@ -714,6 +737,12 @@ static pj_status_t client_create_relay(struct turn_client *client) /* Trigger the first read */ client_on_read_complete(client->key, &client->pkt_read_key, 0); + PJ_LOG(4,(THIS_FILE, "TURN client %s: relay allocated on %s:%s:%d", + client->obj_name, + get_tp_type(client->sock_type), + pj_inet_ntoa(client->client_addr.sin_addr), + (int)pj_ntohs(client->client_addr.sin_port))); + return PJ_SUCCESS; } @@ -734,8 +763,9 @@ static pj_status_t client_destroy_relay(struct turn_client *client) client->sock = PJ_INVALID_SOCKET; } - PJ_LOG(4,(THIS_FILE, "TURN client %s: relay allocation %s:%d destroyed", + PJ_LOG(4,(THIS_FILE, "TURN client %s: relay allocation %s:%s:%d destroyed", client->obj_name, + get_tp_type(client->sock_type), pj_inet_ntoa(client->client_addr.sin_addr), (int)pj_ntohs(client->client_addr.sin_port))); return PJ_SUCCESS; @@ -771,7 +801,8 @@ static struct peer* client_add_peer(struct turn_client *client, peer_addr, sizeof(*peer_addr), hval, peer); PJ_LOG(4,(THIS_FILE, "TURN client %s: peer %s:%s:%d added", - client->obj_name, "udp", pj_inet_ntoa(peer_addr->sin_addr), + client->obj_name, get_tp_type(client->sock_type), + pj_inet_ntoa(peer_addr->sin_addr), (int)pj_ntohs(peer_addr->sin_port))); return peer; @@ -824,7 +855,7 @@ static pj_status_t client_handle_allocate_req(struct turn_client *client, pj_stun_tx_data *response; pj_sockaddr_in req_addr; int addr_len; - unsigned rpp_bits; + unsigned req_bw, rpp_bits; pj_time_val timeout; pj_status_t status; @@ -848,8 +879,9 @@ static pj_status_t client_handle_allocate_req(struct turn_client *client, src_addr, src_addr_len); return PJ_SUCCESS; } else if (a_bw) { - client->bw_kbps = a_bw->value; + client->bw_kbps = req_bw = a_bw->value; } else { + req_bw = 0; client->bw_kbps = client->tu->max_bw_kbps; } @@ -899,11 +931,11 @@ static pj_status_t client_handle_allocate_req(struct turn_client *client, int err_code; PJ_LOG(4,(THIS_FILE, "TURN client %s: received initial Allocate " - "request, requested type:addr:port=%d:%s:%d, rpp " - "bits=%d", - client->obj_name, client->sock_type, + "request, requested type:addr:port=%s:%s:%d, rpp " + "bits=%d, bw=%dkbps, lifetime=%d", + client->obj_name, get_tp_type(client->sock_type), pj_inet_ntoa(req_addr.sin_addr), pj_ntohs(req_addr.sin_port), - rpp_bits)); + rpp_bits, client->bw_kbps, client->lifetime)); status = tu_alloc_port(client->tu, client->sock_type, rpp_bits, &req_addr, &client->sock, &err_code); @@ -930,8 +962,9 @@ static pj_status_t client_handle_allocate_req(struct turn_client *client, } else { /* Otherwise check if the port parameter stays the same */ /* TODO */ - PJ_LOG(4,(THIS_FILE, "TURN client %s: received Allocate refresh", - client->obj_name)); + PJ_LOG(4,(THIS_FILE, "TURN client %s: received Allocate refresh, " + "lifetime=%d", + client->obj_name, client->lifetime)); } /* Refresh timer */ @@ -969,8 +1002,9 @@ static pj_status_t client_handle_allocate_req(struct turn_client *client, &req_addr, addr_len); PJ_LOG(4,(THIS_FILE, "TURN client %s: relay allocated or refreshed, " - "internal address is %s:%d", + "internal address is %s:%s:%d", client->obj_name, + get_tp_type(client->sock_type), pj_inet_ntoa(req_addr.sin_addr), (int)pj_ntohs(req_addr.sin_port))); |