Changeset 990
- Timestamp:
- Feb 20, 2007 9:58:36 PM (16 years ago)
- 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 138 138 # Begin Source File 139 139 140 SOURCE="..\src\pjlib-util\stun_server.c" 141 # End Source File 142 # Begin Source File 143 140 144 SOURCE="..\src\pjlib-util\stun_simple.c" 141 145 # PROP Exclude_From_Build 1 -
pjproject/branches/iceproject/pjlib-util/build/pjlib_util.dsw
r65 r990 20 20 Package=<5> 21 21 {{{ 22 begin source code control23 "$/pjproject/pjlib/build", UIAAAAAA24 ..\..\pjlib\build25 end source code control26 22 }}} 27 23 … … 62 58 ############################################################################### 63 59 60 Project: "pjstun_srv"=".\pjstun_srv.dsp" - Package Owner=<4> 61 62 Package=<5> 63 {{{ 64 }}} 65 66 Package=<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 64 78 Global: 65 79 -
pjproject/branches/iceproject/pjlib-util/include/pjlib-util.h
r913 r990 32 32 #include <pjlib-util/scanner.h> 33 33 //#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> 34 38 #include <pjlib-util/xml.h> 35 39 -
pjproject/branches/iceproject/pjlib-util/include/pjlib-util/errno.h
r913 r990 119 119 */ 120 120 #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 */ 121 126 122 127 -
pjproject/branches/iceproject/pjlib-util/include/pjlib-util/stun_msg.h
r929 r990 179 179 * Determine if the message type is a request. 180 180 */ 181 #define PJ_STUN_IS_REQUEST(msg_type) (((msg_type) & 0x0 F00) == 0x0000)181 #define PJ_STUN_IS_REQUEST(msg_type) (((msg_type) & 0x0110) == 0x0000) 182 182 183 183 … … 185 185 * Determine if the message type is a response. 186 186 */ 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) 189 194 190 195 /** 191 196 * Determine if the message type is an error response. 192 197 */ 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 197 207 /** 198 208 * Determine if the message type is an indication message. 199 209 */ 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) 202 217 203 218 … … 325 340 PJ_STUN_ATTR_NONCE = 0x0015,/**< NONCE attribute. */ 326 341 PJ_STUN_ATTR_RELAY_ADDRESS = 0x0016,/**< RELAY-ADDRESS attribute. */ 342 PJ_STUN_ATTR_REQUESTED_ADDR_TYPE= 0x0017,/**< REQUESTED-ADDRESS-TYPE */ 327 343 PJ_STUN_ATTR_REQUESTED_PORT_PROPS=0x0018,/**< REQUESTED-PORT-PROPS */ 328 344 PJ_STUN_ATTR_REQUESTED_TRANSPORT= 0x0019,/**< REQUESTED-TRANSPORT */ … … 330 346 PJ_STUN_ATTR_TIMER_VAL = 0x0021,/**< TIMER-VAL attribute. */ 331 347 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 332 357 PJ_STUN_ATTR_FINGERPRINT = 0x8021,/**< FINGERPRINT attribute. */ 333 358 PJ_STUN_ATTR_SERVER = 0x8022,/**< SERVER attribute. */ 334 359 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 336 364 } pj_stun_attr_type; 337 365 338 366 339 367 /** 340 * STUN error codes .368 * STUN error codes, which goes into STUN ERROR-CODE attribute. 341 369 */ 342 370 typedef enum pj_stun_status … … 491 519 492 520 /** 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) 513 522 */ 514 523 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. */ 522 527 } addr; 523 528 524 529 } 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 */ 536 typedef 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; 525 544 526 545 … … 900 919 901 920 /** 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 */ 936 typedef struct pj_stun_generic_uint_attr pj_stun_requested_addr_type; 937 938 /** 902 939 * This describes the STUN REQUESTED-PORT-PROPS attribute. 903 940 * This attribute allows the client to request certain properties for … … 936 973 typedef struct pj_stun_generic_ip_addr_attr pj_stun_requested_ip_attr; 937 974 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 */ 985 typedef 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 */ 994 typedef 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 */ 1003 typedef 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 */ 1013 typedef pj_stun_generic_ip_addr_attr pj_stun_xor_internal_addr_attr; 938 1014 939 1015 /** … … 987 1063 * @param pool Pool to create the STUN message. 988 1064 * @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. 989 1067 * @param tsx_id Optional transaction ID, or NULL to let the 990 1068 * function generates a random transaction ID. … … 995 1073 PJ_DECL(pj_status_t) pj_stun_msg_create(pj_pool_t *pool, 996 1074 unsigned msg_type, 1075 pj_uint32_t magic, 997 1076 const pj_uint8_t tsx_id[12], 998 1077 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 */ 1089 PJ_DECL(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg, 1090 pj_stun_attr_hdr *attr); 1091 999 1092 1000 1093 /** … … 1092 1185 * @param pool The pool to allocate memory from. 1093 1186 * @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. 1096 1191 * @param p_attr Pointer to receive the attribute. 1097 1192 * … … 1100 1195 PJ_DECL(pj_status_t) 1101 1196 pj_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, 1105 1201 pj_stun_generic_ip_addr_attr **p_attr); 1106 1202 -
pjproject/branches/iceproject/pjlib-util/include/pjlib-util/stun_server.h
r929 r990 51 51 * The STUN message type. 52 52 */ 53 int 53 int msg_type; 54 54 55 55 /** … … 59 59 * @param msg The STUN message. 60 60 */ 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); 62 64 63 65 } pj_stun_service_handler; … … 68 70 */ 69 71 PJ_DECL(pj_status_t) pj_stun_service_create(pj_pool_t *pool, 72 const char *name, 73 unsigned options, 70 74 unsigned handler_cnt, 71 75 pj_stun_service_handler cb[], … … 89 93 */ 90 94 PJ_DECL(pj_status_t) pj_stun_service_handle_msg(pj_stun_service *svc, 95 void *handle_data, 91 96 const pj_stun_msg *msg); 92 97 -
pjproject/branches/iceproject/pjlib-util/src/pjlib-util/stun_msg.c
r929 r990 80 80 #define ATTR_HDR_LEN 4 81 81 82 #define getval16(p, pos) (pj_uint16_t)(((p)[(pos)] << 8) | \ 83 ((p)[(pos) + 1] << 0)) 84 82 85 83 86 ////////////////////////////////////////////////////////////////////////////// … … 93 96 pj_stun_generic_ip_addr_attr_create(pj_pool_t *pool, 94 97 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, 97 101 pj_stun_generic_ip_addr_attr **p_attr) 98 102 { 99 103 pj_stun_generic_ip_addr_attr *attr; 100 104 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); 102 108 103 109 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_generic_ip_addr_attr); 104 110 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 } 108 124 109 125 *p_attr = attr; … … 117 133 void **p_attr) 118 134 { 119 enum120 {121 ATTR_LEN = STUN_GENERIC_IP_ADDR_LEN + ATTR_HDR_LEN122 };123 135 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; 127 137 128 138 /* 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); 135 141 136 142 /* Convert to host byte order */ 137 143 attr->hdr.type = pj_ntohs(attr->hdr.type); 138 144 attr->hdr.length = pj_ntohs(attr->hdr.length); 139 attr->port = pj_ntohs(attr->port);140 attr->addr.ipv4 = pj_ntohl(attr->addr.ipv4);141 145 142 146 /* Check that the attribute length is valid */ … … 144 148 return PJLIB_UTIL_ESTUNINATTRLEN; 145 149 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 146 162 /* Done */ 147 163 *p_attr = attr; … … 154 170 unsigned len, unsigned *printed) 155 171 { 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 159 174 }; 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; 160 178 pj_stun_generic_ip_addr_attr *attr; 161 179 … … 163 181 return PJ_ETOOSMALL; 164 182 165 /* Copy and convert attributeto 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); 167 185 attr = (pj_stun_generic_ip_addr_attr*) buf; 168 186 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; 175 209 176 210 return PJ_SUCCESS; … … 214 248 215 249 /* 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); 217 251 218 252 /* Copy the header */ … … 247 281 /* Calculated total attr_len (add padding if necessary) */ 248 282 *printed = (ca->value.slen + ATTR_HDR_LEN + 3) & (~3); 249 if (len < *printed) 283 if (len < *printed) { 284 *printed = 0; 250 285 return PJ_ETOOSMALL; 286 } 251 287 252 288 /* Copy header */ 253 289 pj_memcpy(buf, a, ATTR_HDR_LEN); 290 attr = (pj_stun_attr_hdr*)buf; 254 291 255 292 /* Set the correct length */ 256 attr = (pj_stun_attr_hdr*)buf;257 293 attr->length = (pj_uint16_t) ca->value.slen; 258 294 … … 265 301 266 302 /* 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 */ 315 PJ_DEF(pj_status_t) 316 pj_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 333 static 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 361 static 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 267 378 return PJ_SUCCESS; 268 379 } … … 312 423 313 424 /* 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); 315 426 pj_memcpy(attr, buf, ATTR_LEN); 316 427 … … 397 508 398 509 /* 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); 400 511 pj_memcpy(attr, buf, sizeof(pj_stun_msg_integrity_attr)); 401 512 attr->hdr.type = pj_ntohs(attr->hdr.type); … … 486 597 487 598 /* 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); 489 600 490 601 /* Copy the header */ … … 683 794 684 795 /* 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); 686 797 687 798 /* Copy the header */ … … 740 851 struct attr_desc 741 852 { 742 unsigned type;743 const char *attr_name;744 745 853 pj_status_t (*decode_attr)(pj_pool_t *pool, const pj_uint8_t *buf, 746 854 void **p_attr); … … 748 856 unsigned len, unsigned *printed); 749 857 750 } attr_desc[] = 751 { 752 { 753 PJ_STUN_ATTR_MAPPED_ADDR, 754 "MAPPED-ADDRESS", 858 }; 859 860 struct attr_desc mandatory_attr_desc[] = 861 { 862 { 863 /* type zero */ 864 NULL, 865 NULL 866 }, 867 { 868 /* PJ_STUN_ATTR_MAPPED_ADDR, */ 755 869 &decode_generic_ip_addr_attr, 756 870 &encode_generic_ip_addr_attr 757 871 }, 758 872 { 759 PJ_STUN_ATTR_RESPONSE_ADDR, 760 "RESPONSE-ADDRESS", 873 /* PJ_STUN_ATTR_RESPONSE_ADDR, */ 761 874 &decode_generic_ip_addr_attr, 762 875 &encode_generic_ip_addr_attr 763 876 }, 764 877 { 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, */ 767 884 &decode_generic_ip_addr_attr, 768 885 &encode_generic_ip_addr_attr 769 886 }, 770 887 { 771 PJ_STUN_ATTR_SOURCE_ADDR, 772 "SOURCE-ADDRESS", 888 /* PJ_STUN_ATTR_CHANGED_ADDR, */ 773 889 &decode_generic_ip_addr_attr, 774 890 &encode_generic_ip_addr_attr 775 891 }, 776 892 { 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, */ 779 919 &decode_generic_ip_addr_attr, 780 920 &encode_generic_ip_addr_attr 781 921 }, 782 922 { 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, */ 785 964 &decode_generic_string_attr, 786 965 &encode_generic_string_attr 787 966 }, 788 967 { 789 PJ_STUN_ATTR_PASSWORD, 790 "PASSWORD", 968 /* PJ_STUN_ATTR_NONCE, */ 791 969 &decode_generic_string_attr, 792 970 &encode_generic_string_attr 793 971 }, 794 972 { 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, */ 815 974 &decode_generic_ip_addr_attr, 816 975 &encode_generic_ip_addr_attr 817 976 }, 818 977 { 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 1066 static 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, */ 821 1075 &decode_generic_string_attr, 822 1076 &encode_generic_string_attr 823 1077 }, 824 1078 { 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, */ 833 1080 &decode_generic_ip_addr_attr, 834 1081 &encode_generic_ip_addr_attr 835 1082 }, 836 1083 { 837 PJ_STUN_ATTR_FINGERPRINT, 838 "FINGERPRINT", 1084 /* PJ_STUN_ATTR_REFRESH_INTERVAL, */ 839 1085 &decode_generic_uint_attr, 840 1086 &encode_generic_uint_attr 841 1087 }, 842 {843 PJ_STUN_ATTR_SERVER,844 "SERVER",845 &decode_generic_string_attr,846 &encode_generic_string_attr847 },848 {849 PJ_STUN_ATTR_ALTERNATE_SERVER,850 "ALTERNATE-SERVER",851 &decode_generic_ip_addr_attr,852 &encode_generic_ip_addr_attr853 },854 {855 PJ_STUN_ATTR_REFRESH_INTERVAL,856 "REFRESH-INTERVAL",857 &decode_generic_uint_attr,858 &encode_generic_uint_attr859 },860 {861 PJ_STUN_ATTR_LIFETIME,862 "LIFETIME",863 &decode_generic_uint_attr,864 &encode_generic_uint_attr865 },866 {867 PJ_STUN_ATTR_BANDWIDTH,868 "BANDWIDTH",869 &decode_generic_uint_attr,870 &encode_generic_uint_attr871 },872 {873 PJ_STUN_ATTR_REMOTE_ADDRESS,874 "REMOTE-ADDRESS",875 &decode_generic_ip_addr_attr,876 &encode_generic_ip_addr_attr877 },878 {879 PJ_STUN_ATTR_DATA,880 "DATA",881 &decode_binary_attr,882 &encode_binary_attr883 },884 {885 PJ_STUN_ATTR_RELAY_ADDRESS,886 "RELAY-ADDRESS",887 &decode_generic_ip_addr_attr,888 &encode_generic_ip_addr_attr889 },890 {891 PJ_STUN_ATTR_REQUESTED_PORT_PROPS,892 "REQUESTED-PORT-PROPS",893 &decode_generic_uint_attr,894 &encode_generic_uint_attr895 },896 {897 PJ_STUN_ATTR_REQUESTED_TRANSPORT,898 "REQUESTED-TRANSPORT",899 &decode_generic_uint_attr,900 &encode_generic_uint_attr901 },902 {903 PJ_STUN_ATTR_REQUESTED_IP,904 "STUN REQUESTED-IP",905 &decode_generic_ip_addr_attr,906 &encode_generic_ip_addr_attr907 },908 {909 PJ_STUN_ATTR_TIMER_VAL,910 "TIMER-VAL",911 &decode_generic_uint_attr,912 &encode_generic_uint_attr913 }914 1088 }; 915 1089 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 1091 static 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 } 928 1115 929 1116 … … 933 1120 PJ_DEF(pj_status_t) pj_stun_msg_create( pj_pool_t *pool, 934 1121 unsigned msg_type, 1122 pj_uint32_t magic, 935 1123 const pj_uint8_t tsx_id[12], 936 1124 pj_stun_msg **p_msg) … … 942 1130 msg = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msg); 943 1131 msg->hdr.type = (pj_uint16_t) msg_type; 944 msg->hdr.magic = (pj_uint32_t) PJ_STUN_MAGIC;1132 msg->hdr.magic = magic; 945 1133 946 1134 if (tsx_id) { … … 969 1157 970 1158 /* 1159 * Add STUN attribute to STUN message. 1160 */ 1161 PJ_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 /* 971 1173 * Check that the PDU is potentially a valid STUN message. 972 1174 */ … … 985 1187 /* First byte of STUN message is always 0x00 or 0x01. */ 986 1188 if ((*(const char*)pdu) != 0x00 && (*(const char*)pdu) != 0x01) 987 return PJ _FALSE;1189 return PJLIB_UTIL_ESTUNINMSGTYPE; 988 1190 989 1191 /* If magic is set, then there is great possibility that this is … … 991 1193 */ 992 1194 if (pj_ntohl(hdr->magic) == PJ_STUN_MAGIC) 993 return PJ_ TRUE;1195 return PJ_SUCCESS; 994 1196 995 1197 /* Check the PDU length */ 996 1198 if (pj_ntohs(hdr->length) > pdu_len) 997 return PJ _FALSE;1199 return PJLIB_UTIL_ESTUNINMSGLEN; 998 1200 999 1201 /* Could be a STUN message */ 1000 return PJ_ TRUE;1202 return PJ_SUCCESS; 1001 1203 } 1002 1204 … … 1031 1233 1032 1234 /* 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); 1034 1236 pj_memcpy(&msg->hdr, pdu, sizeof(pj_stun_msg_hdr)); 1035 1237 msg->hdr.type = pj_ntohs(msg->hdr.type); … … 1040 1242 pdu_len -= sizeof(pj_stun_msg_hdr); 1041 1243 1244 if (p_err_code) 1245 *p_err_code = 0; 1246 1042 1247 /* Parse attributes */ 1043 1248 uattr_cnt = 0; 1044 1249 while (pdu_len > 0) { 1045 1250 unsigned attr_type, attr_val_len; 1046 struct attr_desc *adesc;1251 const struct attr_desc *adesc; 1047 1252 1048 1253 /* Get attribute type and length. If length is not aligned … … 1053 1258 attr_val_len = (attr_val_len + 3) & (~3); 1054 1259 1055 /* Get the attribute descriptor */1056 adesc = find_attr_desc(attr_type);1057 1058 1260 /* Check length */ 1059 1261 if (pdu_len < attr_val_len) 1060 1262 return PJLIB_UTIL_ESTUNINATTRLEN; 1263 1264 /* Get the attribute descriptor */ 1265 adesc = find_attr_desc(attr_type); 1061 1266 1062 1267 if (adesc == NULL) { … … 1076 1281 * if we don't understand the attribute. 1077 1282 */ 1078 if (p_err_code )1283 if (p_err_code && *p_err_code == 0) 1079 1284 *p_err_code = PJ_STUN_STATUS_UNKNOWN_ATTRIBUTE; 1080 1285 … … 1090 1295 if (status != PJ_SUCCESS) { 1091 1296 PJ_LOG(4,(THIS_FILE, 1092 "Error parsing STUN %s attribute: status=%d",1093 a desc->attr_name, status));1297 "Error parsing STUN attribute type %d: status=%d", 1298 attr_type, status)); 1094 1299 return status; 1095 1300 } … … 1151 1356 /* Print each attribute */ 1152 1357 for (i=0; i<msg->attr_count; ++i) { 1153 struct attr_desc *adesc;1358 const struct attr_desc *adesc; 1154 1359 const pj_stun_attr_hdr *attr_hdr; 1155 1360 unsigned printed; … … 1169 1374 } 1170 1375 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 */ 1172 1379 hdr->length = pj_htons((pj_uint16_t)(buf - start)); 1173 1380
Note: See TracChangeset
for help on using the changeset viewer.