void linphone_proxy_config_register_again_with_updated_contact(LinphoneProxyConfig *obj, osip_message_t *orig_request, osip_message_t *last_answer){ osip_message_t *msg; const char *rport,*received; osip_via_t *via=NULL; osip_generic_param_t *param=NULL; osip_contact_t *ctt=NULL; osip_message_get_via(last_answer,0,&via); if (!via) return; osip_via_param_get_byname(via,"rport",¶m); if (param) rport=param->gvalue; else return; param=NULL; osip_via_param_get_byname(via,"received",¶m); if (param) received=param->gvalue; else return; osip_message_get_contact(orig_request,0,&ctt); if (strcmp(ctt->url->host,received)==0 && (ctt->url->port!=0 && strcmp(ctt->url->port,rport)==0)){ ms_message("Register has up to date contact, doing nothing."); return; } eXosip_lock(); eXosip_register_build_register(obj->rid,obj->expires,&msg); osip_message_get_contact(msg,0,&ctt); if (ctt->url->host!=NULL){ osip_free(ctt->url->host); } ctt->url->host=osip_strdup(received); if (ctt->url->port!=NULL){ osip_free(ctt->url->port); } ctt->url->port=osip_strdup(rport); eXosip_register_send_register(obj->rid,msg); eXosip_unlock(); ms_message("Resending new register with updated contact %s:%i",received,rport); }
int __osip_nict_init (osip_nict_t ** nict, osip_t * osip, osip_message_t * request) { osip_route_t *route; int i; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "allocating NICT context\n")); *nict = (osip_nict_t *) osip_malloc (sizeof (osip_nict_t)); if (*nict == NULL) return OSIP_NOMEM; memset (*nict, 0, sizeof (osip_nict_t)); /* for REQUEST retransmissions */ { osip_via_t *via; char *proto; i = osip_message_get_via (request, 0, &via); /* get top via */ if (i < 0) { osip_free (*nict); *nict = NULL; return i; } proto = via_get_protocol (via); if (proto == NULL) { osip_free (*nict); *nict = NULL; return OSIP_UNDEFINED_ERROR; } #ifdef USE_BLOCKINGSOCKET if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { (*nict)->timer_e_length = DEFAULT_T1; (*nict)->timer_k_length = DEFAULT_T4; (*nict)->timer_e_start.tv_sec = -1; (*nict)->timer_k_start.tv_sec = -1; /* not started */ } else { /* reliable protocol is used: */ (*nict)->timer_e_length = -1; /* E is not ACTIVE */ (*nict)->timer_k_length = 0; /* MUST do the transition immediatly */ (*nict)->timer_e_start.tv_sec = -1; (*nict)->timer_k_start.tv_sec = -1; /* not started */ } } #else if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { (*nict)->timer_e_length = DEFAULT_T1; (*nict)->timer_k_length = DEFAULT_T4; (*nict)->timer_e_start.tv_sec = -1; (*nict)->timer_k_start.tv_sec = -1; /* not started */ } else { /* reliable protocol is used: */ (*nict)->timer_e_length = DEFAULT_T1; (*nict)->timer_k_length = 0; /* MUST do the transition immediatly */ (*nict)->timer_e_start.tv_sec = -1; (*nict)->timer_k_start.tv_sec = -1; /* not started */ } }
/* * SIP_GEN_RESPONSE * * send an proxy generated response back to the client. * Only errors are reported from the proxy itself. * code = SIP result code to deliver * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int sip_gen_response(sip_ticket_t *ticket, int code) { osip_message_t *response; int sts; osip_via_t *via; int port; char *buffer; size_t buflen; struct in_addr addr; /* create the response template */ if ((response=msg_make_template_reply(ticket, code))==NULL) { ERROR("sip_gen_response: error in msg_make_template_reply"); return STS_FAILURE; } /* we must check if first via has x.x.x.x address. If not, we must resolve it */ osip_message_get_via (response, 0, &via); if (via == NULL) { ERROR("sip_gen_response: Cannot send response - no via field"); return STS_FAILURE; } /* name resolution */ if (utils_inet_aton(via->host, &addr) == 0) { /* need name resolution */ DEBUGC(DBCLASS_DNS,"resolving name:%s",via->host); sts = get_ip_by_host(via->host, &addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY, "sip_gen_response: cannot resolve via [%s]", via->host); return STS_FAILURE; } } sts = sip_message_to_str(response, &buffer, &buflen); if (sts != 0) { ERROR("sip_gen_response: msg_2char failed"); return STS_FAILURE; } if (via->port) { port=atoi(via->port); } else { port=SIP_PORT; } /* send to destination */ sipsock_send(addr, port, ticket->protocol, buffer, buflen); /* free the resources */ osip_message_free(response); osip_free(buffer); return STS_SUCCESS; }
void osip_nict_timeout_e_event (osip_transaction_t * nict, osip_event_t * evt) { osip_t *osip = (osip_t *) nict->config; int i; /* reset timer */ if (nict->state == NICT_TRYING) { if (nict->nict_context->timer_e_length < DEFAULT_T1) nict->nict_context->timer_e_length = nict->nict_context->timer_e_length + DEFAULT_T1_TCP_PROGRESS; else nict->nict_context->timer_e_length = nict->nict_context->timer_e_length * 2; if (nict->nict_context->timer_e_length > DEFAULT_T2) nict->nict_context->timer_e_length = DEFAULT_T2; } else /* in PROCEEDING STATE, TIMER is always DEFAULT_T2 */ nict->nict_context->timer_e_length = DEFAULT_T2; osip_gettimeofday (&nict->nict_context->timer_e_start, NULL); add_gettimeofday (&nict->nict_context->timer_e_start, nict->nict_context->timer_e_length); /* retransmit REQUEST */ i = osip->cb_send_message (nict, nict->orig_request, nict->nict_context->destination, nict->nict_context->port, nict->out_socket); if (i < 0) { nict_handle_transport_error (nict, i); return; } #ifndef USE_BLOCKINGSOCKET /* stop timer E in reliable transport - non blocking socket: the message was just sent */ if (i == 0) { /* but message was really sent */ osip_via_t *via; char *proto; i = osip_message_get_via (nict->orig_request, 0, &via); /* get top via */ if (i < 0) { nict_handle_transport_error (nict, -1); return; } proto = via_get_protocol (via); if (proto == NULL) { nict_handle_transport_error (nict, -1); return; } if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { } else { /* reliable protocol is used: */ nict->nict_context->timer_e_length = -1; /* E is not ACTIVE */ nict->nict_context->timer_e_start.tv_sec = -1; } } #endif if (i == 0) /* but message was really sent */ __osip_message_callback (OSIP_NICT_REQUEST_SENT_AGAIN, nict, nict->orig_request); }
void osip_ict_timeout_a_event(osip_transaction_t * ict, osip_event_t * evt) { osip_t *osip = (osip_t *) ict->config; int i; /* reset timer */ ict->ict_context->timer_a_length = ict->ict_context->timer_a_length * 2; osip_gettimeofday(&ict->ict_context->timer_a_start, NULL); add_gettimeofday(&ict->ict_context->timer_a_start, ict->ict_context->timer_a_length); /* retransmit REQUEST */ i = osip->cb_send_message(ict, ict->orig_request, ict->ict_context->destination, ict->ict_context->port, ict->out_socket); if (i < 0) { ict_handle_transport_error(ict, i); return; } #ifndef USE_BLOCKINGSOCKET /* stop timer E in reliable transport - non blocking socket: the message was just sent */ if (i == 0) { /* but message was really sent */ osip_via_t *via; char *proto; i = osip_message_get_via(ict->orig_request, 0, &via); /* get top via */ if (i < 0) { ict_handle_transport_error(ict, i); return; } proto = via_get_protocol(via); if (proto == NULL) { ict_handle_transport_error(ict, i); return; } if (osip_strcasecmp(proto, "TCP") != 0 && osip_strcasecmp(proto, "TLS") != 0 && osip_strcasecmp(proto, "SCTP") != 0) { } else { /* reliable protocol is used: */ ict->ict_context->timer_a_length = -1; /* A is not ACTIVE */ ict->ict_context->timer_a_start.tv_sec = -1; } } #endif if (i == 0) __osip_message_callback(OSIP_ICT_INVITE_SENT_AGAIN, ict, ict->orig_request); }
int __osip_ist_init (osip_ist_t ** ist, osip_t * osip, osip_message_t * invite) { int i; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "allocating IST context\n")); *ist = (osip_ist_t *) osip_malloc (sizeof (osip_ist_t)); if (*ist == NULL) return OSIP_NOMEM; memset (*ist, 0, sizeof (osip_ist_t)); /* for INVITE retransmissions */ { osip_via_t *via; char *proto; i = osip_message_get_via (invite, 0, &via); /* get top via */ if (i < 0) { osip_free (*ist); *ist = NULL; return i; } proto = via_get_protocol (via); if (proto == NULL) { osip_free (*ist); *ist = NULL; return OSIP_UNDEFINED_ERROR; } if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { /* for other reliable protocol than TCP, the timer must be desactived by the external application */ (*ist)->timer_g_length = DEFAULT_T1; (*ist)->timer_i_length = DEFAULT_T4; (*ist)->timer_g_start.tv_sec = -1; /* not started */ (*ist)->timer_i_start.tv_sec = -1; /* not started */ } else { /* reliable protocol is used: */ (*ist)->timer_g_length = -1; /* A is not ACTIVE */ (*ist)->timer_i_length = 0; /* MUST do the transition immediatly */ (*ist)->timer_g_start.tv_sec = -1; /* not started */ (*ist)->timer_i_start.tv_sec = -1; /* not started */ } } (*ist)->timer_h_length = 64 * DEFAULT_T1; (*ist)->timer_h_start.tv_sec = -1; /* not started */ return OSIP_SUCCESS; }
void ict_snd_invite(osip_transaction_t * ict, osip_event_t * evt) { int i; osip_t *osip = (osip_t *) ict->config; /* Here we have ict->orig_request == NULL */ ict->orig_request = evt->sip; i = osip->cb_send_message(ict, evt->sip, ict->ict_context->destination, ict->ict_context->port, ict->out_socket); if (i < 0) { ict_handle_transport_error(ict, i); return; } #ifndef USE_BLOCKINGSOCKET /* stop timer E in reliable transport - non blocking socket: the message was just sent */ if (i == 0) { /* but message was really sent */ osip_via_t *via; char *proto; i = osip_message_get_via(ict->orig_request, 0, &via); /* get top via */ if (i < 0) { ict_handle_transport_error(ict, i); return; } proto = via_get_protocol(via); if (proto == NULL) { ict_handle_transport_error(ict, i); return; } if (osip_strcasecmp(proto, "TCP") != 0 && osip_strcasecmp(proto, "TLS") != 0 && osip_strcasecmp(proto, "SCTP") != 0) { } else { /* reliable protocol is used: */ ict->ict_context->timer_a_length = -1; /* A is not ACTIVE */ ict->ict_context->timer_a_start.tv_sec = -1; } } #endif __osip_message_callback(OSIP_ICT_INVITE_SENT, ict, ict->orig_request); __osip_transaction_set_state(ict, ICT_CALLING); }
int __osip_nist_init (osip_nist_t ** nist, osip_t * osip, osip_message_t * invite) { int i; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "allocating NIST context\n")); *nist = (osip_nist_t *) osip_malloc (sizeof (osip_nist_t)); if (*nist == NULL) return -1; memset (*nist, 0, sizeof (osip_nist_t)); /* for INVITE retransmissions */ { osip_via_t *via; char *proto; i = osip_message_get_via (invite, 0, &via); /* get top via */ if (i != 0) goto ii_error_1; proto = via_get_protocol (via); if (proto == NULL) goto ii_error_1; if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { (*nist)->timer_j_length = 64 * DEFAULT_T1; (*nist)->timer_j_start.tv_sec = -1; /* not started */ } else { /* reliable protocol is used: */ (*nist)->timer_j_length = 0; /* MUST do the transition immediatly */ (*nist)->timer_j_start.tv_sec = -1; /* not started */ } } return 0; ii_error_1: osip_free (*nist); return -1; }
void udp_tl_learn_port_from_via (osip_message_t * sip) { /* EXOSIP_OPT_UDP_LEARN_PORT option set */ if (eXosip.learn_port > 0) { osip_via_t *via = NULL; osip_generic_param_t *br; osip_message_get_via (sip, 0, &via); if (via != NULL && via->protocol != NULL && (osip_strcasecmp (via->protocol, "udp") == 0 || osip_strcasecmp (via->protocol, "dtls-udp") == 0)) { osip_via_param_get_byname (via, "rport", &br); if (br != NULL && br->gvalue != NULL) { struct eXosip_account_info ainfo; memset (&ainfo, 0, sizeof (struct eXosip_account_info)); snprintf (udp_firewall_port, 20, "%s", br->gvalue); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "SIP port modified from rport in SIP answer\r\n")); osip_via_param_get_byname (via, "received", &br); if (br != NULL && br->gvalue != NULL && sip->from != NULL && sip->from->url != NULL && sip->from->url->host != NULL) { snprintf (ainfo.proxy, sizeof (ainfo.proxy), "%s", sip->from->url->host); ainfo.nat_port = atoi (udp_firewall_port); snprintf (ainfo.nat_ip, sizeof (ainfo.nat_ip), "%s", br->gvalue); eXosip_set_option (EXOSIP_OPT_ADD_ACCOUNT_INFO, &ainfo); } } } } return; }
/* * send answer to a registration request. * flag = STS_SUCCESS -> positive answer (200) * flag = STS_FAILURE -> negative answer (503) * flag = STS_NEED_AUTH -> proxy authentication needed (407) * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int register_response(sip_ticket_t *ticket, int flag) { osip_message_t *response; int code; int sts; osip_via_t *via; int port; char *buffer; size_t buflen; struct in_addr addr; osip_header_t *expires_hdr; /* ok -> 200, fail -> 503 */ switch (flag) { case STS_SUCCESS: code = 200; /* OK */ break; case STS_FAILURE: code = 503; /* failed */ break; case STS_NEED_AUTH: code = 407; /* proxy authentication needed */ break; default: code = 503; /* failed */ break; } /* create the response template */ if ((response=msg_make_template_reply(ticket, code))==NULL) { ERROR("register_response: error in msg_make_template_reply"); return STS_FAILURE; } /* insert the expiration header */ osip_message_get_expires(ticket->sipmsg, 0, &expires_hdr); if (expires_hdr) { osip_message_set_expires(response, expires_hdr->hvalue); } /* if we send back an proxy authentication needed, include the Proxy-Authenticate field */ if (code == 407) { auth_include_authrq(response); } /* get the IP address from existing VIA header */ osip_message_get_via (response, 0, &via); if (via == NULL) { ERROR("register_response: Cannot send response - no via field"); return STS_FAILURE; } /* name resolution needed? */ if (utils_inet_aton(via->host,&addr) == 0) { /* yes, get IP address */ sts = get_ip_by_host(via->host, &addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_REG, "register_response: cannot resolve VIA [%s]", via->host); return STS_FAILURE; } } sts = sip_message_to_str(response, &buffer, &buflen); if (sts != 0) { ERROR("register_response: msg_2char failed"); return STS_FAILURE; } /* send answer back */ if (via->port) { port=atoi(via->port); if ((port<=0) || (port>65535)) port=SIP_PORT; } else { port=configuration.sip_listen_port; } sipsock_send(addr, port, ticket->protocol, buffer, buflen); /* free the resources */ osip_message_free(response); free(buffer); return STS_SUCCESS; }
/* It is RECOMMENDED to only cancel INVITE request */ int generating_cancel (osip_message_t ** dest, osip_message_t * request_cancelled) { int i; osip_message_t *request; i = osip_message_init (&request); if (i != 0) return i; /* prepare the request-line */ osip_message_set_method (request, osip_strdup ("CANCEL")); osip_message_set_version (request, osip_strdup ("SIP/2.0")); osip_message_set_status_code (request, 0); osip_message_set_reason_phrase (request, NULL); i = osip_uri_clone (request_cancelled->req_uri, &(request->req_uri)); if (i != 0) { osip_message_free (request); *dest = NULL; return i; } i = osip_to_clone (request_cancelled->to, &(request->to)); if (i != 0) { osip_message_free (request); *dest = NULL; return i; } i = osip_from_clone (request_cancelled->from, &(request->from)); if (i != 0) { osip_message_free (request); *dest = NULL; return i; } /* set the cseq and call_id header */ i = osip_call_id_clone (request_cancelled->call_id, &(request->call_id)); if (i != 0) { osip_message_free (request); *dest = NULL; return i; } i = osip_cseq_clone (request_cancelled->cseq, &(request->cseq)); if (i != 0) { osip_message_free (request); *dest = NULL; return i; } osip_free (request->cseq->method); request->cseq->method = osip_strdup ("CANCEL"); if (request->cseq->method == NULL) { osip_message_free (request); *dest = NULL; return OSIP_NOMEM; } /* copy ONLY the top most Via Field (this method is also used by proxy) */ { osip_via_t *via; osip_via_t *via2; i = osip_message_get_via (request_cancelled, 0, &via); if (i < 0) { osip_message_free (request); *dest = NULL; return i; } i = osip_via_clone (via, &via2); if (i != 0) { osip_message_free (request); *dest = NULL; return i; } osip_list_add (&request->vias, via2, -1); } /* add the same route-set than in the previous request */ { int pos = 0; osip_route_t *route; osip_route_t *route2; while (!osip_list_eol (&request_cancelled->routes, pos)) { route = (osip_route_t *) osip_list_get (&request_cancelled->routes, pos); i = osip_route_clone (route, &route2); if (i != 0) { osip_message_free (request); *dest = NULL; return i; } osip_list_add (&request->routes, route2, -1); pos++; } } osip_message_set_max_forwards (request, "70"); /* a UA should start a request with 70 */ osip_message_set_user_agent (request, eXosip.user_agent); *dest = request; return OSIP_SUCCESS; }
void nict_snd_request (osip_transaction_t * nict, osip_event_t * evt) { int i; osip_t *osip = (osip_t *) nict->config; /* Here we have ict->orig_request == NULL */ nict->orig_request = evt->sip; i = osip->cb_send_message (nict, evt->sip, nict->nict_context->destination, nict->nict_context->port, nict->out_socket); if (i >= 0) { /* invoke the right callback! */ if (MSG_IS_REGISTER (evt->sip)) __osip_message_callback (OSIP_NICT_REGISTER_SENT, nict, nict->orig_request); else if (MSG_IS_BYE (evt->sip)) __osip_message_callback (OSIP_NICT_BYE_SENT, nict, nict->orig_request); else if (MSG_IS_OPTIONS (evt->sip)) __osip_message_callback (OSIP_NICT_OPTIONS_SENT, nict, nict->orig_request); else if (MSG_IS_INFO (evt->sip)) __osip_message_callback (OSIP_NICT_INFO_SENT, nict, nict->orig_request); else if (MSG_IS_CANCEL (evt->sip)) __osip_message_callback (OSIP_NICT_CANCEL_SENT, nict, nict->orig_request); else if (MSG_IS_NOTIFY (evt->sip)) __osip_message_callback (OSIP_NICT_NOTIFY_SENT, nict, nict->orig_request); else if (MSG_IS_SUBSCRIBE (evt->sip)) __osip_message_callback (OSIP_NICT_SUBSCRIBE_SENT, nict, nict->orig_request); else __osip_message_callback (OSIP_NICT_UNKNOWN_REQUEST_SENT, nict, nict->orig_request); #ifndef USE_BLOCKINGSOCKET /* stop timer E in reliable transport - non blocking socket: the message was just sent */ { osip_via_t *via; char *proto; int k; k = osip_message_get_via (nict->orig_request, 0, &via); /* get top via */ if (k < 0) { nict_handle_transport_error (nict, -1); return; } proto = via_get_protocol (via); if (proto == NULL) { nict_handle_transport_error (nict, -1); return; } if (i == 0) { /* but message was really sent */ if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { } else { /* reliable protocol is used: */ nict->nict_context->timer_e_length = -1; /* E is not ACTIVE */ nict->nict_context->timer_e_start.tv_sec = -1; } } else { if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { } else { /* reliable protocol is used: */ nict->nict_context->timer_e_length = DEFAULT_T1_TCP_PROGRESS; } } } #endif if (nict->nict_context->timer_e_length > 0) { osip_gettimeofday (&nict->nict_context->timer_e_start, NULL); add_gettimeofday (&nict->nict_context->timer_e_start, nict->nict_context->timer_e_length); } __osip_transaction_set_state (nict, NICT_TRYING); } else { nict_handle_transport_error (nict, i); } }
int __osip_nict_init (osip_nict_t ** nict, osip_t * osip, osip_message_t * request) { osip_route_t *route; int i; time_t now; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "allocating NICT context\n")); *nict = (osip_nict_t *) osip_malloc (sizeof (osip_nict_t)); if (*nict == NULL) return -1; now = time (NULL); #ifndef DISABLE_MEMSET memset (*nict, 0, sizeof (osip_nict_t)); #else (*ict)->destination = NULL; #endif /* for REQUEST retransmissions */ { osip_via_t *via; char *proto; i = osip_message_get_via (request, 0, &via); /* get top via */ if (i != 0) goto ii_error_1; proto = via_get_protocol (via); if (proto == NULL) goto ii_error_1; i = osip_strncasecmp (proto, "TCP", 3); if (i != 0) { /* for other reliable protocol than TCP, the timer must be desactived by the external application */ (*nict)->timer_e_length = DEFAULT_T1; (*nict)->timer_e_start = now; /* started */ (*nict)->timer_k_length = DEFAULT_T4; (*nict)->timer_k_start = -1; /* not started */ } else { /* TCP is used: */ (*nict)->timer_e_length = -1; /* E is not ACTIVE */ (*nict)->timer_e_start = -1; (*nict)->timer_k_length = 0; /* MUST do the transition immediatly */ (*nict)->timer_k_start = -1; /* not started */ } } /* for PROXY, the destination MUST be set by the application layer, this one may not be correct. */ osip_message_get_route (request, 0, &route); if (route != NULL) { int port = 5060; if (route->url->port != NULL) port = osip_atoi (route->url->port); osip_nict_set_destination ((*nict), osip_strdup (route->url->host), port); } else (*nict)->port = 5060; (*nict)->timer_f_length = 64 * DEFAULT_T1; (*nict)->timer_f_start = now; /* started */ /* Oups! a Bug! */ /* (*nict)->port = 5060; */ return 0; ii_error_1: osip_free (*nict); return -1; }
osip_message_t *ict_create_ack(osip_transaction_t * ict, osip_message_t * response) { int i; osip_message_t *ack; i = osip_message_init(&ack); if (i != 0) return NULL; /* Section 17.1.1.3: Construction of the ACK request: */ i = osip_from_clone(response->from, &(ack->from)); if (i != 0) { osip_message_free(ack); return NULL; } i = osip_to_clone(response->to, &(ack->to)); /* include the tag! */ if (i != 0) { osip_message_free(ack); return NULL; } i = osip_call_id_clone(response->call_id, &(ack->call_id)); if (i != 0) { osip_message_free(ack); return NULL; } i = osip_cseq_clone(response->cseq, &(ack->cseq)); if (i != 0) { osip_message_free(ack); return NULL; } osip_free(ack->cseq->method); ack->cseq->method = osip_strdup("ACK"); if (ack->cseq->method == NULL) { osip_message_free(ack); return NULL; } ack->sip_method = (char *) osip_malloc(5); if (ack->sip_method == NULL) { osip_message_free(ack); return NULL; } sprintf(ack->sip_method, "ACK"); ack->sip_version = osip_strdup(ict->orig_request->sip_version); if (ack->sip_version == NULL) { osip_message_free(ack); return NULL; } ack->status_code = 0; ack->reason_phrase = NULL; /* MUST copy REQUEST-URI from Contact header! */ i = osip_uri_clone(ict->orig_request->req_uri, &(ack->req_uri)); if (i != 0) { osip_message_free(ack); return NULL; } /* ACK MUST contain only the TOP Via field from original request */ { osip_via_t *via; osip_via_t *orig_via; osip_message_get_via(ict->orig_request, 0, &orig_via); if (orig_via == NULL) { osip_message_free(ack); return NULL; } i = osip_via_clone(orig_via, &via); if (i != 0) { osip_message_free(ack); return NULL; } osip_list_add(&ack->vias, via, -1); } /* ack MUST contains the ROUTE headers field from the original request */ /* IS IT TRUE??? */ /* if the answers contains a set of route (or record route), then it */ /* should be used instead?? ......May be not..... */ { int pos = 0; osip_route_t *route; osip_route_t *orig_route; while (!osip_list_eol(&ict->orig_request->routes, pos)) { orig_route = (osip_route_t *) osip_list_get(&ict->orig_request->routes, pos); i = osip_route_clone(orig_route, &route); if (i != 0) { osip_message_free(ack); return NULL; } osip_list_add(&ack->routes, route, -1); pos++; } } /* may be we could add some other headers: */ /* For example "Max-Forward" */ return ack; }
int __osip_ict_init (osip_ict_t ** ict, osip_t * osip, osip_message_t * invite) { osip_route_t *route; int i; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "allocating ICT context\n")); *ict = (osip_ict_t *) osip_malloc (sizeof (osip_ict_t)); if (*ict == NULL) return OSIP_NOMEM; memset (*ict, 0, sizeof (osip_ict_t)); /* for INVITE retransmissions */ { osip_via_t *via; char *proto; i = osip_message_get_via (invite, 0, &via); /* get top via */ if (i < 0) { osip_free (*ict); return i; } proto = via_get_protocol (via); if (proto == NULL) { osip_free (*ict); return OSIP_SYNTAXERROR; } #ifdef USE_BLOCKINGSOCKET if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { /* for other reliable protocol than TCP, the timer must be desactived by the external application */ (*ict)->timer_a_length = DEFAULT_T1; if (64 * DEFAULT_T1 < 32000) (*ict)->timer_d_length = 32000; else (*ict)->timer_d_length = 64 * DEFAULT_T1; osip_gettimeofday (&(*ict)->timer_a_start, NULL); add_gettimeofday (&(*ict)->timer_a_start, (*ict)->timer_a_length); (*ict)->timer_d_start.tv_sec = -1; /* not started */ } else { /* reliable protocol is used: */ (*ict)->timer_a_length = -1; /* A is not ACTIVE */ (*ict)->timer_d_length = 0; /* MUST do the transition immediatly */ (*ict)->timer_a_start.tv_sec = -1; /* not started */ (*ict)->timer_d_start.tv_sec = -1; /* not started */ } } #else if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) { /* for other reliable protocol than TCP, the timer must be desactived by the external application */ (*ict)->timer_a_length = DEFAULT_T1; if (64 * DEFAULT_T1 < 32000) (*ict)->timer_d_length = 32000; else (*ict)->timer_d_length = 64 * DEFAULT_T1; osip_gettimeofday (&(*ict)->timer_a_start, NULL); add_gettimeofday (&(*ict)->timer_a_start, (*ict)->timer_a_length); (*ict)->timer_d_start.tv_sec = -1; /* not started */ } else { /* reliable protocol is used: */ (*ict)->timer_a_length = DEFAULT_T1; (*ict)->timer_d_length = 0; /* MUST do the transition immediatly */ osip_gettimeofday (&(*ict)->timer_a_start, NULL); add_gettimeofday (&(*ict)->timer_a_start, (*ict)->timer_a_length); (*ict)->timer_d_start.tv_sec = -1; /* not started */ } }