Changeset 2580


Ignore:
Timestamp:
Apr 7, 2009 9:42:58 AM (15 years ago)
Author:
bennylp
Message:

Part of ticket #780 (work in progress): added IPv6 support to various STUN attributes and added the test from draft-ietf-behave-stun-test-vectors

Location:
pjproject/trunk/pjnath
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/include/pjnath/errno.h

    r2394 r2580  
    115115 */ 
    116116#define PJNATH_ESTUNIPV6NOTSUPP     (PJNATH_ERRNO_START+41) /* 370041 */ 
     117/** 
     118 * @hideinitializer 
     119 * Invalid address family value in STUN message. 
     120 */ 
     121#define PJNATH_EINVAF               (PJNATH_ERRNO_START+42) /* 370042 */ 
    117122 
    118123/** 
     
    120125 * Invalid STUN server or server not configured. 
    121126 */ 
    122 #define PJNATH_ESTUNINSERVER        (PJNATH_ERRNO_START+42) /* 370042 */ 
     127#define PJNATH_ESTUNINSERVER        (PJNATH_ERRNO_START+50) /* 370050 */ 
    123128 
    124129 
  • pjproject/trunk/pjnath/include/pjnath/types.h

    r2394 r2580  
    9898keep NAT bindings open. 
    9999 
    100 This version of PJNATH implements the following STUN-bis draft: 
    101 - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-18.txt"> 
    102   <B>draft-ietf-behave-rfc3489bis-18</b></A>: Session Traversal  
    103     Utilities for (NAT) (STUN), 
     100This version of PJNATH implements the following STUN RFC: 
     101- <A HREF="http://www.ietf.org/rfc/rfc5389.txt"><B>RFC 5389</b></A>:  
     102    Session Traversal Utilities for (NAT) (STUN), 
    104103 
    105104 
  • pjproject/trunk/pjnath/src/pjnath-test/stun.c

    r2394 r2580  
    431431} 
    432432 
     433/* 
     434 * Test vectors, from: 
     435 * http://tools.ietf.org/html/draft-denis-behave-rfc3489bis-test-vectors-02 
     436 */ 
    433437typedef struct test_vector test_vector; 
    434438 
    435439static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v); 
    436440static pj_stun_msg* create_msgint2(pj_pool_t *pool, test_vector *v); 
     441static pj_stun_msg* create_msgint3(pj_pool_t *pool, test_vector *v); 
    437442 
    438443enum 
     
    442447}; 
    443448 
    444 struct test_vector 
     449static struct test_vector 
    445450{ 
    446451    unsigned       msg_type; 
     
    451456    char          *username; 
    452457    char          *password; 
     458    char          *realm; 
     459    char          *nonce; 
    453460    pj_stun_msg* (*create)(pj_pool_t*, test_vector*); 
    454461} test_vectors[] =  
     
    470477        "evtj:h6vY", 
    471478        "VOkJxbRl1RmTxUk/WvJxBt", 
     479        "", 
     480        "", 
    472481        &create_msgint1 
    473482    }, 
     
    475484        PJ_STUN_BINDING_RESPONSE, 
    476485        "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae", 
    477         "\x01\x01\x00\x3c\x21\x12\xa4\x42\xb7\xe7" 
    478         "\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" 
    479         "\x80\x22\x00\x0b\x74\x65\x73\x74\x20\x76" 
    480         "\x65\x63\x74\x6f\x72\x20\x00\x20\x00\x08" 
    481         "\x00\x01\xa1\x47\x5e\x12\xa4\x43\x00\x08" 
    482         "\x00\x14\xab\x4e\x53\x29\x61\x00\x08\x4c" 
    483         "\x89\xf2\x7c\x69\x30\x33\x5c\xa3\x58\x14" 
    484         "\xea\x90\x80\x28\x00\x04\xae\x25\x8d\xf2", 
     486        "\x01\x01\x00\x3c" 
     487        "\x21\x12\xa4\x42" 
     488        "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" 
     489        "\x80\x22\x00\x0b" 
     490        "\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" 
     491        "\x00\x20\x00\x08" 
     492        "\x00\x01\xa1\x47\xe1\x12\xa6\x43" 
     493        "\x00\x08\x00\x14" 
     494        "\x2b\x91\xf5\x99\xfd\x9e\x90\xc3\x8c\x74\x89\xf9" 
     495        "\x2a\xf9\xba\x53\xf0\x6b\xe7\xd7" 
     496        "\x80\x28\x00\x04" 
     497        "\xc0\x7d\x4c\x96", 
    485498        80, 
    486499        USE_MESSAGE_INTEGRITY | USE_FINGERPRINT, 
    487500        "evtj:h6vY", 
    488501        "VOkJxbRl1RmTxUk/WvJxBt", 
     502        "", 
     503        "", 
    489504        &create_msgint2 
     505    }, 
     506    { 
     507        PJ_STUN_BINDING_RESPONSE, 
     508        "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae", 
     509        "\x01\x01\x00\x48" //     Response type and message length 
     510        "\x21\x12\xa4\x42" //     Message cookie 
     511        "\xb7\xe7\xa7\x01" //  } 
     512        "\xbc\x34\xd6\x86" //  }  Transaction ID 
     513        "\xfa\x87\xdf\xae" //  } 
     514 
     515        "\x80\x22\x00\x0b" // SOFTWARE, length=11 
     516        "\x74\x65\x73\x74" 
     517        "\x20\x76\x65\x63" 
     518        "\x74\x6f\x72\x20" 
     519        "\x00\x20\x00\x14" // XOR-MAPPED-ADDRESS 
     520        "\x00\x02\xa1\x47" 
     521        "\x01\x13\xa9\xfa" 
     522        "\xa5\xd3\xf1\x79" 
     523        "\xbc\x25\xf4\xb5" 
     524        "\xbe\xd2\xb9\xd9" 
     525        "\x00\x08\x00\x14" // MESSAGE-INTEGRITY attribute header 
     526        "\xa3\x82\x95\x4e" // } 
     527        "\x4b\xe6\x7b\xf1" // } 
     528        "\x17\x84\xc9\x7c" // }  HMAC-SHA1 fingerprint 
     529        "\x82\x92\xc2\x75" // } 
     530        "\xbf\xe3\xed\x41" // } 
     531        "\x80\x28\x00\x04" //    FINGERPRINT attribute header 
     532        "\xc8\xfb\x0b\x4c" //    CRC32 fingerprint 
     533, 
     534        92, 
     535        USE_MESSAGE_INTEGRITY | USE_FINGERPRINT, 
     536        "evtj:h6vY", 
     537        "VOkJxbRl1RmTxUk/WvJxBt", 
     538        "", 
     539        "", 
     540        &create_msgint3 
    490541    } 
    491542}; 
     
    538589    int rc = 0; 
    539590 
    540     PJ_LOG(3,(THIS_FILE, "  STUN message test vectors")); 
     591    PJ_LOG(3,(THIS_FILE, "  draft-denis-behave-rfc3489bis-test-vectors-02")); 
    541592 
    542593    pool = pj_pool_create(mem, "fingerprint", 1024, 1024, NULL); 
     
    586637        /* Encode message */ 
    587638        if (v->options & USE_MESSAGE_INTEGRITY) { 
    588             pj_str_t s1, s2; 
    589  
    590             pj_stun_create_key(pool, &key, NULL, pj_cstr(&s1, v->username),  
    591                                PJ_STUN_PASSWD_PLAIN, pj_cstr(&s2, v->password)); 
     639            pj_str_t s1, s2, r; 
     640 
     641            pj_stun_create_key(pool, &key, pj_cstr(&r, v->realm),  
     642                               pj_cstr(&s1, v->username),  
     643                               PJ_STUN_PASSWD_PLAIN,  
     644                               pj_cstr(&s2, v->password)); 
    592645            pj_stun_msg_encode(msg, buf, sizeof(buf), 0, &key, &len); 
    593646 
     
    626679                pj_bzero(&cred, sizeof(cred)); 
    627680                cred.type = PJ_STUN_AUTH_CRED_STATIC; 
     681                cred.data.static_cred.realm = pj_str(v->realm); 
    628682                cred.data.static_cred.username = pj_str(v->username); 
    629683                cred.data.static_cred.data = pj_str(v->password); 
     684                cred.data.static_cred.nonce = pj_str(v->nonce); 
    630685 
    631686                status = pj_stun_authenticate_request(buf, len, msg,  
     
    700755                                pj_cstr(&s1, "test vector")); 
    701756 
    702     pj_sockaddr_in_init(&mapped_addr, pj_cstr(&s1, "127.0.0.1"), 32853); 
     757    pj_sockaddr_in_init(&mapped_addr, pj_cstr(&s1, "192.0.2.1"), 32853); 
    703758    pj_stun_msg_add_sockaddr_attr(pool, msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 
    704759                                  PJ_TRUE, &mapped_addr,  
    705760                                  sizeof(pj_sockaddr_in)); 
     761 
     762    pj_stun_msg_add_msgint_attr(pool, msg); 
     763    pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); 
     764 
     765    return msg; 
     766} 
     767 
     768 
     769static pj_stun_msg* create_msgint3(pj_pool_t *pool, test_vector *v) 
     770{ 
     771    pj_stun_msg *msg; 
     772    pj_sockaddr mapped_addr; 
     773    pj_str_t s1; 
     774 
     775    pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, 
     776                       (pj_uint8_t*)v->tsx_id, &msg); 
     777 
     778    pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE,  
     779                                pj_cstr(&s1, "test vector")); 
     780 
     781    pj_sockaddr_init(pj_AF_INET6(), &mapped_addr, 
     782                     pj_cstr(&s1, "2001:db8:1234:5678:11:2233:4455:6677"), 
     783                     32853); 
     784 
     785    pj_stun_msg_add_sockaddr_attr(pool, msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 
     786                                  PJ_TRUE, &mapped_addr,  
     787                                  sizeof(pj_sockaddr)); 
    706788 
    707789    pj_stun_msg_add_msgint_attr(pool, msg); 
  • pjproject/trunk/pjnath/src/pjnath/errno.c

    r2394 r2580  
    5252    PJ_BUILD_ERR( PJNATH_ESTUNNOMAPPEDADDR, "STUN (XOR-)MAPPED-ADDRESS attribute not found"), 
    5353    PJ_BUILD_ERR( PJNATH_ESTUNIPV6NOTSUPP,  "STUN IPv6 attribute not supported"), 
     54    PJ_BUILD_ERR( PJNATH_EINVAF,            "Invalid STUN address family value"), 
    5455    PJ_BUILD_ERR( PJNATH_ESTUNINSERVER,     "Invalid STUN server or server not configured"), 
    5556 
  • pjproject/trunk/pjnath/src/pjnath/stun_msg.c

    r2394 r2580  
    8989    const char   *name; 
    9090    pj_status_t (*decode_attr)(pj_pool_t *pool, const pj_uint8_t *buf,  
    91                                void **p_attr); 
     91                               const pj_stun_msg_hdr *msghdr, void **p_attr); 
    9292    pj_status_t (*encode_attr)(const void *a, pj_uint8_t *buf,  
    93                                unsigned len, unsigned *printed); 
     93                               unsigned len, const pj_stun_msg_hdr *msghdr, 
     94                               unsigned *printed); 
    9495    void*       (*clone_attr)(pj_pool_t *pool, const void *src); 
    9596}; 
    9697 
    9798static pj_status_t decode_sockaddr_attr(pj_pool_t *pool,  
    98                                        const pj_uint8_t *buf,  
    99                                        void **p_attr); 
     99                                        const pj_uint8_t *buf,  
     100                                        const pj_stun_msg_hdr *msghdr, 
     101                                        void **p_attr); 
    100102static pj_status_t decode_xored_sockaddr_attr(pj_pool_t *pool,  
    101103                                              const pj_uint8_t *buf,  
     104                                              const pj_stun_msg_hdr *msghdr,  
    102105                                              void **p_attr); 
    103106static pj_status_t encode_sockaddr_attr(const void *a, pj_uint8_t *buf,  
    104                                        unsigned len,  
    105                                        unsigned *printed); 
     107                                        unsigned len,  
     108                                        const pj_stun_msg_hdr *msghdr, 
     109                                        unsigned *printed); 
    106110static void*       clone_sockaddr_attr(pj_pool_t *pool, const void *src); 
    107111static pj_status_t decode_string_attr(pj_pool_t *pool,  
    108112                                      const pj_uint8_t *buf,  
     113                                      const pj_stun_msg_hdr *msghdr,  
    109114                                      void **p_attr); 
    110115static pj_status_t encode_string_attr(const void *a, pj_uint8_t *buf,  
    111                                       unsigned len, unsigned *printed); 
     116                                      unsigned len,  
     117                                      const pj_stun_msg_hdr *msghdr, 
     118                                      unsigned *printed); 
    112119static void*       clone_string_attr(pj_pool_t *pool, const void *src); 
    113120static pj_status_t decode_msgint_attr(pj_pool_t *pool,  
    114121                                      const pj_uint8_t *buf, 
     122                                      const pj_stun_msg_hdr *msghdr,  
    115123                                      void **p_attr); 
    116124static pj_status_t encode_msgint_attr(const void *a, pj_uint8_t *buf,  
    117                                       unsigned len, unsigned *printed); 
     125                                      unsigned len,  
     126                                      const pj_stun_msg_hdr *msghdr, 
     127                                      unsigned *printed); 
    118128static void*       clone_msgint_attr(pj_pool_t *pool, const void *src); 
    119129static pj_status_t decode_errcode_attr(pj_pool_t *pool,  
    120130                                       const pj_uint8_t *buf, 
     131                                       const pj_stun_msg_hdr *msghdr,  
    121132                                       void **p_attr); 
    122133static pj_status_t encode_errcode_attr(const void *a, pj_uint8_t *buf,  
    123                                        unsigned len, unsigned *printed); 
     134                                       unsigned len,  
     135                                       const pj_stun_msg_hdr *msghdr, 
     136                                       unsigned *printed); 
    124137static void*       clone_errcode_attr(pj_pool_t *pool, const void *src); 
    125138static pj_status_t decode_unknown_attr(pj_pool_t *pool,  
    126139                                       const pj_uint8_t *buf,  
     140                                       const pj_stun_msg_hdr *msghdr,  
    127141                                       void **p_attr); 
    128142static pj_status_t encode_unknown_attr(const void *a, pj_uint8_t *buf,  
    129                                        unsigned len, unsigned *printed); 
     143                                       unsigned len,  
     144                                       const pj_stun_msg_hdr *msghdr, 
     145                                       unsigned *printed); 
    130146static void*       clone_unknown_attr(pj_pool_t *pool, const void *src); 
    131147static pj_status_t decode_uint_attr(pj_pool_t *pool,  
    132148                                    const pj_uint8_t *buf,  
     149                                    const pj_stun_msg_hdr *msghdr,  
    133150                                    void **p_attr); 
    134151static pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf,  
    135                                     unsigned len, unsigned *printed); 
     152                                    unsigned len,  
     153                                    const pj_stun_msg_hdr *msghdr, 
     154                                    unsigned *printed); 
    136155static void*       clone_uint_attr(pj_pool_t *pool, const void *src); 
    137156static pj_status_t decode_uint64_attr(pj_pool_t *pool,  
    138157                                      const pj_uint8_t *buf,  
     158                                      const pj_stun_msg_hdr *msghdr,  
    139159                                      void **p_attr); 
    140160static pj_status_t encode_uint64_attr(const void *a, pj_uint8_t *buf,  
    141                                       unsigned len, unsigned *printed); 
     161                                      unsigned len,  
     162                                      const pj_stun_msg_hdr *msghdr, 
     163                                      unsigned *printed); 
    142164static void*       clone_uint64_attr(pj_pool_t *pool, const void *src); 
    143165static pj_status_t decode_binary_attr(pj_pool_t *pool,  
    144166                                      const pj_uint8_t *buf, 
     167                                      const pj_stun_msg_hdr *msghdr,  
    145168                                      void **p_attr); 
    146169static pj_status_t encode_binary_attr(const void *a, pj_uint8_t *buf,  
    147                                       unsigned len, unsigned *printed); 
     170                                      unsigned len,  
     171                                      const pj_stun_msg_hdr *msghdr, 
     172                                      unsigned *printed); 
    148173static void*       clone_binary_attr(pj_pool_t *pool, const void *src); 
    149174static pj_status_t decode_empty_attr(pj_pool_t *pool,  
    150175                                     const pj_uint8_t *buf,  
     176                                     const pj_stun_msg_hdr *msghdr,  
    151177                                     void **p_attr); 
    152178static pj_status_t encode_empty_attr(const void *a, pj_uint8_t *buf,  
    153                                      unsigned len, unsigned *printed); 
     179                                     unsigned len,  
     180                                     const pj_stun_msg_hdr *msghdr, 
     181                                     unsigned *printed); 
    154182static void*       clone_empty_attr(pj_pool_t *pool, const void *src); 
    155183 
     
    727755} 
    728756 
    729 static pj_uint16_t GETVAL16N(const pj_uint8_t *buf, unsigned pos) 
     757PJ_INLINE(pj_uint16_t) GETVAL16N(const pj_uint8_t *buf, unsigned pos) 
    730758{ 
    731759    return pj_htons(GETVAL16H(buf,pos)); 
     
    738766} 
    739767 
    740 static pj_uint32_t GETVAL32H(const pj_uint8_t *buf, unsigned pos) 
     768PJ_INLINE(pj_uint32_t) GETVAL32H(const pj_uint8_t *buf, unsigned pos) 
    741769{ 
    742770    return (pj_uint32_t) ((buf[pos + 0] << 24UL) | \ 
     
    746774} 
    747775 
    748 static pj_uint32_t GETVAL32N(const pj_uint8_t *buf, unsigned pos) 
     776PJ_INLINE(pj_uint32_t) GETVAL32N(const pj_uint8_t *buf, unsigned pos) 
    749777{ 
    750778    return pj_htonl(GETVAL32H(buf,pos)); 
     
    782810 * STUN generic IP address container 
    783811 */ 
    784 #define STUN_GENERIC_IP_ADDR_LEN        8 
     812#define STUN_GENERIC_IPV4_ADDR_LEN      8 
     813#define STUN_GENERIC_IPV6_ADDR_LEN      20 
    785814 
    786815/* 
     
    793822                                                unsigned addr_len) 
    794823{ 
     824    unsigned attr_len; 
     825 
    795826    PJ_ASSERT_RETURN(attr && addr_len && addr, PJ_EINVAL); 
    796827    PJ_ASSERT_RETURN(addr_len == sizeof(pj_sockaddr_in) || 
    797828                     addr_len == sizeof(pj_sockaddr_in6), PJ_EINVAL); 
    798829 
    799     INIT_ATTR(attr, attr_type, STUN_GENERIC_IP_ADDR_LEN); 
     830    attr_len = pj_sockaddr_get_addr_len(addr) + 4; 
     831    INIT_ATTR(attr, attr_type, attr_len); 
    800832 
    801833    pj_memcpy(&attr->sockaddr, addr, addr_len); 
     
    849881static pj_status_t decode_sockaddr_attr(pj_pool_t *pool,  
    850882                                        const pj_uint8_t *buf,  
     883                                        const pj_stun_msg_hdr *msghdr,  
    851884                                        void **p_attr) 
    852885{ 
    853886    pj_stun_sockaddr_attr *attr; 
     887    int af; 
     888    unsigned addr_len; 
    854889    pj_uint32_t val; 
    855890 
    856891    PJ_CHECK_STACK(); 
    857892     
     893    PJ_UNUSED_ARG(msghdr); 
     894 
    858895    /* Create the attribute */ 
    859896    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr); 
     
    861898 
    862899    /* Check that the attribute length is valid */ 
    863     if (attr->hdr.length != STUN_GENERIC_IP_ADDR_LEN) 
     900    if (attr->hdr.length != STUN_GENERIC_IPV4_ADDR_LEN && 
     901        attr->hdr.length != STUN_GENERIC_IPV6_ADDR_LEN) 
     902    { 
    864903        return PJNATH_ESTUNINATTRLEN; 
     904    } 
    865905 
    866906    /* Check address family */ 
    867907    val = *(pj_uint8_t*)(buf + ATTR_HDR_LEN + 1); 
    868908 
    869     /* Check address family is valid (only supports ipv4 for now) */ 
    870     if (val != 1) 
    871         return PJNATH_ESTUNIPV6NOTSUPP; 
     909    /* Check address family is valid */ 
     910    if (val == 1) { 
     911        if (attr->hdr.length != STUN_GENERIC_IPV4_ADDR_LEN) 
     912            return PJNATH_ESTUNINATTRLEN; 
     913        af = pj_AF_INET(); 
     914        addr_len = 4; 
     915    } else if (val == 2) { 
     916        if (attr->hdr.length != STUN_GENERIC_IPV6_ADDR_LEN) 
     917            return PJNATH_ESTUNINATTRLEN; 
     918        af = pj_AF_INET6(); 
     919        addr_len = 16; 
     920    } else { 
     921        /* Invalid address family */ 
     922        return PJNATH_EINVAF; 
     923    } 
    872924 
    873925    /* Get port and address */ 
    874     pj_sockaddr_in_init(&attr->sockaddr.ipv4, NULL, 0); 
    875     attr->sockaddr.ipv4.sin_port = GETVAL16N(buf, ATTR_HDR_LEN+2); 
    876     attr->sockaddr.ipv4.sin_addr.s_addr = GETVAL32N(buf, ATTR_HDR_LEN+4); 
     926    pj_sockaddr_init(af, &attr->sockaddr, NULL, 0); 
     927    pj_sockaddr_set_port(&attr->sockaddr,  
     928                         GETVAL16H(buf, ATTR_HDR_LEN+2)); 
     929    pj_memcpy(pj_sockaddr_get_addr(&attr->sockaddr), 
     930              buf+ATTR_HDR_LEN+4, 
     931              addr_len); 
    877932 
    878933    /* Done */ 
     
    885940static pj_status_t decode_xored_sockaddr_attr(pj_pool_t *pool,  
    886941                                              const pj_uint8_t *buf,  
     942                                              const pj_stun_msg_hdr *msghdr,  
    887943                                              void **p_attr) 
    888944{ 
     
    890946    pj_status_t status; 
    891947 
    892     status = decode_sockaddr_attr(pool, buf, p_attr); 
     948    status = decode_sockaddr_attr(pool, buf, msghdr, p_attr); 
    893949    if (status != PJ_SUCCESS) 
    894950        return status; 
     
    897953 
    898954    attr->xor_ed = PJ_TRUE; 
    899     attr->sockaddr.ipv4.sin_port ^= pj_htons(0x2112); 
    900     attr->sockaddr.ipv4.sin_addr.s_addr ^= pj_htonl(0x2112A442); 
     955 
     956    if (attr->sockaddr.addr.sa_family == pj_AF_INET()) { 
     957        attr->sockaddr.ipv4.sin_port ^= pj_htons(PJ_STUN_MAGIC >> 16); 
     958        attr->sockaddr.ipv4.sin_addr.s_addr ^= pj_htonl(PJ_STUN_MAGIC); 
     959    } else if (attr->sockaddr.addr.sa_family == pj_AF_INET6()) { 
     960        unsigned i; 
     961        pj_uint8_t *dst = (pj_uint8_t*) &attr->sockaddr.ipv6.sin6_addr; 
     962        pj_uint32_t magic = pj_htonl(PJ_STUN_MAGIC); 
     963 
     964        attr->sockaddr.ipv6.sin6_port ^= pj_htons(PJ_STUN_MAGIC >> 16); 
     965 
     966        /* If the IP address family is IPv6, X-Address is computed by 
     967         * taking the mapped IP address in host byte order, XOR'ing it 
     968         * with the concatenation of the magic cookie and the 96-bit  
     969         * transaction ID, and converting the result to network byte  
     970         * order. 
     971         */ 
     972        for (i=0; i<4; ++i) { 
     973            dst[i] ^= ((const pj_uint8_t*)&magic)[i]; 
     974        } 
     975        pj_assert(sizeof(msghdr->tsx_id[0]) == 1); 
     976        for (i=0; i<12; ++i) { 
     977            dst[i+4] ^= msghdr->tsx_id[i]; 
     978        } 
     979 
     980    } else { 
     981        return PJNATH_EINVAF; 
     982    } 
    901983 
    902984    /* Done */ 
     
    908990 
    909991static pj_status_t encode_sockaddr_attr(const void *a, pj_uint8_t *buf,  
    910                                         unsigned len, unsigned *printed) 
    911 { 
    912     enum { 
    913         ATTR_LEN = ATTR_HDR_LEN + STUN_GENERIC_IP_ADDR_LEN 
    914     }; 
     992                                        unsigned len,  
     993                                        const pj_stun_msg_hdr *msghdr, 
     994                                        unsigned *printed) 
     995{ 
    915996    pj_uint8_t *start_buf = buf; 
    916997    const pj_stun_sockaddr_attr *ca =  
    917998        (const pj_stun_sockaddr_attr *)a; 
    918999 
    919     if (len < ATTR_LEN)  
    920         return PJ_ETOOSMALL; 
    921  
    9221000    PJ_CHECK_STACK(); 
    9231001     
    924     /* Copy and convert headers to network byte order */ 
     1002    /* Common: attribute type */ 
    9251003    PUTVAL16H(buf, 0, ca->hdr.type); 
    926     PUTVAL16H(buf, 2, STUN_GENERIC_IP_ADDR_LEN); 
    927     buf += ATTR_HDR_LEN; 
     1004 
     1005    if (ca->sockaddr.addr.sa_family == pj_AF_INET()) { 
     1006        enum { 
     1007            ATTR_LEN = ATTR_HDR_LEN + STUN_GENERIC_IPV4_ADDR_LEN 
     1008        }; 
     1009 
     1010        if (len < ATTR_LEN)  
     1011            return PJ_ETOOSMALL; 
     1012 
     1013        /* attribute len */ 
     1014        PUTVAL16H(buf, 2, STUN_GENERIC_IPV4_ADDR_LEN); 
     1015        buf += ATTR_HDR_LEN; 
    9281016     
    929     /* Ignored */ 
    930     *buf++ = '\0'; 
    931  
    932     /* Family (IPv4 only for now) */ 
    933     PJ_ASSERT_RETURN(ca->sockaddr.addr.sa_family == pj_AF_INET(), PJ_EINVAL); 
    934     *buf++ = 1; 
    935  
    936     if (ca->xor_ed) { 
    937         pj_uint32_t addr; 
    938         pj_uint16_t port; 
    939  
    940         addr = ca->sockaddr.ipv4.sin_addr.s_addr; 
    941         port = ca->sockaddr.ipv4.sin_port; 
    942  
    943         port ^= pj_htons(0x2112); 
    944         addr ^= pj_htonl(0x2112A442); 
    945  
    946         /* Port */ 
    947         pj_memcpy(buf, &port, 2); 
    948         buf += 2; 
    949  
    950         /* Address */ 
    951         pj_memcpy(buf, &addr, 4); 
    952         buf += 4; 
     1017        /* Ignored */ 
     1018        *buf++ = '\0'; 
     1019 
     1020        /* Address family, 1 for IPv4 */ 
     1021        *buf++ = 1; 
     1022 
     1023        /* IPv4 address */ 
     1024        if (ca->xor_ed) { 
     1025            pj_uint32_t addr; 
     1026            pj_uint16_t port; 
     1027 
     1028            addr = ca->sockaddr.ipv4.sin_addr.s_addr; 
     1029            port = ca->sockaddr.ipv4.sin_port; 
     1030 
     1031            port ^= pj_htons(PJ_STUN_MAGIC >> 16); 
     1032            addr ^= pj_htonl(PJ_STUN_MAGIC); 
     1033 
     1034            /* Port */ 
     1035            pj_memcpy(buf, &port, 2); 
     1036            buf += 2; 
     1037 
     1038            /* Address */ 
     1039            pj_memcpy(buf, &addr, 4); 
     1040            buf += 4; 
     1041 
     1042        } else { 
     1043            /* Port */ 
     1044            pj_memcpy(buf, &ca->sockaddr.ipv4.sin_port, 2); 
     1045            buf += 2; 
     1046 
     1047            /* Address */ 
     1048            pj_memcpy(buf, &ca->sockaddr.ipv4.sin_addr, 4); 
     1049            buf += 4; 
     1050        } 
     1051 
     1052        pj_assert(buf - start_buf == ATTR_LEN); 
     1053 
     1054    } else if (ca->sockaddr.addr.sa_family == pj_AF_INET6()) { 
     1055        /* IPv6 address */ 
     1056        enum { 
     1057            ATTR_LEN = ATTR_HDR_LEN + STUN_GENERIC_IPV6_ADDR_LEN 
     1058        }; 
     1059 
     1060        if (len < ATTR_LEN)  
     1061            return PJ_ETOOSMALL; 
     1062 
     1063        /* attribute len */ 
     1064        PUTVAL16H(buf, 2, STUN_GENERIC_IPV6_ADDR_LEN); 
     1065        buf += ATTR_HDR_LEN; 
     1066     
     1067        /* Ignored */ 
     1068        *buf++ = '\0'; 
     1069 
     1070        /* Address family, 2 for IPv6 */ 
     1071        *buf++ = 2; 
     1072 
     1073        /* IPv6 address */ 
     1074        if (ca->xor_ed) { 
     1075            unsigned i; 
     1076            pj_uint8_t *dst; 
     1077            const pj_uint8_t *src; 
     1078            pj_uint32_t magic = pj_htonl(PJ_STUN_MAGIC); 
     1079            pj_uint16_t port = ca->sockaddr.ipv6.sin6_port; 
     1080 
     1081            /* Port */ 
     1082            port ^= pj_htons(PJ_STUN_MAGIC >> 16); 
     1083            pj_memcpy(buf, &port, 2); 
     1084            buf += 2; 
     1085 
     1086            /* Address */ 
     1087            dst = buf; 
     1088            src = (const pj_uint8_t*) &ca->sockaddr.ipv6.sin6_addr; 
     1089            for (i=0; i<4; ++i) { 
     1090                dst[i] = (pj_uint8_t)(src[i] ^ ((const pj_uint8_t*)&magic)[i]); 
     1091            } 
     1092            pj_assert(sizeof(msghdr->tsx_id[0]) == 1); 
     1093            for (i=0; i<12; ++i) { 
     1094                dst[i+4] = (pj_uint8_t)(src[i+4] ^ msghdr->tsx_id[i]); 
     1095            } 
     1096 
     1097            buf += 16; 
     1098 
     1099        } else { 
     1100            /* Port */ 
     1101            pj_memcpy(buf, &ca->sockaddr.ipv6.sin6_port, 2); 
     1102            buf += 2; 
     1103 
     1104            /* Address */ 
     1105            pj_memcpy(buf, &ca->sockaddr.ipv6.sin6_addr, 16); 
     1106            buf += 16; 
     1107        } 
     1108 
     1109        pj_assert(buf - start_buf == ATTR_LEN); 
    9531110 
    9541111    } else { 
    955         /* Port */ 
    956         pj_memcpy(buf, &ca->sockaddr.ipv4.sin_port, 2); 
    957         buf += 2; 
    958  
    959         /* Address */ 
    960         pj_memcpy(buf, &ca->sockaddr.ipv4.sin_addr, 4); 
    961         buf += 4; 
    962     } 
    963  
    964     pj_assert(buf - start_buf == ATTR_LEN); 
     1112        return PJNATH_EINVAF; 
     1113    } 
    9651114 
    9661115    /* Done */ 
     
    10411190static pj_status_t decode_string_attr(pj_pool_t *pool,  
    10421191                                      const pj_uint8_t *buf,  
     1192                                      const pj_stun_msg_hdr *msghdr,  
    10431193                                      void **p_attr) 
    10441194{ 
    10451195    pj_stun_string_attr *attr; 
    10461196    pj_str_t value; 
     1197 
     1198    PJ_UNUSED_ARG(msghdr); 
    10471199 
    10481200    /* Create the attribute */ 
     
    10661218 
    10671219static pj_status_t encode_string_attr(const void *a, pj_uint8_t *buf,  
    1068                                       unsigned len, unsigned *printed) 
     1220                                      unsigned len,  
     1221                                      const pj_stun_msg_hdr *msghdr, 
     1222                                      unsigned *printed) 
    10691223{ 
    10701224    const pj_stun_string_attr *ca =  
     
    10731227    PJ_CHECK_STACK(); 
    10741228     
     1229    PJ_UNUSED_ARG(msghdr); 
     1230 
    10751231    /* Calculated total attr_len (add padding if necessary) */ 
    10761232    *printed = (ca->value.slen + ATTR_HDR_LEN + 3) & (~3); 
     
    11551311static pj_status_t decode_empty_attr(pj_pool_t *pool,  
    11561312                                     const pj_uint8_t *buf,  
     1313                                     const pj_stun_msg_hdr *msghdr, 
    11571314                                     void **p_attr) 
    11581315{ 
    11591316    pj_stun_empty_attr *attr; 
     1317 
     1318    PJ_UNUSED_ARG(msghdr); 
    11601319 
    11611320    /* Check that the struct address is valid */ 
     
    11781337 
    11791338static pj_status_t encode_empty_attr(const void *a, pj_uint8_t *buf,  
    1180                                      unsigned len, unsigned *printed) 
     1339                                     unsigned len,  
     1340                                     const pj_stun_msg_hdr *msghdr, 
     1341                                     unsigned *printed) 
    11811342{ 
    11821343    const pj_stun_empty_attr *ca = (pj_stun_empty_attr*)a; 
     1344 
     1345    PJ_UNUSED_ARG(msghdr); 
    11831346 
    11841347    if (len < ATTR_HDR_LEN)  
     
    12481411static pj_status_t decode_uint_attr(pj_pool_t *pool,  
    12491412                                    const pj_uint8_t *buf,  
     1413                                    const pj_stun_msg_hdr *msghdr,  
    12501414                                    void **p_attr) 
    12511415{ 
    12521416    pj_stun_uint_attr *attr; 
     1417 
     1418    PJ_UNUSED_ARG(msghdr); 
    12531419 
    12541420    /* Create the attribute */ 
     
    12701436 
    12711437static pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf,  
    1272                                     unsigned len, unsigned *printed) 
     1438                                    unsigned len,  
     1439                                    const pj_stun_msg_hdr *msghdr, 
     1440                                    unsigned *printed) 
    12731441{ 
    12741442    const pj_stun_uint_attr *ca = (const pj_stun_uint_attr*)a; 
    12751443 
    12761444    PJ_CHECK_STACK(); 
     1445 
     1446    PJ_UNUSED_ARG(msghdr); 
    12771447     
    12781448    if (len < 8)  
     
    13441514static pj_status_t decode_uint64_attr(pj_pool_t *pool,  
    13451515                                      const pj_uint8_t *buf,  
     1516                                      const pj_stun_msg_hdr *msghdr,  
    13461517                                      void **p_attr) 
    13471518{ 
    13481519    pj_stun_uint64_attr *attr; 
     1520 
     1521    PJ_UNUSED_ARG(msghdr); 
    13491522 
    13501523    /* Create the attribute */ 
     
    13651538 
    13661539static pj_status_t encode_uint64_attr(const void *a, pj_uint8_t *buf,  
    1367                                       unsigned len, unsigned *printed) 
     1540                                      unsigned len,  
     1541                                      const pj_stun_msg_hdr *msghdr, 
     1542                                      unsigned *printed) 
    13681543{ 
    13691544    const pj_stun_uint64_attr *ca = (const pj_stun_uint64_attr*)a; 
    13701545 
    13711546    PJ_CHECK_STACK(); 
     1547 
     1548    PJ_UNUSED_ARG(msghdr); 
    13721549     
    13731550    if (len < 12)  
     
    14341611static pj_status_t decode_msgint_attr(pj_pool_t *pool,  
    14351612                                      const pj_uint8_t *buf, 
     1613                                      const pj_stun_msg_hdr *msghdr,  
    14361614                                      void **p_attr) 
    14371615{ 
    14381616    pj_stun_msgint_attr *attr; 
     1617 
     1618    PJ_UNUSED_ARG(msghdr); 
    14391619 
    14401620    /* Create attribute */ 
     
    14561636 
    14571637static pj_status_t encode_msgint_attr(const void *a, pj_uint8_t *buf,  
    1458                                       unsigned len, unsigned *printed) 
     1638                                      unsigned len,  
     1639                                      const pj_stun_msg_hdr *msghdr, 
     1640                                      unsigned *printed) 
    14591641{ 
    14601642    const pj_stun_msgint_attr *ca = (const pj_stun_msgint_attr*)a; 
     
    14621644    PJ_CHECK_STACK(); 
    14631645     
     1646    PJ_UNUSED_ARG(msghdr); 
     1647 
    14641648    if (len < 24)  
    14651649        return PJ_ETOOSMALL; 
     
    15451729static pj_status_t decode_errcode_attr(pj_pool_t *pool,  
    15461730                                       const pj_uint8_t *buf, 
     1731                                       const pj_stun_msg_hdr *msghdr,  
    15471732                                       void **p_attr) 
    15481733{ 
    15491734    pj_stun_errcode_attr *attr; 
    15501735    pj_str_t value; 
     1736 
     1737    PJ_UNUSED_ARG(msghdr); 
    15511738 
    15521739    /* Create the attribute */ 
     
    15711758 
    15721759static pj_status_t encode_errcode_attr(const void *a, pj_uint8_t *buf,  
    1573                                        unsigned len, unsigned *printed) 
     1760                                       unsigned len,  
     1761                                       const pj_stun_msg_hdr *msghdr, 
     1762                                       unsigned *printed) 
    15741763{ 
    15751764    const pj_stun_errcode_attr *ca =  
     
    15781767    PJ_CHECK_STACK(); 
    15791768     
     1769    PJ_UNUSED_ARG(msghdr); 
     1770 
    15801771    if (len < ATTR_HDR_LEN + 4 + (unsigned)ca->reason.slen)  
    15811772        return PJ_ETOOSMALL; 
     
    16731864static pj_status_t decode_unknown_attr(pj_pool_t *pool,  
    16741865                                       const pj_uint8_t *buf,  
     1866                                       const pj_stun_msg_hdr *msghdr,  
    16751867                                       void **p_attr) 
    16761868{ 
     
    16781870    const pj_uint16_t *punk_attr; 
    16791871    unsigned i; 
     1872 
     1873    PJ_UNUSED_ARG(msghdr); 
    16801874 
    16811875    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_unknown_attr); 
     
    16991893 
    17001894static pj_status_t encode_unknown_attr(const void *a, pj_uint8_t *buf,  
    1701                                        unsigned len, unsigned *printed) 
     1895                                       unsigned len,  
     1896                                       const pj_stun_msg_hdr *msghdr, 
     1897                                       unsigned *printed) 
    17021898{ 
    17031899    const pj_stun_unknown_attr *ca = (const pj_stun_unknown_attr*) a; 
     
    17071903    PJ_CHECK_STACK(); 
    17081904     
     1905    PJ_UNUSED_ARG(msghdr); 
     1906 
    17091907    /* Check that buffer is enough */ 
    17101908    if (len < ATTR_HDR_LEN + (ca->attr_count << 1)) 
     
    18082006static pj_status_t decode_binary_attr(pj_pool_t *pool,  
    18092007                                      const pj_uint8_t *buf, 
     2008                                      const pj_stun_msg_hdr *msghdr, 
    18102009                                      void **p_attr) 
    18112010{ 
    18122011    pj_stun_binary_attr *attr; 
     2012 
     2013    PJ_UNUSED_ARG(msghdr); 
    18132014 
    18142015    /* Create the attribute */ 
     
    18302031 
    18312032static pj_status_t encode_binary_attr(const void *a, pj_uint8_t *buf,  
    1832                                       unsigned len, unsigned *printed) 
     2033                                      unsigned len,  
     2034                                      const pj_stun_msg_hdr *msghdr, 
     2035                                      unsigned *printed) 
    18332036{ 
    18342037    const pj_stun_binary_attr *ca = (const pj_stun_binary_attr*)a; 
     
    18362039    PJ_CHECK_STACK(); 
    18372040     
     2041    PJ_UNUSED_ARG(msghdr); 
     2042 
    18382043    /* Calculated total attr_len (add padding if necessary) */ 
    18392044    *printed = (ca->length + ATTR_HDR_LEN + 3) & (~3); 
     
    22212426 
    22222427            /* Parse the attribute */ 
    2223             status = (adesc->decode_attr)(pool, pdu, &attr); 
     2428            status = (adesc->decode_attr)(pool, pdu, &msg->hdr, &attr); 
    22242429 
    22252430            if (status != PJ_SUCCESS) { 
     
    24092614        adesc = find_attr_desc(attr_hdr->type); 
    24102615        if (adesc) { 
    2411             status = adesc->encode_attr(attr_hdr, buf, buf_size, &printed); 
     2616            status = adesc->encode_attr(attr_hdr, buf, buf_size, &msg->hdr,  
     2617                                        &printed); 
    24122618        } else { 
    24132619            /* This may be a generic attribute */ 
     
    24152621                                                   attr_hdr; 
    24162622            PJ_ASSERT_RETURN(bin_attr->magic == PJ_STUN_MAGIC, PJ_EBUG); 
    2417             status = encode_binary_attr(bin_attr, buf, buf_size, &printed); 
     2623            status = encode_binary_attr(bin_attr, buf, buf_size, &msg->hdr, 
     2624                                        &printed); 
    24182625        } 
    24192626 
     
    25202727        /* Put this attribute in the message */ 
    25212728        status = encode_msgint_attr(amsgint, buf, buf_size,  
    2522                                     &printed); 
     2729                                    &msg->hdr, &printed); 
    25232730        if (status != PJ_SUCCESS) 
    25242731            return status; 
     
    25422749        /* Put this attribute in the message */ 
    25432750        status = encode_uint_attr(afingerprint, buf, buf_size,  
    2544                                           &printed); 
     2751                                  &msg->hdr, &printed); 
    25452752        if (status != PJ_SUCCESS) 
    25462753            return status; 
Note: See TracChangeset for help on using the changeset viewer.