- Timestamp:
- Apr 13, 2009 8:54:10 AM (16 years ago)
- Location:
- pjproject/trunk/pjnath
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/include/pjnath/stun_msg.h
r2394 r2589 84 84 85 85 /** 86 * STUN/TURN CreatePermission method as defined by draft-ietf-behave-turn 87 */ 88 PJ_STUN_CREATE_PERM_METHOD = 8, 89 90 /** 86 91 * STUN/TURN ChannelBind as defined by draft-ietf-behave-turn 87 92 */ … … 252 257 */ 253 258 PJ_STUN_DATA_INDICATION = 0x0017, 259 260 261 /** 262 * TURN CreatePermission request 263 */ 264 PJ_STUN_CREATE_PERM_REQUEST = 0x0008, 265 266 /** 267 * TURN CreatePermission successful response. 268 */ 269 PJ_STUN_CREATE_PERM_RESPONSE = 0x0108, 270 271 /** 272 * TURN CreatePermission failure response 273 */ 274 PJ_STUN_CREATE_PERM_ERROR_RESPONSE = 0x0118, 254 275 255 276 … … 293 314 PJ_STUN_ATTR_MAGIC_COOKIE = 0x000F,/**< MAGIC-COOKIE attr (deprec)*/ 294 315 PJ_STUN_ATTR_BANDWIDTH = 0x0010,/**< TURN BANDWIDTH (deprec) */ 295 PJ_STUN_ATTR_ PEER_ADDR = 0x0012,/**< TURN PEER-ADDRESS attr.*/316 PJ_STUN_ATTR_XOR_PEER_ADDR = 0x0012,/**< TURN XOR-PEER-ADDRESS */ 296 317 PJ_STUN_ATTR_DATA = 0x0013,/**< DATA attribute. */ 297 318 PJ_STUN_ATTR_REALM = 0x0014,/**< REALM attribute. */ 298 319 PJ_STUN_ATTR_NONCE = 0x0015,/**< NONCE attribute. */ 299 PJ_STUN_ATTR_ RELAYED_ADDR = 0x0016,/**< RELAYED-ADDRESS attribute.*/320 PJ_STUN_ATTR_XOR_RELAYED_ADDR = 0x0016,/**< TURN XOR-RELAYED-ADDRESS */ 300 321 PJ_STUN_ATTR_REQ_ADDR_TYPE = 0x0017,/**< REQUESTED-ADDRESS-TYPE */ 301 PJ_STUN_ATTR_REQ_PROPS = 0x0018,/**< REQUESTED-PROPS */ 302 PJ_STUN_ATTR_REQ_TRANSPORT = 0x0019,/**< REQUESTED-TRANSPORT */ 322 PJ_STUN_ATTR_EVEN_PORT = 0x0018,/**< TURN EVEN-PORT */ 323 PJ_STUN_ATTR_REQ_TRANSPORT = 0x0019,/**< TURN REQUESTED-TRANSPORT */ 324 PJ_STUN_ATTR_DONT_FRAGMENT = 0x001A,/**< TURN DONT-FRAGMENT */ 303 325 PJ_STUN_ATTR_XOR_MAPPED_ADDR = 0x0020,/**< XOR-MAPPED-ADDRESS */ 304 326 PJ_STUN_ATTR_TIMER_VAL = 0x0021,/**< TIMER-VAL attribute. */ … … 333 355 PJ_STUN_SC_BAD_REQUEST = 400, /**< Bad Request */ 334 356 PJ_STUN_SC_UNAUTHORIZED = 401, /**< Unauthorized */ 357 PJ_STUN_SC_FORBIDDEN = 403, /**< Forbidden (TURN) */ 335 358 PJ_STUN_SC_UNKNOWN_ATTRIBUTE = 420, /**< Unknown Attribute */ 336 359 #if 0 … … 350 373 PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO = 442, /**< Unsupported Transport or 351 374 Protocol (TURN) */ 352 PJ_STUN_SC_INVALID_IP_ADDR = 443, /**< Invalid IP Address(TURN)*/353 PJ_STUN_SC_INVALID_PORT = 444, /**< Invalid Port (TURN) */354 375 PJ_STUN_SC_OPER_TCP_ONLY = 445, /**< Operation for TCP Only */ 355 376 PJ_STUN_SC_CONNECTION_FAILURE = 446, /**< Connection Failure */ … … 359 380 PJ_STUN_SC_ROLE_CONFLICT = 487, /**< Role Conflict */ 360 381 PJ_STUN_SC_SERVER_ERROR = 500, /**< Server Error */ 361 PJ_STUN_SC_INSUFFICIENT_CAPACITY = 507, /**< Insufficient Capacity 362 (TURN) */ 363 PJ_STUN_SC_INSUFFICIENT_PORT_CAPACITY=508, /**< Insufficient Port Capacity 382 PJ_STUN_SC_INSUFFICIENT_CAPACITY = 508, /**< Insufficient Capacity 364 383 (TURN) */ 365 384 PJ_STUN_SC_GLOBAL_FAILURE = 600 /**< Global Failure */ … … 913 932 914 933 /** 915 * This describes the STUN PEER-ADDRESS attribute.916 * The PEER-ADDRESS specifies the address and port of the peer as seen934 * This describes the STUN XOR-PEER-ADDRESS attribute. 935 * The XOR-PEER-ADDRESS specifies the address and port of the peer as seen 917 936 * from the TURN server. It is encoded in the same way as XOR-MAPPED- 918 937 * ADDRESS. 919 938 */ 920 typedef struct pj_stun_sockaddr_attr pj_stun_ peer_addr_attr;939 typedef struct pj_stun_sockaddr_attr pj_stun_xor_peer_addr_attr; 921 940 922 941 … … 932 951 933 952 /** 934 * This describes the STUN RELAYED-ADDRESS attribute.935 * TheRELAYED-ADDRESS is present in Allocate responses. It specifies the953 * This describes the STUN XOR-RELAYED-ADDRESS attribute. The 954 * XOR-RELAYED-ADDRESS is present in Allocate responses. It specifies the 936 955 * address and port that the server allocated to the client. It is 937 956 * encoded in the same way as XOR-MAPPED-ADDRESS. 938 957 */ 939 typedef struct pj_stun_sockaddr_attr pj_stun_ relayed_addr_attr;958 typedef struct pj_stun_sockaddr_attr pj_stun_xor_relayed_addr_attr; 940 959 941 960 … … 956 975 \endverbatim 957 976 */ 958 typedef struct pj_stun_uint_attr pj_stun_req_addr_type; 959 960 /** 961 * This describes the TURN REQUESTED-PROPS attribute, encoded as 962 * STUN 32bit integer attribute. Few macros are provided to manipulate 963 * the values in this attribute: #PJ_STUN_GET_PROP_TYPE(), and 964 * #PJ_STUN_SET_PROP_TYPE(). 977 typedef struct pj_stun_uint_attr pj_stun_req_addr_type_attr; 978 979 980 /** 981 * This describes the TURN REQUESTED-TRANSPORT attribute, encoded in 982 * STUN generic integer attribute. 983 * 984 * This attribute allows the client to request that the port in the 985 * relayed-transport-address be even, and (optionally) that the server 986 * reserve the next-higher port number. The attribute is 8 bits long. 987 * Its format is: 988 989 \verbatim 990 0 991 0 1 2 3 4 5 6 7 992 +-+-+-+-+-+-+-+-+ 993 |R| RFFU | 994 +-+-+-+-+-+-+-+-+ 995 996 \endverbatim 997 998 * The attribute contains a single 1-bit flag: 965 999 * 966 * This attribute allows the client to request that the allocation have 967 * certain properties, and by the server to indicate which properties 968 * are supported. The attribute is 32 bits long. Its format is: 969 970 \verbatim 971 972 0 1 2 3 973 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 974 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 975 | Prop-type | Reserved = 0 | 976 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 977 978 \endverbatim 979 980 * The field labeled "Prop-type" is an 8-bit field specifying the 981 * desired property. The rest of the attribute is RFFU (Reserved For 982 * Future Use) and MUST be set to 0 on transmission and ignored on 983 * reception. 984 * 985 * The "Prop-type" field is formatted as follows: 986 987 \verbatim 988 989 0 1 2 3 4 5 6 7 990 +-+-+-+-+-+-+-+-+ 991 |E|R|P| | 992 +-+-+-+-+-+-+-+-+ 993 994 \endverbatim 995 996 The bits in "Prop-type" are: 997 998 E: If 1, the port number for the relayed-transport-address must be 999 even. If 0, the port number can be even or odd. 1000 1001 R: If 1, the server must reserve the next highest port for a 1002 subsequent allocation. If 0, no such reservation is requested. 1003 If the client sets the R bit to 1, it MUST also set the E bit to 1 1004 (however, the E bit may be 1 when the R bit is 0). 1005 1006 P: If 1, the allocation must be a Preserving allocation. If 0, the 1007 allocation can be either Preserving or Non-Preserving. 1008 1009 */ 1010 typedef struct pj_stun_uint_attr pj_stun_req_props_attr; 1011 1012 /** 1013 * Get the 8bit Prop-type value from a 32bit integral value of TURN 1014 * TURN REQUESTED-PROPS attribute. 1015 */ 1016 #define PJ_STUN_GET_PROP_TYPE(u32) (u32 >> 24) 1017 1018 /** 1019 * Convert 8bit Prop-type value to a 32bit integral value of TURN 1020 * REQUESTED-PROPS attribute. 1021 */ 1022 #define PJ_STUN_SET_PROP_TYPE(PropType) (PropType << 24) 1000 * R: If 1, the server is requested to reserve the next higher port 1001 * number (on the same IP address) for a subsequent allocation. If 1002 * 0, no such reservation is requested. 1003 * 1004 * The other 7 bits of the attribute must be set to zero on transmission 1005 * and ignored on reception. 1006 */ 1007 typedef struct pj_stun_uint_attr pj_stun_even_port_attr; 1023 1008 1024 1009 … … 1064 1049 #define PJ_STUN_SET_RT_PROTO(proto) (((pj_uint32_t)(proto)) << 24) 1065 1050 1051 1052 /** 1053 * This describes the TURN DONT-FRAGMENT attribute. 1054 * 1055 * This attribute is used by the client to request that the server set 1056 * the DF (Don't Fragment) bit in the IP header when relaying the 1057 * application data onward to the peer. This attribute has no value 1058 * part and thus the attribute length field is 0. 1059 */ 1060 typedef struct pj_stun_empty_attr pj_stun_use_candidate_attr; 1066 1061 1067 1062 -
pjproject/trunk/pjnath/include/pjnath/stun_session.h
r2394 r2589 328 328 329 329 /** 330 * Set server name to be included in all response. 331 * 332 * @param sess The STUN session instance. 333 * @param srv_name Server name string. 334 * 335 * @return The user data associated with this STUN session. 336 */ 337 PJ_DECL(pj_status_t) pj_stun_session_set_server_name(pj_stun_session *sess, 338 const pj_str_t *srv_name); 330 * Set SOFTWARE name to be included in all requests and responses. 331 * 332 * @param sess The STUN session instance. 333 * @param sw Software name string. If this argument is NULL or 334 * empty, the session will not include SOFTWARE attribute 335 * in STUN requests and responses. 336 * 337 * @return PJ_SUCCESS on success, or the appropriate error code. 338 */ 339 PJ_DECL(pj_status_t) pj_stun_session_set_software_name(pj_stun_session *sess, 340 const pj_str_t *sw); 339 341 340 342 /** -
pjproject/trunk/pjnath/include/pjnath/turn_session.h
r2394 r2589 435 435 PJ_DECL(void) pj_turn_session_set_log(pj_turn_session *sess, 436 436 unsigned flags); 437 438 439 /** 440 * Configure the SOFTWARE name to be sent in all STUN requests by the 441 * TURN session. 442 * 443 * @param sess The TURN client session. 444 * @param sw Software name string. If this argument is NULL or 445 * empty, the session will not include SOFTWARE attribute 446 * in STUN requests and responses. 447 * 448 * @return PJ_SUCCESS on success, or the appropriate error code. 449 */ 450 PJ_DECL(pj_status_t) pj_turn_session_set_software_name(pj_turn_session *sess, 451 const pj_str_t *sw); 437 452 438 453 … … 520 535 521 536 /** 537 * Create or renew permission in the TURN server for the specified peer IP 538 * addresses. Application must install permission for a particular (peer) 539 * IP address before it sends any data to that IP address, or otherwise 540 * the TURN server will drop the data. 541 * 542 * @param sess The TURN client session. 543 * @param addr_cnt Number of IP addresses. 544 * @param addr Array of peer IP addresses. Only the address family 545 * and IP address portion of the socket address matter. 546 * @param options Specify 1 to let the TURN client session automatically 547 * renew the permission later when they are about to 548 * expire. 549 * 550 * @return PJ_SUCCESS if the operation has been successfully 551 * issued, or the appropriate error code. Note that 552 * the operation itself will complete asynchronously. 553 */ 554 PJ_DECL(pj_status_t) pj_turn_session_set_perm(pj_turn_session *sess, 555 unsigned addr_cnt, 556 const pj_sockaddr addr[], 557 unsigned options); 558 559 560 /** 522 561 * Send a data to the specified peer address via the TURN relay. This 523 562 * function will encapsulate the data as STUN Send Indication or TURN -
pjproject/trunk/pjnath/include/pjnath/turn_sock.h
r2394 r2589 249 249 250 250 /** 251 * Create or renew permission in the TURN server for the specified peer IP 252 * addresses. Application must install permission for a particular (peer) 253 * IP address before it sends any data to that IP address, or otherwise 254 * the TURN server will drop the data. 255 * 256 * @param turn_sock The TURN transport instance. 257 * @param addr_cnt Number of IP addresses. 258 * @param addr Array of peer IP addresses. Only the address family 259 * and IP address portion of the socket address matter. 260 * @param options Specify 1 to let the TURN client session automatically 261 * renew the permission later when they are about to 262 * expire. 263 * 264 * @return PJ_SUCCESS if the operation has been successfully 265 * issued, or the appropriate error code. Note that 266 * the operation itself will complete asynchronously. 267 */ 268 PJ_DECL(pj_status_t) pj_turn_sock_set_perm(pj_turn_sock *turn_sock, 269 unsigned addr_cnt, 270 const pj_sockaddr addr[], 271 unsigned options); 272 273 /** 251 274 * Send a data to the specified peer address via the TURN relay. This 252 275 * function will encapsulate the data as STUN Send Indication or TURN -
pjproject/trunk/pjnath/include/pjnath/types.h
r2580 r2589 108 108 operation of the relay and to exchange packets with its peers using the relay. 109 109 110 This version of PJNATH implements both TCP and UDP client transport and it 111 complies with the following TURN draft: 112 - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-09.txt"> 113 <B>draft-ietf-behave-turn-09</B></A>: Obtaining Relay Addresses 110 Features: 111 - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-13.txt"> 112 <B>draft-ietf-behave-turn-13</B></A>: Obtaining Relay Addresses 114 113 from Simple Traversal Underneath NAT (STUN) 114 - DNS SRV resolution 115 - Fallback to DNS A resolution if SRV record is not found 116 - UDP and TCP connection to TURN server 117 - automatic management of allocation refresh 118 115 119 116 120 -
pjproject/trunk/pjnath/src/pjnath-test/server.c
r2394 r2589 311 311 pj_stun_msg_add_uint_attr(pool, resp, PJ_STUN_ATTR_LIFETIME, lifetime); 312 312 if (lifetime != 0) { 313 /* Add RELAYED-ADDRESS */314 pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_ RELAYED_ADDR, PJ_TRUE, &alloc->alloc_addr,313 /* Add XOR-RELAYED-ADDRESS */ 314 pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_RELAYED_ADDR, PJ_TRUE, &alloc->alloc_addr, 315 315 pj_sockaddr_get_len(&alloc->alloc_addr)); 316 316 /* Add XOR-MAPPED-ADDRESS */ -
pjproject/trunk/pjnath/src/pjnath/stun_msg.c
r2580 r2589 44 44 "Send", /* 6 */ 45 45 "Data", /* 7 */ 46 " ???",/* 8 */46 "CreatePermission", /* 8 */ 47 47 "ChannelBind", /* 9 */ 48 48 }; … … 57 57 { PJ_STUN_SC_BAD_REQUEST, "Bad Request"}, 58 58 { PJ_STUN_SC_UNAUTHORIZED, "Unauthorized"}, 59 { PJ_STUN_SC_FORBIDDEN, "Forbidden"}, 59 60 { PJ_STUN_SC_UNKNOWN_ATTRIBUTE, "Unknown Attribute"}, 60 61 //{ PJ_STUN_SC_STALE_CREDENTIALS, "Stale Credentials"}, … … 70 71 { PJ_STUN_SC_WRONG_CREDENTIALS, "Wrong Credentials"}, 71 72 { PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO, "Unsupported Transport Protocol"}, 72 { PJ_STUN_SC_INVALID_IP_ADDR, "Invalid IP Address"},73 { PJ_STUN_SC_INVALID_PORT, "Invalid Port"},74 73 { PJ_STUN_SC_OPER_TCP_ONLY, "Operation for TCP Only"}, 75 74 { PJ_STUN_SC_CONNECTION_FAILURE, "Connection Failure"}, … … 79 78 { PJ_STUN_SC_SERVER_ERROR, "Server Error"}, 80 79 { PJ_STUN_SC_INSUFFICIENT_CAPACITY, "Insufficient Capacity"}, 81 { PJ_STUN_SC_INSUFFICIENT_PORT_CAPACITY,"Insufficient Port Capacity"},82 80 { PJ_STUN_SC_GLOBAL_FAILURE, "Global Failure"} 83 81 }; … … 311 309 }, 312 310 { 313 /* PJ_STUN_ATTR_ PEER_ADDRESS, */314 " PEER-ADDRESS",311 /* PJ_STUN_ATTR_XOR_PEER_ADDRESS, */ 312 "XOR-PEER-ADDRESS", 315 313 &decode_xored_sockaddr_attr, 316 314 &encode_sockaddr_attr, … … 339 337 }, 340 338 { 341 /* PJ_STUN_ATTR_ RELAY_ADDRESS, */342 " RELAYED-ADDRESS",339 /* PJ_STUN_ATTR_XOR_RELAYED_ADDR, */ 340 "XOR-RELAYED-ADDRESS", 343 341 &decode_xored_sockaddr_attr, 344 342 &encode_sockaddr_attr, … … 353 351 }, 354 352 { 355 /* PJ_STUN_ATTR_ REQUESTED_PROPS, */356 " REQUESTED-PROPS",353 /* PJ_STUN_ATTR_EVEN_PORT, */ 354 "EVEN-PORT", 357 355 &decode_uint_attr, 358 356 &encode_uint_attr, … … 367 365 }, 368 366 { 369 /* ID 0x001A is not assigned*/370 NULL,371 NULL,372 NULL,373 NULL367 /* PJ_STUN_ATTR_DONT_FRAGMENT */ 368 "DONT-FRAGMENT", 369 &decode_empty_attr, 370 &encode_empty_attr, 371 &clone_empty_attr 374 372 }, 375 373 { -
pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c
r2394 r2589 73 73 case PJ_STUN_ATTR_CHANGED_ADDR: 74 74 case PJ_STUN_ATTR_REFLECTED_FROM: 75 case PJ_STUN_ATTR_ PEER_ADDR:76 case PJ_STUN_ATTR_ RELAYED_ADDR:75 case PJ_STUN_ATTR_XOR_PEER_ADDR: 76 case PJ_STUN_ATTR_XOR_RELAYED_ADDR: 77 77 case PJ_STUN_ATTR_XOR_MAPPED_ADDR: 78 78 case PJ_STUN_ATTR_XOR_REFLECTED_FROM: … … 117 117 case PJ_STUN_ATTR_BANDWIDTH: 118 118 case PJ_STUN_ATTR_REQ_ADDR_TYPE: 119 case PJ_STUN_ATTR_ REQ_PROPS:119 case PJ_STUN_ATTR_EVEN_PORT: 120 120 case PJ_STUN_ATTR_REQ_TRANSPORT: 121 121 case PJ_STUN_ATTR_TIMER_VAL: … … 224 224 break; 225 225 case PJ_STUN_ATTR_USE_CANDIDATE: 226 case PJ_STUN_ATTR_DONT_FRAGMENT: 226 227 default: 227 228 len = pj_ansi_snprintf(p, end-p, "\n"); -
pjproject/trunk/pjnath/src/pjnath/stun_session.c
r2394 r2589 218 218 pj_str_t realm, username, nonce, auth_key; 219 219 220 /* The server SHOULD include a SOFTWARE attribute in all responses */ 221 if (sess->srv_name.slen && PJ_STUN_IS_RESPONSE(msg->hdr.type)) { 220 /* If the agent is sending a request, it SHOULD add a SOFTWARE attribute 221 * to the request. The server SHOULD include a SOFTWARE attribute in all 222 * responses 223 */ 224 if (sess->srv_name.slen && !PJ_STUN_IS_INDICATION(msg->hdr.type) && 225 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_SOFTWARE, 0)==NULL) 226 { 222 227 pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE, 223 228 &sess->srv_name); … … 487 492 sess->srv_name.ptr = (char*) pj_pool_alloc(pool, 32); 488 493 sess->srv_name.slen = pj_ansi_snprintf(sess->srv_name.ptr, 32, 489 "pj _stun-%s", pj_get_version());494 "pjnath-%s", pj_get_version()); 490 495 491 496 sess->rx_pool = pj_pool_create(sess->cfg->pf, name, … … 591 596 } 592 597 593 PJ_DEF(pj_status_t) pj_stun_session_set_s erver_name(pj_stun_session *sess,594 const pj_str_t *srv_name)598 PJ_DEF(pj_status_t) pj_stun_session_set_software_name(pj_stun_session *sess, 599 const pj_str_t *sw) 595 600 { 596 601 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 597 if (s rv_name)598 pj_strdup(sess->pool, &sess->srv_name, s rv_name);602 if (sw && sw->slen) 603 pj_strdup(sess->pool, &sess->srv_name, sw); 599 604 else 600 605 sess->srv_name.slen = 0; -
pjproject/trunk/pjnath/src/pjnath/turn_session.c
r2407 r2589 29 29 #include <pj/os.h> 30 30 #include <pj/pool.h> 31 #include <pj/rand.h> 31 32 #include <pj/sock.h> 32 33 33 34 #define PJ_TURN_CHANNEL_MIN 0x4000 34 #define PJ_TURN_CHANNEL_MAX 0xFFFE /* inclusive */ 35 #define PJ_TURN_PEER_HTABLE_SIZE 8 35 #define PJ_TURN_CHANNEL_MAX 0x7FFF /* inclusive */ 36 #define PJ_TURN_CHANNEL_HTABLE_SIZE 8 37 #define PJ_TURN_PERM_HTABLE_SIZE 8 38 #define PJ_TURN_RENEWAL_BEFORE 10 /* seconds before renewals */ 36 39 37 40 static const char *state_names[] = … … 54 57 }; 55 58 56 57 struct peer 58 { 59 pj_uint16_t ch_id; 59 /* This structure describes a channel binding. A channel binding is index by 60 * the channel number or IP address and port number of the peer. 61 */ 62 struct ch_t 63 { 64 /* The channel number */ 65 pj_uint16_t num; 66 67 /* PJ_TRUE if we've received successful response to ChannelBind request 68 * for this channel. 69 */ 60 70 pj_bool_t bound; 71 72 /* The peer IP address and port */ 61 73 pj_sockaddr addr; 74 75 /* The channel binding expiration */ 62 76 pj_time_val expiry; 63 77 }; 64 78 79 80 /* This structure describes a permission. A permission is identified by the 81 * IP address only. 82 */ 83 struct perm_t 84 { 85 /* Cache of hash value to speed-up lookup */ 86 pj_uint32_t hval; 87 88 /* The permission IP address. The port number MUST be zero */ 89 pj_sockaddr addr; 90 91 /* Number of peers that uses this permission. */ 92 unsigned peer_cnt; 93 94 /* Automatically renew this permission once it expires? */ 95 pj_bool_t renew; 96 97 /* The permission expiration */ 98 pj_time_val expiry; 99 100 /* Arbitrary/random pointer value (token) to map this perm with the 101 * request to create it. It is used to invalidate this perm when the 102 * request fails. 103 */ 104 void *req_token; 105 }; 106 107 108 /* The TURN client session structure */ 65 109 struct pj_turn_session 66 110 { … … 103 147 pj_sockaddr relay_addr; 104 148 105 pj_hash_table_t *peer_table; 149 pj_hash_table_t *ch_table; 150 pj_hash_table_t *perm_table; 106 151 107 152 pj_uint32_t send_ind_tsx_id[3]; … … 143 188 pj_status_t status, 144 189 const pj_dns_srv_record *rec); 145 static struct peer *lookup_peer_by_addr(pj_turn_session *sess, 146 const pj_sockaddr_t *addr, 147 unsigned addr_len, 148 pj_bool_t update, 149 pj_bool_t bind_channel); 150 static struct peer *lookup_peer_by_chnum(pj_turn_session *sess, 151 pj_uint16_t chnum); 190 static struct ch_t *lookup_ch_by_addr(pj_turn_session *sess, 191 const pj_sockaddr_t *addr, 192 unsigned addr_len, 193 pj_bool_t update, 194 pj_bool_t bind_channel); 195 static struct ch_t *lookup_ch_by_chnum(pj_turn_session *sess, 196 pj_uint16_t chnum); 197 static struct perm_t *lookup_perm(pj_turn_session *sess, 198 const pj_sockaddr_t *addr, 199 unsigned addr_len, 200 pj_bool_t update); 201 static void invalidate_perm(pj_turn_session *sess, 202 struct perm_t *perm); 152 203 static void on_timer_event(pj_timer_heap_t *th, pj_timer_entry *e); 153 204 … … 225 276 226 277 /* Peer hash table */ 227 sess->peer_table = pj_hash_create(pool, PJ_TURN_PEER_HTABLE_SIZE); 278 sess->ch_table = pj_hash_create(pool, PJ_TURN_CHANNEL_HTABLE_SIZE); 279 280 /* Permission hash table */ 281 sess->perm_table = pj_hash_create(pool, PJ_TURN_PERM_HTABLE_SIZE); 228 282 229 283 /* Session lock */ … … 483 537 484 538 539 /* 540 * Set software name 541 */ 542 PJ_DEF(pj_status_t) pj_turn_session_set_software_name( pj_turn_session *sess, 543 const pj_str_t *sw) 544 { 545 pj_status_t status; 546 547 pj_lock_acquire(sess->lock); 548 status = pj_stun_session_set_software_name(sess->stun, sw); 549 pj_lock_release(sess->lock); 550 551 return status; 552 } 553 554 485 555 /** 486 556 * Set the server or domain name of the server. … … 705 775 706 776 /* 777 * Install or renew permissions 778 */ 779 PJ_DEF(pj_status_t) pj_turn_session_set_perm( pj_turn_session *sess, 780 unsigned addr_cnt, 781 const pj_sockaddr addr[], 782 unsigned options) 783 { 784 pj_stun_tx_data *tdata; 785 pj_hash_iterator_t it_buf, *it; 786 void *req_token; 787 unsigned i, attr_added=0; 788 pj_status_t status; 789 790 PJ_ASSERT_RETURN(sess && addr_cnt && addr, PJ_EINVAL); 791 792 pj_lock_acquire(sess->lock); 793 794 /* Create a bare CreatePermission request */ 795 status = pj_stun_session_create_req(sess->stun, 796 PJ_STUN_CREATE_PERM_REQUEST, 797 PJ_STUN_MAGIC, NULL, &tdata); 798 if (status != PJ_SUCCESS) { 799 pj_lock_release(sess->lock); 800 return status; 801 } 802 803 /* Create request token to map the request to the perm structures 804 * which the request belongs. 805 */ 806 req_token = (void*)(long)pj_rand(); 807 808 /* Process the addresses */ 809 for (i=0; i<addr_cnt; ++i) { 810 struct perm_t *perm; 811 812 /* Lookup the perm structure and create if it doesn't exist */ 813 perm = lookup_perm(sess, &addr[i], pj_sockaddr_get_len(&addr[i]), 814 PJ_TRUE); 815 perm->renew = (options & 0x01); 816 817 /* Only add to the request if the request doesn't contain this 818 * address yet. 819 */ 820 if (perm->req_token != req_token) { 821 perm->req_token = req_token; 822 823 /* Add XOR-PEER-ADDRESS */ 824 status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 825 PJ_STUN_ATTR_XOR_PEER_ADDR, 826 PJ_TRUE, 827 &addr[i], 828 sizeof(addr[i])); 829 if (status != PJ_SUCCESS) 830 goto on_error; 831 832 ++attr_added; 833 } 834 } 835 836 pj_assert(attr_added != 0); 837 838 /* Send the request */ 839 status = pj_stun_session_send_msg(sess->stun, req_token, PJ_FALSE, 840 (sess->conn_type==PJ_TURN_TP_UDP), 841 sess->srv_addr, 842 pj_sockaddr_get_len(sess->srv_addr), 843 tdata); 844 if (status != PJ_SUCCESS) { 845 /* tdata is already destroyed */ 846 tdata = NULL; 847 goto on_error; 848 } 849 850 pj_lock_release(sess->lock); 851 return PJ_SUCCESS; 852 853 on_error: 854 /* destroy tdata */ 855 if (tdata) { 856 pj_stun_msg_destroy_tdata(sess->stun, tdata); 857 } 858 /* invalidate perm structures associated with this request */ 859 it = pj_hash_first(sess->perm_table, &it_buf); 860 while (it) { 861 struct perm_t *perm = (struct perm_t*) 862 pj_hash_this(sess->perm_table, it); 863 it = pj_hash_next(sess->perm_table, it); 864 if (perm->req_token == req_token) 865 invalidate_perm(sess, perm); 866 } 867 pj_lock_release(sess->lock); 868 return status; 869 } 870 871 /* 707 872 * Send REFRESH 708 873 */ … … 758 923 unsigned addr_len) 759 924 { 760 struct peer *peer; 925 struct ch_t *ch; 926 struct perm_t *perm; 761 927 pj_status_t status; 762 928 … … 772 938 pj_lock_acquire(sess->lock); 773 939 774 /* Lookup peer to see whether we've assigned a channel number 775 * to this peer. 776 */ 777 peer = lookup_peer_by_addr(sess, addr, addr_len, PJ_TRUE, PJ_FALSE); 778 pj_assert(peer != NULL); 779 780 if (peer->ch_id != PJ_TURN_INVALID_CHANNEL && peer->bound) { 781 /* Peer is assigned Channel number, we can use ChannelData */ 940 /* Lookup permission first */ 941 perm = lookup_perm(sess, addr, pj_sockaddr_get_len(addr), PJ_FALSE); 942 if (perm == NULL) { 943 /* Permission doesn't exist, install it first */ 944 char ipstr[PJ_INET6_ADDRSTRLEN+2]; 945 946 PJ_LOG(4,(sess->obj_name, 947 "sendto(): IP %s has no permission, requesting it first..", 948 pj_sockaddr_print(addr, ipstr, sizeof(ipstr), 2))); 949 950 status = pj_turn_session_set_perm(sess, 1, (const pj_sockaddr*)addr, 951 0); 952 if (status != PJ_SUCCESS) { 953 pj_lock_release(sess->lock); 954 return status; 955 } 956 } 957 958 /* See if the peer is bound to a channel number */ 959 ch = lookup_ch_by_addr(sess, addr, pj_sockaddr_get_len(addr), 960 PJ_FALSE, PJ_FALSE); 961 if (ch && ch->num != PJ_TURN_INVALID_CHANNEL && ch->bound) { 962 /* Peer is assigned a channel number, we can use ChannelData */ 782 963 pj_turn_channel_data *cd = (pj_turn_channel_data*)sess->tx_pkt; 783 964 … … 789 970 } 790 971 791 cd->ch_number = pj_htons((pj_uint16_t) peer->ch_id);972 cd->ch_number = pj_htons((pj_uint16_t)ch->num); 792 973 cd->length = pj_htons((pj_uint16_t)pkt_len); 793 974 pj_memcpy(cd+1, pkt, pkt_len); … … 800 981 801 982 } else { 802 /* Peer has not been assigned Channel number, must use Send 803 * Indication. 804 */ 983 /* Use Send Indication. */ 805 984 pj_stun_sockaddr_attr peer_attr; 806 985 pj_stun_binary_attr data_attr; … … 818 997 goto on_return; 819 998 820 /* Add PEER-ADDRESS */821 pj_stun_sockaddr_attr_init(&peer_attr, PJ_STUN_ATTR_ PEER_ADDR,999 /* Add XOR-PEER-ADDRESS */ 1000 pj_stun_sockaddr_attr_init(&peer_attr, PJ_STUN_ATTR_XOR_PEER_ADDR, 822 1001 PJ_TRUE, addr, addr_len); 823 1002 pj_stun_msg_add_attr(&send_ind, (pj_stun_attr_hdr*)&peer_attr); … … 855 1034 unsigned addr_len) 856 1035 { 857 struct peer *peer;1036 struct ch_t *ch; 858 1037 pj_stun_tx_data *tdata; 859 1038 pj_uint16_t ch_num; … … 872 1051 goto on_return; 873 1052 874 /* Lookup peer */ 875 peer = lookup_peer_by_addr(sess, peer_adr, addr_len, PJ_TRUE, PJ_FALSE); 876 pj_assert(peer); 877 878 if (peer->ch_id != PJ_TURN_INVALID_CHANNEL) { 1053 /* Lookup if this peer has already been assigned a number */ 1054 ch = lookup_ch_by_addr(sess, peer_adr, pj_sockaddr_get_len(peer_adr), 1055 PJ_TRUE, PJ_FALSE); 1056 pj_assert(ch); 1057 1058 if (ch->num != PJ_TURN_INVALID_CHANNEL) { 879 1059 /* Channel is already bound. This is a refresh request. */ 880 ch_num = peer->ch_id;1060 ch_num = ch->num; 881 1061 } else { 882 1062 PJ_ASSERT_ON_FAIL(sess->next_ch <= PJ_TURN_CHANNEL_MAX, 883 1063 {status=PJ_ETOOMANY; goto on_return;}); 884 peer->ch_id= ch_num = sess->next_ch++;1064 ch->num = ch_num = sess->next_ch++; 885 1065 } 886 1066 … … 890 1070 PJ_STUN_SET_CH_NB(ch_num)); 891 1071 892 /* Add PEER-ADDRESS attribute */1072 /* Add XOR-PEER-ADDRESS attribute */ 893 1073 pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 894 PJ_STUN_ATTR_ PEER_ADDR, PJ_TRUE,1074 PJ_STUN_ATTR_XOR_PEER_ADDR, PJ_TRUE, 895 1075 peer_adr, addr_len); 896 1076 … … 898 1078 * for future reference when we receive the ChannelBind response. 899 1079 */ 900 status = pj_stun_session_send_msg(sess->stun, peer, PJ_FALSE,1080 status = pj_stun_session_send_msg(sess->stun, ch, PJ_FALSE, 901 1081 (sess->conn_type==PJ_TURN_TP_UDP), 902 1082 sess->srv_addr, … … 950 1130 /* This must be ChannelData. */ 951 1131 pj_turn_channel_data cd; 952 struct peer *peer;1132 struct ch_t *ch; 953 1133 954 1134 if (pkt_len < 4) { … … 981 1161 } 982 1162 983 /* Lookup peer*/984 peer = lookup_peer_by_chnum(sess, cd.ch_number);985 if (! peer || !peer->bound) {1163 /* Lookup channel */ 1164 ch = lookup_ch_by_chnum(sess, cd.ch_number); 1165 if (!ch || !ch->bound) { 986 1166 status = PJ_ENOTFOUND; 987 1167 goto on_return; … … 991 1171 if (sess->cb.on_rx_data) { 992 1172 (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)pkt)+sizeof(cd), 993 cd.length, & peer->addr,994 pj_sockaddr_get_len(& peer->addr));1173 cd.length, &ch->addr, 1174 pj_sockaddr_get_len(&ch->addr)); 995 1175 } 996 1176 … … 1090 1270 { 1091 1271 const pj_stun_lifetime_attr *lf_attr; 1092 const pj_stun_ relayed_addr_attr *raddr_attr;1272 const pj_stun_xor_relayed_addr_attr *raddr_attr; 1093 1273 const pj_stun_sockaddr_attr *mapped_attr; 1094 1274 pj_str_t s; … … 1138 1318 * address family. 1139 1319 */ 1140 raddr_attr = (const pj_stun_ relayed_addr_attr*)1141 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ RELAYED_ADDR, 0);1320 raddr_attr = (const pj_stun_xor_relayed_addr_attr*) 1321 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_RELAYED_ADDR, 0); 1142 1322 if (raddr_attr == NULL && method==PJ_STUN_ALLOCATE_METHOD) { 1143 1323 on_session_fail(sess, method, PJNATH_EINSTUNMSG, … … 1302 1482 { 1303 1483 /* Successful ChannelBind response */ 1304 struct peer *peer = (struct peer*)token;1305 1306 pj_assert( peer->ch_id!= PJ_TURN_INVALID_CHANNEL);1307 peer->bound = PJ_TRUE;1484 struct ch_t *ch = (struct ch_t*)token; 1485 1486 pj_assert(ch->num != PJ_TURN_INVALID_CHANNEL); 1487 ch->bound = PJ_TRUE; 1308 1488 1309 1489 /* Update hash table */ 1310 lookup_ peer_by_addr(sess, &peer->addr,1311 pj_sockaddr_get_len(&peer->addr),1312 1490 lookup_ch_by_addr(sess, &ch->addr, 1491 pj_sockaddr_get_len(&ch->addr), 1492 PJ_TRUE, PJ_TRUE); 1313 1493 1314 1494 } else { … … 1333 1513 } 1334 1514 1515 } else if (method == PJ_STUN_CREATE_PERM_METHOD) { 1516 /* Handle CreatePermission response */ 1517 if (status==PJ_SUCCESS && 1518 PJ_STUN_IS_SUCCESS_RESPONSE(response->hdr.type)) 1519 { 1520 /* No special handling when the request is successful. */ 1521 } else { 1522 /* Iterate the permission table and invalidate all permissions 1523 * that are related to this request. 1524 */ 1525 pj_hash_iterator_t it_buf, *it; 1526 char ipstr[PJ_INET6_ADDRSTRLEN+10]; 1527 int err_code; 1528 char errbuf[PJ_ERR_MSG_SIZE]; 1529 pj_str_t reason; 1530 1531 if (status != PJ_SUCCESS) { 1532 err_code = status; 1533 reason = pj_strerror(status, errbuf, sizeof(errbuf)); 1534 } else { 1535 const pj_stun_errcode_attr *eattr; 1536 1537 eattr = (const pj_stun_errcode_attr*) 1538 pj_stun_msg_find_attr(response, 1539 PJ_STUN_ATTR_ERROR_CODE, 0); 1540 if (eattr) { 1541 err_code = eattr->err_code; 1542 reason = eattr->reason; 1543 } else { 1544 err_code = -1; 1545 reason = pj_str("?"); 1546 } 1547 } 1548 1549 it = pj_hash_first(sess->perm_table, &it_buf); 1550 while (it) { 1551 struct perm_t *perm = (struct perm_t*) 1552 pj_hash_this(sess->perm_table, it); 1553 it = pj_hash_next(sess->perm_table, it); 1554 1555 if (perm->req_token == token) { 1556 PJ_LOG(1,(sess->obj_name, 1557 "CreatePermission failed for IP %s: %d/%.*s", 1558 pj_sockaddr_print(&perm->addr, ipstr, 1559 sizeof(ipstr), 2), 1560 err_code, (int)reason.slen, reason.ptr)); 1561 1562 invalidate_perm(sess, perm); 1563 } 1564 } 1565 } 1566 1335 1567 } else { 1336 1568 PJ_LOG(4,(sess->obj_name, "Unexpected STUN %s response", … … 1353 1585 { 1354 1586 pj_turn_session *sess; 1355 pj_stun_ peer_addr_attr *peer_attr;1587 pj_stun_xor_peer_addr_attr *peer_attr; 1356 1588 pj_stun_icmp_attr *icmp; 1357 1589 pj_stun_data_attr *data_attr; … … 1380 1612 } 1381 1613 1382 /* Get PEER-ADDRESS attribute */1383 peer_attr = (pj_stun_ peer_addr_attr*)1384 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ PEER_ADDR, 0);1614 /* Get XOR-PEER-ADDRESS attribute */ 1615 peer_attr = (pj_stun_xor_peer_addr_attr*) 1616 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0); 1385 1617 1386 1618 /* Get DATA attribute */ … … 1388 1620 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_DATA, 0); 1389 1621 1390 /* Must have both PEER-ADDRESS and DATA attributes */1622 /* Must have both XOR-PEER-ADDRESS and DATA attributes */ 1391 1623 if (!peer_attr || !data_attr) { 1392 1624 PJ_LOG(4,(sess->obj_name, … … 1473 1705 * Lookup peer descriptor from its address. 1474 1706 */ 1475 static struct peer *lookup_peer_by_addr(pj_turn_session *sess, 1476 const pj_sockaddr_t *addr, 1477 unsigned addr_len, 1478 pj_bool_t update, 1479 pj_bool_t bind_channel) 1480 { 1481 unsigned hval = 0; 1482 struct peer *peer; 1483 1484 peer = (struct peer*) pj_hash_get(sess->peer_table, addr, addr_len, &hval); 1485 if (peer == NULL && update) { 1486 peer = PJ_POOL_ZALLOC_T(sess->pool, struct peer); 1487 peer->ch_id = PJ_TURN_INVALID_CHANNEL; 1488 pj_memcpy(&peer->addr, addr, addr_len); 1707 static struct ch_t *lookup_ch_by_addr(pj_turn_session *sess, 1708 const pj_sockaddr_t *addr, 1709 unsigned addr_len, 1710 pj_bool_t update, 1711 pj_bool_t bind_channel) 1712 { 1713 pj_uint32_t hval = 0; 1714 struct ch_t *ch; 1715 1716 ch = (struct ch_t*) 1717 pj_hash_get(sess->ch_table, addr, addr_len, &hval); 1718 if (ch == NULL && update) { 1719 ch = PJ_POOL_ZALLOC_T(sess->pool, struct ch_t); 1720 ch->num = PJ_TURN_INVALID_CHANNEL; 1721 pj_memcpy(&ch->addr, addr, addr_len); 1489 1722 1490 1723 /* Register by peer address */ 1491 pj_hash_set(sess->pool, sess->peer_table, &peer->addr, addr_len, 1492 hval, peer); 1493 } 1494 1495 if (peer && update) { 1496 pj_gettimeofday(&peer->expiry); 1497 if (peer->bound) { 1498 peer->expiry.sec += PJ_TURN_CHANNEL_TIMEOUT - 10; 1499 } else { 1500 peer->expiry.sec += PJ_TURN_PERM_TIMEOUT - 10; 1501 } 1724 pj_hash_set(sess->pool, sess->ch_table, &ch->addr, addr_len, 1725 hval, ch); 1726 } 1727 1728 if (ch && update) { 1729 pj_gettimeofday(&ch->expiry); 1730 ch->expiry.sec += PJ_TURN_PERM_TIMEOUT - PJ_TURN_RENEWAL_BEFORE; 1502 1731 1503 1732 if (bind_channel) { 1504 1733 pj_uint32_t hval = 0; 1505 1734 /* Register by channel number */ 1506 pj_assert( peer->ch_id != PJ_TURN_INVALID_CHANNEL && peer->bound);1507 1508 if (pj_hash_get(sess-> peer_table, &peer->ch_id,1509 sizeof( peer->ch_id), &hval)==0) {1510 pj_hash_set(sess->pool, sess-> peer_table, &peer->ch_id,1511 sizeof( peer->ch_id), hval, peer);1735 pj_assert(ch->num != PJ_TURN_INVALID_CHANNEL && ch->bound); 1736 1737 if (pj_hash_get(sess->ch_table, &ch->num, 1738 sizeof(ch->num), &hval)==0) { 1739 pj_hash_set(sess->pool, sess->ch_table, &ch->num, 1740 sizeof(ch->num), hval, ch); 1512 1741 } 1513 1742 } 1514 1743 } 1515 1744 1516 return peer;1517 } 1518 1519 1520 /* 1521 * Lookup peerdescriptor from its channel number.1522 */ 1523 static struct peer *lookup_peer_by_chnum(pj_turn_session *sess,1745 return ch; 1746 } 1747 1748 1749 /* 1750 * Lookup channel descriptor from its channel number. 1751 */ 1752 static struct ch_t *lookup_ch_by_chnum(pj_turn_session *sess, 1524 1753 pj_uint16_t chnum) 1525 1754 { 1526 return (struct peer*) pj_hash_get(sess->peer_table, &chnum,1755 return (struct ch_t*) pj_hash_get(sess->ch_table, &chnum, 1527 1756 sizeof(chnum), NULL); 1528 1757 } 1529 1758 1759 1760 /* 1761 * Lookup permission and optionally create if it doesn't exist. 1762 */ 1763 static struct perm_t *lookup_perm(pj_turn_session *sess, 1764 const pj_sockaddr_t *addr, 1765 unsigned addr_len, 1766 pj_bool_t update) 1767 { 1768 pj_uint32_t hval = 0; 1769 pj_sockaddr perm_addr; 1770 struct perm_t *perm; 1771 1772 /* make sure port number if zero */ 1773 if (pj_sockaddr_get_port(addr) != 0) { 1774 pj_memcpy(&perm_addr, addr, addr_len); 1775 pj_sockaddr_set_port(&perm_addr, 0); 1776 addr = &perm_addr; 1777 } 1778 1779 /* lookup and create if it doesn't exist and wanted */ 1780 perm = (struct perm_t*) 1781 pj_hash_get(sess->perm_table, addr, addr_len, &hval); 1782 if (perm == NULL && update) { 1783 perm = PJ_POOL_ZALLOC_T(sess->pool, struct perm_t); 1784 pj_memcpy(&perm->addr, addr, addr_len); 1785 perm->hval = hval; 1786 1787 pj_hash_set(sess->pool, sess->perm_table, &perm->addr, addr_len, 1788 perm->hval, perm); 1789 } 1790 1791 if (perm && update) { 1792 pj_gettimeofday(&perm->expiry); 1793 perm->expiry.sec += PJ_TURN_PERM_TIMEOUT - PJ_TURN_RENEWAL_BEFORE; 1794 1795 } 1796 1797 return perm; 1798 } 1799 1800 /* 1801 * Delete permission 1802 */ 1803 static void invalidate_perm(pj_turn_session *sess, 1804 struct perm_t *perm) 1805 { 1806 pj_hash_set(NULL, sess->perm_table, &perm->addr, 1807 pj_sockaddr_get_len(&perm->addr), perm->hval, NULL); 1808 } 1530 1809 1531 1810 /* … … 1565 1844 1566 1845 /* Scan hash table to refresh bound channels */ 1567 it = pj_hash_first(sess-> peer_table, &itbuf);1846 it = pj_hash_first(sess->ch_table, &itbuf); 1568 1847 while (it) { 1569 struct peer *peer = (struct peer*)1570 pj_hash_this(sess->peer_table, it);1571 if ( peer->bound && PJ_TIME_VAL_LTE(peer->expiry, now)) {1848 struct ch_t *ch = (struct ch_t*) 1849 pj_hash_this(sess->ch_table, it); 1850 if (ch->bound && PJ_TIME_VAL_LTE(ch->expiry, now)) { 1572 1851 1573 1852 /* Send ChannelBind to refresh channel binding and 1574 1853 * permission. 1575 1854 */ 1576 pj_turn_session_bind_channel(sess, & peer->addr,1577 pj_sockaddr_get_len(& peer->addr));1855 pj_turn_session_bind_channel(sess, &ch->addr, 1856 pj_sockaddr_get_len(&ch->addr)); 1578 1857 pkt_sent = PJ_TRUE; 1579 1858 } 1580 1859 1581 it = pj_hash_next(sess-> peer_table, it);1860 it = pj_hash_next(sess->ch_table, it); 1582 1861 } 1583 1862 -
pjproject/trunk/pjnath/src/pjnath/turn_sock.c
r2394 r2589 388 388 389 389 /* 390 * Install permission 391 */ 392 PJ_DEF(pj_status_t) pj_turn_sock_set_perm( pj_turn_sock *turn_sock, 393 unsigned addr_cnt, 394 const pj_sockaddr addr[], 395 unsigned options) 396 { 397 if (turn_sock->sess == NULL) 398 return PJ_EINVALIDOP; 399 400 return pj_turn_session_set_perm(turn_sock->sess, addr_cnt, addr, options); 401 } 402 403 /* 390 404 * Send packet. 391 405 */ -
pjproject/trunk/pjnath/src/pjturn-client/client_main.c
r2408 r2589 139 139 char name[] = "peer0"; 140 140 pj_uint16_t port; 141 pj_stun_sock_cfg ss_cfg; 141 142 pj_str_t server; 142 143 … … 147 148 g.peer[i].mapped_addr.addr.sa_family = pj_AF_INET(); 148 149 150 pj_stun_sock_cfg_default(&ss_cfg); 151 #if 1 152 /* make reading the log easier */ 153 ss_cfg.ka_interval = 300; 154 #endif 155 149 156 name[strlen(name)-1] = '0'+i; 150 157 status = pj_stun_sock_create(&g.stun_config, name, pj_AF_INET(), 151 &stun_sock_cb, NULL,158 &stun_sock_cb, &ss_cfg, 152 159 &g.peer[i], &g.peer[i].stun_sock); 153 160 if (status != PJ_SUCCESS) { … … 416 423 417 424 puts("\n"); 418 puts("+==================================================================== +");419 puts("| CLIENT | PEER-0 |");420 puts("| | |");421 printf("| State : %-12s | Address: %-21s |\n",425 puts("+=====================================================================+"); 426 puts("| CLIENT | PEER-0 |"); 427 puts("| | |"); 428 printf("| State : %-12s | Address: %-21s |\n", 422 429 client_state, peer0_addr); 423 printf("| Relay addr: %-21s | |\n",430 printf("| Relay addr: %-21s | |\n", 424 431 relay_addr); 425 puts("| | 0 Send data to relay address |"); 426 puts("| a Allocate relay +--------------------------------+ "); 427 puts("| s,ss Send data to peer 0/1 | PEER-1 |"); 428 puts("| b,bb BindChannel to peer 0/1 | |"); 429 printf("| x Delete allocation | Address: %-21s |\n", 432 puts("| | 0 Send data to relay address |"); 433 puts("| a Allocate relay | |"); 434 puts("| p,pp Set permission for peer 0/1 +--------------------------------+"); 435 puts("| s,ss Send data to peer 0/1 | PEER-1 |"); 436 puts("| b,bb BindChannel to peer 0/1 | |"); 437 printf("| x Delete allocation | Address: %-21s |\n", 430 438 peer1_addr); 431 puts("+----------------------------------- + |");432 puts("| q Quit d Dump | 1 Send data to relay adderss |");433 puts("+----------------------------------- +--------------------------------+");439 puts("+------------------------------------+ |"); 440 puts("| q Quit d Dump | 1 Send data to relay adderss |"); 441 puts("+------------------------------------+--------------------------------+"); 434 442 printf(">>> "); 435 443 fflush(stdout); … … 488 496 if (status != PJ_SUCCESS) 489 497 my_perror("turn_udp_bind_channel() failed", status); 498 break; 499 case 'p': 500 if (g.relay == NULL) { 501 puts("Error: no relay"); 502 continue; 503 } 504 if (input[1]!='p') 505 peer = &g.peer[0]; 506 else 507 peer = &g.peer[1]; 508 509 status = pj_turn_sock_set_perm(g.relay, 1, &peer->mapped_addr, 1); 510 if (status != PJ_SUCCESS) 511 my_perror("pj_turn_sock_set_perm() failed", status); 490 512 break; 491 513 case 'x': -
pjproject/trunk/pjnath/src/pjturn-srv/allocation.c
r2394 r2589 110 110 pj_stun_req_transport_attr *attr_req_tp; 111 111 pj_stun_res_token_attr *attr_res_token; 112 pj_stun_req_props_attr *attr_rpp;113 112 pj_stun_lifetime_attr *attr_lifetime; 114 113 … … 165 164 } 166 165 167 /* Get REQUESTED-PROPS attribute, if any */168 attr_rpp = (pj_stun_req_props_attr*)169 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REQ_PROPS, 0);170 if (attr_rpp) {171 /* We don't support REQUESTED-PROPS for now */172 pj_stun_session_respond(sess, rdata,173 PJ_STUN_SC_BAD_REQUEST,174 "REQUESTED-PROPS is not supported",175 NULL, PJ_TRUE, src_addr, src_addr_len);176 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);177 }178 179 166 /* Get LIFETIME attribute */ 180 167 attr_lifetime = (pj_stun_uint_attr*) … … 212 199 return status; 213 200 214 /* Add RELAYED-ADDRESS attribute */201 /* Add XOR-RELAYED-ADDRESS attribute */ 215 202 pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 216 PJ_STUN_ATTR_ RELAYED_ADDR, PJ_TRUE,203 PJ_STUN_ATTR_XOR_RELAYED_ADDR, PJ_TRUE, 217 204 &alloc->relay.hkey.addr, 218 205 pj_sockaddr_get_len(&alloc->relay.hkey.addr)); … … 1071 1058 1072 1059 pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 1073 PJ_STUN_ATTR_ PEER_ADDR, PJ_TRUE,1060 PJ_STUN_ATTR_XOR_PEER_ADDR, PJ_TRUE, 1074 1061 src_addr, pj_sockaddr_get_len(src_addr)); 1075 1062 pj_stun_msg_add_binary_attr(tdata->pool, tdata->msg, … … 1231 1218 */ 1232 1219 pj_stun_channel_number_attr *ch_attr; 1233 pj_stun_ peer_addr_attr *peer_attr;1220 pj_stun_xor_peer_addr_attr *peer_attr; 1234 1221 pj_turn_permission *p1, *p2; 1235 1222 1236 1223 ch_attr = (pj_stun_channel_number_attr*) 1237 1224 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_CHANNEL_NUMBER, 0); 1238 peer_attr = (pj_stun_ peer_addr_attr*)1239 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ PEER_ADDR, 0);1225 peer_attr = (pj_stun_xor_peer_addr_attr*) 1226 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0); 1240 1227 1241 1228 if (!ch_attr || !peer_attr) { … … 1334 1321 unsigned src_addr_len) 1335 1322 { 1336 pj_stun_ peer_addr_attr *peer_attr;1323 pj_stun_xor_peer_addr_attr *peer_attr; 1337 1324 pj_stun_data_attr *data_attr; 1338 1325 pj_turn_allocation *alloc; … … 1354 1341 } 1355 1342 1356 /* Get PEER-ADDRESS attribute */1357 peer_attr = (pj_stun_ peer_addr_attr*)1358 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ PEER_ADDR, 0);1359 1360 /* MUST have PEER-ADDRESS attribute */1343 /* Get XOR-PEER-ADDRESS attribute */ 1344 peer_attr = (pj_stun_xor_peer_addr_attr*) 1345 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0); 1346 1347 /* MUST have XOR-PEER-ADDRESS attribute */ 1361 1348 if (!peer_attr) 1362 1349 return PJ_SUCCESS;
Note: See TracChangeset
for help on using the changeset viewer.