Ejemplo n.º 1
0
/* Respond to ALLOCATE request */
static pj_status_t send_allocate_response(pj_turn_allocation *alloc,
					  pj_stun_session *srv_sess,
					  pj_turn_transport *transport,
					  const pj_stun_rx_data *rdata)
{
    pj_stun_tx_data *tdata;
    pj_status_t status;

    /* Respond the original ALLOCATE request */
    status = pj_stun_session_create_res(srv_sess, rdata, 0, NULL, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* Add XOR-RELAYED-ADDRESS attribute */
    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
				  PJ_STUN_ATTR_XOR_RELAYED_ADDR, PJ_TRUE,
				  &alloc->relay.hkey.addr,
				  pj_sockaddr_get_len(&alloc->relay.hkey.addr));

    /* Add LIFETIME. */
    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
			      PJ_STUN_ATTR_LIFETIME,
			      (unsigned)alloc->relay.lifetime);

    /* Add BANDWIDTH */
    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
			      PJ_STUN_ATTR_BANDWIDTH,
			      alloc->bandwidth);

    /* Add RESERVATION-TOKEN */
    PJ_TODO(ADD_RESERVATION_TOKEN);

    /* Add XOR-MAPPED-ADDRESS */
    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
				  PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE,
				  &alloc->hkey.clt_addr,
				  pj_sockaddr_get_len(&alloc->hkey.clt_addr));

    /* Send the response */
    return pj_stun_session_send_msg(srv_sess, transport, PJ_TRUE,
				    PJ_FALSE, &alloc->hkey.clt_addr,
				    pj_sockaddr_get_len(&alloc->hkey.clt_addr),
				    tdata);
}
Ejemplo n.º 2
0
/* Create and send successful response */
static void send_reply_ok(pj_turn_allocation *alloc,
		          const pj_stun_rx_data *rdata)
{
    pj_status_t status;
    unsigned interval;
    pj_stun_tx_data *tdata;

    status = pj_stun_session_create_res(alloc->sess, rdata, 0, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	alloc_err(alloc, "Error creating STUN success response", status);
	return;
    }

    /* Calculate time to expiration */
    if (alloc->relay.lifetime != 0) {
	pj_time_val now;
	pj_gettimeofday(&now);
	interval = alloc->relay.expiry.sec - now.sec;
    } else {
	interval = 0;
    }

    /* 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 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, NULL, PJ_TRUE,
				      PJ_FALSE, &alloc->hkey.clt_addr,
				      pj_sockaddr_get_len(&alloc->hkey.clt_addr),
				      tdata);
    if (status != PJ_SUCCESS) {
	alloc_err(alloc, "Error sending STUN success response", status);
	return;
    }
}
static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v)
{
    pj_stun_msg *msg;
    pj_timestamp u64;
    pj_str_t s1;
    pj_status_t status;

    status = pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC,
				(pj_uint8_t*)v->tsx_id, &msg);
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_PRIORITY, 
				       0x6e0001ff);
    if (status != PJ_SUCCESS)
	goto on_error;

    u64.u32.hi = 0x932ff9b1;
    u64.u32.lo = 0x51263b36;
    status = pj_stun_msg_add_uint64_attr(pool, msg, 
					 PJ_STUN_ATTR_ICE_CONTROLLED, &u64);
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_USERNAME, 
					 pj_cstr(&s1, v->username));
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_stun_msg_add_msgint_attr(pool, msg);
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0);
    if (status != PJ_SUCCESS)
	goto on_error;

    return msg;

on_error:
    app_perror("    error: create_msgint1()", status);
    return NULL;
}
Ejemplo n.º 4
0
static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v)
{
    pj_stun_msg *msg;
    pj_timestamp u64;
    pj_str_t s1;

    pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC,
		       (pj_uint8_t*)v->tsx_id, &msg);

    pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_PRIORITY, 0x6e0001ff);
    u64.u32.hi = 0x932ff9b1;
    u64.u32.lo = 0x51263b36;
    pj_stun_msg_add_uint64_attr(pool, msg, PJ_STUN_ATTR_ICE_CONTROLLED,
				&u64);

    pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_USERNAME, 
				pj_cstr(&s1, v->username));

    pj_stun_msg_add_msgint_attr(pool, msg);

    pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0);

    return msg;
}
static pj_stun_msg* create_msgint3(pj_pool_t *pool, test_vector *v)
{
    pj_stun_msg *msg;
    pj_sockaddr mapped_addr;
    pj_str_t s1;
    pj_status_t status;

    status = pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC,
				(pj_uint8_t*)v->tsx_id, &msg);
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE, 
					 pj_cstr(&s1, "test vector"));
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_sockaddr_init(pj_AF_INET6(), &mapped_addr,
		      pj_cstr(&s1, "2001:db8:1234:5678:11:2233:4455:6677"),
		      32853);
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_stun_msg_add_sockaddr_attr(pool, msg, 
					   PJ_STUN_ATTR_XOR_MAPPED_ADDR,
					   PJ_TRUE, &mapped_addr, 
					   sizeof(pj_sockaddr));
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_stun_msg_add_msgint_attr(pool, msg);
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0);
    if (status != PJ_SUCCESS)
	goto on_error;

    return msg;

on_error:
    app_perror("    error: create_msgint3()", status);
    return NULL;
}
Ejemplo n.º 6
0
/*
 * Send REFRESH
 */
static void send_refresh(pj_tcp_session *sess, int lifetime)
{
    pj_stun_tx_data *tdata;
    pj_status_t status;

    PJ_ASSERT_ON_FAIL(sess->state==PJ_TCP_STATE_READY, return);

    /* Create a bare REFRESH request */
    status = pj_stun_session_create_req(sess->stun, PJ_STUN_REFRESH_REQUEST,
                                        PJ_STUN_MAGIC, NULL, &tdata);
    if (status != PJ_SUCCESS)
        goto on_error;

    /* Add LIFETIME */
    if (lifetime >= 0) {
        pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
                                  PJ_STUN_ATTR_LIFETIME, lifetime);
    }

#if TCP_TODO
    /* Send request */
    if (lifetime == 0) {
        pj_tcp_session_set_state(sess, PJ_TCP_STATE_DISCONNECTING);
    }

    status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE,
                                      (sess->conn_type==PJ_TCP_TP_UDP),
                                      sess->srv_addr,
                                      pj_sockaddr_get_len(sess->srv_addr),
                                      tdata);
    if (status != PJ_SUCCESS)
        goto on_error;
#endif
    return;

on_error:
    if (lifetime == 0) {
        pj_tcp_session_set_state(sess, PJ_TCP_STATE_DISCONNECTED);
        sess_shutdown(sess, status);
    }
}
Ejemplo n.º 7
0
static pj_stun_msg* create_msgint2(pj_pool_t *pool, test_vector *v)
{
    pj_stun_msg *msg;
    pj_sockaddr_in mapped_addr;
    pj_str_t s1;

    pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC,
		       (pj_uint8_t*)v->tsx_id, &msg);

    pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE, 
				pj_cstr(&s1, "test vector"));

    pj_sockaddr_in_init(&mapped_addr, pj_cstr(&s1, "127.0.0.1"), 32853);
    pj_stun_msg_add_sockaddr_attr(pool, msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR,
				  PJ_TRUE, &mapped_addr, 
				  sizeof(pj_sockaddr_in));

    pj_stun_msg_add_msgint_attr(pool, msg);
    pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0);

    return msg;
}
Ejemplo n.º 8
0
static pj_stun_msg* create_success_response(test_server *test_srv,
					    turn_allocation *alloc,
					    pj_stun_msg *req,
					    pj_pool_t *pool,
					    unsigned lifetime,
					    pj_str_t *auth_key)
{
    pj_stun_msg *resp;
    pj_str_t tmp;
    pj_status_t status;

    /* Create response */
    status = pj_stun_msg_create_response(pool, req, 0, NULL, &resp);
    if (status != PJ_SUCCESS) {
	return NULL;
    }
    /* Add TURN_NONCE */
    pj_stun_msg_add_string_attr(pool, resp, PJ_STUN_ATTR_NONCE, pj_cstr(&tmp, TURN_NONCE));
    /* Add LIFETIME */
    pj_stun_msg_add_uint_attr(pool, resp, PJ_STUN_ATTR_LIFETIME, lifetime);
    if (lifetime != 0) {
	/* Add XOR-RELAYED-ADDRESS */
	pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_RELAYED_ADDR, PJ_TRUE, &alloc->alloc_addr,
				      pj_sockaddr_get_len(&alloc->alloc_addr));
	/* Add XOR-MAPPED-ADDRESS */
	pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, &alloc->client_addr,
				      pj_sockaddr_get_len(&alloc->client_addr));
    }

    /* Add blank MESSAGE-INTEGRITY */
    pj_stun_msg_add_msgint_attr(pool, resp);

    /* Set auth key */
    pj_stun_create_key(pool, auth_key, &test_srv->domain, &test_srv->username,
		       PJ_STUN_PASSWD_PLAIN, &test_srv->passwd);

    return resp;
}
Ejemplo n.º 9
0
static pj_status_t apply_msg_options(pj_stun_session *sess,
				     pj_pool_t *pool,
				     const pj_stun_req_cred_info *auth_info,
				     pj_stun_msg *msg)
{
    pj_status_t status = 0;
    pj_str_t realm, username, nonce, auth_key;

    /* If the agent is sending a request, it SHOULD add a SOFTWARE attribute
     * to the request. The server SHOULD include a SOFTWARE attribute in all 
     * responses.
     *
     * If magic value is not PJ_STUN_MAGIC, only apply the attribute for
     * responses.
     */
    if (sess->srv_name.slen && 
	pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_SOFTWARE, 0)==NULL &&
	(PJ_STUN_IS_RESPONSE(msg->hdr.type) ||
	 (PJ_STUN_IS_REQUEST(msg->hdr.type) && msg->hdr.magic==PJ_STUN_MAGIC))) 
    {
	pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE,
				    &sess->srv_name);
    }

    if (pj_stun_auth_valid_for_msg(msg) && auth_info) {
	realm = auth_info->realm;
	username = auth_info->username;
	nonce = auth_info->nonce;
	auth_key = auth_info->auth_key;
    } else {
	realm.slen = username.slen = nonce.slen = auth_key.slen = 0;
    }

    /* Create and add USERNAME attribute if needed */
    if (username.slen && PJ_STUN_IS_REQUEST(msg->hdr.type)) {
	status = pj_stun_msg_add_string_attr(pool, msg,
					     PJ_STUN_ATTR_USERNAME,
					     &username);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    }

    /* Add REALM only when long term credential is used */
    if (realm.slen &&  PJ_STUN_IS_REQUEST(msg->hdr.type)) {
	status = pj_stun_msg_add_string_attr(pool, msg,
					    PJ_STUN_ATTR_REALM,
					    &realm);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    }

    /* Add NONCE when desired */
    if (nonce.slen && 
	(PJ_STUN_IS_REQUEST(msg->hdr.type) ||
	 PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))) 
    {
	status = pj_stun_msg_add_string_attr(pool, msg,
					    PJ_STUN_ATTR_NONCE,
					    &nonce);
    }

    /* Add MESSAGE-INTEGRITY attribute */
    if (username.slen && auth_key.slen) {
	status = pj_stun_msg_add_msgint_attr(pool, msg);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    }


    /* Add FINGERPRINT attribute if necessary */
    if (sess->use_fingerprint) {
	status = pj_stun_msg_add_uint_attr(pool, msg, 
					  PJ_STUN_ATTR_FINGERPRINT, 0);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    }

    return PJ_SUCCESS;
}
Ejemplo n.º 10
0
/* Perform test */
static pj_status_t send_test(nat_detect_session *sess,
			     enum test_type test_id,
			     const pj_sockaddr_in *alt_addr,
			     pj_uint32_t change_flag)
{
    pj_uint32_t magic, tsx_id[3];
    pj_status_t status;

    sess->result[test_id].executed = PJ_TRUE;

    /* Randomize tsx id */
    do {
	magic = pj_rand();
    } while (magic == PJ_STUN_MAGIC);

    tsx_id[0] = pj_rand();
    tsx_id[1] = pj_rand();
    tsx_id[2] = test_id;

    /* Create BIND request */
    status = pj_stun_session_create_req(sess->stun_sess, 
					PJ_STUN_BINDING_REQUEST, magic,
					(pj_uint8_t*)tsx_id, 
					&sess->result[test_id].tdata);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Add CHANGE-REQUEST attribute */
    status = pj_stun_msg_add_uint_attr(sess->pool, 
				       sess->result[test_id].tdata->msg,
				       PJ_STUN_ATTR_CHANGE_REQUEST,
				       change_flag);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Configure alternate address */
    if (alt_addr)
	sess->cur_server = (pj_sockaddr_in*) alt_addr;
    else
	sess->cur_server = &sess->server;

    PJ_LOG(5,(sess->pool->obj_name, 
              "Performing %s to %s:%d", 
	      test_names[test_id],
	      pj_inet_ntoa(sess->cur_server->sin_addr),
	      pj_ntohs(sess->cur_server->sin_port)));

    /* Send the request */
    status = pj_stun_session_send_msg(sess->stun_sess, NULL, PJ_TRUE,
				      PJ_TRUE, sess->cur_server, 
				      sizeof(pj_sockaddr_in),
				      sess->result[test_id].tdata);
    if (status != PJ_SUCCESS)
	goto on_error;

    return PJ_SUCCESS;

on_error:
    sess->result[test_id].complete = PJ_TRUE;
    sess->result[test_id].status = status;

    return status;
}
Ejemplo n.º 11
0
/* Perform test */
static pj_status_t send_test(nat_detect_session *sess,
			     enum test_type test_id,
			     const pj_sockaddr *alt_addr,
			     pj_uint32_t change_flag)
{
    pj_uint32_t magic, tsx_id[3];
    char addr[PJ_INET6_ADDRSTRLEN];
    pj_status_t status;

    sess->result[test_id].executed = PJ_TRUE;

    /* Randomize tsx id */
    do {
	magic = pj_rand();
    } while (magic == PJ_STUN_MAGIC);

    tsx_id[0] = pj_rand();
    tsx_id[1] = pj_rand();
    tsx_id[2] = test_id;

    /* Create BIND request */
    status = pj_stun_session_create_req(sess->stun_sess, 
					PJ_STUN_BINDING_REQUEST, magic,
					(pj_uint8_t*)tsx_id, 
					&sess->result[test_id].tdata);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Add CHANGE-REQUEST attribute */
    status = pj_stun_msg_add_uint_attr(sess->pool, 
				       sess->result[test_id].tdata->msg,
				       PJ_STUN_ATTR_CHANGE_REQUEST,
				       change_flag);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Configure alternate address, synthesize it if necessary */
    if (alt_addr) {
        status = pj_sockaddr_synthesize(sess->server.addr.sa_family,
        				&sess->cur_addr, alt_addr);
        if (status != PJ_SUCCESS)
            goto on_error;

	sess->cur_server = &sess->cur_addr;
    } else {
	sess->cur_server = &sess->server;
    }

    PJ_LOG(5,(sess->pool->obj_name, 
              "Performing %s to %s:%d", 
	      test_names[test_id],
	      pj_sockaddr_print(sess->cur_server, addr, sizeof(addr), 0),
	      pj_sockaddr_get_port(sess->cur_server)));

    /* Send the request */
    status = pj_stun_session_send_msg(sess->stun_sess, NULL, PJ_TRUE,
				      PJ_TRUE, sess->cur_server, 
				      pj_sockaddr_get_len(sess->cur_server),
				      sess->result[test_id].tdata);
    if (status != PJ_SUCCESS)
	goto on_error;

    return PJ_SUCCESS;

on_error:
    sess->result[test_id].complete = PJ_TRUE;
    sess->result[test_id].status = status;

    return status;
}