Changeset 1002 for pjproject/trunk
- Timestamp:
- Feb 26, 2007 2:33:14 AM (18 years ago)
- Location:
- pjproject/trunk/pjlib-util
- Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/build/Makefile
r1001 r1002 27 27 export PJLIB_UTIL_SRCDIR = ../src/pjlib-util 28 28 export PJLIB_UTIL_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 29 errno.o dns.o dns_dump.o getopt.o \29 crc32.o errno.o dns.o dns_dump.o getopt.o \ 30 30 hmac_md5.o hmac_sha1.o md5.o resolver.o \ 31 31 scanner.o sha1.o string.o stun_simple.o \ -
pjproject/trunk/pjlib-util/build/pjlib_util.dsp
r1001 r1002 88 88 # Begin Source File 89 89 90 SOURCE="..\src\pjlib-util\crc32.c" 91 # End Source File 92 # Begin Source File 93 90 94 SOURCE="..\src\pjlib-util\dns.c" 91 95 # End Source File … … 93 97 94 98 SOURCE="..\src\pjlib-util\dns_dump.c" 95 # End Source File96 # Begin Source File97 98 SOURCE="..\src\pjlib-util-test\encryption.c"99 99 # End Source File 100 100 # Begin Source File … … 187 187 188 188 SOURCE="..\include\pjlib-util\config.h" 189 # End Source File 190 # Begin Source File 191 192 SOURCE="..\include\pjlib-util\crc32.h" 189 193 # End Source File 190 194 # Begin Source File -
pjproject/trunk/pjlib-util/build/pjlib_util.vcproj
r1001 r1002 176 176 > 177 177 <File 178 RelativePath="..\src\pjlib-util\crc32.c" 179 > 180 </File> 181 <File 178 182 RelativePath="..\src\pjlib-util\dns.c" 179 183 > … … 493 497 </File> 494 498 <File 499 RelativePath="..\include\pjlib-util\crc32.h" 500 > 501 </File> 502 <File 495 503 RelativePath="..\include\pjlib-util\dns.h" 496 504 > -
pjproject/trunk/pjlib-util/build/wince-evc4/pjlib_util_wince.vcp
r1001 r1002 319 319 # Begin Source File 320 320 321 SOURCE="..\..\src\pjlib-util\crc32.c" 322 323 !IF "$(CFG)" == "pjlib_util_wince - Win32 (WCE emulator) Release" 324 325 DEP_CPP_CRC32=\ 326 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 327 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 328 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 329 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 330 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 331 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 332 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 333 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 334 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 335 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 336 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 337 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 338 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 339 "..\..\..\pjlib\include\pj\config.h"\ 340 "..\..\..\pjlib\include\pj\config_site.h"\ 341 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 342 "..\..\..\pjlib\include\pj\types.h"\ 343 "..\..\include\pjlib-util\crc32.h"\ 344 345 346 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE emulator) Debug" 347 348 DEP_CPP_CRC32=\ 349 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 350 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 351 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 352 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 353 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 354 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 355 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 356 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 357 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 358 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 359 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 360 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 361 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 362 "..\..\..\pjlib\include\pj\config.h"\ 363 "..\..\..\pjlib\include\pj\config_site.h"\ 364 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 365 "..\..\..\pjlib\include\pj\types.h"\ 366 "..\..\include\pjlib-util\crc32.h"\ 367 368 369 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4I) Release" 370 371 DEP_CPP_CRC32=\ 372 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 373 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 374 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 375 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 376 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 377 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 378 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 379 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 380 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 381 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 382 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 383 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 384 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 385 "..\..\..\pjlib\include\pj\config.h"\ 386 "..\..\..\pjlib\include\pj\config_site.h"\ 387 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 388 "..\..\..\pjlib\include\pj\types.h"\ 389 "..\..\include\pjlib-util\crc32.h"\ 390 391 392 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4I) Debug" 393 394 DEP_CPP_CRC32=\ 395 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 396 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 397 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 398 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 399 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 400 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 401 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 402 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 403 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 404 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 405 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 406 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 407 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 408 "..\..\..\pjlib\include\pj\config.h"\ 409 "..\..\..\pjlib\include\pj\config_site.h"\ 410 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 411 "..\..\..\pjlib\include\pj\types.h"\ 412 "..\..\include\pjlib-util\crc32.h"\ 413 414 415 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Release" 416 417 DEP_CPP_CRC32=\ 418 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 419 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 420 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 421 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 422 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 423 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 424 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 425 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 426 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 427 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 428 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 429 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 430 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 431 "..\..\..\pjlib\include\pj\config.h"\ 432 "..\..\..\pjlib\include\pj\config_site.h"\ 433 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 434 "..\..\..\pjlib\include\pj\types.h"\ 435 "..\..\include\pjlib-util\crc32.h"\ 436 437 438 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4) Debug" 439 440 DEP_CPP_CRC32=\ 441 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 442 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 443 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 444 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 445 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 446 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 447 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 448 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 449 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 450 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 451 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 452 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 453 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 454 "..\..\..\pjlib\include\pj\config.h"\ 455 "..\..\..\pjlib\include\pj\config_site.h"\ 456 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 457 "..\..\..\pjlib\include\pj\types.h"\ 458 "..\..\include\pjlib-util\crc32.h"\ 459 460 461 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4T) Release" 462 463 DEP_CPP_CRC32=\ 464 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 465 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 466 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 467 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 468 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 469 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 470 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 471 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 472 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 473 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 474 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 475 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 476 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 477 "..\..\..\pjlib\include\pj\config.h"\ 478 "..\..\..\pjlib\include\pj\config_site.h"\ 479 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 480 "..\..\..\pjlib\include\pj\types.h"\ 481 "..\..\include\pjlib-util\crc32.h"\ 482 483 484 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE ARMV4T) Debug" 485 486 DEP_CPP_CRC32=\ 487 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 488 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 489 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 490 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 491 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 492 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 493 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 494 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 495 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 496 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 497 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 498 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 499 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 500 "..\..\..\pjlib\include\pj\config.h"\ 501 "..\..\..\pjlib\include\pj\config_site.h"\ 502 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 503 "..\..\..\pjlib\include\pj\types.h"\ 504 "..\..\include\pjlib-util\crc32.h"\ 505 506 507 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE x86) Release" 508 509 DEP_CPP_CRC32=\ 510 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 511 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 512 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 513 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 514 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 515 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 516 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 517 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 518 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 519 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 520 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 521 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 522 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 523 "..\..\..\pjlib\include\pj\config.h"\ 524 "..\..\..\pjlib\include\pj\config_site.h"\ 525 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 526 "..\..\..\pjlib\include\pj\types.h"\ 527 "..\..\include\pjlib-util\crc32.h"\ 528 529 530 !ELSEIF "$(CFG)" == "pjlib_util_wince - Win32 (WCE x86) Debug" 531 532 DEP_CPP_CRC32=\ 533 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 534 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 535 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 536 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 537 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 538 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 539 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 540 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 541 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 542 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 543 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 544 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 545 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 546 "..\..\..\pjlib\include\pj\config.h"\ 547 "..\..\..\pjlib\include\pj\config_site.h"\ 548 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 549 "..\..\..\pjlib\include\pj\types.h"\ 550 "..\..\include\pjlib-util\crc32.h"\ 551 552 553 !ENDIF 554 555 # End Source File 556 # Begin Source File 557 321 558 SOURCE="..\..\src\pjlib-util\dns.c" 322 559 … … 6627 6864 "..\..\..\pjlib\include\pjlib.h"\ 6628 6865 "..\..\include\pjlib-util\config.h"\ 6866 "..\..\include\pjlib-util\crc32.h"\ 6629 6867 "..\..\include\pjlib-util\errno.h"\ 6868 "..\..\include\pjlib-util\hmac_sha1.h"\ 6869 "..\..\include\pjlib-util\md5.h"\ 6630 6870 "..\..\include\pjlib-util\stun_msg.h"\ 6631 6871 "..\..\include\pjlib-util\types.h"\ … … 10778 11018 # Begin Source File 10779 11019 11020 SOURCE="..\..\include\pjlib-util\crc32.h" 11021 # End Source File 11022 # Begin Source File 11023 10780 11024 SOURCE="..\..\include\pjlib-util\dns.h" 10781 11025 # End Source File -
pjproject/trunk/pjlib-util/include/pjlib-util.h
r1001 r1002 33 33 34 34 /* Crypto */ 35 #include <pjlib-util/crc32.h> 35 36 #include <pjlib-util/hmac_md5.h> 36 37 #include <pjlib-util/hmac_sha1.h> -
pjproject/trunk/pjlib-util/include/pjlib-util/errno.h
r992 r1002 94 94 */ 95 95 #define PJLIB_UTIL_ESTUNSYMMETRIC (PJLIB_UTIL_ERRNO_START+11) /* 320011 */ 96 /** 97 * @hideinitializer 98 * Invalid STUN magic value 99 */ 100 #define PJLIB_UTIL_ESTUNNOTMAGIC (PJLIB_UTIL_ERRNO_START+12) /* 320012 */ 101 /** 102 * @hideinitializer 103 * Invalid STUN fingerprint value 104 */ 105 #define PJLIB_UTIL_ESTUNFINGERPRINT (PJLIB_UTIL_ERRNO_START+13) /* 320013 */ 96 106 97 107 … … 267 277 /** 268 278 * @hideinitializer 269 * Invalid socket address length.279 * Invalid STUN socket address length. 270 280 */ 271 281 #define PJLIB_UTIL_ESTUNINADDRLEN (PJLIB_UTIL_ERRNO_START+113)/* 320113 */ 272 282 /** 273 283 * @hideinitializer 274 * IPv6 attribute not supported284 * STUN IPv6 attribute not supported 275 285 */ 276 286 #define PJLIB_UTIL_ESTUNIPV6NOTSUPP (PJLIB_UTIL_ERRNO_START+113)/* 320113 */ … … 282 292 /** 283 293 * @hideinitializer 284 * Transaction ID mismatch.294 * STUN transaction ID mismatch. 285 295 */ 286 296 #define PJLIB_UTIL_ESTUNINVALIDID (PJLIB_UTIL_ERRNO_START+115)/* 320115 */ … … 290 300 */ 291 301 #define PJLIB_UTIL_ESTUNNOHANDLER (PJLIB_UTIL_ERRNO_START+116)/* 320116 */ 292 293 294 #define PJ_STATUS_FROM_STUN_CODE(code) -1 302 /** 303 * @hideinitializer 304 * Invalid STUN MESSAGE-INTEGRITY attribute position in message. 305 * STUN MESSAGE-INTEGRITY must be put last in the message, or before 306 * FINGERPRINT attribute. 307 */ 308 #define PJLIB_UTIL_ESTUNMSGINT (PJLIB_UTIL_ERRNO_START+117)/* 320117 */ 309 /** 310 * @hideinitializer 311 * Missing STUN USERNAME attribute. 312 * When credential is included in the STUN message (MESSAGE-INTEGRITY is 313 * present), the USERNAME attribute must be present in the message. 314 */ 315 #define PJLIB_UTIL_ESTUNNOUSERNAME (PJLIB_UTIL_ERRNO_START+118)/* 320118 */ 316 317 318 #define PJ_STATUS_FROM_STUN_CODE(code) (PJLIB_UTIL_ERRNO_START+code) 295 319 296 320 -
pjproject/trunk/pjlib-util/include/pjlib-util/stun_msg.h
r1001 r1002 602 602 * The raw data. 603 603 */ 604 char*data;604 pj_uint8_t *data; 605 605 606 606 } pj_stun_binary_attr; … … 1047 1047 1048 1048 1049 /** STUN decoding options */ 1050 enum pj_stun_options 1051 { 1052 /** 1053 * Tell the decoder that the message was received from datagram 1054 * oriented transport (such as UDP). 1055 */ 1056 PJ_STUN_IS_DATAGRAM = 1, 1057 1058 /** 1059 * Tell pj_stun_msg_decode() to check the validity of the STUN 1060 * message by calling pj_stun_msg_check() before starting to 1061 * decode the packet. 1062 */ 1063 PJ_STUN_CHECK_PACKET = 2 1064 }; 1065 1049 1066 /** 1050 1067 * Get STUN message method name. … … 1088 1105 1089 1106 /** 1090 * Create a blankSTUN message.1107 * Create a generic STUN message. 1091 1108 * 1092 1109 * @param pool Pool to create the STUN message. … … 1106 1123 pj_stun_msg **p_msg); 1107 1124 1125 /** 1126 * Create STUN response message. 1127 * 1128 * @param pool Pool to create the mesage. 1129 * @param req_msg The request message. 1130 * @param err_code STUN error code. If this value is not zero, 1131 * then error response will be created, otherwise 1132 * successful response will be created. 1133 * @param err_msg Optional error message to explain err_code. 1134 * If this value is NULL and err_code is not zero, 1135 * the error string will be taken from the default 1136 * STUN error message. 1137 * @param p_response Pointer to receive the response. 1138 * 1139 * @return PJ_SUCCESS on success, or the appropriate error. 1140 */ 1141 PJ_DECL(pj_status_t) pj_stun_msg_create_response(pj_pool_t *pool, 1142 const pj_stun_msg *req_msg, 1143 unsigned err_code, 1144 const pj_str_t *err_msg, 1145 pj_stun_msg **p_response); 1146 1108 1147 1109 1148 /** … … 1119 1158 pj_stun_attr_hdr *attr); 1120 1159 1121 1122 /**1123 * Check that the PDU is potentially a valid STUN message. This function1124 * is useful when application needs to multiplex STUN packets with other1125 * application traffic. When this function returns PJ_SUCCESS, there is a1126 * big chance that the packet is a STUN packet.1127 *1128 * Note that we cannot be sure that the PDU is a really valid STUN message1129 * until we actually parse the PDU.1130 *1131 * @param pdu The packet buffer.1132 * @param pdu_len The length of the packet buffer.1133 * @param options Options.1134 *1135 * @return PJ_SUCCESS if the PDU is a potentially valid STUN1136 * message.1137 */1138 PJ_DECL(pj_status_t) pj_stun_msg_check(const void *pdu, unsigned pdu_len,1139 unsigned options);1140 1141 1142 /**1143 * Parse incoming packet into STUN message.1144 *1145 * @param pool Pool to allocate the message.1146 * @param pdu The incoming packet to be parsed.1147 * @param pdu_len The length of the incoming packet.1148 * @param options Parsing flags.1149 * @param p_msg Pointer to receive the parsed message.1150 * @param p_parsed_len Optional pointer to receive how many bytes have1151 * been parsed for the STUN message. This is useful1152 * when the packet is received over stream oriented1153 * transport.1154 * @param p_err_code Optional pointer to receive STUN error code when1155 * parsing failed.1156 * @param uattr_cnt Optional pointer to specify the number of elements1157 * in uattr array. On return, this will be filled with1158 * the actual number of attributes set in the uattr.1159 * @param uattr Optional array to receive unknown attribute types.1160 *1161 * @return PJ_SUCCESS on success or the appropriate error code.1162 */1163 PJ_DECL(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,1164 const pj_uint8_t *pdu,1165 unsigned pdu_len,1166 unsigned options,1167 pj_stun_msg **p_msg,1168 unsigned *p_parsed_len,1169 unsigned *p_err_code,1170 unsigned *uattr_cnt,1171 pj_uint16_t uattr[]);1172 1160 1173 1161 /** … … 1206 1194 unsigned *p_msg_len); 1207 1195 1196 /** 1197 * Check that the PDU is potentially a valid STUN message. This function 1198 * is useful when application needs to multiplex STUN packets with other 1199 * application traffic. When this function returns PJ_SUCCESS, there is a 1200 * big chance that the packet is a STUN packet. 1201 * 1202 * Note that we cannot be sure that the PDU is a really valid STUN message 1203 * until we actually parse the PDU. 1204 * 1205 * @param pdu The packet buffer. 1206 * @param pdu_len The length of the packet buffer. 1207 * @param options Additional options to be applied in the checking, 1208 * which can be taken from pj_stun_options. One of the 1209 * useful option is PJ_STUN_IS_DATAGRAM which means that 1210 * the pdu represents a whole STUN packet. 1211 * 1212 * @return PJ_SUCCESS if the PDU is a potentially valid STUN 1213 * message. 1214 */ 1215 PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, unsigned pdu_len, 1216 unsigned options); 1217 1218 1219 /** 1220 * Decode incoming packet into STUN message. 1221 * 1222 * @param pool Pool to allocate the message. 1223 * @param pdu The incoming packet to be parsed. 1224 * @param pdu_len The length of the incoming packet. 1225 * @param options Parsing flags, according to pj_stun_options. 1226 * @param p_msg Pointer to receive the parsed message. 1227 * @param p_parsed_len Optional pointer to receive how many bytes have 1228 * been parsed for the STUN message. This is useful 1229 * when the packet is received over stream oriented 1230 * transport. 1231 * @param p_response Optional pointer to receive an instance of response 1232 * message, if one can be created. If the packet being 1233 * decoded is a request message, and it contains error, 1234 * and a response can be created, then the STUN 1235 * response message will be returned on this argument. 1236 * 1237 * @return PJ_SUCCESS if a STUN message has been successfully 1238 * decoded. 1239 */ 1240 PJ_DECL(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool, 1241 const pj_uint8_t *pdu, 1242 unsigned pdu_len, 1243 unsigned options, 1244 pj_stun_msg **p_msg, 1245 unsigned *p_parsed_len, 1246 pj_stun_msg **p_response); 1247 1248 /** 1249 * Verify credential in the STUN message. Note that before calling this 1250 * function, application must have checked that the message contains 1251 * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr() 1252 * function, because this function will reject the message with 401 error 1253 * if it doesn't contain PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute. 1254 * 1255 * @param msg The message to be verified. 1256 * @param realm Realm, if long term credential is required. If 1257 * short term credential is required, this argument 1258 * must be set to NULL. 1259 * @param username If this attribute is specified, then the USERNAME 1260 * attribute in the message will be compared against 1261 * this value. If NULL is specified, then this function 1262 * will accept any usernames. 1263 * @param password The password. 1264 * @param options Options, must be zero for now. 1265 * @param pool If response is to be created, then memory will 1266 * be allocated from this pool. 1267 * @param p_response Optional pointer to receive the response message 1268 * then the credential in the request fails to 1269 * authenticate. 1270 * 1271 * @return PJ_SUCCESS if credential is verified successfully. 1272 * If the verification fails and \a p_response is not 1273 * NULL, an appropriate response will be returned in 1274 * \a p_response. 1275 */ 1276 PJ_DECL(pj_status_t) pj_stun_verify_credential(const pj_stun_msg *msg, 1277 const pj_str_t *realm, 1278 const pj_str_t *username, 1279 const pj_str_t *password, 1280 unsigned options, 1281 pj_pool_t *pool, 1282 pj_stun_msg **p_response); 1283 1208 1284 1209 1285 /** … … 1244 1320 1245 1321 /** 1246 * Create a generic STUN IP address attribute for IPv4 address. Note that 1247 * the port and ip_addr parameters are in host byte order. 1322 * Create a generic STUN IP address attribute. The \a addr_len and 1323 * \a addr parameters specify whether the address is IPv4 or IPv4 1324 * address. 1248 1325 * 1249 1326 * @param pool The pool to allocate memory from. … … 1267 1344 1268 1345 /** 1346 * Create and add generic STUN IP address attribute to a STUN message. 1347 * The \a addr_len and \a addr parameters specify whether the address is 1348 * IPv4 or IPv4 address. 1349 * 1350 * @param pool The pool to allocate memory from. 1351 * @param msg The STUN message. 1352 * @param attr_type Attribute type, from #pj_stun_attr_type. 1353 * @param xor_ed If non-zero, the port and address will be XOR-ed 1354 * with magic, to make the XOR-MAPPED-ADDRESS attribute. 1355 * @param addr_len Length of \a addr parameter. 1356 * @param addr A pj_sockaddr_in or pj_sockaddr_in6 structure. 1357 * 1358 * @return PJ_SUCCESS on success or the appropriate error code. 1359 */ 1360 PJ_DECL(pj_status_t) 1361 pj_stun_msg_add_generic_ip_addr_attr(pj_pool_t *pool, 1362 pj_stun_msg *msg, 1363 int attr_type, 1364 pj_bool_t xor_ed, 1365 unsigned addr_len, 1366 const pj_sockaddr_t *addr); 1367 1368 /** 1269 1369 * Create a STUN generic string attribute. 1270 1370 * … … 1282 1382 pj_stun_generic_string_attr **p_attr); 1283 1383 1384 /** 1385 * Create and add STUN generic string attribute to the message. 1386 * 1387 * @param pool The pool to allocate memory from. 1388 * @param msg The STUN message. 1389 * @param attr_type Attribute type, from #pj_stun_attr_type. 1390 * @param value The string value to be assigned to the attribute. 1391 * 1392 * @return PJ_SUCCESS on success or the appropriate error code. 1393 */ 1394 PJ_DECL(pj_status_t) 1395 pj_stun_msg_add_generic_string_attr(pj_pool_t *pool, 1396 pj_stun_msg *msg, 1397 int attr_type, 1398 const pj_str_t *value); 1284 1399 1285 1400 /** … … 1299 1414 pj_stun_generic_uint_attr **p_attr); 1300 1415 1416 /** 1417 * Create and add STUN generic 32bit value attribute to the message. 1418 * 1419 * @param pool The pool to allocate memory from. 1420 * @param msg The STUN message 1421 * @param attr_type Attribute type, from #pj_stun_attr_type. 1422 * @param value The 32bit value to be assigned to the attribute. 1423 * 1424 * @return PJ_SUCCESS on success or the appropriate error code. 1425 */ 1426 PJ_DECL(pj_status_t) 1427 pj_stun_msg_add_generic_uint_attr(pj_pool_t *pool, 1428 pj_stun_msg *msg, 1429 int attr_type, 1430 pj_uint32_t value); 1431 1301 1432 1302 1433 /** … … 1311 1442 pj_stun_msg_integrity_attr_create(pj_pool_t *pool, 1312 1443 pj_stun_msg_integrity_attr **p_attr); 1313 1314 1444 1315 1445 /** … … 1332 1462 1333 1463 /** 1334 * Create an empty instance of STUN UNKNOWN-ATTRIBUTES attribute. 1464 * Create instance of STUN UNKNOWN-ATTRIBUTES attribute and copy the 1465 * unknown attribute array to the attribute. 1335 1466 * 1336 1467 * @param pool The pool to allocate memory from. … … 1344 1475 pj_stun_unknown_attr_create(pj_pool_t *pool, 1345 1476 unsigned attr_cnt, 1346 pj_uint16_t attr[],1477 const pj_uint16_t attr[], 1347 1478 pj_stun_unknown_attr **p_attr); 1348 1479 1349 1350 /** 1351 * Create a blank binary attribute. 1480 /** 1481 * Create and add STUN UNKNOWN-ATTRIBUTES attribute to the message. 1482 * 1483 * @param pool The pool to allocate memory from. 1484 * @param msg The STUN message. 1485 * @param attr_cnt Number of attributes in the array (can be zero). 1486 * @param attr Optional array of attributes. 1487 * 1488 * @return PJ_SUCCESS on success or the appropriate error code. 1489 */ 1490 PJ_DECL(pj_status_t) 1491 pj_stun_msg_add_unknown_attr(pj_pool_t *pool, 1492 pj_stun_msg *msg, 1493 unsigned attr_cnt, 1494 const pj_uint16_t attr[]); 1495 1496 /** 1497 * Create STUN binary attribute. 1352 1498 * 1353 1499 * @param pool The pool to allocate memory from. 1354 1500 * @param attr_type The attribute type, from #pj_stun_attr_type. 1501 * @param data Data to be coped to the attribute, or NULL 1502 * if no data to be copied now. 1503 * @param length Length of data, or zero if no data is to be 1504 * copied now. 1355 1505 * @param p_attr Pointer to receive the attribute. 1356 1506 * … … 1360 1510 pj_stun_binary_attr_create(pj_pool_t *pool, 1361 1511 int attr_type, 1512 const pj_uint8_t *data, 1513 unsigned length, 1362 1514 pj_stun_binary_attr **p_attr); 1363 1515 1516 /** 1517 * Create STUN binary attribute and add the attribute to the message. 1518 * 1519 * @param pool The pool to allocate memory from. 1520 * @param msg The STUN message. 1521 * @param attr_type The attribute type, from #pj_stun_attr_type. 1522 * @param data Data to be coped to the attribute, or NULL 1523 * if no data to be copied now. 1524 * @param length Length of data, or zero if no data is to be 1525 * copied now. 1526 * @param p_attr Pointer to receive the attribute. 1527 * 1528 * @return PJ_SUCCESS on success or the appropriate error code. 1529 */ 1530 PJ_DECL(pj_status_t) 1531 pj_stun_msg_add_binary_attr(pj_pool_t *pool, 1532 pj_stun_msg *msg, 1533 int attr_type, 1534 const pj_uint8_t *data, 1535 unsigned length); 1536 1364 1537 1365 1538 /** -
pjproject/trunk/pjlib-util/src/pjlib-util-test/encryption.c
r1001 r1002 384 384 } 385 385 386 /* CRC32 test data, generated from crc32 test on a Linux box */ 387 struct 388 { 389 char *input; 390 pj_uint32_t crc; 391 } crc32_test_data[] = 392 { 393 { 394 "", 395 0x0 396 }, 397 { 398 "Hello World", 399 0x4a17b156 400 }, 401 { 402 /* Something read from /dev/random */ 403 "\x21\x21\x98\x10\x62\x59\xbc\x58\x42\x24\xe5\xf3\x92\x0a\x68\x3c\xa7\x67\x73\xc3", 404 0x506693be 405 }, 406 { 407 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 408 0xcab11777 409 }, 410 { 411 "123456789", 412 0xCBF43926 413 } 414 }; 415 416 /* 417 * CRC32 test 418 */ 419 static int crc32_test(void) 420 { 421 unsigned i; 422 423 PJ_LOG(3, (THIS_FILE, " crc32 test..")); 424 425 for (i=0; i<PJ_ARRAY_SIZE(crc32_test_data); ++i) { 426 pj_uint32_t crc; 427 428 crc = pj_crc32_calc((pj_uint8_t*)crc32_test_data[i].input, 429 pj_ansi_strlen(crc32_test_data[i].input)); 430 if (crc != crc32_test_data[i].crc) { 431 PJ_LOG(3,(THIS_FILE, " error: crc mismatch on test %d", i)); 432 return -80; 433 } 434 } 435 return 0; 436 } 437 386 438 387 439 int encryption_test() … … 401 453 return rc; 402 454 455 rc = crc32_test(); 456 if (rc != 0) 457 return rc; 458 403 459 return 0; 404 460 } -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_msg.c
r1001 r1002 18 18 */ 19 19 #include <pjlib-util/stun_msg.h> 20 #include <pjlib-util/crc32.h> 20 21 #include <pjlib-util/errno.h> 22 #include <pjlib-util/hmac_sha1.h> 23 #include <pjlib-util/md5.h> 21 24 #include <pj/assert.h> 22 25 #include <pj/log.h> … … 26 29 #include <pj/string.h> 27 30 28 #define THIS_FILE 29 31 #define THIS_FILE "stun_msg.c" 32 #define STUN_XOR_FINGERPRINT 0x5354554eL 30 33 31 34 static const char *stun_method_names[] = … … 548 551 549 552 553 /* 554 * Create and add generic STUN IP address attribute to a STUN message. 555 */ 556 PJ_DEF(pj_status_t) 557 pj_stun_msg_add_generic_ip_addr_attr(pj_pool_t *pool, 558 pj_stun_msg *msg, 559 int attr_type, 560 pj_bool_t xor_ed, 561 unsigned addr_len, 562 const pj_sockaddr_t *addr) 563 { 564 pj_stun_generic_ip_addr_attr *attr; 565 pj_status_t status; 566 567 status = pj_stun_generic_ip_addr_attr_create(pool, attr_type, xor_ed, 568 addr_len, addr, &attr); 569 if (status != PJ_SUCCESS) 570 return status; 571 572 return pj_stun_msg_add_attr(msg, &attr->hdr); 573 } 574 550 575 static pj_status_t decode_generic_ip_addr_attr(pj_pool_t *pool, 551 576 const pj_uint8_t *buf, … … 659 684 660 685 686 /* 687 * Create and add STUN generic string attribute to the message. 688 */ 689 PJ_DEF(pj_status_t) 690 pj_stun_msg_add_generic_string_attr(pj_pool_t *pool, 691 pj_stun_msg *msg, 692 int attr_type, 693 const pj_str_t *value) 694 { 695 pj_stun_generic_string_attr *attr; 696 pj_status_t status; 697 698 status = pj_stun_generic_string_attr_create(pool, attr_type, value, 699 &attr); 700 if (status != PJ_SUCCESS) 701 return status; 702 703 return pj_stun_msg_add_attr(msg, &attr->hdr); 704 } 705 706 661 707 static pj_status_t decode_generic_string_attr(pj_pool_t *pool, 662 708 const pj_uint8_t *buf, … … 828 874 } 829 875 876 /* Create and add STUN generic 32bit value attribute to the message. */ 877 PJ_DEF(pj_status_t) 878 pj_stun_msg_add_generic_uint_attr(pj_pool_t *pool, 879 pj_stun_msg *msg, 880 int attr_type, 881 pj_uint32_t value) 882 { 883 pj_stun_generic_uint_attr *attr; 884 pj_status_t status; 885 886 status = pj_stun_generic_uint_attr_create(pool, attr_type, value, &attr); 887 if (status != PJ_SUCCESS) 888 return status; 889 890 return pj_stun_msg_add_attr(msg, &attr->hdr); 891 } 830 892 831 893 static pj_status_t decode_generic_uint_attr(pj_pool_t *pool, … … 1088 1150 pj_stun_unknown_attr_create(pj_pool_t *pool, 1089 1151 unsigned attr_cnt, 1090 pj_uint16_t attr_array[],1152 const pj_uint16_t attr_array[], 1091 1153 pj_stun_unknown_attr **p_attr) 1092 1154 { … … 1117 1179 1118 1180 1181 /* Create and add STUN UNKNOWN-ATTRIBUTES attribute to the message. */ 1182 PJ_DEF(pj_status_t) 1183 pj_stun_msg_add_unknown_attr(pj_pool_t *pool, 1184 pj_stun_msg *msg, 1185 unsigned attr_cnt, 1186 const pj_uint16_t attr_types[]) 1187 { 1188 pj_stun_unknown_attr *attr; 1189 pj_status_t status; 1190 1191 status = pj_stun_unknown_attr_create(pool, attr_cnt, attr_types, &attr); 1192 if (status != PJ_SUCCESS) 1193 return status; 1194 1195 return pj_stun_msg_add_attr(msg, &attr->hdr); 1196 } 1197 1119 1198 static pj_status_t decode_unknown_attr(pj_pool_t *pool, 1120 1199 const pj_uint8_t *buf, … … 1194 1273 pj_stun_binary_attr_create(pj_pool_t *pool, 1195 1274 int attr_type, 1275 const pj_uint8_t *data, 1276 unsigned length, 1196 1277 pj_stun_binary_attr **p_attr) 1197 1278 { … … 1203 1284 INIT_ATTR(attr, attr_type, sizeof(pj_stun_binary_attr)); 1204 1285 1286 if (data && length) { 1287 attr->length = length; 1288 attr->data = pj_pool_alloc(pool, length); 1289 pj_memcpy(attr->data, data, length); 1290 } 1291 1205 1292 *p_attr = attr; 1206 1293 1207 1294 return PJ_SUCCESS; 1295 } 1296 1297 1298 /* Create and add binary attr. */ 1299 PJ_DEF(pj_status_t) 1300 pj_stun_msg_add_binary_attr(pj_pool_t *pool, 1301 pj_stun_msg *msg, 1302 int attr_type, 1303 const pj_uint8_t *data, 1304 unsigned length) 1305 { 1306 pj_stun_binary_attr *attr; 1307 pj_status_t status; 1308 1309 status = pj_stun_binary_attr_create(pool, attr_type, 1310 data, length, &attr); 1311 if (status != PJ_SUCCESS) 1312 return status; 1313 1314 return pj_stun_msg_add_attr(msg, &attr->hdr); 1208 1315 } 1209 1316 … … 1325 1432 1326 1433 1434 PJ_INLINE(pj_uint16_t) GET_VAL16(const pj_uint8_t *pdu, unsigned pos) 1435 { 1436 pj_uint16_t val = (pj_uint16_t) ((pdu[pos] << 8) + pdu[pos+1]); 1437 return pj_ntohs(val); 1438 } 1439 1440 PJ_INLINE(pj_uint32_t) GET_VAL32(const pj_uint8_t *pdu, unsigned pos) 1441 { 1442 pj_uint32_t val = (pdu[pos+0] << 24) + 1443 (pdu[pos+1] << 16) + 1444 (pdu[pos+2] << 8) + 1445 (pdu[pos+3]); 1446 return pj_ntohl(val); 1447 } 1448 1449 1327 1450 /* 1328 1451 * Check that the PDU is potentially a valid STUN message. 1329 1452 */ 1330 PJ_DEF(pj_status_t) pj_stun_msg_check(const void*pdu, unsigned pdu_len,1453 PJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, unsigned pdu_len, 1331 1454 unsigned options) 1332 1455 { 1333 pj_stun_msg_hdr *hdr;1456 unsigned msg_len; 1334 1457 1335 1458 PJ_ASSERT_RETURN(pdu, PJ_EINVAL); … … 1338 1461 return PJLIB_UTIL_ESTUNINMSGLEN; 1339 1462 1340 PJ_UNUSED_ARG(options);1341 1342 hdr = (pj_stun_msg_hdr*) pdu;1343 1344 1463 /* First byte of STUN message is always 0x00 or 0x01. */ 1345 if ( (*(const char*)pdu) != 0x00 && (*(const char*)pdu)!= 0x01)1464 if (*pdu != 0x00 && *pdu != 0x01) 1346 1465 return PJLIB_UTIL_ESTUNINMSGTYPE; 1347 1466 … … 1349 1468 * a STUN message. 1350 1469 */ 1351 if ( pj_ntohl(hdr->magic) == PJ_STUN_MAGIC)1352 return PJ _SUCCESS;1470 if (GET_VAL32(pdu, 4) != PJ_STUN_MAGIC) 1471 return PJLIB_UTIL_ESTUNNOTMAGIC; 1353 1472 1354 1473 /* Check the PDU length */ 1355 if (pj_ntohs(hdr->length) > pdu_len) 1474 msg_len = GET_VAL16(pdu, 2); 1475 if ((msg_len > pdu_len) || 1476 ((options & PJ_STUN_IS_DATAGRAM) && msg_len != pdu_len)) 1477 { 1356 1478 return PJLIB_UTIL_ESTUNINMSGLEN; 1479 } 1480 1481 /* Check if FINGERPRINT attribute is present */ 1482 if (GET_VAL16(pdu, msg_len + 20) == PJ_STUN_ATTR_FINGERPRINT) { 1483 pj_uint16_t attr_len = GET_VAL16(pdu, msg_len + 22); 1484 pj_uint32_t fingerprint = GET_VAL32(pdu, msg_len + 24); 1485 pj_uint32_t crc; 1486 1487 if (attr_len != 4) 1488 return PJLIB_UTIL_ESTUNINATTRLEN; 1489 1490 crc = pj_crc32_calc(pdu, msg_len + 20); 1491 crc ^= STUN_XOR_FINGERPRINT; 1492 1493 if (crc != fingerprint) 1494 return PJLIB_UTIL_ESTUNFINGERPRINT; 1495 } 1357 1496 1358 1497 /* Could be a STUN message */ 1498 return PJ_SUCCESS; 1499 } 1500 1501 1502 /* Create error response */ 1503 PJ_DEF(pj_status_t) pj_stun_msg_create_response(pj_pool_t *pool, 1504 const pj_stun_msg *req_msg, 1505 unsigned err_code, 1506 const pj_str_t *err_msg, 1507 pj_stun_msg **p_response) 1508 { 1509 unsigned msg_type = req_msg->hdr.type; 1510 pj_stun_msg *response; 1511 pj_stun_error_code_attr *err_attr; 1512 pj_status_t status; 1513 1514 PJ_ASSERT_RETURN(pool && p_response, PJ_EINVAL); 1515 1516 PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(msg_type), 1517 PJLIB_UTIL_ESTUNINMSGTYPE); 1518 1519 /* Create response or error response */ 1520 if (err_code) 1521 msg_type |= PJ_STUN_ERROR_RESPONSE_BIT; 1522 else 1523 msg_type |= PJ_STUN_RESPONSE_BIT; 1524 1525 status = pj_stun_msg_create(pool, msg_type, req_msg->hdr.magic, 1526 req_msg->hdr.tsx_id, &response); 1527 if (status != PJ_SUCCESS) { 1528 return status; 1529 } 1530 1531 /* Add error code attribute */ 1532 if (err_code) { 1533 status = pj_stun_error_code_attr_create(pool, err_code, err_msg, 1534 &err_attr); 1535 if (status != PJ_SUCCESS) { 1536 return status; 1537 } 1538 1539 pj_stun_msg_add_attr(response, &err_attr->hdr); 1540 } 1541 1542 *p_response = response; 1359 1543 return PJ_SUCCESS; 1360 1544 } … … 1370 1554 pj_stun_msg **p_msg, 1371 1555 unsigned *p_parsed_len, 1372 unsigned *p_err_code, 1373 unsigned *p_uattr_cnt, 1374 pj_uint16_t uattr[]) 1556 pj_stun_msg **p_response) 1375 1557 { 1376 1558 … … 1385 1567 PJ_ASSERT_RETURN(sizeof(pj_stun_msg_hdr) == 20, PJ_EBUG); 1386 1568 1387 /* Application should have checked that this is a valid STUN msg */ 1388 PJ_ASSERT_RETURN((status=pj_stun_msg_check(pdu, pdu_len, options)) 1389 == PJ_SUCCESS, status); 1569 if (p_parsed_len) 1570 *p_parsed_len = 0; 1571 if (p_response) 1572 *p_response = NULL; 1573 1574 /* Check if this is a STUN message, if necessary */ 1575 if (options & PJ_STUN_CHECK_PACKET) { 1576 status = pj_stun_msg_check(pdu, pdu_len, options); 1577 if (status != PJ_SUCCESS) 1578 return status; 1579 } 1390 1580 1391 1581 /* Create the message, copy the header, and convert to host byte order */ … … 1399 1589 pdu_len -= sizeof(pj_stun_msg_hdr); 1400 1590 1401 if (p_err_code) 1402 *p_err_code = 0; 1591 /* No need to create response if this is not a request */ 1592 if (!PJ_STUN_IS_REQUEST(msg->hdr.type)) 1593 p_response = NULL; 1403 1594 1404 1595 /* Parse attributes */ … … 1416 1607 1417 1608 /* Check length */ 1418 if (pdu_len < attr_val_len) 1609 if (pdu_len < attr_val_len) { 1610 pj_str_t err_msg; 1611 char err_msg_buf[80]; 1612 1613 err_msg.ptr = err_msg_buf; 1614 err_msg.slen = pj_ansi_snprintf(err_msg_buf, sizeof(err_msg_buf), 1615 "Attribute %s has invalid length", 1616 pj_stun_get_attr_name(attr_type)); 1617 1618 PJ_LOG(4,(THIS_FILE, "Error decoding message: %.*s", 1619 (int)err_msg.slen, err_msg.ptr)); 1620 1621 if (p_response) { 1622 pj_stun_msg_create_response(pool, msg, 1623 PJ_STUN_STATUS_BAD_REQUEST, 1624 &err_msg, p_response); 1625 } 1419 1626 return PJLIB_UTIL_ESTUNINATTRLEN; 1627 } 1420 1628 1421 1629 /* Get the attribute descriptor */ … … 1427 1635 PJ_LOG(4,(THIS_FILE, "Unrecognized attribute type %d", 1428 1636 attr_type)); 1429 1430 /* Put to unrecognized attribute array */1431 if (p_uattr_cnt && uattr && uattr_cnt < *p_uattr_cnt) {1432 uattr[uattr_cnt++] = (pj_uint16_t)attr_type;1433 }1434 1637 1435 1638 /* Is this a fatal condition? */ … … 1438 1641 * if we don't understand the attribute. 1439 1642 */ 1440 if (p_err_code && *p_err_code == 0) 1441 *p_err_code = PJ_STUN_STATUS_UNKNOWN_ATTRIBUTE; 1643 if (p_response) { 1644 unsigned err_code = PJ_STUN_STATUS_UNKNOWN_ATTRIBUTE; 1645 1646 status = pj_stun_msg_create_response(pool, msg, 1647 err_code, NULL, 1648 p_response); 1649 if (status==PJ_SUCCESS) { 1650 pj_uint16_t d = (pj_uint16_t)attr_type; 1651 pj_stun_msg_add_unknown_attr(pool, *p_response, 1, &d); 1652 } 1653 } 1442 1654 1443 1655 return PJLIB_UTIL_ESTUNUNKNOWNATTR; … … 1446 1658 } else { 1447 1659 void *attr; 1660 char err_msg1[PJ_ERR_MSG_SIZE], 1661 err_msg2[PJ_ERR_MSG_SIZE]; 1448 1662 1449 1663 /* Parse the attribute */ … … 1451 1665 1452 1666 if (status != PJ_SUCCESS) { 1667 pj_strerror(status, err_msg1, sizeof(err_msg1)); 1668 1669 if (p_response) { 1670 pj_str_t e; 1671 1672 e.ptr = err_msg2; 1673 e.slen= pj_ansi_snprintf(err_msg2, sizeof(err_msg2), 1674 "%s in %s", 1675 err_msg1, 1676 pj_stun_get_attr_name(attr_type)); 1677 1678 pj_stun_msg_create_response(pool, msg, 1679 PJ_STUN_STATUS_BAD_REQUEST, 1680 &e, p_response); 1681 } 1682 1453 1683 PJ_LOG(4,(THIS_FILE, 1454 "Error parsing STUN attribute type %d: status=%d", 1455 attr_type, status)); 1684 "Error parsing STUN attribute %s: %s", 1685 pj_stun_get_attr_name(attr_type), 1686 err_msg1)); 1687 1456 1688 return status; 1457 1689 } 1458 1690 1459 1691 /* Make sure we have rooms for the new attribute */ 1460 if (msg->attr_count >= PJ_STUN_MAX_ATTR) 1692 if (msg->attr_count >= PJ_STUN_MAX_ATTR) { 1693 if (p_response) { 1694 pj_str_t e; 1695 1696 e = pj_str("Too many attributes"); 1697 pj_stun_msg_create_response(pool, msg, 1698 PJ_STUN_STATUS_BAD_REQUEST, 1699 &e, p_response); 1700 } 1461 1701 return PJLIB_UTIL_ESTUNTOOMANYATTR; 1702 } 1462 1703 1463 1704 /* Add the attribute */ … … 1470 1711 1471 1712 *p_msg = msg; 1472 1473 if (p_uattr_cnt)1474 *p_uattr_cnt = uattr_cnt;1475 1713 1476 1714 if (p_parsed_len) … … 1495 1733 pj_stun_username_attr *auname = NULL; 1496 1734 pj_stun_msg_integrity_attr *amsg_integrity = NULL; 1497 unsigned i; 1735 pj_stun_fingerprint_attr *afingerprint = NULL; 1736 unsigned printed; 1737 pj_status_t status; 1738 unsigned i, length; 1739 1498 1740 1499 1741 PJ_ASSERT_RETURN(msg && buf && buf_size, PJ_EINVAL); … … 1520 1762 const struct attr_desc *adesc; 1521 1763 const pj_stun_attr_hdr *attr_hdr; 1522 unsigned printed;1523 pj_status_t status;1524 1764 1525 1765 attr_hdr = msg->attr[i]; … … 1535 1775 pj_assert(auname == NULL); 1536 1776 auname = (pj_stun_username_attr*) attr_hdr; 1777 1537 1778 } else if (attr_hdr->type == PJ_STUN_ATTR_REALM) { 1538 1779 pj_assert(arealm == NULL); 1539 1780 arealm = (pj_stun_realm_attr*) attr_hdr; 1781 1782 } else if (attr_hdr->type == PJ_STUN_ATTR_FINGERPRINT) { 1783 afingerprint = (pj_stun_fingerprint_attr*) attr_hdr; 1784 break; 1540 1785 } 1541 1786 … … 1551 1796 } 1552 1797 1798 /* Calculate message integrity, if present */ 1553 1799 if (amsg_integrity != NULL) { 1554 PJ_TODO(IMPLEMENT_MSG_INTEGRITY); 1555 } 1556 1800 1801 pj_uint8_t md5_key_buf[16]; 1802 pj_str_t key; 1803 1804 /* MESSAGE-INTEGRITY must be the last attribute in the message, or 1805 * the last attribute before FINGERPRINT. 1806 */ 1807 if (i < msg->attr_count-2) { 1808 /* Should not happen for message generated by us */ 1809 pj_assert(PJ_FALSE); 1810 return PJLIB_UTIL_ESTUNMSGINT; 1811 1812 } else if (i == msg->attr_count-2) { 1813 if (msg->attr[i+1]->type != PJ_STUN_ATTR_FINGERPRINT) { 1814 /* Should not happen for message generated by us */ 1815 pj_assert(PJ_FALSE); 1816 return PJLIB_UTIL_ESTUNMSGINT; 1817 } else { 1818 afingerprint = (pj_stun_fingerprint_attr*) msg->attr[i+1]; 1819 } 1820 } 1821 1822 /* Must have USERNAME attribute */ 1823 if (auname == NULL) { 1824 /* Should not happen for message generated by us */ 1825 pj_assert(PJ_FALSE); 1826 return PJLIB_UTIL_ESTUNNOUSERNAME; 1827 } 1828 1829 /* Password must be specified */ 1830 PJ_ASSERT_RETURN(password, PJ_EINVAL); 1831 1832 /* Get the key to sign the message */ 1833 if (arealm == NULL ) { 1834 /* For short term credential, the key is the password */ 1835 key = *password; 1836 1837 } else { 1838 /* The 16-byte key for MESSAGE-INTEGRITY HMAC is formed by taking 1839 * the MD5 hash of the result of concatenating the following five 1840 * fields: (1) The username, with any quotes and trailing nulls 1841 * removed, (2) A single colon, (3) The realm, with any quotes and 1842 * trailing nulls removed, (4) A single colon, and (5) The 1843 * password, with any trailing nulls removed. 1844 */ 1845 pj_md5_context ctx; 1846 pj_str_t s; 1847 1848 pj_md5_init(&ctx); 1849 1850 #define REMOVE_QUOTE(s) if (s.slen && *s.ptr=='"') \ 1851 s.ptr++, s.slen--; \ 1852 if (s.slen && s.ptr[s.slen-1]=='"') \ 1853 s.slen--; 1854 1855 /* Add username */ 1856 s = auname->value; 1857 REMOVE_QUOTE(s); 1858 pj_md5_update(&ctx, (pj_uint8_t*)s.ptr, s.slen); 1859 1860 /* Add single colon */ 1861 pj_md5_update(&ctx, (pj_uint8_t*)":", 1); 1862 1863 /* Add realm */ 1864 s = arealm->value; 1865 REMOVE_QUOTE(s); 1866 pj_md5_update(&ctx, (pj_uint8_t*)s.ptr, s.slen); 1867 1868 #undef REMOVE_QUOTE 1869 1870 /* Another colon */ 1871 pj_md5_update(&ctx, (pj_uint8_t*)":", 1); 1872 1873 /* Add password */ 1874 pj_md5_update(&ctx, (pj_uint8_t*)password->ptr, password->slen); 1875 1876 /* Done */ 1877 pj_md5_final(&ctx, md5_key_buf); 1878 key.ptr = (char*) md5_key_buf; 1879 key.slen = 16; 1880 } 1881 1882 /* Calculate HMAC-SHA1 digest */ 1883 pj_hmac_sha1((pj_uint8_t*)buf, buf-start, 1884 (pj_uint8_t*)key.ptr, key.slen, 1885 amsg_integrity->hmac); 1886 1887 /* Put this attribute in the message */ 1888 status = encode_msg_integrity_attr(amsg_integrity, buf, buf_size, 1889 &printed); 1890 if (status != PJ_SUCCESS) 1891 return status; 1892 1893 buf += printed; 1894 buf_size -= printed; 1895 } 1896 1897 /* Calculate FINGERPRINT if present */ 1898 if (afingerprint != NULL) { 1899 afingerprint->value = pj_crc32_calc(start, buf-start); 1900 afingerprint->value ^= STUN_XOR_FINGERPRINT; 1901 1902 /* Put this attribute in the message */ 1903 status = encode_generic_uint_attr(afingerprint, buf, buf_size, 1904 &printed); 1905 if (status != PJ_SUCCESS) 1906 return status; 1907 1908 buf += printed; 1909 buf_size -= printed; 1910 } 1557 1911 1558 1912 /* Update the message length in the header. 1559 1913 * Note that length is not including the 20 bytes header. 1560 1914 */ 1561 hdr->length = (pj_uint16_t)((buf - start) - 20); 1562 hdr->length = pj_htons(hdr->length); 1915 length = (pj_uint16_t)((buf - start) - 20); 1916 /* hdr->length = pj_htons(length); */ 1917 *(buf+2) = (pj_uint8_t)((length >> 8) & 0x00FF); 1918 *(buf+3) = (pj_uint8_t)(length & 0x00FF); 1919 1563 1920 1564 1921 /* Done */ … … 1588 1945 } 1589 1946 1947 1948 /* Verify credential */ 1949 PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_stun_msg *msg, 1950 const pj_str_t *realm, 1951 const pj_str_t *username, 1952 const pj_str_t *password, 1953 unsigned options, 1954 pj_pool_t *pool, 1955 pj_stun_msg **p_response) 1956 { 1957 const pj_stun_msg_integrity_attr *amsgi; 1958 const pj_stun_username_attr *auser; 1959 const pj_stun_realm_attr *arealm; 1960 1961 PJ_ASSERT_RETURN(msg && password, PJ_EINVAL); 1962 PJ_ASSERT_RETURN(options==0, PJ_EINVAL); 1963 PJ_UNUSED_ARG(options); 1964 1965 if (p_response) 1966 *p_response = NULL; 1967 1968 /* First check that MESSAGE-INTEGRITY is present */ 1969 amsgi = (const pj_stun_msg_integrity_attr*) 1970 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 0); 1971 if (amsgi == NULL) { 1972 if (pool && p_response) { 1973 pj_status_t rc; 1974 1975 rc = pj_stun_msg_create_response(pool, msg, 1976 PJ_STUN_STATUS_UNAUTHORIZED, 1977 NULL, p_response); 1978 if (rc==PJ_SUCCESS && realm) { 1979 pj_stun_msg_add_generic_string_attr(pool, *p_response, 1980 PJ_STUN_ATTR_REALM, 1981 realm); 1982 } 1983 } 1984 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_UNAUTHORIZED); 1985 } 1986 1987 /* Next check that USERNAME is present */ 1988 auser = (const pj_stun_username_attr*) 1989 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USERNAME, 0); 1990 if (auser == NULL) { 1991 if (pool && p_response) { 1992 pj_status_t rc; 1993 1994 rc = pj_stun_msg_create_response(pool, msg, 1995 PJ_STUN_STATUS_MISSING_USERNAME, 1996 NULL, p_response); 1997 if (rc==PJ_SUCCESS && realm) { 1998 pj_stun_msg_add_generic_string_attr(pool, *p_response, 1999 PJ_STUN_ATTR_REALM, 2000 realm); 2001 } 2002 } 2003 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_MISSING_USERNAME); 2004 } 2005 2006 /* Check if username match */ 2007 if (username && pj_stricmp(&auser->value, username) != 0) { 2008 /* Username mismatch */ 2009 if (pool && p_response) { 2010 pj_status_t rc; 2011 2012 rc = pj_stun_msg_create_response(pool, msg, 2013 PJ_STUN_STATUS_WRONG_USERNAME, 2014 NULL, p_response); 2015 if (rc==PJ_SUCCESS && realm) { 2016 pj_stun_msg_add_generic_string_attr(pool, *p_response, 2017 PJ_STUN_ATTR_REALM, 2018 realm); 2019 } 2020 } 2021 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_WRONG_USERNAME); 2022 } 2023 2024 /* Next check that REALM is present */ 2025 arealm = (const pj_stun_realm_attr*) 2026 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_REALM, 0); 2027 if (realm != NULL && arealm == NULL) { 2028 /* Long term credential is required */ 2029 if (pool && p_response) { 2030 pj_status_t rc; 2031 2032 rc = pj_stun_msg_create_response(pool, msg, 2033 PJ_STUN_STATUS_MISSING_REALM, 2034 NULL, p_response); 2035 if (rc==PJ_SUCCESS) { 2036 pj_stun_msg_add_generic_string_attr(pool, *p_response, 2037 PJ_STUN_ATTR_REALM, 2038 realm); 2039 } 2040 } 2041 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_MISSING_REALM); 2042 2043 } else if (realm != NULL && arealm != NULL) { 2044 2045 2046 } else if (realm == NULL && arealm != NULL) { 2047 /* We want to use short term credential, but client uses long 2048 * term credential. The draft doesn't mention anything about 2049 * switching between long term and short term. 2050 */ 2051 PJ_TODO(SWITCHING_BETWEEN_SHORT_TERM_AND_LONG_TERM); 2052 } 2053 2054 PJ_TODO(CONTINUE_IMPLEMENTATION); 2055 2056 return PJ_SUCCESS; 2057 } 2058 2059 -
pjproject/trunk/pjlib-util/src/pjstun-client/stun_session.c
r996 r1002 485 485 /* Encode message */ 486 486 status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len, 487 0, &tdata->pkt_size);487 0, NULL, &tdata->pkt_size); 488 488 if (status != PJ_SUCCESS) { 489 489 LOG_ERR_(sess, "STUN encode() error", status); … … 541 541 unsigned *parsed_len) 542 542 { 543 pj_stun_msg *msg ;543 pj_stun_msg *msg, *response; 544 544 pj_pool_t *tmp_pool; 545 545 char *dump; … … 555 555 status = pj_stun_msg_decode(tmp_pool, (const pj_uint8_t*)packet, 556 556 pkt_size, 0, &msg, parsed_len, 557 NULL, NULL, NULL);557 &response); 558 558 if (status != PJ_SUCCESS) { 559 559 LOG_ERR_(sess, "STUN msg_decode() error", status); 560 if (response) { 561 PJ_TODO(SEND_RESPONSE); 562 } 560 563 pj_pool_release(tmp_pool); 561 564 return status; -
pjproject/trunk/pjlib-util/src/pjstun-srv/server_main.c
r996 r1002 52 52 pj_uint32_t msg_type = req_msg->hdr.type; 53 53 pj_stun_msg *response; 54 pj_stun_error_code_attr *err_attr; 55 pj_status_t status; 56 57 /* Create response or error response */ 58 if (err_code) 59 msg_type |= PJ_STUN_ERROR_RESPONSE_BIT; 60 else 61 msg_type |= PJ_STUN_RESPONSE_BIT; 62 63 status = pj_stun_msg_create(pool, msg_type, req_msg->hdr.magic, 64 req_msg->hdr.tsx_id, &response); 65 if (status != PJ_SUCCESS) { 54 pj_status_t status; 55 56 status = pj_stun_msg_create_response(pool, req_msg, err_code, NULL, 57 &response); 58 if (status != PJ_SUCCESS) 66 59 return status; 67 }68 69 /* Add error code attribute */70 if (err_code) {71 status = pj_stun_error_code_attr_create(pool, err_code, NULL,72 &err_attr);73 if (status != PJ_SUCCESS) {74 return status;75 }76 77 pj_stun_msg_add_attr(response, &err_attr->hdr);78 }79 60 80 61 /* Add unknown_attribute attributes if err_code is 420 */ … … 111 92 tx_pkt_len = sizeof(svc->tx_pkt); 112 93 status = pj_stun_msg_encode(msg, svc->tx_pkt, tx_pkt_len, 0, 113 &tx_pkt_len);94 NULL, &tx_pkt_len); 114 95 if (status != PJ_SUCCESS) 115 96 return status; … … 224 205 struct service *svc = (struct service *) pj_ioqueue_get_user_data(key); 225 206 pj_pool_t *pool = NULL; 226 pj_stun_msg *rx_msg; 227 unsigned err_code; 228 unsigned uattr_cnt; 229 pj_uint16_t uattr_types[16]; 207 pj_stun_msg *rx_msg, *response; 230 208 char dump[512]; 231 209 pj_status_t status; … … 236 214 pool = pj_pool_create(&server.cp.factory, "service", 4000, 4000, NULL); 237 215 238 err_code = 0;239 uattr_cnt = PJ_ARRAY_SIZE(uattr_types);240 216 rx_msg = NULL; 241 217 status = pj_stun_msg_decode(pool, svc->rx_pkt, bytes_read, 0, &rx_msg, 242 NULL, & err_code, &uattr_cnt, uattr_types);218 NULL, &response); 243 219 if (status != PJ_SUCCESS) { 244 220 server_perror(THIS_FILE, "STUN msg_decode() error", status); 245 if (err_code != 0 && rx_msg && PJ_STUN_IS_REQUEST(rx_msg->hdr.type)) { 246 err_respond(svc, pool, rx_msg, err_code, 247 uattr_cnt, uattr_types); 221 if (response) { 222 send_msg(svc, response); 248 223 } 249 224 goto next_read;
Note: See TracChangeset
for help on using the changeset viewer.