Changeset 990


Ignore:
Timestamp:
Feb 20, 2007 9:58:36 PM (17 years ago)
Author:
bennylp
Message:

Checked in latest changes in iceproject branch before merging in to the trunk

Location:
pjproject/branches/iceproject/pjlib-util
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/iceproject/pjlib-util/build/pjlib_util.dsp

    r929 r990  
    138138# Begin Source File 
    139139 
     140SOURCE="..\src\pjlib-util\stun_server.c" 
     141# End Source File 
     142# Begin Source File 
     143 
    140144SOURCE="..\src\pjlib-util\stun_simple.c" 
    141145# PROP Exclude_From_Build 1 
  • pjproject/branches/iceproject/pjlib-util/build/pjlib_util.dsw

    r65 r990  
    2020Package=<5> 
    2121{{{ 
    22     begin source code control 
    23     "$/pjproject/pjlib/build", UIAAAAAA 
    24     ..\..\pjlib\build 
    25     end source code control 
    2622}}} 
    2723 
     
    6258############################################################################### 
    6359 
     60Project: "pjstun_srv"=".\pjstun_srv.dsp" - Package Owner=<4> 
     61 
     62Package=<5> 
     63{{{ 
     64}}} 
     65 
     66Package=<4> 
     67{{{ 
     68    Begin Project Dependency 
     69    Project_Dep_Name pjlib 
     70    End Project Dependency 
     71    Begin Project Dependency 
     72    Project_Dep_Name pjlib_util 
     73    End Project Dependency 
     74}}} 
     75 
     76############################################################################### 
     77 
    6478Global: 
    6579 
  • pjproject/branches/iceproject/pjlib-util/include/pjlib-util.h

    r913 r990  
    3232#include <pjlib-util/scanner.h> 
    3333//#include <pjlib-util/stun.h> 
     34#include <pjlib-util/stun_endpoint.h> 
     35#include <pjlib-util/stun_msg.h> 
     36#include <pjlib-util/stun_server.h> 
     37#include <pjlib-util/stun_transaction.h> 
    3438#include <pjlib-util/xml.h> 
    3539 
  • pjproject/branches/iceproject/pjlib-util/include/pjlib-util/errno.h

    r913 r990  
    119119 */ 
    120120#define PJLIB_UTIL_ESTUNINVALIDID   (PJLIB_UTIL_ERRNO_START+16) /* 320016 */ 
     121/** 
     122 * @hideinitializer 
     123 * Unable to find handler for the request. 
     124 */ 
     125#define PJLIB_UTIL_ESTUNNOHANDLER   (PJLIB_UTIL_ERRNO_START+17) /* 320017 */ 
    121126 
    122127 
  • pjproject/branches/iceproject/pjlib-util/include/pjlib-util/stun_msg.h

    r929 r990  
    179179 * Determine if the message type is a request. 
    180180 */ 
    181 #define PJ_STUN_IS_REQUEST(msg_type)    (((msg_type) & 0x0F00) == 0x0000) 
     181#define PJ_STUN_IS_REQUEST(msg_type)    (((msg_type) & 0x0110) == 0x0000) 
    182182 
    183183 
     
    185185 * Determine if the message type is a response. 
    186186 */ 
    187 #define PJ_STUN_IS_RESPONSE(msg_type)   (((msg_type) & 0x0F00) == 0x0100) 
    188  
     187#define PJ_STUN_IS_RESPONSE(msg_type)   (((msg_type) & 0x0110) == 0x0100) 
     188 
     189 
     190/** 
     191 * The response bit in the message type. 
     192 */ 
     193#define PJ_STUN_RESPONSE_BIT            (0x0100) 
    189194 
    190195/** 
    191196 * Determine if the message type is an error response. 
    192197 */ 
    193 #define PJ_STUN_IS_ERROR_RESPONSE(msg_type) (((msg_type) & 0x0FF0) == 0x0110) 
    194  
    195  
    196 #if 0 
     198#define PJ_STUN_IS_ERROR_RESPONSE(msg_type) (((msg_type) & 0x0110) == 0x0110) 
     199 
     200 
     201/** 
     202 * The error response bit in the message type. 
     203 */ 
     204#define PJ_STUN_ERROR_RESPONSE_BIT      (0x0110) 
     205 
     206 
    197207/** 
    198208 * Determine if the message type is an indication message. 
    199209 */ 
    200 #define PJ_STUN_IS_INDICATION(msg_type) (((msg_type) & 0x0FF0) == 0x0010) 
    201 #endif 
     210#define PJ_STUN_IS_INDICATION(msg_type) (((msg_type) & 0x0110) == 0x0010) 
     211 
     212 
     213/** 
     214 * The error response bit in the message type. 
     215 */ 
     216#define PJ_STUN_INDICATION_BIT          (0x0010) 
    202217 
    203218 
     
    325340    PJ_STUN_ATTR_NONCE              = 0x0015,/**< NONCE attribute.          */ 
    326341    PJ_STUN_ATTR_RELAY_ADDRESS      = 0x0016,/**< RELAY-ADDRESS attribute.  */ 
     342    PJ_STUN_ATTR_REQUESTED_ADDR_TYPE= 0x0017,/**< REQUESTED-ADDRESS-TYPE    */ 
    327343    PJ_STUN_ATTR_REQUESTED_PORT_PROPS=0x0018,/**< REQUESTED-PORT-PROPS      */ 
    328344    PJ_STUN_ATTR_REQUESTED_TRANSPORT= 0x0019,/**< REQUESTED-TRANSPORT       */ 
     
    330346    PJ_STUN_ATTR_TIMER_VAL          = 0x0021,/**< TIMER-VAL attribute.      */ 
    331347    PJ_STUN_ATTR_REQUESTED_IP       = 0x0022,/**< REQUESTED-IP attribute    */ 
     348    PJ_STUN_ATTR_XOR_REFLECTED_FROM = 0x0023,/**< XOR-REFLECTED-FROM        */ 
     349    PJ_STUN_ATTR_PRIORITY           = 0x0024,/**< PRIORITY                  */ 
     350    PJ_STUN_ATTR_USE_CANDIDATE      = 0x0025,/**< USE-CANDIDATE             */ 
     351    PJ_STUN_ATTR_XOR_INTERNAL_ADDR  = 0x0026,/**< XOR-INTERNAL-ADDRESS      */ 
     352 
     353    PJ_STUN_ATTR_END_MANDATORY_ATTR, 
     354 
     355    PJ_STUN_ATTR_START_EXTENDED_ATTR= 0x8021, 
     356 
    332357    PJ_STUN_ATTR_FINGERPRINT        = 0x8021,/**< FINGERPRINT attribute.    */ 
    333358    PJ_STUN_ATTR_SERVER             = 0x8022,/**< SERVER attribute.         */ 
    334359    PJ_STUN_ATTR_ALTERNATE_SERVER   = 0x8023,/**< ALTERNATE-SERVER.         */ 
    335     PJ_STUN_ATTR_REFRESH_INTERVAL   = 0x8024 /**< REFRESH-INTERVAL.         */ 
     360    PJ_STUN_ATTR_REFRESH_INTERVAL   = 0x8024,/**< REFRESH-INTERVAL.         */ 
     361 
     362    PJ_STUN_ATTR_END_EXTENDED_ATTR 
     363 
    336364} pj_stun_attr_type; 
    337365 
    338366 
    339367/** 
    340  * STUN error codes. 
     368 * STUN error codes, which goes into STUN ERROR-CODE attribute. 
    341369 */ 
    342370typedef enum pj_stun_status 
     
    491519 
    492520    /** 
    493      * The first 8 bits of the attribute are ignored for the purposes 
    494      * of aligning parameters on natural 32 bit boundaries. 
    495      */ 
    496     pj_uint8_t          ignored; 
    497  
    498     /** 
    499      * The address family can take on the following values: 
    500      *  
    501      * 0x01:IPv4 
    502      * 0x02:IPv6 
    503      */ 
    504     pj_uint8_t          family; 
    505  
    506     /** 
    507      * Port number. 
    508      */ 
    509     pj_uint16_t         port; 
    510  
    511     /** 
    512      * The address. 
     521     * The socket address (as a union) 
    513522     */ 
    514523    union { 
    515  
    516         /** IPv4 address. */ 
    517         pj_uint32_t     ipv4; 
    518  
    519         /** IPv6 address. */ 
    520         char            ipv6[1]; 
    521  
     524        pj_sockaddr         addr;   /**< Generic socket address.    */ 
     525        pj_sockaddr_in      ipv4;   /**< IPv4 socket address.       */ 
     526        pj_sockaddr_in6     ipv6;   /**< IPv6 socket address.       */ 
    522527    } addr; 
    523528 
    524529} pj_stun_generic_ip_addr_attr; 
     530 
     531 
     532/** 
     533 * This structure represents a generic STUN attributes with no payload, 
     534 * and it is used for example by ICE USE-CANDIDATE attribute. 
     535 */ 
     536typedef struct pj_stun_empty_attr 
     537{ 
     538    /** 
     539     * Standard STUN attribute header. 
     540     */ 
     541    pj_stun_attr_hdr    hdr; 
     542 
     543} pj_stun_empty_attr; 
    525544 
    526545 
     
    900919 
    901920/** 
     921 * This describes the REQUESTED-ADDRESS-TYPE attribute. 
     922 * The REQUESTED-ADDRESS-TYPE attribute is used by clients to request 
     923 * the allocation of a specific address type from a server.  The 
     924 * following is the format of the REQUESTED-ADDRESS-TYPE attribute. 
     925 
     926 \verbatim 
     927 
     928      0                   1                   2                   3 
     929      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
     930     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
     931     |        Family                 |           Reserved            | 
     932     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
     933 
     934 \endverbatim 
     935 */ 
     936typedef struct pj_stun_generic_uint_attr pj_stun_requested_addr_type; 
     937 
     938/** 
    902939 * This describes the STUN REQUESTED-PORT-PROPS attribute. 
    903940 * This attribute allows the client to request certain properties for 
     
    936973typedef struct pj_stun_generic_ip_addr_attr pj_stun_requested_ip_attr; 
    937974 
     975/** 
     976 * This describes the XOR-REFLECTED-FROM attribute, as described by 
     977 * draft-macdonald-behave-nat-behavior-discovery-00. 
     978 * The XOR-REFLECTED-FROM attribute is used in place of the REFLECTED- 
     979 * FROM attribute.  It provides the same information, but because the 
     980 * NAT's public address is obfuscated through the XOR function, It can 
     981 * pass through a NAT that would otherwise attempt to translate it to 
     982 * the private network address.  XOR-REFLECTED-FROM has identical syntax 
     983 * to XOR-MAPPED-ADDRESS. 
     984 */ 
     985typedef struct pj_stun_generic_ip_addr_attr pj_stun_xor_reflected_from_attr; 
     986 
     987/** 
     988 * This describes the PRIORITY attribute from draft-ietf-mmusic-ice-13. 
     989 * The PRIORITY attribute indicates the priority that is to be 
     990 * associated with a peer reflexive candidate, should one be discovered 
     991 * by this check.  It is a 32 bit unsigned integer, and has an attribute 
     992 * type of 0x0024. 
     993 */ 
     994typedef struct pj_stun_generic_uint_attr pj_stun_priority_attr; 
     995 
     996/** 
     997 * This describes the USE-CANDIDATE attribute from draft-ietf-mmusic-ice-13. 
     998 * The USE-CANDIDATE attribute indicates that the candidate pair 
     999 * resulting from this check should be used for transmission of media. 
     1000 * The attribute has no content (the Length field of the attribute is 
     1001 * zero); it serves as a flag. 
     1002 */ 
     1003typedef struct pj_stun_empty_attr pj_stun_use_candidate_attr; 
     1004 
     1005/** 
     1006 * This structure describes STUN XOR-INTERNAL-ADDRESS attribute from 
     1007 * draft-wing-behave-nat-control-stun-usage-00. 
     1008 * This attribute MUST be present in a Binding Response and may be used 
     1009 * in other responses as well.  This attribute is necessary to allow a 
     1010 * STUN client to 'walk backwards' and communicate directly with all of 
     1011 * the STUN-aware NATs along the path. 
     1012 */ 
     1013typedef pj_stun_generic_ip_addr_attr pj_stun_xor_internal_addr_attr; 
    9381014 
    9391015/** 
     
    9871063 * @param pool          Pool to create the STUN message. 
    9881064 * @param msg_type      The 14bit message type. 
     1065 * @param magic         Magic value to be put to the mesage; for requests, 
     1066 *                      the value should be PJ_STUN_MAGIC. 
    9891067 * @param tsx_id        Optional transaction ID, or NULL to let the 
    9901068 *                      function generates a random transaction ID. 
     
    9951073PJ_DECL(pj_status_t) pj_stun_msg_create(pj_pool_t *pool, 
    9961074                                        unsigned msg_type, 
     1075                                        pj_uint32_t magic, 
    9971076                                        const pj_uint8_t tsx_id[12], 
    9981077                                        pj_stun_msg **p_msg); 
     1078 
     1079 
     1080/** 
     1081 * Add STUN attribute to STUN message. 
     1082 * 
     1083 * @param msg           The STUN message. 
     1084 * @param attr          The STUN attribute to be added to the message. 
     1085 * 
     1086 * @return              PJ_SUCCESS on success, or PJ_ETOOMANY if there are 
     1087 *                      already too many attributes in the message. 
     1088 */ 
     1089PJ_DECL(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg, 
     1090                                          pj_stun_attr_hdr *attr); 
     1091 
    9991092 
    10001093/** 
     
    10921185 * @param pool          The pool to allocate memory from. 
    10931186 * @param attr_type     Attribute type. 
    1094  * @param ip_addr       IP address, in host byte order. 
    1095  * @param port          Port number, in host byte order. 
     1187 * @param xor_ed        If non-zero, the port and address will be XOR-ed 
     1188 *                      with magic, to make the XOR-MAPPED-ADDRESS attribute. 
     1189 * @param addr_len      Length of \a addr parameter. 
     1190 * @param addr          A pj_sockaddr_in or pj_sockaddr_in6 structure. 
    10961191 * @param p_attr        Pointer to receive the attribute. 
    10971192 * 
     
    11001195PJ_DECL(pj_status_t)  
    11011196pj_stun_generic_ip_addr_attr_create(pj_pool_t *pool, 
    1102                                     int attr_type, 
    1103                                     pj_uint32_t ip_addr, 
    1104                                     int port, 
     1197                                    int attr_type,  
     1198                                    pj_bool_t xor_ed, 
     1199                                    unsigned addr_len, 
     1200                                    const pj_sockaddr_t *addr, 
    11051201                                    pj_stun_generic_ip_addr_attr **p_attr); 
    11061202 
  • pjproject/branches/iceproject/pjlib-util/include/pjlib-util/stun_server.h

    r929 r990  
    5151     * The STUN message type. 
    5252     */ 
    53     int     msg_type; 
     53    int         msg_type; 
    5454 
    5555    /**  
     
    5959     * @param msg   The STUN message. 
    6060     */ 
    61     void    (*handle_msg)(pj_stun_service *svc, const pj_stun_msg *msg); 
     61    pj_status_t (*handle_msg)(pj_stun_service *svc,  
     62                              void *handle_data, 
     63                              const pj_stun_msg *msg); 
    6264 
    6365} pj_stun_service_handler; 
     
    6870 */ 
    6971PJ_DECL(pj_status_t) pj_stun_service_create(pj_pool_t *pool, 
     72                                            const char *name, 
     73                                            unsigned options, 
    7074                                            unsigned handler_cnt, 
    7175                                            pj_stun_service_handler cb[], 
     
    8993 */ 
    9094PJ_DECL(pj_status_t) pj_stun_service_handle_msg(pj_stun_service *svc, 
     95                                                void *handle_data, 
    9196                                                const pj_stun_msg *msg); 
    9297 
  • pjproject/branches/iceproject/pjlib-util/src/pjlib-util/stun_msg.c

    r929 r990  
    8080#define ATTR_HDR_LEN        4 
    8181 
     82#define getval16(p, pos)    (pj_uint16_t)(((p)[(pos)] << 8) | \ 
     83                                          ((p)[(pos) + 1] << 0)) 
     84 
    8285 
    8386////////////////////////////////////////////////////////////////////////////// 
     
    9396pj_stun_generic_ip_addr_attr_create(pj_pool_t *pool, 
    9497                                    int attr_type, 
    95                                     pj_uint32_t ip_addr, 
    96                                     int port, 
     98                                    pj_bool_t xor_ed, 
     99                                    unsigned addr_len, 
     100                                    const pj_sockaddr_t *addr, 
    97101                                    pj_stun_generic_ip_addr_attr **p_attr) 
    98102{ 
    99103    pj_stun_generic_ip_addr_attr *attr; 
    100104 
    101     PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL); 
     105    PJ_ASSERT_RETURN(pool && addr_len && addr && p_attr, PJ_EINVAL); 
     106    PJ_ASSERT_RETURN(addr_len == sizeof(pj_sockaddr_in) || 
     107                     addr_len == sizeof(pj_sockaddr_in6), PJ_EINVAL); 
    102108 
    103109    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_generic_ip_addr_attr); 
    104110    INIT_ATTR(attr, attr_type, STUN_GENERIC_IP_ADDR_LEN); 
    105     attr->family = 1; 
    106     attr->port = (pj_uint16_t) port; 
    107     attr->addr.ipv4 = ip_addr; 
     111 
     112    if (!xor_ed) { 
     113        pj_memcpy(&attr->addr, addr, addr_len); 
     114    } else if (addr_len == sizeof(pj_sockaddr_in)) { 
     115        const pj_sockaddr_in *addr4 = (const pj_sockaddr_in*) addr; 
     116 
     117        pj_sockaddr_in_init(&attr->addr.ipv4, NULL, 0); 
     118        attr->addr.ipv4.sin_port = (pj_uint16_t)(addr4->sin_port ^ 0x2112); 
     119        attr->addr.ipv4.sin_addr.s_addr = (addr4->sin_addr.s_addr ^  
     120                                           pj_htonl(0x2112A442)); 
     121    } else { 
     122        return PJ_ENOTSUP; 
     123    } 
    108124 
    109125    *p_attr = attr; 
     
    117133                                               void **p_attr) 
    118134{ 
    119     enum 
    120     { 
    121         ATTR_LEN = STUN_GENERIC_IP_ADDR_LEN + ATTR_HDR_LEN 
    122     }; 
    123135    pj_stun_generic_ip_addr_attr *attr; 
    124  
    125     /* Check that the struct address is valid */ 
    126     pj_assert(sizeof(pj_stun_generic_ip_addr_attr) == ATTR_LEN); 
     136    pj_uint32_t val; 
    127137 
    128138    /* Create the attribute */ 
    129     attr = PJ_POOL_ALLOC_TYPE(pool, pj_stun_generic_ip_addr_attr); 
    130     pj_memcpy(attr, buf, ATTR_LEN); 
    131  
    132     /* Check address family is valid (only supports ipv4 for now) */ 
    133     if (attr->family != 1) 
    134         return PJLIB_UTIL_ESTUNINATTR; 
     139    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_generic_ip_addr_attr); 
     140    pj_memcpy(attr, buf, ATTR_HDR_LEN); 
    135141 
    136142    /* Convert to host byte order */ 
    137143    attr->hdr.type = pj_ntohs(attr->hdr.type); 
    138144    attr->hdr.length = pj_ntohs(attr->hdr.length); 
    139     attr->port = pj_ntohs(attr->port); 
    140     attr->addr.ipv4 = pj_ntohl(attr->addr.ipv4); 
    141145 
    142146    /* Check that the attribute length is valid */ 
     
    144148        return PJLIB_UTIL_ESTUNINATTRLEN; 
    145149 
     150    /* Check address family */ 
     151    val = *(pj_uint8_t*)(buf + ATTR_HDR_LEN + 1); 
     152 
     153    /* Check address family is valid (only supports ipv4 for now) */ 
     154    if (val != 1) 
     155        return PJLIB_UTIL_ESTUNINATTR; 
     156 
     157    /* Get port and address */ 
     158    pj_sockaddr_in_init(&attr->addr.ipv4, NULL, 0); 
     159    attr->addr.ipv4.sin_port = getval16(buf, ATTR_HDR_LEN + 2); 
     160    pj_memcpy(&attr->addr.ipv4.sin_addr, buf+ATTR_HDR_LEN+4, 4); 
     161 
    146162    /* Done */ 
    147163    *p_attr = attr; 
     
    154170                                               unsigned len, unsigned *printed) 
    155171{ 
    156     enum 
    157     { 
    158         ATTR_LEN = STUN_GENERIC_IP_ADDR_LEN + ATTR_HDR_LEN 
     172    enum { 
     173        ATTR_LEN = ATTR_HDR_LEN + STUN_GENERIC_IP_ADDR_LEN 
    159174    }; 
     175    pj_uint8_t *start_buf = buf; 
     176    const pj_stun_generic_ip_addr_attr *ca =  
     177        (const pj_stun_generic_ip_addr_attr *)a; 
    160178    pj_stun_generic_ip_addr_attr *attr; 
    161179 
     
    163181        return PJ_ETOOSMALL; 
    164182 
    165     /* Copy and convert attribute to network byte order */ 
    166     pj_memcpy(buf, a, ATTR_LEN); 
     183    /* Copy and convert headers to network byte order */ 
     184    pj_memcpy(buf, a, ATTR_HDR_LEN); 
    167185    attr = (pj_stun_generic_ip_addr_attr*) buf; 
    168186    attr->hdr.type = pj_htons(attr->hdr.type); 
    169     attr->hdr.length = pj_htons(attr->hdr.length); 
    170     attr->port = pj_htons(attr->port); 
    171     attr->addr.ipv4 = pj_htonl(attr->addr.ipv4); 
    172  
    173     /* Done */ 
    174     *printed = ATTR_LEN; 
     187    attr->hdr.length = pj_htons((pj_uint16_t)ATTR_LEN); 
     188    buf += ATTR_HDR_LEN; 
     189     
     190    /* Ignored */ 
     191    *buf++ = '\0'; 
     192 
     193    /* Family (IPv4 only for now) */ 
     194    PJ_ASSERT_RETURN(ca->addr.addr.sa_family == PJ_AF_INET, PJ_EINVAL); 
     195    *buf++ = 1; 
     196 
     197    /* Port */ 
     198    pj_memcpy(buf, &ca->addr.ipv4.sin_port, 2); 
     199    buf += 2; 
     200 
     201    /* Address */ 
     202    pj_memcpy(buf, &ca->addr.ipv4.sin_addr, 4); 
     203    buf += 4; 
     204 
     205    pj_assert(buf - start_buf == ATTR_LEN); 
     206 
     207    /* Done */ 
     208    *printed = buf - start_buf; 
    175209 
    176210    return PJ_SUCCESS; 
     
    214248 
    215249    /* Create the attribute */ 
    216     attr = PJ_POOL_ALLOC_TYPE(pool, pj_stun_generic_string_attr); 
     250    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_generic_string_attr); 
    217251 
    218252    /* Copy the header */ 
     
    247281    /* Calculated total attr_len (add padding if necessary) */ 
    248282    *printed = (ca->value.slen + ATTR_HDR_LEN + 3) & (~3); 
    249     if (len < *printed) 
     283    if (len < *printed) { 
     284        *printed = 0; 
    250285        return PJ_ETOOSMALL; 
     286    } 
    251287 
    252288    /* Copy header */ 
    253289    pj_memcpy(buf, a, ATTR_HDR_LEN); 
     290    attr = (pj_stun_attr_hdr*)buf; 
    254291 
    255292    /* Set the correct length */ 
    256     attr = (pj_stun_attr_hdr*)buf; 
    257293    attr->length = (pj_uint16_t) ca->value.slen; 
    258294 
     
    265301 
    266302    /* Done */ 
     303    return PJ_SUCCESS; 
     304} 
     305 
     306 
     307////////////////////////////////////////////////////////////////////////////// 
     308/* 
     309 * STUN empty attribute (used by USE-CANDIDATE). 
     310 */ 
     311 
     312/* 
     313 * Create a STUN empty attribute. 
     314 */ 
     315PJ_DEF(pj_status_t)  
     316pj_stun_empty_attr_create(pj_pool_t *pool, 
     317                          int attr_type, 
     318                          pj_stun_empty_attr **p_attr) 
     319{ 
     320    pj_stun_empty_attr *attr; 
     321 
     322    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL); 
     323 
     324    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_empty_attr); 
     325    INIT_ATTR(attr, attr_type, sizeof(pj_stun_empty_attr)); 
     326 
     327    *p_attr = attr; 
     328 
     329    return PJ_SUCCESS; 
     330} 
     331 
     332 
     333static pj_status_t decode_empty_attr(pj_pool_t *pool,  
     334                                     const pj_uint8_t *buf,  
     335                                     void **p_attr) 
     336{ 
     337    pj_stun_empty_attr *attr; 
     338 
     339    /* Check that the struct address is valid */ 
     340    pj_assert(sizeof(pj_stun_empty_attr) == ATTR_HDR_LEN); 
     341 
     342    /* Create the attribute */ 
     343    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_empty_attr); 
     344    pj_memcpy(attr, buf, ATTR_HDR_LEN); 
     345 
     346    /* Convert to host byte order */ 
     347    attr->hdr.type = pj_ntohs(attr->hdr.type); 
     348    attr->hdr.length = pj_ntohs(attr->hdr.length); 
     349 
     350    /* Check that the attribute length is valid */ 
     351    if (attr->hdr.length != ATTR_HDR_LEN) 
     352        return PJLIB_UTIL_ESTUNINATTRLEN; 
     353 
     354    /* Done */ 
     355    *p_attr = attr; 
     356 
     357    return PJ_SUCCESS; 
     358} 
     359 
     360 
     361static pj_status_t encode_empty_attr(const void *a, pj_uint8_t *buf,  
     362                                     unsigned len, unsigned *printed) 
     363{ 
     364    pj_stun_empty_attr *attr; 
     365 
     366    if (len < ATTR_HDR_LEN)  
     367        return PJ_ETOOSMALL; 
     368 
     369    /* Copy and convert attribute to network byte order */ 
     370    pj_memcpy(buf, a, ATTR_HDR_LEN); 
     371    attr = (pj_stun_empty_attr*) buf; 
     372    attr->hdr.type = pj_htons(attr->hdr.type); 
     373    attr->hdr.length = pj_htons(attr->hdr.length); 
     374 
     375    /* Done */ 
     376    *printed = ATTR_HDR_LEN; 
     377 
    267378    return PJ_SUCCESS; 
    268379} 
     
    312423 
    313424    /* Create the attribute */ 
    314     attr = PJ_POOL_ALLOC_TYPE(pool, pj_stun_generic_uint_attr); 
     425    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_generic_uint_attr); 
    315426    pj_memcpy(attr, buf, ATTR_LEN); 
    316427 
     
    397508 
    398509    /* Create attribute */ 
    399     attr = PJ_POOL_ALLOC_TYPE(pool, pj_stun_msg_integrity_attr); 
     510    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msg_integrity_attr); 
    400511    pj_memcpy(attr, buf, sizeof(pj_stun_msg_integrity_attr)); 
    401512    attr->hdr.type = pj_ntohs(attr->hdr.type); 
     
    486597 
    487598    /* Create the attribute */ 
    488     attr = PJ_POOL_ALLOC_TYPE(pool, pj_stun_error_code_attr); 
     599    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_error_code_attr); 
    489600 
    490601    /* Copy the header */ 
     
    683794 
    684795    /* Create the attribute */ 
    685     attr = PJ_POOL_ALLOC_TYPE(pool, pj_stun_binary_attr); 
     796    attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_binary_attr); 
    686797 
    687798    /* Copy the header */ 
     
    740851struct attr_desc 
    741852{ 
    742     unsigned  type; 
    743     const char *attr_name; 
    744  
    745853    pj_status_t (*decode_attr)(pj_pool_t *pool, const pj_uint8_t *buf,  
    746854                               void **p_attr); 
     
    748856                               unsigned len, unsigned *printed); 
    749857 
    750 } attr_desc[] =  
    751 { 
    752     { 
    753         PJ_STUN_ATTR_MAPPED_ADDR, 
    754         "MAPPED-ADDRESS", 
     858}; 
     859 
     860struct attr_desc mandatory_attr_desc[] =  
     861{ 
     862    { 
     863        /* type zero */ 
     864        NULL, 
     865        NULL 
     866    }, 
     867    { 
     868        /* PJ_STUN_ATTR_MAPPED_ADDR, */ 
    755869        &decode_generic_ip_addr_attr, 
    756870        &encode_generic_ip_addr_attr 
    757871    }, 
    758872    { 
    759         PJ_STUN_ATTR_RESPONSE_ADDR, 
    760         "RESPONSE-ADDRESS", 
     873        /* PJ_STUN_ATTR_RESPONSE_ADDR, */ 
    761874        &decode_generic_ip_addr_attr, 
    762875        &encode_generic_ip_addr_attr 
    763876    }, 
    764877    { 
    765         PJ_STUN_ATTR_CHANGE_REQUEST, 
    766         "CHANGE-REQUEST", 
     878        /* PJ_STUN_ATTR_CHANGE_REQUEST, */ 
     879        &decode_generic_uint_attr, 
     880        &encode_generic_uint_attr 
     881    }, 
     882    { 
     883        /* PJ_STUN_ATTR_SOURCE_ADDR, */ 
    767884        &decode_generic_ip_addr_attr, 
    768885        &encode_generic_ip_addr_attr 
    769886    }, 
    770887    { 
    771         PJ_STUN_ATTR_SOURCE_ADDR, 
    772         "SOURCE-ADDRESS", 
     888        /* PJ_STUN_ATTR_CHANGED_ADDR, */ 
    773889        &decode_generic_ip_addr_attr, 
    774890        &encode_generic_ip_addr_attr 
    775891    }, 
    776892    { 
    777         PJ_STUN_ATTR_CHANGED_ADDR, 
    778         "CHANGED-ADDRESS", 
     893        /* PJ_STUN_ATTR_USERNAME, */ 
     894        &decode_generic_string_attr, 
     895        &encode_generic_string_attr 
     896    }, 
     897    { 
     898        /* PJ_STUN_ATTR_PASSWORD, */ 
     899        &decode_generic_string_attr, 
     900        &encode_generic_string_attr 
     901    }, 
     902    { 
     903        /* PJ_STUN_ATTR_MESSAGE_INTEGRITY, */ 
     904        &decode_msg_integrity_attr, 
     905        &encode_msg_integrity_attr 
     906    }, 
     907    { 
     908        /* PJ_STUN_ATTR_ERROR_CODE, */ 
     909        &decode_error_code_attr, 
     910        &encode_error_code_attr 
     911    }, 
     912    { 
     913        /* PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES, */ 
     914        &decode_unknown_attr, 
     915        &encode_unknown_attr 
     916    }, 
     917    { 
     918        /* PJ_STUN_ATTR_REFLECTED_FROM, */ 
    779919        &decode_generic_ip_addr_attr, 
    780920        &encode_generic_ip_addr_attr 
    781921    }, 
    782922    { 
    783         PJ_STUN_ATTR_USERNAME, 
    784         "USERNAME", 
     923        /* ID 0x000C is not assigned */ 
     924        NULL, 
     925        NULL 
     926    }, 
     927    { 
     928        /* PJ_STUN_ATTR_LIFETIME, */ 
     929        &decode_generic_uint_attr, 
     930        &encode_generic_uint_attr 
     931    }, 
     932    { 
     933        /* ID 0x000E is not assigned */ 
     934        NULL, 
     935        NULL 
     936    }, 
     937    { 
     938        /* ID 0x000F is not assigned */ 
     939        NULL, 
     940        NULL 
     941    }, 
     942    { 
     943        /* PJ_STUN_ATTR_BANDWIDTH, */ 
     944        &decode_generic_uint_attr, 
     945        &encode_generic_uint_attr 
     946    }, 
     947    { 
     948        /* ID 0x0011 is not assigned */ 
     949        NULL, 
     950        NULL 
     951    }, 
     952    { 
     953        /* PJ_STUN_ATTR_REMOTE_ADDRESS, */ 
     954        &decode_generic_ip_addr_attr, 
     955        &encode_generic_ip_addr_attr 
     956    }, 
     957    { 
     958        /* PJ_STUN_ATTR_DATA, */ 
     959        &decode_binary_attr, 
     960        &encode_binary_attr 
     961    }, 
     962    { 
     963        /* PJ_STUN_ATTR_REALM, */ 
    785964        &decode_generic_string_attr, 
    786965        &encode_generic_string_attr 
    787966    }, 
    788967    { 
    789         PJ_STUN_ATTR_PASSWORD, 
    790         "PASSWORD", 
     968        /* PJ_STUN_ATTR_NONCE, */ 
    791969        &decode_generic_string_attr, 
    792970        &encode_generic_string_attr 
    793971    }, 
    794972    { 
    795         PJ_STUN_ATTR_MESSAGE_INTEGRITY, 
    796         "MESSAGE-INTEGRITY", 
    797         &decode_msg_integrity_attr, 
    798         &encode_msg_integrity_attr 
    799     }, 
    800     { 
    801         PJ_STUN_ATTR_ERROR_CODE, 
    802         "ERROR-CODE", 
    803         &decode_error_code_attr, 
    804         &encode_error_code_attr 
    805     }, 
    806     { 
    807         PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES, 
    808         "UNKNOWN-ATTRIBUTES", 
    809         &decode_unknown_attr, 
    810         &encode_unknown_attr 
    811     }, 
    812     { 
    813         PJ_STUN_ATTR_REFLECTED_FROM, 
    814         "REFLECTED-FROM", 
     973        /* PJ_STUN_ATTR_RELAY_ADDRESS, */ 
    815974        &decode_generic_ip_addr_attr, 
    816975        &encode_generic_ip_addr_attr 
    817976    }, 
    818977    { 
    819         PJ_STUN_ATTR_REALM, 
    820         "REALM", 
     978        /* PJ_STUN_ATTR_REQUESTED_ADDR_TYPE, */ 
     979        &decode_generic_uint_attr, 
     980        &encode_generic_uint_attr 
     981    }, 
     982    { 
     983        /* PJ_STUN_ATTR_REQUESTED_PORT_PROPS, */ 
     984        &decode_generic_uint_attr, 
     985        &encode_generic_uint_attr 
     986    }, 
     987    { 
     988        /* PJ_STUN_ATTR_REQUESTED_TRANSPORT, */ 
     989        &decode_generic_uint_attr, 
     990        &encode_generic_uint_attr 
     991    }, 
     992    { 
     993        /* ID 0x001A is not assigned */ 
     994        NULL, 
     995        NULL 
     996    }, 
     997    { 
     998        /* ID 0x001B is not assigned */ 
     999        NULL, 
     1000        NULL 
     1001    }, 
     1002    { 
     1003        /* ID 0x001C is not assigned */ 
     1004        NULL, 
     1005        NULL 
     1006    }, 
     1007    { 
     1008        /* ID 0x001D is not assigned */ 
     1009        NULL, 
     1010        NULL 
     1011    }, 
     1012    { 
     1013        /* ID 0x001E is not assigned */ 
     1014        NULL, 
     1015        NULL 
     1016    }, 
     1017    { 
     1018        /* ID 0x001F is not assigned */ 
     1019        NULL, 
     1020        NULL 
     1021    }, 
     1022    { 
     1023        /* PJ_STUN_ATTR_XOR_MAPPED_ADDRESS, */ 
     1024        &decode_generic_ip_addr_attr, 
     1025        &encode_generic_ip_addr_attr 
     1026    }, 
     1027    { 
     1028        /* PJ_STUN_ATTR_TIMER_VAL, */ 
     1029        &decode_generic_uint_attr, 
     1030        &encode_generic_uint_attr 
     1031    }, 
     1032    { 
     1033        /* PJ_STUN_ATTR_REQUESTED_IP, */ 
     1034        &decode_generic_ip_addr_attr, 
     1035        &encode_generic_ip_addr_attr 
     1036    }, 
     1037    { 
     1038        /* PJ_STUN_ATTR_XOR_REFLECTED_FROM, */ 
     1039        &decode_generic_ip_addr_attr, 
     1040        &encode_generic_ip_addr_attr 
     1041    }, 
     1042    { 
     1043        /* PJ_STUN_ATTR_PRIORITY, */ 
     1044        &decode_generic_uint_attr, 
     1045        &encode_generic_uint_attr 
     1046    }, 
     1047    { 
     1048        /* PJ_STUN_ATTR_USE_CANDIDATE, */ 
     1049        &decode_empty_attr, 
     1050        &encode_empty_attr 
     1051    }, 
     1052    { 
     1053        /* PJ_STUN_ATTR_XOR_INTERNAL_ADDR, */ 
     1054        &decode_generic_ip_addr_attr, 
     1055        &encode_generic_ip_addr_attr 
     1056    }, 
     1057 
     1058    /* Sentinel */ 
     1059    { 
     1060        /* PJ_STUN_ATTR_END_MANDATORY_ATTR */ 
     1061        NULL, 
     1062        NULL 
     1063    } 
     1064}; 
     1065 
     1066static struct attr_desc extended_attr_desc[] = 
     1067{ 
     1068    { 
     1069        /* PJ_STUN_ATTR_FINGERPRINT, */ 
     1070        &decode_generic_uint_attr, 
     1071        &encode_generic_uint_attr 
     1072    }, 
     1073    { 
     1074        /* PJ_STUN_ATTR_SERVER, */ 
    8211075        &decode_generic_string_attr, 
    8221076        &encode_generic_string_attr 
    8231077    }, 
    8241078    { 
    825         PJ_STUN_ATTR_NONCE, 
    826         "NONCE", 
    827         &decode_generic_string_attr, 
    828         &encode_generic_string_attr 
    829     }, 
    830     { 
    831         PJ_STUN_ATTR_XOR_MAPPED_ADDRESS, 
    832         "XOR-MAPPED-ADDRESS", 
     1079        /* PJ_STUN_ATTR_ALTERNATE_SERVER, */ 
    8331080        &decode_generic_ip_addr_attr, 
    8341081        &encode_generic_ip_addr_attr 
    8351082    }, 
    8361083    { 
    837         PJ_STUN_ATTR_FINGERPRINT, 
    838         "FINGERPRINT", 
     1084        /* PJ_STUN_ATTR_REFRESH_INTERVAL, */ 
    8391085        &decode_generic_uint_attr, 
    8401086        &encode_generic_uint_attr 
    8411087    }, 
    842     { 
    843         PJ_STUN_ATTR_SERVER, 
    844         "SERVER", 
    845         &decode_generic_string_attr, 
    846         &encode_generic_string_attr 
    847     }, 
    848     { 
    849         PJ_STUN_ATTR_ALTERNATE_SERVER, 
    850         "ALTERNATE-SERVER", 
    851         &decode_generic_ip_addr_attr, 
    852         &encode_generic_ip_addr_attr 
    853     }, 
    854     { 
    855         PJ_STUN_ATTR_REFRESH_INTERVAL, 
    856         "REFRESH-INTERVAL", 
    857         &decode_generic_uint_attr, 
    858         &encode_generic_uint_attr 
    859     }, 
    860     { 
    861         PJ_STUN_ATTR_LIFETIME, 
    862         "LIFETIME", 
    863         &decode_generic_uint_attr, 
    864         &encode_generic_uint_attr 
    865     }, 
    866     { 
    867         PJ_STUN_ATTR_BANDWIDTH, 
    868         "BANDWIDTH", 
    869         &decode_generic_uint_attr, 
    870         &encode_generic_uint_attr 
    871     }, 
    872     { 
    873         PJ_STUN_ATTR_REMOTE_ADDRESS, 
    874         "REMOTE-ADDRESS", 
    875         &decode_generic_ip_addr_attr, 
    876         &encode_generic_ip_addr_attr 
    877     }, 
    878     { 
    879         PJ_STUN_ATTR_DATA, 
    880         "DATA", 
    881         &decode_binary_attr, 
    882         &encode_binary_attr 
    883     }, 
    884     { 
    885         PJ_STUN_ATTR_RELAY_ADDRESS, 
    886         "RELAY-ADDRESS", 
    887         &decode_generic_ip_addr_attr, 
    888         &encode_generic_ip_addr_attr 
    889     }, 
    890     { 
    891         PJ_STUN_ATTR_REQUESTED_PORT_PROPS, 
    892         "REQUESTED-PORT-PROPS", 
    893         &decode_generic_uint_attr, 
    894         &encode_generic_uint_attr 
    895     }, 
    896     { 
    897         PJ_STUN_ATTR_REQUESTED_TRANSPORT, 
    898         "REQUESTED-TRANSPORT", 
    899         &decode_generic_uint_attr, 
    900         &encode_generic_uint_attr 
    901     }, 
    902     { 
    903         PJ_STUN_ATTR_REQUESTED_IP, 
    904         "STUN REQUESTED-IP", 
    905         &decode_generic_ip_addr_attr, 
    906         &encode_generic_ip_addr_attr 
    907     }, 
    908     { 
    909         PJ_STUN_ATTR_TIMER_VAL, 
    910         "TIMER-VAL", 
    911         &decode_generic_uint_attr, 
    912         &encode_generic_uint_attr 
    913     } 
    9141088}; 
    9151089 
    916 static struct attr_desc *find_attr_desc(unsigned attr_type) 
    917 { 
    918     unsigned i; 
    919  
    920     for (i=0; i<PJ_ARRAY_SIZE(attr_desc); ++i) { 
    921         if (attr_desc[i].type == attr_type) 
    922             return &attr_desc[i]; 
    923     } 
    924  
    925     return NULL; 
    926 } 
    927  
     1090 
     1091static const struct attr_desc *find_attr_desc(unsigned attr_type) 
     1092{ 
     1093    struct attr_desc *desc; 
     1094 
     1095    /* Check that attr_desc array is valid */ 
     1096    pj_assert(PJ_ARRAY_SIZE(mandatory_attr_desc)== 
     1097              PJ_STUN_ATTR_END_MANDATORY_ATTR+1); 
     1098    pj_assert(mandatory_attr_desc[PJ_STUN_ATTR_END_MANDATORY_ATTR].decode_attr 
     1099              == NULL); 
     1100    pj_assert(mandatory_attr_desc[PJ_STUN_ATTR_USE_CANDIDATE].decode_attr  
     1101              == &decode_empty_attr); 
     1102    pj_assert(PJ_ARRAY_SIZE(extended_attr_desc) == 
     1103              PJ_STUN_ATTR_END_EXTENDED_ATTR-PJ_STUN_ATTR_START_EXTENDED_ATTR); 
     1104 
     1105    if (attr_type < PJ_STUN_ATTR_START_EXTENDED_ATTR) 
     1106        desc = &mandatory_attr_desc[attr_type]; 
     1107    else if (attr_type >= PJ_STUN_ATTR_START_EXTENDED_ATTR && 
     1108             attr_type < PJ_STUN_ATTR_END_EXTENDED_ATTR) 
     1109        desc = &extended_attr_desc[attr_type-PJ_STUN_ATTR_START_EXTENDED_ATTR]; 
     1110    else 
     1111        return NULL; 
     1112 
     1113    return desc->decode_attr == NULL ? NULL : desc; 
     1114} 
    9281115 
    9291116 
     
    9331120PJ_DEF(pj_status_t) pj_stun_msg_create( pj_pool_t *pool, 
    9341121                                        unsigned msg_type, 
     1122                                        pj_uint32_t magic, 
    9351123                                        const pj_uint8_t tsx_id[12], 
    9361124                                        pj_stun_msg **p_msg) 
     
    9421130    msg = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msg); 
    9431131    msg->hdr.type = (pj_uint16_t) msg_type; 
    944     msg->hdr.magic = (pj_uint32_t) PJ_STUN_MAGIC; 
     1132    msg->hdr.magic = magic; 
    9451133 
    9461134    if (tsx_id) { 
     
    9691157 
    9701158/* 
     1159 * Add STUN attribute to STUN message. 
     1160 */ 
     1161PJ_DEF(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg, 
     1162                                         pj_stun_attr_hdr *attr) 
     1163{ 
     1164    PJ_ASSERT_RETURN(msg && attr, PJ_EINVAL); 
     1165    PJ_ASSERT_RETURN(msg->attr_count < PJ_STUN_MAX_ATTR, PJ_ETOOMANY); 
     1166 
     1167    msg->attr[msg->attr_count++] = attr; 
     1168    return PJ_SUCCESS; 
     1169} 
     1170 
     1171 
     1172/* 
    9711173 * Check that the PDU is potentially a valid STUN message. 
    9721174 */ 
     
    9851187    /* First byte of STUN message is always 0x00 or 0x01. */ 
    9861188    if ((*(const char*)pdu) != 0x00 && (*(const char*)pdu) != 0x01) 
    987         return PJ_FALSE; 
     1189        return PJLIB_UTIL_ESTUNINMSGTYPE; 
    9881190 
    9891191    /* If magic is set, then there is great possibility that this is 
     
    9911193     */ 
    9921194    if (pj_ntohl(hdr->magic) == PJ_STUN_MAGIC) 
    993         return PJ_TRUE; 
     1195        return PJ_SUCCESS; 
    9941196 
    9951197    /* Check the PDU length */ 
    9961198    if (pj_ntohs(hdr->length) > pdu_len) 
    997         return PJ_FALSE; 
     1199        return PJLIB_UTIL_ESTUNINMSGLEN; 
    9981200 
    9991201    /* Could be a STUN message */ 
    1000     return PJ_TRUE; 
     1202    return PJ_SUCCESS; 
    10011203} 
    10021204 
     
    10311233 
    10321234    /* Create the message, copy the header, and convert to host byte order */ 
    1033     msg = PJ_POOL_ALLOC_TYPE(pool, pj_stun_msg); 
     1235    msg = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msg); 
    10341236    pj_memcpy(&msg->hdr, pdu, sizeof(pj_stun_msg_hdr)); 
    10351237    msg->hdr.type = pj_ntohs(msg->hdr.type); 
     
    10401242    pdu_len -= sizeof(pj_stun_msg_hdr); 
    10411243 
     1244    if (p_err_code) 
     1245        *p_err_code = 0; 
     1246 
    10421247    /* Parse attributes */ 
    10431248    uattr_cnt = 0; 
    10441249    while (pdu_len > 0) { 
    10451250        unsigned attr_type, attr_val_len; 
    1046         struct attr_desc *adesc; 
     1251        const struct attr_desc *adesc; 
    10471252 
    10481253        /* Get attribute type and length. If length is not aligned 
     
    10531258        attr_val_len = (attr_val_len + 3) & (~3); 
    10541259 
    1055         /* Get the attribute descriptor */ 
    1056         adesc = find_attr_desc(attr_type); 
    1057  
    10581260        /* Check length */ 
    10591261        if (pdu_len < attr_val_len) 
    10601262            return PJLIB_UTIL_ESTUNINATTRLEN; 
     1263 
     1264        /* Get the attribute descriptor */ 
     1265        adesc = find_attr_desc(attr_type); 
    10611266 
    10621267        if (adesc == NULL) { 
     
    10761281                 * if we don't understand the attribute. 
    10771282                 */ 
    1078                 if (p_err_code) 
     1283                if (p_err_code && *p_err_code == 0) 
    10791284                    *p_err_code = PJ_STUN_STATUS_UNKNOWN_ATTRIBUTE; 
    10801285 
     
    10901295            if (status != PJ_SUCCESS) { 
    10911296                PJ_LOG(4,(THIS_FILE,  
    1092                           "Error parsing STUN %s attribute: status=%d", 
    1093                           adesc->attr_name, status)); 
     1297                          "Error parsing STUN attribute type %d: status=%d", 
     1298                          attr_type, status)); 
    10941299                return status; 
    10951300            } 
     
    11511356    /* Print each attribute */ 
    11521357    for (i=0; i<msg->attr_count; ++i) { 
    1153         struct attr_desc *adesc; 
     1358        const struct attr_desc *adesc; 
    11541359        const pj_stun_attr_hdr *attr_hdr; 
    11551360        unsigned printed; 
     
    11691374    } 
    11701375 
    1171     /* Update the message length in the header */ 
     1376    /* Update the message length in the header.  
     1377     * Note that length is not including the 20 bytes header. 
     1378     */ 
    11721379    hdr->length = pj_htons((pj_uint16_t)(buf - start)); 
    11731380 
Note: See TracChangeset for help on using the changeset viewer.