- Timestamp:
- Jun 8, 2016 3:17:45 AM (8 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c
r4949 r5339 51 51 pjmedia_transport base; 52 52 pj_pool_t *pool; 53 int af;54 53 unsigned options; /**< Transport options. */ 55 54 … … 236 235 tp_ice = PJ_POOL_ZALLOC_T(pool, struct transport_ice); 237 236 tp_ice->pool = pool; 238 tp_ice->af = cfg->af;239 237 tp_ice->options = options; 240 238 tp_ice->comp_cnt = comp_cnt; … … 823 821 pj_sockaddr rem_conn_addr, rtcp_addr; 824 822 unsigned i; 823 int rem_af = 0; 825 824 pj_status_t status; 826 825 … … 849 848 850 849 /* Verify address family matches */ 850 /* 851 851 if ((tp_ice->af==pj_AF_INET() && 852 852 pj_strcmp(&rem_conn->addr_type, &STR_IP4)!=0) || … … 856 856 return PJMEDIA_SDP_ETPORTNOTEQUAL; 857 857 } 858 */ 859 860 /* Get remote address family */ 861 if (pj_strcmp(&rem_conn->addr_type, &STR_IP4)==0) 862 rem_af = pj_AF_INET(); 863 else if (pj_strcmp(&rem_conn->addr_type, &STR_IP6)==0) 864 rem_af = pj_AF_INET6(); 865 else 866 pj_assert(!"Unsupported address family"); 858 867 859 868 /* Assign remote connection address */ 860 status = pj_sockaddr_init( tp_ice->af, &rem_conn_addr, &rem_conn->addr,869 status = pj_sockaddr_init(rem_af, &rem_conn_addr, &rem_conn->addr, 861 870 (pj_uint16_t)rem_m->desc.port); 862 871 if (status != PJ_SUCCESS) … … 884 893 if (rtcp_attr.addr.slen) { 885 894 /* Verify address family matches */ 895 /* 886 896 if ((tp_ice->af==pj_AF_INET() && 887 897 pj_strcmp(&rtcp_attr.addr_type, &STR_IP4)!=0) || … … 891 901 return PJMEDIA_SDP_ETPORTNOTEQUAL; 892 902 } 903 */ 893 904 894 905 /* Assign RTCP address */ 895 status = pj_sockaddr_init( tp_ice->af, &rtcp_addr,906 status = pj_sockaddr_init(rem_af, &rtcp_addr, 896 907 &rtcp_attr.addr, 897 908 (pj_uint16_t)rtcp_attr.port); … … 901 912 } else { 902 913 /* Assign RTCP address */ 903 status = pj_sockaddr_init( tp_ice->af, &rtcp_addr,914 status = pj_sockaddr_init(rem_af, &rtcp_addr, 904 915 NULL, 905 916 (pj_uint16_t)rtcp_attr.port); -
pjproject/trunk/pjnath/include/pjnath/config.h
r4199 r5339 243 243 #ifndef PJ_ICE_ST_MAX_CAND 244 244 # define PJ_ICE_ST_MAX_CAND 8 245 #endif 246 247 248 /** 249 * Maximum number of STUN transports for each ICE stream transport component. 250 * Valid values are 1 - 64. 251 * 252 * Default: 2 253 */ 254 #ifndef PJ_ICE_MAX_STUN 255 # define PJ_ICE_MAX_STUN 2 256 #endif 257 258 259 /** 260 * Maximum number of TURN transports for each ICE stream transport component. 261 * Valid values are 1 - 64. 262 * 263 * Default: 2 264 */ 265 #ifndef PJ_ICE_MAX_TURN 266 # define PJ_ICE_MAX_TURN 2 245 267 #endif 246 268 -
pjproject/trunk/pjnath/include/pjnath/ice_session.h
r4602 r5339 654 654 655 655 /** Array of transport datas */ 656 pj_ice_msg_data tp_data[ 4];656 pj_ice_msg_data tp_data[PJ_ICE_MAX_STUN + PJ_ICE_MAX_TURN]; 657 657 658 658 /* List of eearly checks */ -
pjproject/trunk/pjnath/include/pjnath/ice_strans.h
r5282 r5339 176 176 177 177 /** 178 * STUN and local transport settings for ICE stream transport. 179 */ 180 typedef struct pj_ice_strans_stun_cfg 181 { 182 /** 183 * Address family, IPv4 or IPv6. 184 * 185 * Default value is pj_AF_INET() (IPv4) 186 */ 187 int af; 188 189 /** 190 * Optional configuration for STUN transport. The default 191 * value will be initialized with #pj_stun_sock_cfg_default(). 192 */ 193 pj_stun_sock_cfg cfg; 194 195 /** 196 * Maximum number of host candidates to be added. If the 197 * value is zero, no host candidates will be added. 198 * 199 * Default: 64 200 */ 201 unsigned max_host_cands; 202 203 /** 204 * Include loopback addresses in the host candidates. 205 * 206 * Default: PJ_FALSE 207 */ 208 pj_bool_t loop_addr; 209 210 /** 211 * Specify the STUN server domain or hostname or IP address. 212 * If DNS SRV resolution is required, application must fill 213 * in this setting with the domain name of the STUN server 214 * and set the resolver instance in the \a resolver field. 215 * Otherwise if the \a resolver setting is not set, this 216 * field will be resolved with hostname resolution and in 217 * this case the \a port field must be set. 218 * 219 * The \a port field should also be set even when DNS SRV 220 * resolution is used, in case the DNS SRV resolution fails. 221 * 222 * When this field is empty, STUN mapped address resolution 223 * will not be performed. In this case only ICE host candidates 224 * will be added to the ICE transport, unless if \a no_host_cands 225 * field is set. In this case, both host and srflx candidates 226 * are disabled. 227 * 228 * If there are more than one STUN candidates per ICE stream 229 * transport component, the standard recommends to use the same 230 * STUN server for all STUN candidates. 231 * 232 * The default value is empty. 233 */ 234 pj_str_t server; 235 236 /** 237 * The port number of the STUN server, when \a server 238 * field specifies a hostname rather than domain name. This 239 * field should also be set even when the \a server 240 * specifies a domain name, to allow DNS SRV resolution 241 * to fallback to DNS A/AAAA resolution when the DNS SRV 242 * resolution fails. 243 * 244 * The default value is PJ_STUN_PORT. 245 */ 246 pj_uint16_t port; 247 248 /** 249 * Ignore STUN resolution error and proceed with just local 250 * addresses. 251 * 252 * The default is PJ_FALSE 253 */ 254 pj_bool_t ignore_stun_error; 255 256 } pj_ice_strans_stun_cfg; 257 258 259 /** 260 * TURN transport settings for ICE stream transport. 261 */ 262 typedef struct pj_ice_strans_turn_cfg 263 { 264 /** 265 * Address family, IPv4 or IPv6. 266 * 267 * Default value is pj_AF_INET() (IPv4) 268 */ 269 int af; 270 271 /** 272 * Optional TURN socket settings. The default values will be 273 * initialized by #pj_turn_sock_cfg_default(). This contains 274 * settings such as QoS. 275 */ 276 pj_turn_sock_cfg cfg; 277 278 /** 279 * Specify the TURN server domain or hostname or IP address. 280 * If DNS SRV resolution is required, application must fill 281 * in this setting with the domain name of the TURN server 282 * and set the resolver instance in the \a resolver field. 283 * Otherwise if the \a resolver setting is not set, this 284 * field will be resolved with hostname resolution and in 285 * this case the \a port field must be set. 286 * 287 * The \a port field should also be set even when DNS SRV 288 * resolution is used, in case the DNS SRV resolution fails. 289 * 290 * When this field is empty, relay candidate will not be 291 * created. 292 * 293 * The default value is empty. 294 */ 295 pj_str_t server; 296 297 /** 298 * The port number of the TURN server, when \a server 299 * field specifies a hostname rather than domain name. This 300 * field should also be set even when the \a server 301 * specifies a domain name, to allow DNS SRV resolution 302 * to fallback to DNS A/AAAA resolution when the DNS SRV 303 * resolution fails. 304 * 305 * Default is zero. 306 */ 307 pj_uint16_t port; 308 309 /** 310 * Type of connection to the TURN server. 311 * 312 * Default is PJ_TURN_TP_UDP. 313 */ 314 pj_turn_tp_type conn_type; 315 316 /** 317 * Credential to be used for the TURN session. This setting 318 * is mandatory. 319 * 320 * Default is to have no credential. 321 */ 322 pj_stun_auth_cred auth_cred; 323 324 /** 325 * Optional TURN Allocate parameter. The default value will be 326 * initialized by #pj_turn_alloc_param_default(). 327 */ 328 pj_turn_alloc_param alloc_param; 329 330 } pj_ice_strans_turn_cfg; 331 332 333 /** 178 334 * This structure describes ICE stream transport configuration. Application 179 335 * should initialize the structure by calling #pj_ice_strans_cfg_default() … … 183 339 { 184 340 /** 185 * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4) 186 * is supported, and this is the default value. 187 */ 188 int af; 341 * Warning: this field is deprecated and will be ignored. Please specify 342 * transport address family in STUN and TURN transport setting, i.e: 343 * \a stun_tp and \a turn_tp. 344 */ 345 int af; 189 346 190 347 /** … … 214 371 215 372 /** 216 * STUN and local transport settings. This specifies the 217 * settings for local UDP socket, which will be resolved 218 * to get the STUN mapped address. 219 */ 220 struct { 221 /** 222 * Optional configuration for STUN transport. The default 223 * value will be initialized with #pj_stun_sock_cfg_default(). 224 */ 225 pj_stun_sock_cfg cfg; 226 227 /** 228 * Maximum number of host candidates to be added. If the 229 * value is zero, no host candidates will be added. 230 * 231 * Default: 64 232 */ 233 unsigned max_host_cands; 234 235 /** 236 * Include loopback addresses in the host candidates. 237 * 238 * Default: PJ_FALSE 239 */ 240 pj_bool_t loop_addr; 241 242 /** 243 * Specify the STUN server domain or hostname or IP address. 244 * If DNS SRV resolution is required, application must fill 245 * in this setting with the domain name of the STUN server 246 * and set the resolver instance in the \a resolver field. 247 * Otherwise if the \a resolver setting is not set, this 248 * field will be resolved with hostname resolution and in 249 * this case the \a port field must be set. 250 * 251 * The \a port field should also be set even when DNS SRV 252 * resolution is used, in case the DNS SRV resolution fails. 253 * 254 * When this field is empty, STUN mapped address resolution 255 * will not be performed. In this case only ICE host candidates 256 * will be added to the ICE transport, unless if \a no_host_cands 257 * field is set. In this case, both host and srflx candidates 258 * are disabled. 259 * 260 * The default value is empty. 261 */ 262 pj_str_t server; 263 264 /** 265 * The port number of the STUN server, when \a server 266 * field specifies a hostname rather than domain name. This 267 * field should also be set even when the \a server 268 * specifies a domain name, to allow DNS SRV resolution 269 * to fallback to DNS A/AAAA resolution when the DNS SRV 270 * resolution fails. 271 * 272 * The default value is PJ_STUN_PORT. 273 */ 274 pj_uint16_t port; 275 276 /** 277 * Ignore STUN resolution error and proceed with just local 278 * addresses. 279 * 280 * The default is PJ_FALSE 281 */ 282 pj_bool_t ignore_stun_error; 283 284 } stun; 285 286 /** 287 * TURN specific settings. 288 */ 289 struct { 290 /** 291 * Optional TURN socket settings. The default values will be 292 * initialized by #pj_turn_sock_cfg_default(). This contains 293 * settings such as QoS. 294 */ 295 pj_turn_sock_cfg cfg; 296 297 /** 298 * Specify the TURN server domain or hostname or IP address. 299 * If DNS SRV resolution is required, application must fill 300 * in this setting with the domain name of the TURN server 301 * and set the resolver instance in the \a resolver field. 302 * Otherwise if the \a resolver setting is not set, this 303 * field will be resolved with hostname resolution and in 304 * this case the \a port field must be set. 305 * 306 * The \a port field should also be set even when DNS SRV 307 * resolution is used, in case the DNS SRV resolution fails. 308 * 309 * When this field is empty, relay candidate will not be 310 * created. 311 * 312 * The default value is empty. 313 */ 314 pj_str_t server; 315 316 /** 317 * The port number of the TURN server, when \a server 318 * field specifies a hostname rather than domain name. This 319 * field should also be set even when the \a server 320 * specifies a domain name, to allow DNS SRV resolution 321 * to fallback to DNS A/AAAA resolution when the DNS SRV 322 * resolution fails. 323 * 324 * Default is zero. 325 */ 326 pj_uint16_t port; 327 328 /** 329 * Type of connection to the TURN server. 330 * 331 * Default is PJ_TURN_TP_UDP. 332 */ 333 pj_turn_tp_type conn_type; 334 335 /** 336 * Credential to be used for the TURN session. This setting 337 * is mandatory. 338 * 339 * Default is to have no credential. 340 */ 341 pj_stun_auth_cred auth_cred; 342 343 /** 344 * Optional TURN Allocate parameter. The default value will be 345 * initialized by #pj_turn_alloc_param_default(). 346 */ 347 pj_turn_alloc_param alloc_param; 348 349 } turn; 373 * Warning: this field is deprecated, please use \a stun_tp field instead. 374 * To maintain backward compatibility, if \a stun_tp_cnt is zero, the 375 * value of this field will be copied to \a stun_tp. 376 * 377 * STUN and local transport settings. This specifies the settings 378 * for local UDP socket address and STUN resolved address. 379 */ 380 pj_ice_strans_stun_cfg stun; 381 382 /** 383 * Number of STUN transports. 384 * 385 * Default: 0 386 */ 387 unsigned stun_tp_cnt; 388 389 /** 390 * STUN and local transport settings. This specifies the settings 391 * for local UDP socket address and STUN resolved address. 392 */ 393 pj_ice_strans_stun_cfg stun_tp[PJ_ICE_MAX_STUN]; 394 395 /** 396 * Warning: this field is deprecated, please use \a turn_tp field instead. 397 * To maintain backward compatibility, if \a turn_tp_cnt is zero, the 398 * value of this field will be copied to \a turn_tp. 399 * 400 * TURN transport settings. 401 */ 402 pj_ice_strans_turn_cfg turn; 403 404 /** 405 * Number of TURN transports. 406 * 407 * Default: 0 408 */ 409 unsigned turn_tp_cnt; 410 411 /** 412 * TURN transport settings. 413 */ 414 pj_ice_strans_turn_cfg turn_tp[PJ_ICE_MAX_TURN]; 350 415 351 416 /** … … 467 532 468 533 534 /** 535 * Initialize ICE STUN transport configuration with default values. 536 * 537 * @param cfg The configuration to be initialized. 538 */ 539 PJ_DECL(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg); 540 541 542 /** 543 * Initialize ICE TURN transport configuration with default values. 544 * 545 * @param cfg The configuration to be initialized. 546 */ 547 PJ_DECL(void) pj_ice_strans_turn_cfg_default(pj_ice_strans_turn_cfg *cfg); 548 549 469 550 /** 470 551 * Copy configuration. -
pjproject/trunk/pjnath/include/pjnath/stun_sock.h
r4606 r5339 372 372 * 373 373 * @param stun_sock The STUN transport instance. 374 * @param domain The domain, hostname, or IP address of the TURN374 * @param domain The domain, hostname, or IP address of the STUN 375 375 * server. When this parameter contains domain name, 376 376 * the \a resolver parameter must be set to activate -
pjproject/trunk/pjnath/src/pjnath-test/concur_test.c
r4898 r5339 27 27 #define WORKER_THREAD_CNT 4 28 28 #define SERVER_THREAD_CNT 4 29 #define MAX_SOCK_CLIENTS 8029 #define MAX_SOCK_CLIENTS (PJ_IOQUEUE_MAX_HANDLES/2) 30 30 31 31 struct stun_test_session … … 220 220 } 221 221 222 /* Give some time to ioqueue to free sockets */ 223 pj_thread_sleep(PJ_IOQUEUE_KEY_FREE_DELAY); 224 222 225 return 0; 223 226 } -
pjproject/trunk/pjnath/src/pjnath/ice_session.c
r5221 r5339 397 397 /* Initialize transport datas */ 398 398 for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) { 399 ice->tp_data[i].transport_id = i;399 ice->tp_data[i].transport_id = 0; 400 400 ice->tp_data[i].has_req_data = PJ_FALSE; 401 401 } … … 724 724 pj_status_t status = PJ_SUCCESS; 725 725 char address[PJ_INET6_ADDRSTRLEN]; 726 unsigned i; 726 727 727 728 PJ_ASSERT_RETURN(ice && comp_id && … … 748 749 rel_addr = base_addr; 749 750 pj_memcpy(&lcand->rel_addr, rel_addr, addr_len); 751 752 /* Update transport data */ 753 for (i = 0; i < PJ_ARRAY_SIZE(ice->tp_data); ++i) { 754 /* Check if this transport has been registered */ 755 if (ice->tp_data[i].transport_id == transport_id) 756 break; 757 758 if (ice->tp_data[i].transport_id == 0) { 759 /* Found an empty slot, register this transport here */ 760 ice->tp_data[i].transport_id = transport_id; 761 break; 762 } 763 } 764 pj_assert(i < PJ_ARRAY_SIZE(ice->tp_data) && 765 ice->tp_data[i].transport_id == transport_id); 750 766 751 767 pj_ansi_strcpy(ice->tmp.txt, pj_sockaddr_print(&lcand->addr, address, -
pjproject/trunk/pjnath/src/pjnath/ice_strans.c
r5282 r5339 49 49 }; 50 50 51 52 #define CREATE_TP_ID(type, idx) (pj_uint8_t)((type << 6) | idx) 53 #define GET_TP_TYPE(transport_id) ((transport_id & 0xC0) >> 6) 54 #define GET_TP_IDX(transport_id) (transport_id & 0x3F) 55 56 51 57 /* Candidate's local preference values. This is mostly used to 52 58 * specify preference among candidates with the same type. Since … … 149 155 unsigned comp_id; /**< Component ID. */ 150 156 151 pj_stun_sock *stun_sock; /**< STUN transport. */ 152 pj_turn_sock *turn_sock; /**< TURN relay transport. */ 153 pj_bool_t turn_log_off; /**< TURN loggin off? */ 154 unsigned turn_err_cnt; /**< TURN disconnected count. */ 157 struct { 158 pj_stun_sock *sock; /**< STUN transport. */ 159 } stun[PJ_ICE_MAX_STUN]; 160 161 struct { 162 pj_turn_sock *sock; /**< TURN relay transport. */ 163 pj_bool_t log_off; /**< TURN loggin off? */ 164 unsigned err_cnt; /**< TURN disconnected count. */ 165 } turn[PJ_ICE_MAX_TURN]; 155 166 156 167 unsigned cand_cnt; /**< # of candidates/aliaes. */ … … 188 199 189 200 201 /** 202 * This structure describe user data for STUN/TURN sockets of the 203 * ICE stream transport. 204 */ 205 typedef struct sock_user_data 206 { 207 pj_ice_strans_comp *comp; 208 pj_uint8_t transport_id; 209 210 } sock_user_data; 211 212 190 213 /* Validate configuration */ 191 214 static pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg) … … 209 232 210 233 pj_stun_config_init(&cfg->stun_cfg, NULL, 0, NULL, NULL); 211 pj_stun_sock_cfg_default(&cfg->stun.cfg); 212 pj_turn_alloc_param_default(&cfg->turn.alloc_param); 213 pj_turn_sock_cfg_default(&cfg->turn.cfg); 214 234 pj_ice_strans_stun_cfg_default(&cfg->stun); 235 pj_ice_strans_turn_cfg_default(&cfg->turn); 215 236 pj_ice_sess_options_default(&cfg->opt); 237 } 238 239 240 /* 241 * Initialize ICE STUN transport configuration with default values. 242 */ 243 PJ_DEF(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg) 244 { 245 pj_bzero(cfg, sizeof(*cfg)); 216 246 217 247 cfg->af = pj_AF_INET(); 218 cfg->stun.port = PJ_STUN_PORT; 219 cfg->turn.conn_type = PJ_TURN_TP_UDP; 220 221 cfg->stun.max_host_cands = 64; 222 cfg->stun.ignore_stun_error = PJ_FALSE; 248 cfg->port = PJ_STUN_PORT; 249 cfg->max_host_cands = 64; 250 cfg->ignore_stun_error = PJ_FALSE; 251 pj_stun_sock_cfg_default(&cfg->cfg); 252 } 253 254 255 /* 256 * Initialize ICE TURN transport configuration with default values. 257 */ 258 PJ_DEF(void) pj_ice_strans_turn_cfg_default(pj_ice_strans_turn_cfg *cfg) 259 { 260 pj_bzero(cfg, sizeof(*cfg)); 261 262 cfg->af = pj_AF_INET(); 263 cfg->conn_type = PJ_TURN_TP_UDP; 264 pj_turn_alloc_param_default(&cfg->alloc_param); 265 pj_turn_sock_cfg_default(&cfg->cfg); 223 266 } 224 267 … … 231 274 const pj_ice_strans_cfg *src) 232 275 { 276 unsigned i; 277 233 278 pj_memcpy(dst, src, sizeof(*src)); 234 279 235 280 if (src->stun.server.slen) 236 281 pj_strdup(pool, &dst->stun.server, &src->stun.server); 282 283 for (i = 0; i < src->stun_tp_cnt; ++i) { 284 if (src->stun_tp[i].server.slen) 285 pj_strdup(pool, &dst->stun_tp[i].server, 286 &src->stun_tp[i].server); 287 } 288 237 289 if (src->turn.server.slen) 238 290 pj_strdup(pool, &dst->turn.server, &src->turn.server); 239 pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, 240 &src->turn.auth_cred); 291 pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, &src->turn.auth_cred); 292 293 for (i = 0; i < src->turn_tp_cnt; ++i) { 294 if (src->turn_tp[i].server.slen) 295 pj_strdup(pool, &dst->turn_tp[i].server, 296 &src->turn_tp[i].server); 297 pj_stun_auth_cred_dup(pool, &dst->turn_tp[i].auth_cred, 298 &src->turn_tp[i].auth_cred); 299 } 241 300 } 242 301 … … 246 305 */ 247 306 static pj_status_t add_update_turn(pj_ice_strans *ice_st, 248 pj_ice_strans_comp *comp) 249 { 307 pj_ice_strans_comp *comp, 308 unsigned idx) 309 { 310 pj_ice_sess_cand *cand = NULL; 311 pj_ice_strans_turn_cfg *turn_cfg = &ice_st->cfg.turn_tp[idx]; 312 pj_turn_sock_cfg *sock_cfg = &turn_cfg->cfg; 313 unsigned comp_idx = comp->comp_id - 1; 250 314 pj_turn_sock_cb turn_sock_cb; 251 pj_ice_sess_cand *cand = NULL;315 sock_user_data *data; 252 316 unsigned i; 317 pj_uint8_t tp_id; 253 318 pj_status_t status; 254 319 320 /* Check if TURN transport is configured */ 321 if (turn_cfg->server.slen == 0) 322 return PJ_SUCCESS; 323 255 324 /* Find relayed candidate in the component */ 325 tp_id = CREATE_TP_ID(TP_TURN, idx); 256 326 for (i=0; i<comp->cand_cnt; ++i) { 257 if (comp->cand_list[i].t ype == PJ_ICE_CAND_TYPE_RELAYED) {327 if (comp->cand_list[i].transport_id == tp_id) { 258 328 cand = &comp->cand_list[i]; 259 329 break; … … 287 357 288 358 /* Override with component specific QoS settings, if any */ 289 if (ice_st->cfg.comp[comp->comp_id-1].qos_type) { 290 ice_st->cfg.turn.cfg.qos_type = 291 ice_st->cfg.comp[comp->comp_id-1].qos_type; 292 } 293 if (ice_st->cfg.comp[comp->comp_id-1].qos_params.flags) { 294 pj_memcpy(&ice_st->cfg.turn.cfg.qos_params, 295 &ice_st->cfg.comp[comp->comp_id-1].qos_params, 296 sizeof(ice_st->cfg.turn.cfg.qos_params)); 297 } 359 if (ice_st->cfg.comp[comp_idx].qos_type) 360 sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type; 361 if (ice_st->cfg.comp[comp_idx].qos_params.flags) 362 pj_memcpy(&sock_cfg->qos_params, 363 &ice_st->cfg.comp[comp_idx].qos_params, 364 sizeof(sock_cfg->qos_params)); 298 365 299 366 /* Override with component specific socket buffer size settings, if any */ 300 if (ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size > 0) { 301 ice_st->cfg.turn.cfg.so_rcvbuf_size = 302 ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size; 303 } 304 if (ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size > 0) { 305 ice_st->cfg.turn.cfg.so_sndbuf_size = 306 ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size; 307 } 367 if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) 368 sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size; 369 if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) 370 sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size; 371 372 /* Add relayed candidate with pending status if there's no existing one */ 373 if (cand == NULL) { 374 cand = &comp->cand_list[comp->cand_cnt]; 375 cand->type = PJ_ICE_CAND_TYPE_RELAYED; 376 cand->status = PJ_EPENDING; 377 cand->local_pref = RELAY_PREF; 378 cand->transport_id = CREATE_TP_ID(TP_TURN, idx); 379 cand->comp_id = (pj_uint8_t) comp->comp_id; 380 } 381 382 /* Allocate and initialize TURN socket data */ 383 data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data); 384 data->comp = comp; 385 data->transport_id = cand->transport_id; 308 386 309 387 /* Create the TURN transport */ 310 status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, ice_st->cfg.af,311 ice_st->cfg.turn.conn_type,312 &turn_sock_cb, &ice_st->cfg.turn.cfg,313 comp, &comp->turn_sock);388 status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, turn_cfg->af, 389 turn_cfg->conn_type, 390 &turn_sock_cb, sock_cfg, 391 data, &comp->turn[idx].sock); 314 392 if (status != PJ_SUCCESS) { 315 393 return status; … … 320 398 321 399 /* Start allocation */ 322 status=pj_turn_sock_alloc(comp->turn _sock,323 & ice_st->cfg.turn.server,324 ice_st->cfg.turn.port,400 status=pj_turn_sock_alloc(comp->turn[idx].sock, 401 &turn_cfg->server, 402 turn_cfg->port, 325 403 ice_st->cfg.resolver, 326 & ice_st->cfg.turn.auth_cred,327 & ice_st->cfg.turn.alloc_param);404 &turn_cfg->auth_cred, 405 &turn_cfg->alloc_param); 328 406 if (status != PJ_SUCCESS) { 329 407 ///sess_dec_ref(ice_st); … … 331 409 } 332 410 333 /* Add relayed candidate with pending status if there's no existing one */ 334 if (cand == NULL) { 335 cand = &comp->cand_list[comp->cand_cnt++]; 336 cand->type = PJ_ICE_CAND_TYPE_RELAYED; 337 cand->status = PJ_EPENDING; 338 cand->local_pref = RELAY_PREF; 339 cand->transport_id = TP_TURN; 340 cand->comp_id = (pj_uint8_t) comp->comp_id; 341 } 411 /* Commit the relayed candidate. */ 412 comp->cand_cnt++; 342 413 343 414 PJ_LOG(4,(ice_st->obj_name, … … 373 444 } 374 445 446 447 static pj_status_t add_stun_and_host(pj_ice_strans *ice_st, 448 pj_ice_strans_comp *comp, 449 unsigned idx) 450 { 451 pj_ice_sess_cand *cand; 452 pj_ice_strans_stun_cfg *stun_cfg = &ice_st->cfg.stun_tp[idx]; 453 pj_stun_sock_cfg *sock_cfg = &stun_cfg->cfg; 454 unsigned comp_idx = comp->comp_id - 1; 455 pj_stun_sock_cb stun_sock_cb; 456 sock_user_data *data; 457 pj_status_t status; 458 459 /* Check if STUN transport or host candidate is configured */ 460 if (stun_cfg->server.slen == 0 && stun_cfg->max_host_cands == 0) 461 return PJ_SUCCESS; 462 463 /* Initialize STUN socket callback */ 464 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 465 stun_sock_cb.on_rx_data = &stun_on_rx_data; 466 stun_sock_cb.on_status = &stun_on_status; 467 stun_sock_cb.on_data_sent = &stun_on_data_sent; 468 469 /* Override component specific QoS settings, if any */ 470 if (ice_st->cfg.comp[comp_idx].qos_type) { 471 sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type; 472 } 473 if (ice_st->cfg.comp[comp_idx].qos_params.flags) { 474 pj_memcpy(&sock_cfg->qos_params, 475 &ice_st->cfg.comp[comp_idx].qos_params, 476 sizeof(sock_cfg->qos_params)); 477 } 478 479 /* Override component specific socket buffer size settings, if any */ 480 if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) { 481 sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size; 482 } 483 if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) { 484 sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size; 485 } 486 487 /* Prepare srflx candidate with pending status. */ 488 cand = &comp->cand_list[comp->cand_cnt]; 489 cand->type = PJ_ICE_CAND_TYPE_SRFLX; 490 cand->status = PJ_EPENDING; 491 cand->local_pref = SRFLX_PREF; 492 cand->transport_id = CREATE_TP_ID(TP_STUN, idx); 493 cand->comp_id = (pj_uint8_t) comp->comp_id; 494 495 /* Allocate and initialize STUN socket data */ 496 data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data); 497 data->comp = comp; 498 data->transport_id = cand->transport_id; 499 500 /* Create the STUN transport */ 501 status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 502 stun_cfg->af, &stun_sock_cb, 503 sock_cfg, data, &comp->stun[idx].sock); 504 if (status != PJ_SUCCESS) 505 return status; 506 507 /* Start STUN Binding resolution and add srflx candidate 508 * only if server is set 509 */ 510 if (stun_cfg->server.slen) { 511 pj_stun_sock_info stun_sock_info; 512 513 /* Add pending job */ 514 ///sess_add_ref(ice_st); 515 516 PJ_LOG(4,(ice_st->obj_name, 517 "Comp %d: srflx candidate starts Binding discovery", 518 comp->comp_id)); 519 520 pj_log_push_indent(); 521 522 /* Start Binding resolution */ 523 status = pj_stun_sock_start(comp->stun[idx].sock, &stun_cfg->server, 524 stun_cfg->port, ice_st->cfg.resolver); 525 if (status != PJ_SUCCESS) { 526 ///sess_dec_ref(ice_st); 527 pj_log_pop_indent(); 528 return status; 529 } 530 531 /* Enumerate addresses */ 532 status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info); 533 if (status != PJ_SUCCESS) { 534 ///sess_dec_ref(ice_st); 535 pj_log_pop_indent(); 536 return status; 537 } 538 539 /* Update and commit the srflx candidate. */ 540 pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]); 541 pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr); 542 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 543 cand->type, &cand->base_addr); 544 comp->cand_cnt++; 545 546 /* Set default candidate to srflx */ 547 comp->default_cand = (unsigned)(cand - comp->cand_list); 548 549 pj_log_pop_indent(); 550 } 551 552 /* Add local addresses to host candidates, unless max_host_cands 553 * is set to zero. 554 */ 555 if (stun_cfg->max_host_cands) { 556 pj_stun_sock_info stun_sock_info; 557 unsigned i; 558 559 /* Enumerate addresses */ 560 status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info); 561 if (status != PJ_SUCCESS) 562 return status; 563 564 for (i=0; i<stun_sock_info.alias_cnt && 565 i<stun_cfg->max_host_cands; ++i) 566 { 567 unsigned j; 568 pj_bool_t cand_duplicate = PJ_FALSE; 569 char addrinfo[PJ_INET6_ADDRSTRLEN+10]; 570 const pj_sockaddr *addr = &stun_sock_info.aliases[i]; 571 572 /* Leave one candidate for relay */ 573 if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) { 574 PJ_LOG(4,(ice_st->obj_name, "Too many host candidates")); 575 break; 576 } 577 578 /* Ignore loopback addresses if cfg->stun.loop_addr is unset */ 579 if (stun_cfg->loop_addr==PJ_FALSE) { 580 if (stun_cfg->af == pj_AF_INET() && 581 (pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) 582 { 583 continue; 584 } 585 else if (stun_cfg->af == pj_AF_INET6()) { 586 pj_in6_addr in6addr = {0}; 587 in6addr.s6_addr[15] = 1; 588 if (pj_memcmp(&in6addr, &addr->ipv6.sin6_addr, 589 sizeof(in6addr))==0) 590 { 591 continue; 592 } 593 } 594 } 595 596 cand = &comp->cand_list[comp->cand_cnt]; 597 598 cand->type = PJ_ICE_CAND_TYPE_HOST; 599 cand->status = PJ_SUCCESS; 600 cand->local_pref = HOST_PREF; 601 cand->transport_id = CREATE_TP_ID(TP_STUN, idx); 602 cand->comp_id = (pj_uint8_t) comp->comp_id; 603 pj_sockaddr_cp(&cand->addr, addr); 604 pj_sockaddr_cp(&cand->base_addr, addr); 605 pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr)); 606 607 /* Check if not already in list */ 608 for (j=0; j<comp->cand_cnt; j++) { 609 if (ice_cand_equals(cand, &comp->cand_list[j])) { 610 cand_duplicate = PJ_TRUE; 611 break; 612 } 613 } 614 615 if (cand_duplicate) { 616 PJ_LOG(4, (ice_st->obj_name, 617 "Comp %d: host candidate %s is a duplicate", 618 comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 619 sizeof(addrinfo), 3))); 620 621 pj_bzero(&cand->addr, sizeof(cand->addr)); 622 pj_bzero(&cand->base_addr, sizeof(cand->base_addr)); 623 continue; 624 } else { 625 comp->cand_cnt+=1; 626 } 627 628 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 629 cand->type, &cand->base_addr); 630 631 PJ_LOG(4,(ice_st->obj_name, 632 "Comp %d: host candidate %s added", 633 comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 634 sizeof(addrinfo), 3))); 635 } 636 } 637 638 return PJ_SUCCESS; 639 } 640 641 375 642 /* 376 643 * Create the component. … … 379 646 { 380 647 pj_ice_strans_comp *comp = NULL; 648 unsigned i; 381 649 pj_status_t status; 382 650 … … 398 666 399 667 /* Create STUN transport if configured */ 400 if (ice_st->cfg.stun.server.slen || ice_st->cfg.stun.max_host_cands) { 401 pj_stun_sock_cb stun_sock_cb; 402 pj_ice_sess_cand *cand; 403 404 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 405 stun_sock_cb.on_rx_data = &stun_on_rx_data; 406 stun_sock_cb.on_status = &stun_on_status; 407 stun_sock_cb.on_data_sent = &stun_on_data_sent; 408 409 /* Override component specific QoS settings, if any */ 410 if (ice_st->cfg.comp[comp_id-1].qos_type) { 411 ice_st->cfg.stun.cfg.qos_type = 412 ice_st->cfg.comp[comp_id-1].qos_type; 413 } 414 if (ice_st->cfg.comp[comp_id-1].qos_params.flags) { 415 pj_memcpy(&ice_st->cfg.stun.cfg.qos_params, 416 &ice_st->cfg.comp[comp_id-1].qos_params, 417 sizeof(ice_st->cfg.stun.cfg.qos_params)); 418 } 419 420 /* Override component specific socket buffer size settings, if any */ 421 if (ice_st->cfg.comp[comp_id-1].so_rcvbuf_size > 0) { 422 ice_st->cfg.stun.cfg.so_rcvbuf_size = 423 ice_st->cfg.comp[comp_id-1].so_rcvbuf_size; 424 } 425 if (ice_st->cfg.comp[comp_id-1].so_sndbuf_size > 0) { 426 ice_st->cfg.stun.cfg.so_sndbuf_size = 427 ice_st->cfg.comp[comp_id-1].so_sndbuf_size; 428 } 429 430 /* Create the STUN transport */ 431 status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 432 ice_st->cfg.af, &stun_sock_cb, 433 &ice_st->cfg.stun.cfg, 434 comp, &comp->stun_sock); 668 for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) { 669 status = add_stun_and_host(ice_st, comp, i); 435 670 if (status != PJ_SUCCESS) 436 671 return status; 437 438 /* Start STUN Binding resolution and add srflx candidate439 * only if server is set440 */441 if (ice_st->cfg.stun.server.slen) {442 pj_stun_sock_info stun_sock_info;443 444 /* Add pending job */445 ///sess_add_ref(ice_st);446 447 PJ_LOG(4,(ice_st->obj_name,448 "Comp %d: srflx candidate starts Binding discovery",449 comp_id));450 451 pj_log_push_indent();452 453 /* Start Binding resolution */454 status = pj_stun_sock_start(comp->stun_sock,455 &ice_st->cfg.stun.server,456 ice_st->cfg.stun.port,457 ice_st->cfg.resolver);458 if (status != PJ_SUCCESS) {459 ///sess_dec_ref(ice_st);460 pj_log_pop_indent();461 return status;462 }463 464 /* Enumerate addresses */465 status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info);466 if (status != PJ_SUCCESS) {467 ///sess_dec_ref(ice_st);468 pj_log_pop_indent();469 return status;470 }471 472 /* Add srflx candidate with pending status. */473 cand = &comp->cand_list[comp->cand_cnt++];474 cand->type = PJ_ICE_CAND_TYPE_SRFLX;475 cand->status = PJ_EPENDING;476 cand->local_pref = SRFLX_PREF;477 cand->transport_id = TP_STUN;478 cand->comp_id = (pj_uint8_t) comp_id;479 pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]);480 pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr);481 pj_ice_calc_foundation(ice_st->pool, &cand->foundation,482 cand->type, &cand->base_addr);483 484 /* Set default candidate to srflx */485 comp->default_cand = (unsigned)(cand - comp->cand_list);486 487 pj_log_pop_indent();488 }489 490 /* Add local addresses to host candidates, unless max_host_cands491 * is set to zero.492 */493 if (ice_st->cfg.stun.max_host_cands) {494 pj_stun_sock_info stun_sock_info;495 unsigned i;496 497 /* Enumerate addresses */498 status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info);499 if (status != PJ_SUCCESS)500 return status;501 502 for (i=0; i<stun_sock_info.alias_cnt &&503 i<ice_st->cfg.stun.max_host_cands; ++i)504 {505 unsigned j;506 pj_bool_t cand_duplicate = PJ_FALSE;507 char addrinfo[PJ_INET6_ADDRSTRLEN+10];508 const pj_sockaddr *addr = &stun_sock_info.aliases[i];509 510 /* Leave one candidate for relay */511 if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) {512 PJ_LOG(4,(ice_st->obj_name, "Too many host candidates"));513 break;514 }515 516 /* Ignore loopback addresses unless cfg->stun.loop_addr517 * is set518 */519 if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) {520 if (ice_st->cfg.stun.loop_addr==PJ_FALSE)521 continue;522 }523 524 cand = &comp->cand_list[comp->cand_cnt];525 526 cand->type = PJ_ICE_CAND_TYPE_HOST;527 cand->status = PJ_SUCCESS;528 cand->local_pref = HOST_PREF;529 cand->transport_id = TP_STUN;530 cand->comp_id = (pj_uint8_t) comp_id;531 pj_sockaddr_cp(&cand->addr, addr);532 pj_sockaddr_cp(&cand->base_addr, addr);533 pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr));534 535 /* Check if not already in list */536 for (j=0; j<comp->cand_cnt; j++) {537 if (ice_cand_equals(cand, &comp->cand_list[j])) {538 cand_duplicate = PJ_TRUE;539 break;540 }541 }542 543 if (cand_duplicate) {544 PJ_LOG(4, (ice_st->obj_name,545 "Comp %d: host candidate %s is a duplicate",546 comp_id, pj_sockaddr_print(&cand->addr, addrinfo,547 sizeof(addrinfo), 3)));548 549 pj_bzero(&cand->addr, sizeof(cand->addr));550 pj_bzero(&cand->base_addr, sizeof(cand->base_addr));551 continue;552 } else {553 comp->cand_cnt+=1;554 }555 556 pj_ice_calc_foundation(ice_st->pool, &cand->foundation,557 cand->type, &cand->base_addr);558 559 PJ_LOG(4,(ice_st->obj_name,560 "Comp %d: host candidate %s added",561 comp_id, pj_sockaddr_print(&cand->addr, addrinfo,562 sizeof(addrinfo), 3)));563 }564 }565 672 } 566 673 567 674 /* Create TURN relay if configured. */ 568 if (ice_st->cfg.turn.server.slen) { 569 add_update_turn(ice_st, comp); 675 for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) { 676 status = add_update_turn(ice_st, comp, i); 677 if (status != PJ_SUCCESS) 678 return status; 570 679 } 571 680 … … 630 739 631 740 pj_ice_strans_cfg_copy(pool, &ice_st->cfg, cfg); 632 ice_st->cfg.stun.cfg.grp_lock = ice_st->grp_lock; 633 ice_st->cfg.turn.cfg.grp_lock = ice_st->grp_lock; 741 742 /* To maintain backward compatibility, check if old/deprecated setting is set 743 * and the new setting is not, copy the value to the new setting. 744 */ 745 if (cfg->stun_tp_cnt == 0 && 746 (cfg->stun.server.slen || cfg->stun.max_host_cands)) 747 { 748 ice_st->cfg.stun_tp_cnt = 1; 749 ice_st->cfg.stun_tp[0] = ice_st->cfg.stun; 750 } 751 if (cfg->turn_tp_cnt == 0 && cfg->turn.server.slen) { 752 ice_st->cfg.turn_tp_cnt = 1; 753 ice_st->cfg.turn_tp[0] = ice_st->cfg.turn; 754 } 755 756 for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) 757 ice_st->cfg.stun_tp[i].cfg.grp_lock = ice_st->grp_lock; 758 for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) 759 ice_st->cfg.turn_tp[i].cfg.grp_lock = ice_st->grp_lock; 634 760 pj_memcpy(&ice_st->cb, cb, sizeof(*cb)); 635 761 … … 709 835 for (i=0; i<ice_st->comp_cnt; ++i) { 710 836 if (ice_st->comp[i]) { 711 if (ice_st->comp[i]->stun_sock) { 712 pj_stun_sock_destroy(ice_st->comp[i]->stun_sock); 713 ice_st->comp[i]->stun_sock = NULL; 837 pj_ice_strans_comp *comp = ice_st->comp[i]; 838 unsigned j; 839 for (j = 0; j < ice_st->cfg.stun_tp_cnt; ++j) { 840 if (comp->stun[j].sock) { 841 pj_stun_sock_destroy(comp->stun[j].sock); 842 comp->stun[j].sock = NULL; 843 } 714 844 } 715 if (ice_st->comp[i]->turn_sock) { 716 pj_turn_sock_destroy(ice_st->comp[i]->turn_sock); 717 ice_st->comp[i]->turn_sock = NULL; 845 for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) { 846 if (comp->turn[j].sock) { 847 pj_turn_sock_destroy(comp->turn[j].sock); 848 comp->turn[j].sock = NULL; 849 } 718 850 } 719 851 } … … 912 1044 913 1045 /* Re-enable logging for Send/Data indications */ 914 if ( comp->turn_sock) {1046 if (ice_st->cfg.turn_tp_cnt) { 915 1047 PJ_LOG(5,(ice_st->obj_name, 916 " Disabling STUN Indication logging for "1048 "Enabling STUN Indication logging for " 917 1049 "component %d", i+1)); 918 pj_turn_sock_set_log(comp->turn_sock, 0xFFFF); 919 comp->turn_log_off = PJ_FALSE; 1050 } 1051 for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) { 1052 if (comp->turn[j].sock) { 1053 pj_turn_sock_set_log(comp->turn[j].sock, 0xFFFF); 1054 comp->turn[j].log_off = PJ_FALSE; 1055 } 920 1056 } 921 1057 … … 1123 1259 const pj_ice_sess_cand rem_cand[]) 1124 1260 { 1261 unsigned n; 1125 1262 pj_status_t status; 1126 1263 … … 1138 1275 1139 1276 /* If we have TURN candidate, now is the time to create the permissions */ 1140 if (ice_st->comp[0]->turn_sock) {1277 for (n = 0; n < ice_st->cfg.turn_tp_cnt; ++n) { 1141 1278 unsigned i; 1142 1279 … … 1148 1285 /* Gather remote addresses for this component */ 1149 1286 for (j=0; j<rem_cand_cnt && count<PJ_ARRAY_SIZE(addrs); ++j) { 1150 if (rem_cand[j].comp_id==i+1) { 1151 pj_memcpy(&addrs[count++], &rem_cand[j].addr, 1152 pj_sockaddr_get_len(&rem_cand[j].addr)); 1287 if (rem_cand[j].comp_id==i+1 && 1288 rem_cand[j].addr.addr.sa_family== 1289 ice_st->cfg.turn_tp[n].af) 1290 { 1291 pj_sockaddr_cp(&addrs[count++], &rem_cand[j].addr); 1153 1292 } 1154 1293 } 1155 1294 1156 1295 if (count) { 1157 status = pj_turn_sock_set_perm(comp->turn _sock, count,1296 status = pj_turn_sock_set_perm(comp->turn[n].sock, count, 1158 1297 addrs, 0); 1159 1298 if (status != PJ_SUCCESS) { … … 1228 1367 { 1229 1368 pj_ice_strans_comp *comp; 1230 unsigneddef_cand;1369 pj_ice_sess_cand *def_cand; 1231 1370 pj_status_t status; 1232 1371 … … 1237 1376 1238 1377 /* Check that default candidate for the component exists */ 1239 def_cand = comp->default_cand; 1240 if (def_cand >= comp->cand_cnt) 1378 if (comp->default_cand >= comp->cand_cnt) 1241 1379 return PJ_EINVALIDOP; 1242 1380 … … 1262 1400 1263 1401 pj_grp_lock_release(ice_st->grp_lock); 1402 1403 def_cand = &comp->cand_list[comp->default_cand]; 1264 1404 1265 if (comp->cand_list[def_cand].status == PJ_SUCCESS) { 1266 1267 if (comp->cand_list[def_cand].type == PJ_ICE_CAND_TYPE_RELAYED) { 1405 if (def_cand->status == PJ_SUCCESS) { 1406 unsigned tp_idx = GET_TP_IDX(def_cand->transport_id); 1407 1408 if (def_cand->type == PJ_ICE_CAND_TYPE_RELAYED) { 1268 1409 1269 1410 enum { … … 1274 1415 1275 1416 /* https://trac.pjsip.org/repos/ticket/1316 */ 1276 if (comp->turn _sock == NULL) {1417 if (comp->turn[tp_idx].sock == NULL) { 1277 1418 /* TURN socket error */ 1278 1419 return PJ_EINVALIDOP; 1279 1420 } 1280 1421 1281 if (!comp->turn _log_off) {1422 if (!comp->turn[tp_idx].log_off) { 1282 1423 /* Disable logging for Send/Data indications */ 1283 1424 PJ_LOG(5,(ice_st->obj_name, 1284 1425 "Disabling STUN Indication logging for " 1285 1426 "component %d", comp->comp_id)); 1286 pj_turn_sock_set_log(comp->turn_sock, msg_disable_ind); 1287 comp->turn_log_off = PJ_TRUE; 1427 pj_turn_sock_set_log(comp->turn[tp_idx].sock, 1428 msg_disable_ind); 1429 comp->turn[tp_idx].log_off = PJ_TRUE; 1288 1430 } 1289 1431 1290 status = pj_turn_sock_sendto(comp->turn _sock,1432 status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 1291 1433 (const pj_uint8_t*)data, 1292 1434 (unsigned)data_len, … … 1295 1437 PJ_SUCCESS : status; 1296 1438 } else { 1297 status = pj_stun_sock_sendto(comp->stun _sock, NULL, data,1439 status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, data, 1298 1440 (unsigned)data_len, 0, dst_addr, 1299 1441 dst_addr_len); … … 1343 1485 for (i=0; i<ice_st->comp_cnt; ++i) { 1344 1486 const pj_ice_sess_check *check; 1487 pj_ice_strans_comp *comp = ice_st->comp[i]; 1345 1488 1346 1489 check = pj_ice_strans_get_valid_pair(ice_st, i+1); … … 1348 1491 char lip[PJ_INET6_ADDRSTRLEN+10]; 1349 1492 char rip[PJ_INET6_ADDRSTRLEN+10]; 1493 unsigned tp_idx = GET_TP_IDX(check->lcand->transport_id); 1494 unsigned tp_typ = GET_TP_TYPE(check->lcand->transport_id); 1350 1495 1351 1496 pj_sockaddr_print(&check->lcand->addr, lip, … … 1354 1499 sizeof(rip), 3); 1355 1500 1356 if ( check->lcand->transport_id== TP_TURN) {1501 if (tp_typ == TP_TURN) { 1357 1502 /* Activate channel binding for the remote address 1358 1503 * for more efficient data transfer using TURN. 1359 1504 */ 1360 1505 status = pj_turn_sock_bind_channel( 1361 ice_st->comp[i]->turn_sock,1506 comp->turn[tp_idx].sock, 1362 1507 &check->rcand->addr, 1363 1508 sizeof(check->rcand->addr)); … … 1367 1512 "Disabling STUN Indication logging for " 1368 1513 "component %d", i+1)); 1369 pj_turn_sock_set_log( ice_st->comp[i]->turn_sock,1514 pj_turn_sock_set_log(comp->turn[tp_idx].sock, 1370 1515 msg_disable_ind); 1371 ice_st->comp[i]->turn_log_off = PJ_TRUE;1516 comp->turn[tp_idx].log_off = PJ_TRUE; 1372 1517 } 1373 1518 … … 1417 1562 char daddr[PJ_INET6_ADDRSTRLEN]; 1418 1563 #endif 1564 unsigned tp_idx = GET_TP_IDX(transport_id); 1565 unsigned tp_typ = GET_TP_TYPE(transport_id); 1419 1566 1420 1567 PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); … … 1427 1574 pj_sockaddr_print(dst_addr, daddr, sizeof(addr), 0), 1428 1575 pj_sockaddr_get_port(dst_addr), 1429 t ransport_id));1430 1431 if (t ransport_id== TP_TURN) {1432 if (comp->turn _sock) {1433 status = pj_turn_sock_sendto(comp->turn _sock,1576 tp_typ)); 1577 1578 if (tp_typ == TP_TURN) { 1579 if (comp->turn[tp_idx].sock) { 1580 status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 1434 1581 (const pj_uint8_t*)pkt, 1435 1582 (unsigned)size, … … 1438 1585 status = PJ_EINVALIDOP; 1439 1586 } 1440 } else if (t ransport_id== TP_STUN) {1441 status = pj_stun_sock_sendto(comp->stun _sock, NULL,1587 } else if (tp_typ == TP_STUN) { 1588 status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, 1442 1589 pkt, (unsigned)size, 0, 1443 1590 dst_addr, dst_addr_len); … … 1479 1626 unsigned addr_len) 1480 1627 { 1628 sock_user_data *data; 1481 1629 pj_ice_strans_comp *comp; 1482 1630 pj_ice_strans *ice_st; 1483 1631 pj_status_t status; 1484 1632 1485 comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock);1486 if ( comp== NULL) {1633 data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock); 1634 if (data == NULL) { 1487 1635 /* We have disassociated ourselves from the STUN socket */ 1488 1636 return PJ_FALSE; 1489 1637 } 1490 1638 1639 comp = data->comp; 1491 1640 ice_st = comp->ice_st; 1492 1641 … … 1507 1656 /* Hand over the packet to ICE session */ 1508 1657 status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 1509 TP_STUN, pkt, pkt_len, 1658 data->transport_id, 1659 pkt, pkt_len, 1510 1660 src_addr, addr_len); 1511 1661 … … 1537 1687 pj_status_t status) 1538 1688 { 1689 sock_user_data *data; 1539 1690 pj_ice_strans_comp *comp; 1540 1691 pj_ice_strans *ice_st; 1541 1692 pj_ice_sess_cand *cand = NULL; 1542 1693 unsigned i; 1694 int tp_idx; 1543 1695 1544 1696 pj_assert(status != PJ_EPENDING); 1545 1697 1546 comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock); 1698 data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock); 1699 comp = data->comp; 1547 1700 ice_st = comp->ice_st; 1548 1701 … … 1554 1707 /* Find the srflx cancidate */ 1555 1708 for (i=0; i<comp->cand_cnt; ++i) { 1556 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX) { 1709 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX && 1710 comp->cand_list[i].transport_id == data->transport_id) 1711 { 1557 1712 cand = &comp->cand_list[i]; 1558 1713 break; … … 1570 1725 } 1571 1726 1727 tp_idx = GET_TP_IDX(data->transport_id); 1728 1572 1729 switch (op) { 1573 1730 case PJ_STUN_SOCK_DNS_OP: … … 1576 1733 if (cand) 1577 1734 cand->status = status; 1578 if (!ice_st->cfg.stun .ignore_stun_error) {1735 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) { 1579 1736 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1580 1737 "DNS resolution failed", status); … … 1656 1813 if (cand) 1657 1814 cand->status = status; 1658 if (!ice_st->cfg.stun.ignore_stun_error || comp->cand_cnt==1) { 1815 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error || 1816 comp->cand_cnt==1) 1817 { 1659 1818 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1660 1819 "STUN binding request failed", status); … … 1681 1840 pj_assert(cand != NULL); 1682 1841 cand->status = status; 1683 if (!ice_st->cfg.stun .ignore_stun_error) {1842 if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) { 1684 1843 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1685 1844 "STUN keep-alive failed", status); … … 1702 1861 { 1703 1862 pj_ice_strans_comp *comp; 1863 sock_user_data *data; 1704 1864 pj_status_t status; 1705 1865 1706 comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock);1707 if ( comp== NULL) {1866 data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock); 1867 if (data == NULL) { 1708 1868 /* We have disassociated ourselves from the TURN socket */ 1709 1869 return; 1710 1870 } 1871 1872 comp = data->comp; 1711 1873 1712 1874 pj_grp_lock_add_ref(comp->ice_st->grp_lock); … … 1727 1889 /* Hand over the packet to ICE */ 1728 1890 status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 1729 TP_TURN, pkt, pkt_len,1891 data->transport_id, pkt, pkt_len, 1730 1892 peer_addr, addr_len); 1731 1893 … … 1746 1908 { 1747 1909 pj_ice_strans_comp *comp; 1748 1749 comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 1750 if (comp == NULL) { 1910 sock_user_data *data; 1911 int tp_idx; 1912 1913 data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock); 1914 if (data == NULL) { 1751 1915 /* Not interested in further state notification once the relay is 1752 1916 * disconnecting. … … 1754 1918 return; 1755 1919 } 1920 1921 comp = data->comp; 1922 tp_idx = GET_TP_IDX(data->transport_id); 1756 1923 1757 1924 PJ_LOG(5,(comp->ice_st->obj_name, "TURN client state changed %s --> %s", … … 1767 1934 unsigned i; 1768 1935 1769 comp->turn _err_cnt = 0;1936 comp->turn[tp_idx].err_cnt = 0; 1770 1937 1771 1938 /* Get allocation info */ … … 1777 1944 /* Find relayed candidate in the component */ 1778 1945 for (i=0; i<comp->cand_cnt; ++i) { 1779 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) { 1946 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED && 1947 comp->cand_list[i].transport_id == data->transport_id) 1948 { 1780 1949 cand = &comp->cand_list[i]; 1781 1950 break; … … 1809 1978 pj_turn_session_info info; 1810 1979 1811 ++comp->turn _err_cnt;1980 ++comp->turn[tp_idx].err_cnt; 1812 1981 1813 1982 pj_turn_sock_get_info(turn_sock, &info); … … 1815 1984 /* Unregister ourself from the TURN relay */ 1816 1985 pj_turn_sock_set_user_data(turn_sock, NULL); 1817 comp->turn _sock = NULL;1986 comp->turn[tp_idx].sock = NULL; 1818 1987 1819 1988 /* Set session to fail on error. last_status PJ_SUCCESS means normal … … 1825 1994 sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_INIT, 1826 1995 "TURN allocation failed", info.last_status); 1827 } else if (comp->turn _err_cnt > 1) {1996 } else if (comp->turn[tp_idx].err_cnt > 1) { 1828 1997 sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_KEEP_ALIVE, 1829 1998 "TURN refresh failed", info.last_status); … … 1832 2001 "Comp %d: TURN allocation failed, retrying", 1833 2002 comp->comp_id)); 1834 add_update_turn(comp->ice_st, comp );2003 add_update_turn(comp->ice_st, comp, tp_idx); 1835 2004 } 1836 2005 } -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r5326 r5339 845 845 pjsip_endpt_get_timer_heap(pjsua_var.endpt)); 846 846 847 ice_cfg.af = pj_AF_INET();848 847 ice_cfg.resolver = pjsua_var.resolver; 849 848 850 849 ice_cfg.opt = acc_cfg->ice_cfg.ice_opt; 850 851 /* Check if STUN transport is configured */ 852 if ((pj_sockaddr_has_addr(&pjsua_var.stun_srv) && 853 pjsua_media_acc_is_using_stun(call_med->call->acc_id)) || 854 acc_cfg->ice_cfg.ice_max_host_cands != 0) 855 { 856 ice_cfg.stun_tp_cnt = 1; 857 pj_ice_strans_stun_cfg_default(&ice_cfg.stun_tp[0]); 858 } 851 859 852 860 /* Configure STUN settings */ … … 855 863 { 856 864 pj_sockaddr_print(&pjsua_var.stun_srv, stunip, sizeof(stunip), 0); 857 ice_cfg.stun .server = pj_str(stunip);858 ice_cfg.stun .port = pj_sockaddr_get_port(&pjsua_var.stun_srv);865 ice_cfg.stun_tp[0].server = pj_str(stunip); 866 ice_cfg.stun_tp[0].port = pj_sockaddr_get_port(&pjsua_var.stun_srv); 859 867 } 860 868 if (acc_cfg->ice_cfg.ice_max_host_cands >= 0) 861 ice_cfg.stun .max_host_cands = acc_cfg->ice_cfg.ice_max_host_cands;869 ice_cfg.stun_tp[0].max_host_cands = acc_cfg->ice_cfg.ice_max_host_cands; 862 870 863 871 /* Copy binding port setting to STUN setting */ 864 pj_sockaddr_init(ice_cfg. af, &ice_cfg.stun.cfg.bound_addr,872 pj_sockaddr_init(ice_cfg.stun_tp[0].af, &ice_cfg.stun_tp[0].cfg.bound_addr, 865 873 &cfg->bound_addr, (pj_uint16_t)cfg->port); 866 ice_cfg.stun .cfg.port_range = (pj_uint16_t)cfg->port_range;867 if (cfg->port != 0 && ice_cfg.stun .cfg.port_range == 0)868 ice_cfg.stun .cfg.port_range =874 ice_cfg.stun_tp[0].cfg.port_range = (pj_uint16_t)cfg->port_range; 875 if (cfg->port != 0 && ice_cfg.stun_tp[0].cfg.port_range == 0) 876 ice_cfg.stun_tp[0].cfg.port_range = 869 877 (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10); 870 878 871 879 /* Copy QoS setting to STUN setting */ 872 ice_cfg.stun .cfg.qos_type = cfg->qos_type;873 pj_memcpy(&ice_cfg.stun .cfg.qos_params, &cfg->qos_params,880 ice_cfg.stun_tp[0].cfg.qos_type = cfg->qos_type; 881 pj_memcpy(&ice_cfg.stun_tp[0].cfg.qos_params, &cfg->qos_params, 874 882 sizeof(cfg->qos_params)); 875 883 876 884 /* Configure TURN settings */ 877 885 if (acc_cfg->turn_cfg.enable_turn) { 886 ice_cfg.turn_tp_cnt = 1; 887 pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[0]); 878 888 status = parse_host_port(&acc_cfg->turn_cfg.turn_server, 879 &ice_cfg.turn .server,880 &ice_cfg.turn .port);881 if (status != PJ_SUCCESS || ice_cfg.turn .server.slen == 0) {889 &ice_cfg.turn_tp[0].server, 890 &ice_cfg.turn_tp[0].port); 891 if (status != PJ_SUCCESS || ice_cfg.turn_tp[0].server.slen == 0) { 882 892 PJ_LOG(1,(THIS_FILE, "Invalid TURN server setting")); 883 893 return PJ_EINVAL; 884 894 } 885 if (ice_cfg.turn .port == 0)886 ice_cfg.turn .port = 3479;887 ice_cfg.turn .conn_type = acc_cfg->turn_cfg.turn_conn_type;888 pj_memcpy(&ice_cfg.turn .auth_cred,895 if (ice_cfg.turn_tp[0].port == 0) 896 ice_cfg.turn_tp[0].port = 3479; 897 ice_cfg.turn_tp[0].conn_type = acc_cfg->turn_cfg.turn_conn_type; 898 pj_memcpy(&ice_cfg.turn_tp[0].auth_cred, 889 899 &acc_cfg->turn_cfg.turn_auth_cred, 890 sizeof(ice_cfg.turn .auth_cred));900 sizeof(ice_cfg.turn_tp[0].auth_cred)); 891 901 892 902 /* Copy QoS setting to TURN setting */ 893 ice_cfg.turn .cfg.qos_type = cfg->qos_type;894 pj_memcpy(&ice_cfg.turn .cfg.qos_params, &cfg->qos_params,903 ice_cfg.turn_tp[0].cfg.qos_type = cfg->qos_type; 904 pj_memcpy(&ice_cfg.turn_tp[0].cfg.qos_params, &cfg->qos_params, 895 905 sizeof(cfg->qos_params)); 896 906 897 907 /* Copy binding port setting to TURN setting */ 898 pj_sockaddr_init(ice_cfg. af, &ice_cfg.turn.cfg.bound_addr,908 pj_sockaddr_init(ice_cfg.turn_tp[0].af, &ice_cfg.turn_tp[0].cfg.bound_addr, 899 909 &cfg->bound_addr, (pj_uint16_t)cfg->port); 900 ice_cfg.turn .cfg.port_range = (pj_uint16_t)cfg->port_range;901 if (cfg->port != 0 && ice_cfg.turn .cfg.port_range == 0)902 ice_cfg.turn .cfg.port_range =910 ice_cfg.turn_tp[0].cfg.port_range = (pj_uint16_t)cfg->port_range; 911 if (cfg->port != 0 && ice_cfg.turn_tp[0].cfg.port_range == 0) 912 ice_cfg.turn_tp[0].cfg.port_range = 903 913 (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10); 904 914 } 905 915 906 916 /* Configure packet size for STUN and TURN sockets */ 907 ice_cfg.stun .cfg.max_pkt_size = PJMEDIA_MAX_MRU;908 ice_cfg.turn .cfg.max_pkt_size = PJMEDIA_MAX_MRU;917 ice_cfg.stun_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 918 ice_cfg.turn_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 909 919 910 920 pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb));
Note: See TracChangeset
for help on using the changeset viewer.