Changeset 1002


Ignore:
Timestamp:
Feb 26, 2007 2:33:14 AM (13 years ago)
Author:
bennylp
Message:

Added CRC32 code to pjlib-util, and implemented STUN FINGERPRINT and MESSAGE-INTEGRITY

Location:
pjproject/trunk/pjlib-util
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/build/Makefile

    r1001 r1002  
    2727export PJLIB_UTIL_SRCDIR = ../src/pjlib-util 
    2828export 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 \ 
    3030                hmac_md5.o hmac_sha1.o md5.o resolver.o \ 
    3131                scanner.o sha1.o string.o stun_simple.o \ 
  • pjproject/trunk/pjlib-util/build/pjlib_util.dsp

    r1001 r1002  
    8888# Begin Source File 
    8989 
     90SOURCE="..\src\pjlib-util\crc32.c" 
     91# End Source File 
     92# Begin Source File 
     93 
    9094SOURCE="..\src\pjlib-util\dns.c" 
    9195# End Source File 
     
    9397 
    9498SOURCE="..\src\pjlib-util\dns_dump.c" 
    95 # End Source File 
    96 # Begin Source File 
    97  
    98 SOURCE="..\src\pjlib-util-test\encryption.c" 
    9999# End Source File 
    100100# Begin Source File 
     
    187187 
    188188SOURCE="..\include\pjlib-util\config.h" 
     189# End Source File 
     190# Begin Source File 
     191 
     192SOURCE="..\include\pjlib-util\crc32.h" 
    189193# End Source File 
    190194# Begin Source File 
  • pjproject/trunk/pjlib-util/build/pjlib_util.vcproj

    r1001 r1002  
    176176                        > 
    177177                        <File 
     178                                RelativePath="..\src\pjlib-util\crc32.c" 
     179                                > 
     180                        </File> 
     181                        <File 
    178182                                RelativePath="..\src\pjlib-util\dns.c" 
    179183                                > 
     
    493497                        </File> 
    494498                        <File 
     499                                RelativePath="..\include\pjlib-util\crc32.h" 
     500                                > 
     501                        </File> 
     502                        <File 
    495503                                RelativePath="..\include\pjlib-util\dns.h" 
    496504                                > 
  • pjproject/trunk/pjlib-util/build/wince-evc4/pjlib_util_wince.vcp

    r1001 r1002  
    319319# Begin Source File 
    320320 
     321SOURCE="..\..\src\pjlib-util\crc32.c" 
     322 
     323!IF  "$(CFG)" == "pjlib_util_wince - Win32 (WCE emulator) Release" 
     324 
     325DEP_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 
     348DEP_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 
     371DEP_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 
     394DEP_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 
     417DEP_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 
     440DEP_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 
     463DEP_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 
     486DEP_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 
     509DEP_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 
     532DEP_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 
    321558SOURCE="..\..\src\pjlib-util\dns.c" 
    322559 
     
    66276864        "..\..\..\pjlib\include\pjlib.h"\ 
    66286865        "..\..\include\pjlib-util\config.h"\ 
     6866        "..\..\include\pjlib-util\crc32.h"\ 
    66296867        "..\..\include\pjlib-util\errno.h"\ 
     6868        "..\..\include\pjlib-util\hmac_sha1.h"\ 
     6869        "..\..\include\pjlib-util\md5.h"\ 
    66306870        "..\..\include\pjlib-util\stun_msg.h"\ 
    66316871        "..\..\include\pjlib-util\types.h"\ 
     
    1077811018# Begin Source File 
    1077911019 
     11020SOURCE="..\..\include\pjlib-util\crc32.h" 
     11021# End Source File 
     11022# Begin Source File 
     11023 
    1078011024SOURCE="..\..\include\pjlib-util\dns.h" 
    1078111025# End Source File 
  • pjproject/trunk/pjlib-util/include/pjlib-util.h

    r1001 r1002  
    3333 
    3434/* Crypto */ 
     35#include <pjlib-util/crc32.h> 
    3536#include <pjlib-util/hmac_md5.h> 
    3637#include <pjlib-util/hmac_sha1.h> 
  • pjproject/trunk/pjlib-util/include/pjlib-util/errno.h

    r992 r1002  
    9494 */ 
    9595#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 */ 
    96106 
    97107 
     
    267277/** 
    268278 * @hideinitializer 
    269  * Invalid socket address length. 
     279 * Invalid STUN socket address length. 
    270280 */ 
    271281#define PJLIB_UTIL_ESTUNINADDRLEN   (PJLIB_UTIL_ERRNO_START+113)/* 320113 */ 
    272282/** 
    273283 * @hideinitializer 
    274  * IPv6 attribute not supported 
     284 * STUN IPv6 attribute not supported 
    275285 */ 
    276286#define PJLIB_UTIL_ESTUNIPV6NOTSUPP (PJLIB_UTIL_ERRNO_START+113)/* 320113 */ 
     
    282292/** 
    283293 * @hideinitializer 
    284  * Transaction ID mismatch. 
     294 * STUN transaction ID mismatch. 
    285295 */ 
    286296#define PJLIB_UTIL_ESTUNINVALIDID   (PJLIB_UTIL_ERRNO_START+115)/* 320115 */ 
     
    290300 */ 
    291301#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) 
    295319 
    296320 
  • pjproject/trunk/pjlib-util/include/pjlib-util/stun_msg.h

    r1001 r1002  
    602602     * The raw data. 
    603603     */ 
    604     char               *data; 
     604    pj_uint8_t         *data; 
    605605 
    606606} pj_stun_binary_attr; 
     
    10471047 
    10481048 
     1049/** STUN decoding options */ 
     1050enum 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 
    10491066/** 
    10501067 * Get STUN message method name. 
     
    10881105 
    10891106/** 
    1090  * Create a blank STUN message. 
     1107 * Create a generic STUN message. 
    10911108 * 
    10921109 * @param pool          Pool to create the STUN message. 
     
    11061123                                        pj_stun_msg **p_msg); 
    11071124 
     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 */ 
     1141PJ_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 
    11081147 
    11091148/** 
     
    11191158                                          pj_stun_attr_hdr *attr); 
    11201159 
    1121  
    1122 /** 
    1123  * Check that the PDU is potentially a valid STUN message. This function 
    1124  * is useful when application needs to multiplex STUN packets with other 
    1125  * application traffic. When this function returns PJ_SUCCESS, there is a 
    1126  * 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 message  
    1129  * 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 STUN 
    1136  *                      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 have 
    1151  *                      been parsed for the STUN message. This is useful 
    1152  *                      when the packet is received over stream oriented 
    1153  *                      transport. 
    1154  * @param p_err_code    Optional pointer to receive STUN error code when 
    1155  *                      parsing failed. 
    1156  * @param uattr_cnt     Optional pointer to specify the number of elements 
    1157  *                      in uattr array. On return, this will be filled with 
    1158  *                      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[]); 
    11721160 
    11731161/** 
     
    12061194                                        unsigned *p_msg_len); 
    12071195 
     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 */ 
     1215PJ_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 */ 
     1240PJ_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 */ 
     1276PJ_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 
    12081284 
    12091285/** 
     
    12441320 
    12451321/** 
    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. 
    12481325 * 
    12491326 * @param pool          The pool to allocate memory from. 
     
    12671344 
    12681345/** 
     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 */ 
     1360PJ_DECL(pj_status_t)  
     1361pj_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/** 
    12691369 * Create a STUN generic string attribute. 
    12701370 * 
     
    12821382                                   pj_stun_generic_string_attr **p_attr); 
    12831383 
     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 */ 
     1394PJ_DECL(pj_status_t)  
     1395pj_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); 
    12841399 
    12851400/** 
     
    12991414                                 pj_stun_generic_uint_attr **p_attr); 
    13001415 
     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 */ 
     1426PJ_DECL(pj_status_t)  
     1427pj_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 
    13011432 
    13021433/** 
     
    13111442pj_stun_msg_integrity_attr_create(pj_pool_t *pool, 
    13121443                                  pj_stun_msg_integrity_attr **p_attr); 
    1313  
    13141444 
    13151445/** 
     
    13321462 
    13331463/** 
    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. 
    13351466 * 
    13361467 * @param pool          The pool to allocate memory from. 
     
    13441475pj_stun_unknown_attr_create(pj_pool_t *pool, 
    13451476                            unsigned attr_cnt, 
    1346                             pj_uint16_t attr[], 
     1477                            const pj_uint16_t attr[], 
    13471478                            pj_stun_unknown_attr **p_attr); 
    13481479 
    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 */ 
     1490PJ_DECL(pj_status_t)  
     1491pj_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. 
    13521498 * 
    13531499 * @param pool          The pool to allocate memory from. 
    13541500 * @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. 
    13551505 * @param p_attr        Pointer to receive the attribute. 
    13561506 * 
     
    13601510pj_stun_binary_attr_create(pj_pool_t *pool, 
    13611511                           int attr_type, 
     1512                           const pj_uint8_t *data, 
     1513                           unsigned length, 
    13621514                           pj_stun_binary_attr **p_attr); 
    13631515 
     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 */ 
     1530PJ_DECL(pj_status_t) 
     1531pj_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 
    13641537 
    13651538/** 
  • pjproject/trunk/pjlib-util/src/pjlib-util-test/encryption.c

    r1001 r1002  
    384384} 
    385385 
     386/* CRC32 test data, generated from crc32 test on a Linux box */ 
     387struct 
     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 */ 
     419static 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 
    386438 
    387439int encryption_test() 
     
    401453        return rc; 
    402454 
     455    rc = crc32_test(); 
     456    if (rc != 0) 
     457        return rc; 
     458 
    403459    return 0; 
    404460} 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_msg.c

    r1001 r1002  
    1818 */ 
    1919#include <pjlib-util/stun_msg.h> 
     20#include <pjlib-util/crc32.h> 
    2021#include <pjlib-util/errno.h> 
     22#include <pjlib-util/hmac_sha1.h> 
     23#include <pjlib-util/md5.h> 
    2124#include <pj/assert.h> 
    2225#include <pj/log.h> 
     
    2629#include <pj/string.h> 
    2730 
    28 #define THIS_FILE   "stun_msg.c" 
    29  
     31#define THIS_FILE               "stun_msg.c" 
     32#define STUN_XOR_FINGERPRINT    0x5354554eL 
    3033 
    3134static const char *stun_method_names[] =  
     
    548551 
    549552 
     553/* 
     554 * Create and add generic STUN IP address attribute to a STUN message. 
     555 */ 
     556PJ_DEF(pj_status_t)  
     557pj_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 
    550575static pj_status_t decode_generic_ip_addr_attr(pj_pool_t *pool,  
    551576                                               const pj_uint8_t *buf,  
     
    659684 
    660685 
     686/* 
     687 * Create and add STUN generic string attribute to the message. 
     688 */ 
     689PJ_DEF(pj_status_t)  
     690pj_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 
    661707static pj_status_t decode_generic_string_attr(pj_pool_t *pool,  
    662708                                              const pj_uint8_t *buf,  
     
    828874} 
    829875 
     876/* Create and add STUN generic 32bit value attribute to the message. */ 
     877PJ_DEF(pj_status_t)  
     878pj_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} 
    830892 
    831893static pj_status_t decode_generic_uint_attr(pj_pool_t *pool,  
     
    10881150pj_stun_unknown_attr_create(pj_pool_t *pool, 
    10891151                            unsigned attr_cnt, 
    1090                             pj_uint16_t attr_array[], 
     1152                            const pj_uint16_t attr_array[], 
    10911153                            pj_stun_unknown_attr **p_attr) 
    10921154{ 
     
    11171179 
    11181180 
     1181/* Create and add STUN UNKNOWN-ATTRIBUTES attribute to the message. */ 
     1182PJ_DEF(pj_status_t)  
     1183pj_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 
    11191198static pj_status_t decode_unknown_attr(pj_pool_t *pool,  
    11201199                                       const pj_uint8_t *buf,  
     
    11941273pj_stun_binary_attr_create(pj_pool_t *pool, 
    11951274                           int attr_type, 
     1275                           const pj_uint8_t *data, 
     1276                           unsigned length, 
    11961277                           pj_stun_binary_attr **p_attr) 
    11971278{ 
     
    12031284    INIT_ATTR(attr, attr_type, sizeof(pj_stun_binary_attr)); 
    12041285 
     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 
    12051292    *p_attr = attr; 
    12061293 
    12071294    return PJ_SUCCESS; 
     1295} 
     1296 
     1297 
     1298/* Create and add binary attr. */ 
     1299PJ_DEF(pj_status_t) 
     1300pj_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); 
    12081315} 
    12091316 
     
    13251432 
    13261433 
     1434PJ_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 
     1440PJ_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 
    13271450/* 
    13281451 * Check that the PDU is potentially a valid STUN message. 
    13291452 */ 
    1330 PJ_DEF(pj_status_t) pj_stun_msg_check(const void *pdu, unsigned pdu_len, 
     1453PJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, unsigned pdu_len, 
    13311454                                      unsigned options) 
    13321455{ 
    1333     pj_stun_msg_hdr *hdr; 
     1456    unsigned msg_len; 
    13341457 
    13351458    PJ_ASSERT_RETURN(pdu, PJ_EINVAL); 
     
    13381461        return PJLIB_UTIL_ESTUNINMSGLEN; 
    13391462 
    1340     PJ_UNUSED_ARG(options); 
    1341  
    1342     hdr = (pj_stun_msg_hdr*) pdu; 
    1343  
    13441463    /* 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) 
    13461465        return PJLIB_UTIL_ESTUNINMSGTYPE; 
    13471466 
     
    13491468     * a STUN message. 
    13501469     */ 
    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; 
    13531472 
    13541473    /* 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    { 
    13561478        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    } 
    13571496 
    13581497    /* Could be a STUN message */ 
     1498    return PJ_SUCCESS; 
     1499} 
     1500 
     1501 
     1502/* Create error response */ 
     1503PJ_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; 
    13591543    return PJ_SUCCESS; 
    13601544} 
     
    13701554                                       pj_stun_msg **p_msg, 
    13711555                                       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) 
    13751557{ 
    13761558     
     
    13851567    PJ_ASSERT_RETURN(sizeof(pj_stun_msg_hdr) == 20, PJ_EBUG); 
    13861568 
    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    } 
    13901580 
    13911581    /* Create the message, copy the header, and convert to host byte order */ 
     
    13991589    pdu_len -= sizeof(pj_stun_msg_hdr); 
    14001590 
    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; 
    14031594 
    14041595    /* Parse attributes */ 
     
    14161607 
    14171608        /* 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            } 
    14191626            return PJLIB_UTIL_ESTUNINATTRLEN; 
     1627        } 
    14201628 
    14211629        /* Get the attribute descriptor */ 
     
    14271635            PJ_LOG(4,(THIS_FILE, "Unrecognized attribute type %d",  
    14281636                      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             } 
    14341637 
    14351638            /* Is this a fatal condition? */ 
     
    14381641                 * if we don't understand the attribute. 
    14391642                 */ 
    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                } 
    14421654 
    14431655                return PJLIB_UTIL_ESTUNUNKNOWNATTR; 
     
    14461658        } else { 
    14471659            void *attr; 
     1660            char err_msg1[PJ_ERR_MSG_SIZE], 
     1661                 err_msg2[PJ_ERR_MSG_SIZE]; 
    14481662 
    14491663            /* Parse the attribute */ 
     
    14511665 
    14521666            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 
    14531683                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 
    14561688                return status; 
    14571689            } 
    14581690             
    14591691            /* 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                } 
    14611701                return PJLIB_UTIL_ESTUNTOOMANYATTR; 
     1702            } 
    14621703 
    14631704            /* Add the attribute */ 
     
    14701711 
    14711712    *p_msg = msg; 
    1472  
    1473     if (p_uattr_cnt) 
    1474         *p_uattr_cnt = uattr_cnt; 
    14751713 
    14761714    if (p_parsed_len) 
     
    14951733    pj_stun_username_attr *auname = NULL; 
    14961734    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 
    14981740 
    14991741    PJ_ASSERT_RETURN(msg && buf && buf_size, PJ_EINVAL); 
     
    15201762        const struct attr_desc *adesc; 
    15211763        const pj_stun_attr_hdr *attr_hdr; 
    1522         unsigned printed; 
    1523         pj_status_t status; 
    15241764 
    15251765        attr_hdr = msg->attr[i]; 
     
    15351775            pj_assert(auname == NULL); 
    15361776            auname = (pj_stun_username_attr*) attr_hdr; 
     1777 
    15371778        } else if (attr_hdr->type == PJ_STUN_ATTR_REALM) { 
    15381779            pj_assert(arealm == NULL); 
    15391780            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; 
    15401785        } 
    15411786 
     
    15511796    } 
    15521797 
     1798    /* Calculate message integrity, if present */ 
    15531799    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    } 
    15571911 
    15581912    /* Update the message length in the header.  
    15591913     * Note that length is not including the 20 bytes header. 
    15601914     */ 
    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 
    15631920 
    15641921    /* Done */ 
     
    15881945} 
    15891946 
     1947 
     1948/* Verify credential */ 
     1949PJ_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  
    485485    /* Encode message */ 
    486486    status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len, 
    487                                 0, &tdata->pkt_size); 
     487                                0, NULL, &tdata->pkt_size); 
    488488    if (status != PJ_SUCCESS) { 
    489489        LOG_ERR_(sess, "STUN encode() error", status); 
     
    541541                                              unsigned *parsed_len) 
    542542{ 
    543     pj_stun_msg *msg; 
     543    pj_stun_msg *msg, *response; 
    544544    pj_pool_t *tmp_pool; 
    545545    char *dump; 
     
    555555    status = pj_stun_msg_decode(tmp_pool, (const pj_uint8_t*)packet, 
    556556                                pkt_size, 0, &msg, parsed_len, 
    557                                 NULL, NULL, NULL); 
     557                                &response); 
    558558    if (status != PJ_SUCCESS) { 
    559559        LOG_ERR_(sess, "STUN msg_decode() error", status); 
     560        if (response) { 
     561            PJ_TODO(SEND_RESPONSE); 
     562        } 
    560563        pj_pool_release(tmp_pool); 
    561564        return status; 
  • pjproject/trunk/pjlib-util/src/pjstun-srv/server_main.c

    r996 r1002  
    5252    pj_uint32_t msg_type = req_msg->hdr.type; 
    5353    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) 
    6659        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     } 
    7960 
    8061    /* Add unknown_attribute attributes if err_code is 420 */ 
     
    11192    tx_pkt_len = sizeof(svc->tx_pkt); 
    11293    status = pj_stun_msg_encode(msg, svc->tx_pkt, tx_pkt_len, 0, 
    113                                 &tx_pkt_len); 
     94                                NULL, &tx_pkt_len); 
    11495    if (status != PJ_SUCCESS) 
    11596        return status; 
     
    224205    struct service *svc = (struct service *) pj_ioqueue_get_user_data(key); 
    225206    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; 
    230208    char dump[512]; 
    231209    pj_status_t status; 
     
    236214    pool = pj_pool_create(&server.cp.factory, "service", 4000, 4000, NULL); 
    237215 
    238     err_code = 0; 
    239     uattr_cnt = PJ_ARRAY_SIZE(uattr_types); 
    240216    rx_msg = NULL; 
    241217    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); 
    243219    if (status != PJ_SUCCESS) { 
    244220        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); 
    248223        } 
    249224        goto next_read; 
Note: See TracChangeset for help on using the changeset viewer.