Changeset 2580
- Timestamp:
- Apr 7, 2009 9:42:58 AM (16 years ago)
- Location:
- pjproject/trunk/pjnath
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/include/pjnath/errno.h
r2394 r2580 115 115 */ 116 116 #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 */ 117 122 118 123 /** … … 120 125 * Invalid STUN server or server not configured. 121 126 */ 122 #define PJNATH_ESTUNINSERVER (PJNATH_ERRNO_START+ 42) /* 370042*/127 #define PJNATH_ESTUNINSERVER (PJNATH_ERRNO_START+50) /* 370050 */ 123 128 124 129 -
pjproject/trunk/pjnath/include/pjnath/types.h
r2394 r2580 98 98 keep NAT bindings open. 99 99 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), 100 This 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), 104 103 105 104 -
pjproject/trunk/pjnath/src/pjnath-test/stun.c
r2394 r2580 431 431 } 432 432 433 /* 434 * Test vectors, from: 435 * http://tools.ietf.org/html/draft-denis-behave-rfc3489bis-test-vectors-02 436 */ 433 437 typedef struct test_vector test_vector; 434 438 435 439 static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v); 436 440 static pj_stun_msg* create_msgint2(pj_pool_t *pool, test_vector *v); 441 static pj_stun_msg* create_msgint3(pj_pool_t *pool, test_vector *v); 437 442 438 443 enum … … 442 447 }; 443 448 444 st ruct test_vector449 static struct test_vector 445 450 { 446 451 unsigned msg_type; … … 451 456 char *username; 452 457 char *password; 458 char *realm; 459 char *nonce; 453 460 pj_stun_msg* (*create)(pj_pool_t*, test_vector*); 454 461 } test_vectors[] = … … 470 477 "evtj:h6vY", 471 478 "VOkJxbRl1RmTxUk/WvJxBt", 479 "", 480 "", 472 481 &create_msgint1 473 482 }, … … 475 484 PJ_STUN_BINDING_RESPONSE, 476 485 "\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", 485 498 80, 486 499 USE_MESSAGE_INTEGRITY | USE_FINGERPRINT, 487 500 "evtj:h6vY", 488 501 "VOkJxbRl1RmTxUk/WvJxBt", 502 "", 503 "", 489 504 &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 490 541 } 491 542 }; … … 538 589 int rc = 0; 539 590 540 PJ_LOG(3,(THIS_FILE, " STUN message test vectors"));591 PJ_LOG(3,(THIS_FILE, " draft-denis-behave-rfc3489bis-test-vectors-02")); 541 592 542 593 pool = pj_pool_create(mem, "fingerprint", 1024, 1024, NULL); … … 586 637 /* Encode message */ 587 638 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)); 592 645 pj_stun_msg_encode(msg, buf, sizeof(buf), 0, &key, &len); 593 646 … … 626 679 pj_bzero(&cred, sizeof(cred)); 627 680 cred.type = PJ_STUN_AUTH_CRED_STATIC; 681 cred.data.static_cred.realm = pj_str(v->realm); 628 682 cred.data.static_cred.username = pj_str(v->username); 629 683 cred.data.static_cred.data = pj_str(v->password); 684 cred.data.static_cred.nonce = pj_str(v->nonce); 630 685 631 686 status = pj_stun_authenticate_request(buf, len, msg, … … 700 755 pj_cstr(&s1, "test vector")); 701 756 702 pj_sockaddr_in_init(&mapped_addr, pj_cstr(&s1, "1 27.0.0.1"), 32853);757 pj_sockaddr_in_init(&mapped_addr, pj_cstr(&s1, "192.0.2.1"), 32853); 703 758 pj_stun_msg_add_sockaddr_attr(pool, msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 704 759 PJ_TRUE, &mapped_addr, 705 760 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 769 static 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)); 706 788 707 789 pj_stun_msg_add_msgint_attr(pool, msg); -
pjproject/trunk/pjnath/src/pjnath/errno.c
r2394 r2580 52 52 PJ_BUILD_ERR( PJNATH_ESTUNNOMAPPEDADDR, "STUN (XOR-)MAPPED-ADDRESS attribute not found"), 53 53 PJ_BUILD_ERR( PJNATH_ESTUNIPV6NOTSUPP, "STUN IPv6 attribute not supported"), 54 PJ_BUILD_ERR( PJNATH_EINVAF, "Invalid STUN address family value"), 54 55 PJ_BUILD_ERR( PJNATH_ESTUNINSERVER, "Invalid STUN server or server not configured"), 55 56 -
pjproject/trunk/pjnath/src/pjnath/stun_msg.c
r2394 r2580 89 89 const char *name; 90 90 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); 92 92 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); 94 95 void* (*clone_attr)(pj_pool_t *pool, const void *src); 95 96 }; 96 97 97 98 static 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); 100 102 static pj_status_t decode_xored_sockaddr_attr(pj_pool_t *pool, 101 103 const pj_uint8_t *buf, 104 const pj_stun_msg_hdr *msghdr, 102 105 void **p_attr); 103 106 static 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); 106 110 static void* clone_sockaddr_attr(pj_pool_t *pool, const void *src); 107 111 static pj_status_t decode_string_attr(pj_pool_t *pool, 108 112 const pj_uint8_t *buf, 113 const pj_stun_msg_hdr *msghdr, 109 114 void **p_attr); 110 115 static 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); 112 119 static void* clone_string_attr(pj_pool_t *pool, const void *src); 113 120 static pj_status_t decode_msgint_attr(pj_pool_t *pool, 114 121 const pj_uint8_t *buf, 122 const pj_stun_msg_hdr *msghdr, 115 123 void **p_attr); 116 124 static 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); 118 128 static void* clone_msgint_attr(pj_pool_t *pool, const void *src); 119 129 static pj_status_t decode_errcode_attr(pj_pool_t *pool, 120 130 const pj_uint8_t *buf, 131 const pj_stun_msg_hdr *msghdr, 121 132 void **p_attr); 122 133 static 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); 124 137 static void* clone_errcode_attr(pj_pool_t *pool, const void *src); 125 138 static pj_status_t decode_unknown_attr(pj_pool_t *pool, 126 139 const pj_uint8_t *buf, 140 const pj_stun_msg_hdr *msghdr, 127 141 void **p_attr); 128 142 static 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); 130 146 static void* clone_unknown_attr(pj_pool_t *pool, const void *src); 131 147 static pj_status_t decode_uint_attr(pj_pool_t *pool, 132 148 const pj_uint8_t *buf, 149 const pj_stun_msg_hdr *msghdr, 133 150 void **p_attr); 134 151 static 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); 136 155 static void* clone_uint_attr(pj_pool_t *pool, const void *src); 137 156 static pj_status_t decode_uint64_attr(pj_pool_t *pool, 138 157 const pj_uint8_t *buf, 158 const pj_stun_msg_hdr *msghdr, 139 159 void **p_attr); 140 160 static 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); 142 164 static void* clone_uint64_attr(pj_pool_t *pool, const void *src); 143 165 static pj_status_t decode_binary_attr(pj_pool_t *pool, 144 166 const pj_uint8_t *buf, 167 const pj_stun_msg_hdr *msghdr, 145 168 void **p_attr); 146 169 static 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); 148 173 static void* clone_binary_attr(pj_pool_t *pool, const void *src); 149 174 static pj_status_t decode_empty_attr(pj_pool_t *pool, 150 175 const pj_uint8_t *buf, 176 const pj_stun_msg_hdr *msghdr, 151 177 void **p_attr); 152 178 static 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); 154 182 static void* clone_empty_attr(pj_pool_t *pool, const void *src); 155 183 … … 727 755 } 728 756 729 static pj_uint16_tGETVAL16N(const pj_uint8_t *buf, unsigned pos)757 PJ_INLINE(pj_uint16_t) GETVAL16N(const pj_uint8_t *buf, unsigned pos) 730 758 { 731 759 return pj_htons(GETVAL16H(buf,pos)); … … 738 766 } 739 767 740 static pj_uint32_tGETVAL32H(const pj_uint8_t *buf, unsigned pos)768 PJ_INLINE(pj_uint32_t) GETVAL32H(const pj_uint8_t *buf, unsigned pos) 741 769 { 742 770 return (pj_uint32_t) ((buf[pos + 0] << 24UL) | \ … … 746 774 } 747 775 748 static pj_uint32_tGETVAL32N(const pj_uint8_t *buf, unsigned pos)776 PJ_INLINE(pj_uint32_t) GETVAL32N(const pj_uint8_t *buf, unsigned pos) 749 777 { 750 778 return pj_htonl(GETVAL32H(buf,pos)); … … 782 810 * STUN generic IP address container 783 811 */ 784 #define STUN_GENERIC_IP_ADDR_LEN 8 812 #define STUN_GENERIC_IPV4_ADDR_LEN 8 813 #define STUN_GENERIC_IPV6_ADDR_LEN 20 785 814 786 815 /* … … 793 822 unsigned addr_len) 794 823 { 824 unsigned attr_len; 825 795 826 PJ_ASSERT_RETURN(attr && addr_len && addr, PJ_EINVAL); 796 827 PJ_ASSERT_RETURN(addr_len == sizeof(pj_sockaddr_in) || 797 828 addr_len == sizeof(pj_sockaddr_in6), PJ_EINVAL); 798 829 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); 800 832 801 833 pj_memcpy(&attr->sockaddr, addr, addr_len); … … 849 881 static pj_status_t decode_sockaddr_attr(pj_pool_t *pool, 850 882 const pj_uint8_t *buf, 883 const pj_stun_msg_hdr *msghdr, 851 884 void **p_attr) 852 885 { 853 886 pj_stun_sockaddr_attr *attr; 887 int af; 888 unsigned addr_len; 854 889 pj_uint32_t val; 855 890 856 891 PJ_CHECK_STACK(); 857 892 893 PJ_UNUSED_ARG(msghdr); 894 858 895 /* Create the attribute */ 859 896 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr); … … 861 898 862 899 /* 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 { 864 903 return PJNATH_ESTUNINATTRLEN; 904 } 865 905 866 906 /* Check address family */ 867 907 val = *(pj_uint8_t*)(buf + ATTR_HDR_LEN + 1); 868 908 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 } 872 924 873 925 /* 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); 877 932 878 933 /* Done */ … … 885 940 static pj_status_t decode_xored_sockaddr_attr(pj_pool_t *pool, 886 941 const pj_uint8_t *buf, 942 const pj_stun_msg_hdr *msghdr, 887 943 void **p_attr) 888 944 { … … 890 946 pj_status_t status; 891 947 892 status = decode_sockaddr_attr(pool, buf, p_attr);948 status = decode_sockaddr_attr(pool, buf, msghdr, p_attr); 893 949 if (status != PJ_SUCCESS) 894 950 return status; … … 897 953 898 954 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 } 901 983 902 984 /* Done */ … … 908 990 909 991 static 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 { 915 996 pj_uint8_t *start_buf = buf; 916 997 const pj_stun_sockaddr_attr *ca = 917 998 (const pj_stun_sockaddr_attr *)a; 918 999 919 if (len < ATTR_LEN)920 return PJ_ETOOSMALL;921 922 1000 PJ_CHECK_STACK(); 923 1001 924 /* Co py and convert headers to network byte order*/1002 /* Common: attribute type */ 925 1003 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; 928 1016 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); 953 1110 954 1111 } 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 } 965 1114 966 1115 /* Done */ … … 1041 1190 static pj_status_t decode_string_attr(pj_pool_t *pool, 1042 1191 const pj_uint8_t *buf, 1192 const pj_stun_msg_hdr *msghdr, 1043 1193 void **p_attr) 1044 1194 { 1045 1195 pj_stun_string_attr *attr; 1046 1196 pj_str_t value; 1197 1198 PJ_UNUSED_ARG(msghdr); 1047 1199 1048 1200 /* Create the attribute */ … … 1066 1218 1067 1219 static 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) 1069 1223 { 1070 1224 const pj_stun_string_attr *ca = … … 1073 1227 PJ_CHECK_STACK(); 1074 1228 1229 PJ_UNUSED_ARG(msghdr); 1230 1075 1231 /* Calculated total attr_len (add padding if necessary) */ 1076 1232 *printed = (ca->value.slen + ATTR_HDR_LEN + 3) & (~3); … … 1155 1311 static pj_status_t decode_empty_attr(pj_pool_t *pool, 1156 1312 const pj_uint8_t *buf, 1313 const pj_stun_msg_hdr *msghdr, 1157 1314 void **p_attr) 1158 1315 { 1159 1316 pj_stun_empty_attr *attr; 1317 1318 PJ_UNUSED_ARG(msghdr); 1160 1319 1161 1320 /* Check that the struct address is valid */ … … 1178 1337 1179 1338 static 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) 1181 1342 { 1182 1343 const pj_stun_empty_attr *ca = (pj_stun_empty_attr*)a; 1344 1345 PJ_UNUSED_ARG(msghdr); 1183 1346 1184 1347 if (len < ATTR_HDR_LEN) … … 1248 1411 static pj_status_t decode_uint_attr(pj_pool_t *pool, 1249 1412 const pj_uint8_t *buf, 1413 const pj_stun_msg_hdr *msghdr, 1250 1414 void **p_attr) 1251 1415 { 1252 1416 pj_stun_uint_attr *attr; 1417 1418 PJ_UNUSED_ARG(msghdr); 1253 1419 1254 1420 /* Create the attribute */ … … 1270 1436 1271 1437 static 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) 1273 1441 { 1274 1442 const pj_stun_uint_attr *ca = (const pj_stun_uint_attr*)a; 1275 1443 1276 1444 PJ_CHECK_STACK(); 1445 1446 PJ_UNUSED_ARG(msghdr); 1277 1447 1278 1448 if (len < 8) … … 1344 1514 static pj_status_t decode_uint64_attr(pj_pool_t *pool, 1345 1515 const pj_uint8_t *buf, 1516 const pj_stun_msg_hdr *msghdr, 1346 1517 void **p_attr) 1347 1518 { 1348 1519 pj_stun_uint64_attr *attr; 1520 1521 PJ_UNUSED_ARG(msghdr); 1349 1522 1350 1523 /* Create the attribute */ … … 1365 1538 1366 1539 static 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) 1368 1543 { 1369 1544 const pj_stun_uint64_attr *ca = (const pj_stun_uint64_attr*)a; 1370 1545 1371 1546 PJ_CHECK_STACK(); 1547 1548 PJ_UNUSED_ARG(msghdr); 1372 1549 1373 1550 if (len < 12) … … 1434 1611 static pj_status_t decode_msgint_attr(pj_pool_t *pool, 1435 1612 const pj_uint8_t *buf, 1613 const pj_stun_msg_hdr *msghdr, 1436 1614 void **p_attr) 1437 1615 { 1438 1616 pj_stun_msgint_attr *attr; 1617 1618 PJ_UNUSED_ARG(msghdr); 1439 1619 1440 1620 /* Create attribute */ … … 1456 1636 1457 1637 static 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) 1459 1641 { 1460 1642 const pj_stun_msgint_attr *ca = (const pj_stun_msgint_attr*)a; … … 1462 1644 PJ_CHECK_STACK(); 1463 1645 1646 PJ_UNUSED_ARG(msghdr); 1647 1464 1648 if (len < 24) 1465 1649 return PJ_ETOOSMALL; … … 1545 1729 static pj_status_t decode_errcode_attr(pj_pool_t *pool, 1546 1730 const pj_uint8_t *buf, 1731 const pj_stun_msg_hdr *msghdr, 1547 1732 void **p_attr) 1548 1733 { 1549 1734 pj_stun_errcode_attr *attr; 1550 1735 pj_str_t value; 1736 1737 PJ_UNUSED_ARG(msghdr); 1551 1738 1552 1739 /* Create the attribute */ … … 1571 1758 1572 1759 static 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) 1574 1763 { 1575 1764 const pj_stun_errcode_attr *ca = … … 1578 1767 PJ_CHECK_STACK(); 1579 1768 1769 PJ_UNUSED_ARG(msghdr); 1770 1580 1771 if (len < ATTR_HDR_LEN + 4 + (unsigned)ca->reason.slen) 1581 1772 return PJ_ETOOSMALL; … … 1673 1864 static pj_status_t decode_unknown_attr(pj_pool_t *pool, 1674 1865 const pj_uint8_t *buf, 1866 const pj_stun_msg_hdr *msghdr, 1675 1867 void **p_attr) 1676 1868 { … … 1678 1870 const pj_uint16_t *punk_attr; 1679 1871 unsigned i; 1872 1873 PJ_UNUSED_ARG(msghdr); 1680 1874 1681 1875 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_unknown_attr); … … 1699 1893 1700 1894 static 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) 1702 1898 { 1703 1899 const pj_stun_unknown_attr *ca = (const pj_stun_unknown_attr*) a; … … 1707 1903 PJ_CHECK_STACK(); 1708 1904 1905 PJ_UNUSED_ARG(msghdr); 1906 1709 1907 /* Check that buffer is enough */ 1710 1908 if (len < ATTR_HDR_LEN + (ca->attr_count << 1)) … … 1808 2006 static pj_status_t decode_binary_attr(pj_pool_t *pool, 1809 2007 const pj_uint8_t *buf, 2008 const pj_stun_msg_hdr *msghdr, 1810 2009 void **p_attr) 1811 2010 { 1812 2011 pj_stun_binary_attr *attr; 2012 2013 PJ_UNUSED_ARG(msghdr); 1813 2014 1814 2015 /* Create the attribute */ … … 1830 2031 1831 2032 static 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) 1833 2036 { 1834 2037 const pj_stun_binary_attr *ca = (const pj_stun_binary_attr*)a; … … 1836 2039 PJ_CHECK_STACK(); 1837 2040 2041 PJ_UNUSED_ARG(msghdr); 2042 1838 2043 /* Calculated total attr_len (add padding if necessary) */ 1839 2044 *printed = (ca->length + ATTR_HDR_LEN + 3) & (~3); … … 2221 2426 2222 2427 /* Parse the attribute */ 2223 status = (adesc->decode_attr)(pool, pdu, & attr);2428 status = (adesc->decode_attr)(pool, pdu, &msg->hdr, &attr); 2224 2429 2225 2430 if (status != PJ_SUCCESS) { … … 2409 2614 adesc = find_attr_desc(attr_hdr->type); 2410 2615 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); 2412 2618 } else { 2413 2619 /* This may be a generic attribute */ … … 2415 2621 attr_hdr; 2416 2622 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); 2418 2625 } 2419 2626 … … 2520 2727 /* Put this attribute in the message */ 2521 2728 status = encode_msgint_attr(amsgint, buf, buf_size, 2522 & printed);2729 &msg->hdr, &printed); 2523 2730 if (status != PJ_SUCCESS) 2524 2731 return status; … … 2542 2749 /* Put this attribute in the message */ 2543 2750 status = encode_uint_attr(afingerprint, buf, buf_size, 2544 2751 &msg->hdr, &printed); 2545 2752 if (status != PJ_SUCCESS) 2546 2753 return status;
Note: See TracChangeset
for help on using the changeset viewer.