int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *peer, UINT4 RTO, nr_stun_client_ctx **ctxp) { nr_stun_client_ctx *ctx=0; int r,_status; if ((r=nr_stun_startup())) ABORT(r); if(!(ctx=RCALLOC(sizeof(nr_stun_client_ctx)))) ABORT(R_NO_MEMORY); ctx->state=NR_STUN_CLIENT_STATE_INITTED; if(!(ctx->label=r_strdup(label))) ABORT(R_NO_MEMORY); ctx->sock=sock; nr_socket_getaddr(sock,&ctx->my_addr); nr_transport_addr_copy(&ctx->peer_addr,peer); if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_RETRANSMIT_TIMEOUT, &ctx->rto_ms)) { if (RTO != 0) ctx->rto_ms = RTO; else ctx->rto_ms = 100; } if (NR_reg_get_double(NR_STUN_REG_PREF_CLNT_RETRANSMIT_BACKOFF, &ctx->retransmission_backoff_factor)) ctx->retransmission_backoff_factor = 2.0; if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_MAXIMUM_TRANSMITS, &ctx->maximum_transmits)) ctx->maximum_transmits = 7; if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF, &ctx->final_retransmit_backoff_ms)) ctx->final_retransmit_backoff_ms = 16 * ctx->rto_ms; *ctxp=ctx; _status=0; abort: if(_status) { nr_stun_client_ctx_destroy(&ctx); } return(_status); }
int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *peer, UINT4 RTO, nr_stun_client_ctx **ctxp) { nr_stun_client_ctx *ctx=0; char allow_loopback; int r,_status; if ((r=nr_stun_startup())) ABORT(r); if(!(ctx=RCALLOC(sizeof(nr_stun_client_ctx)))) ABORT(R_NO_MEMORY); ctx->state=NR_STUN_CLIENT_STATE_INITTED; if(!(ctx->label=r_strdup(label))) ABORT(R_NO_MEMORY); ctx->sock=sock; nr_socket_getaddr(sock,&ctx->my_addr); nr_transport_addr_copy(&ctx->peer_addr,peer); if (RTO != 0) { ctx->rto_ms = RTO; } else if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_RETRANSMIT_TIMEOUT, &ctx->rto_ms)) { ctx->rto_ms = 100; } if (NR_reg_get_double(NR_STUN_REG_PREF_CLNT_RETRANSMIT_BACKOFF, &ctx->retransmission_backoff_factor)) ctx->retransmission_backoff_factor = 2.0; if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_MAXIMUM_TRANSMITS, &ctx->maximum_transmits)) ctx->maximum_transmits = 7; if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF, &ctx->maximum_transmits_timeout_ms)) ctx->maximum_transmits_timeout_ms = 16 * ctx->rto_ms; ctx->mapped_addr_check_mask = NR_STUN_TRANSPORT_ADDR_CHECK_WILDCARD; if (NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, &allow_loopback) || !allow_loopback) { ctx->mapped_addr_check_mask |= NR_STUN_TRANSPORT_ADDR_CHECK_LOOPBACK; } if (ctx->my_addr.protocol == IPPROTO_TCP) { /* Because TCP is reliable there is only one final timeout value. * We store the timeout value for TCP in here, because timeout_ms gets * reset to 0 in client_reset() which gets called from client_start() */ ctx->maximum_transmits_timeout_ms = ctx->rto_ms * pow(ctx->retransmission_backoff_factor, ctx->maximum_transmits); ctx->maximum_transmits = 1; } *ctxp=ctx; _status=0; abort: if(_status){ nr_stun_client_ctx_destroy(&ctx); } return(_status); }