- Timestamp:
- Feb 23, 2007 1:07:54 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/src/pjstun-client/stun_session.c
r993 r996 27 27 void *user_data; 28 28 29 pj_str_t realm; 30 pj_str_t username; 31 pj_str_t password; 32 33 pj_bool_t fingerprint_enabled; 29 /* Long term credential */ 30 pj_str_t l_realm; 31 pj_str_t l_username; 32 pj_str_t l_password; 33 34 /* Short term credential */ 35 pj_str_t s_username; 36 pj_str_t s_password; 34 37 35 38 pj_stun_tx_data pending_request_list; … … 65 68 66 69 static void tsx_on_complete(pj_stun_client_tsx *tsx, 67 68 70 pj_status_t status, 71 const pj_stun_msg *response); 69 72 static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx, 70 73 const void *stun_pkt, … … 165 168 static pj_status_t session_apply_req(pj_stun_session *sess, 166 169 pj_pool_t *pool, 170 unsigned options, 167 171 pj_stun_msg *msg) 168 172 { … … 172 176 * Section 8.3.1. Formulating the Request Message 173 177 */ 174 if ( sess->realm.slen || sess->username.slen) {178 if (options & PJ_STUN_USE_LONG_TERM_CRED) { 175 179 pj_stun_generic_string_attr *auname; 176 180 pj_stun_msg_integrity_attr *amsgi; 181 pj_stun_generic_string_attr *arealm; 177 182 178 183 /* Create and add USERNAME attribute */ 179 184 status = pj_stun_generic_string_attr_create(sess->pool, 180 185 PJ_STUN_ATTR_USERNAME, 181 &sess-> username,186 &sess->l_username, 182 187 &auname); 183 188 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); … … 186 191 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 187 192 188 if (sess->realm.slen) { 189 /* Add REALM only when long term credential is used */ 190 pj_stun_generic_string_attr *arealm; 191 status = pj_stun_generic_string_attr_create(sess->pool, 192 PJ_STUN_ATTR_REALM, 193 &sess->realm, 194 &arealm); 195 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 196 197 status = pj_stun_msg_add_attr(msg, &arealm->hdr); 198 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 199 } 193 /* Add REALM only when long term credential is used */ 194 status = pj_stun_generic_string_attr_create(sess->pool, 195 PJ_STUN_ATTR_REALM, 196 &sess->l_realm, 197 &arealm); 198 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 199 200 status = pj_stun_msg_add_attr(msg, &arealm->hdr); 201 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 200 202 201 203 /* Add MESSAGE-INTEGRITY attribute */ … … 206 208 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 207 209 208 PJ_TODO(COMPUTE_MESSAGE_INTEGRITY); 209 210 PJ_TODO(COMPUTE_MESSAGE_INTEGRITY1); 211 212 } else if (options & PJ_STUN_USE_SHORT_TERM_CRED) { 213 pj_stun_generic_string_attr *auname; 214 pj_stun_msg_integrity_attr *amsgi; 215 216 /* Create and add USERNAME attribute */ 217 status = pj_stun_generic_string_attr_create(sess->pool, 218 PJ_STUN_ATTR_USERNAME, 219 &sess->s_username, 220 &auname); 221 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 222 223 status = pj_stun_msg_add_attr(msg, &auname->hdr); 224 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 225 226 /* Add MESSAGE-INTEGRITY attribute */ 227 status = pj_stun_msg_integrity_attr_create(sess->pool, &amsgi); 228 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 229 230 status = pj_stun_msg_add_attr(msg, &amsgi->hdr); 231 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 232 233 PJ_TODO(COMPUTE_MESSAGE_INTEGRITY2); 210 234 } 211 235 212 236 /* Add FINGERPRINT attribute if necessary */ 213 if ( sess->fingerprint_enabled) {237 if (options & PJ_STUN_USE_FINGERPRINT) { 214 238 pj_stun_fingerprint_attr *af; 215 239 … … 227 251 228 252 229 230 231 253 static void tsx_on_complete(pj_stun_client_tsx *tsx, 254 pj_status_t status, 255 const pj_stun_msg *response) 256 { 257 pj_stun_tx_data *tdata; 258 259 tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 260 261 switch (PJ_STUN_GET_METHOD(tdata->msg->hdr.type)) { 262 case PJ_STUN_BINDING_METHOD: 263 tdata->sess->cb.on_bind_response(tdata->sess, status, tdata, response); 264 break; 265 case PJ_STUN_ALLOCATE_METHOD: 266 tdata->sess->cb.on_allocate_response(tdata->sess, status, 267 tdata, response); 268 break; 269 case PJ_STUN_SET_ACTIVE_DESTINATION_METHOD: 270 tdata->sess->cb.on_set_active_destination_response(tdata->sess, status, 271 tdata, response); 272 break; 273 case PJ_STUN_CONNECT_METHOD: 274 tdata->sess->cb.on_connect_response(tdata->sess, status, tdata, 275 response); 276 break; 277 default: 278 pj_assert(!"Unknown method"); 279 break; 280 } 281 } 282 283 static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx, 284 const void *stun_pkt, 285 pj_size_t pkt_size) 286 { 287 pj_stun_tx_data *tdata; 288 289 tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 290 291 return tdata->sess->cb.on_send_msg(tdata, stun_pkt, pkt_size, 292 tdata->addr_len, tdata->dst_addr); 293 } 294 295 /* **************************************************************************/ 232 296 233 297 PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_endpoint *endpt, … … 261 325 { 262 326 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 327 263 328 pj_pool_release(sess->pool); 264 329 … … 281 346 } 282 347 283 PJ_DEF(pj_status_t) pj_stun_session_set_credential( pj_stun_session *sess, 284 const pj_str_t *realm, 285 const pj_str_t *user, 286 const pj_str_t *passwd) 287 { 288 pj_str_t empty = { NULL, 0 }; 348 PJ_DEF(pj_status_t) 349 pj_stun_session_set_long_term_credential(pj_stun_session *sess, 350 const pj_str_t *realm, 351 const pj_str_t *user, 352 const pj_str_t *passwd) 353 { 354 pj_str_t nil = { NULL, 0 }; 289 355 290 356 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 291 pj_strdup_with_null(sess->pool, &sess->realm, realm ? realm : &empty); 292 pj_strdup_with_null(sess->pool, &sess->username, user ? user : &empty); 293 pj_strdup_with_null(sess->pool, &sess->password, passwd ? passwd : &empty); 294 295 return PJ_SUCCESS; 296 } 297 298 PJ_DEF(pj_status_t) pj_stun_session_enable_fingerprint(pj_stun_session *sess, 299 pj_bool_t enabled) 300 { 357 pj_strdup_with_null(sess->pool, &sess->l_realm, realm ? realm : &nil); 358 pj_strdup_with_null(sess->pool, &sess->l_username, user ? user : &nil); 359 pj_strdup_with_null(sess->pool, &sess->l_password, passwd ? passwd : &nil); 360 361 return PJ_SUCCESS; 362 } 363 364 365 PJ_DEF(pj_status_t) 366 pj_stun_session_set_short_term_credential(pj_stun_session *sess, 367 const pj_str_t *user, 368 const pj_str_t *passwd) 369 { 370 pj_str_t nil = { NULL, 0 }; 371 301 372 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 302 sess->fingerprint_enabled = enabled; 373 pj_strdup_with_null(sess->pool, &sess->s_username, user ? user : &nil); 374 pj_strdup_with_null(sess->pool, &sess->s_password, passwd ? passwd : &nil); 375 303 376 return PJ_SUCCESS; 304 377 } … … 308 381 pj_stun_tx_data **p_tdata) 309 382 { 310 pj_pool_t *pool;311 383 pj_stun_tx_data *tdata; 312 384 pj_status_t status; … … 318 390 return status; 319 391 320 status = session_apply_req(sess, pool, tdata->msg);321 if (status != PJ_SUCCESS) {322 destroy_tdata(tdata);323 return status;324 }325 326 392 *p_tdata = tdata; 327 393 return PJ_SUCCESS; … … 368 434 369 435 PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess, 436 unsigned options, 370 437 unsigned addr_len, 371 438 const pj_sockaddr_t *server, … … 376 443 PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL); 377 444 445 /* Allocate packet */ 446 tdata->max_len = PJ_STUN_MAX_PKT_LEN; 447 tdata->pkt = pj_pool_alloc(tdata->pool, tdata->max_len); 448 378 449 if (PJ_LOG_MAX_LEVEL >= 5) { 379 char buf[512]; 380 unsigned buflen = sizeof(buf); 450 char *buf = (char*) tdata->pkt; 381 451 const char *dst_name; 382 452 int dst_port; … … 398 468 PJ_LOG(5,(SNAME(sess), 399 469 "Sending STUN message to %s:%d:\n" 400 "%s\n", 470 "--- begin STUN message ---\n" 471 "%s" 472 "--- end of STUN message ---\n", 401 473 dst_name, dst_port, 402 pj_stun_msg_dump(tdata->msg, buf, &buflen))); 403 } 404 474 pj_stun_msg_dump(tdata->msg, buf, tdata->max_len, NULL))); 475 } 476 477 /* Apply options */ 478 status = session_apply_req(sess, tdata->pool, options, tdata->msg); 479 if (status != PJ_SUCCESS) { 480 LOG_ERR_(sess, "Error applying options", status); 481 destroy_tdata(tdata); 482 return status; 483 } 484 485 /* Encode message */ 486 status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len, 487 0, &tdata->pkt_size); 488 if (status != PJ_SUCCESS) { 489 LOG_ERR_(sess, "STUN encode() error", status); 490 destroy_tdata(tdata); 491 return status; 492 } 405 493 406 494 /* If this is a STUN request message, then send the request with … … 410 498 411 499 /* Create STUN client transaction */ 412 status = pj_stun_client_tsx_create(sess->endpt, &tsx_cb,413 &t data->client_tsx);500 status = pj_stun_client_tsx_create(sess->endpt, tdata->pool, 501 &tsx_cb, &tdata->client_tsx); 414 502 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 415 503 pj_stun_client_tsx_set_data(tdata->client_tsx, (void*)tdata); 504 505 /* Save the remote address */ 506 tdata->addr_len = addr_len; 507 tdata->dst_addr = server; 416 508 417 509 /* Send the request! */ 418 510 status = pj_stun_client_tsx_send_msg(tdata->client_tsx, PJ_TRUE, 419 tdata-> msg);511 tdata->pkt, tdata->pkt_size); 420 512 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 421 513 LOG_ERR_(sess, "Error sending STUN request", status); 514 destroy_tdata(tdata); 422 515 return status; 423 516 } … … 428 521 } else { 429 522 /* Otherwise for non-request message, send directly to transport. */ 430 status = sess->cb.on_send_msg(tdata, addr_len, server); 523 status = sess->cb.on_send_msg(tdata, tdata->pkt, tdata->pkt_size, 524 addr_len, server); 525 526 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 527 LOG_ERR_(sess, "Error sending STUN request", status); 528 destroy_tdata(tdata); 529 return status; 530 } 431 531 } 432 532 … … 442 542 { 443 543 pj_stun_msg *msg; 544 pj_pool_t *tmp_pool; 545 char *dump; 444 546 pj_status_t status; 445 547 446 548 PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL); 447 549 550 tmp_pool = pj_pool_create(sess->endpt->pf, "tmpstun", 1024, 1024, NULL); 551 if (!tmp_pool) 552 return PJ_ENOMEM; 553 448 554 /* Try to parse the message */ 449 status = pj_stun_msg_decode(t sx->pool, (const pj_uint8_t*)packet,555 status = pj_stun_msg_decode(tmp_pool, (const pj_uint8_t*)packet, 450 556 pkt_size, 0, &msg, parsed_len, 451 557 NULL, NULL, NULL); 452 558 if (status != PJ_SUCCESS) { 453 559 LOG_ERR_(sess, "STUN msg_decode() error", status); 560 pj_pool_release(tmp_pool); 454 561 return status; 455 562 } 563 564 dump = pj_pool_alloc(tmp_pool, PJ_STUN_MAX_PKT_LEN); 565 566 PJ_LOG(4,(SNAME(sess), 567 "RX STUN message:\n" 568 "--- begin STUN message ---" 569 "%s" 570 "--- end of STUN message ---\n", 571 pj_stun_msg_dump(msg, dump, PJ_STUN_MAX_PKT_LEN, NULL))); 572 456 573 457 574 if (PJ_STUN_IS_RESPONSE(msg->hdr.type) || … … 464 581 if (tdata == NULL) { 465 582 LOG_ERR_(sess, "STUN error finding transaction", PJ_ENOTFOUND); 583 pj_pool_release(tmp_pool); 466 584 return PJ_ENOTFOUND; 467 585 } … … 472 590 */ 473 591 status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg); 474 if (status != PJ_SUCCESS) 592 if (status != PJ_SUCCESS) { 593 pj_pool_release(tmp_pool); 475 594 return status; 595 } 476 596 477 597 /* If transaction has completed, destroy the transmit data. … … 483 603 } 484 604 605 pj_pool_release(tmp_pool); 485 606 return PJ_SUCCESS; 486 607 487 608 } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 488 609 610 PJ_TODO(HANDLE_INCOMING_STUN_REQUEST); 489 611 490 612 } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) { 491 613 614 PJ_TODO(HANDLE_INCOMING_STUN_INDICATION); 492 615 493 616 } else { 494 617 pj_assert(!"Unexpected!"); 495 return PJ_EBUG; 496 } 497 498 } 499 618 } 619 620 pj_pool_release(tmp_pool); 621 return PJ_ENOTSUP; 622 } 623
Note: See TracChangeset
for help on using the changeset viewer.