void ist_snd_3456xx (osip_transaction_t * ist, osip_event_t * evt) { int i; if (ist->last_response != NULL) { osip_message_free (ist->last_response); } ist->last_response = evt->sip; i = __osip_transaction_snd_xxx (ist, evt->sip); if (i != 0) { ist_handle_transport_error (ist, i); return; } else { if (MSG_IS_STATUS_3XX (ist->last_response)) __osip_message_callback (OSIP_IST_STATUS_3XX_SENT, ist, ist->last_response); else if (MSG_IS_STATUS_4XX (ist->last_response)) __osip_message_callback (OSIP_IST_STATUS_4XX_SENT, ist, ist->last_response); else if (MSG_IS_STATUS_5XX (ist->last_response)) __osip_message_callback (OSIP_IST_STATUS_5XX_SENT, ist, ist->last_response); else __osip_message_callback (OSIP_IST_STATUS_6XX_SENT, ist, ist->last_response); } if (ist->ist_context->timer_g_length != -1) { osip_gettimeofday (&ist->ist_context->timer_g_start, NULL); add_gettimeofday (&ist->ist_context->timer_g_start, ist->ist_context->timer_g_length); } osip_gettimeofday (&ist->ist_context->timer_h_start, NULL); add_gettimeofday (&ist->ist_context->timer_h_start, ist->ist_context->timer_h_length); __osip_transaction_set_state (ist, IST_COMPLETED); return; }
void nict_rcv_23456xx (osip_transaction_t * nict, osip_event_t * evt) { /* leave this answer to the core application */ if (nict->last_response != NULL) { osip_message_free (nict->last_response); } nict->last_response = evt->sip; if (EVT_IS_RCV_STATUS_2XX (evt)) __osip_message_callback (OSIP_NICT_STATUS_2XX_RECEIVED, nict, nict->last_response); else if (MSG_IS_STATUS_3XX (nict->last_response)) __osip_message_callback (OSIP_NICT_STATUS_3XX_RECEIVED, nict, nict->last_response); else if (MSG_IS_STATUS_4XX (nict->last_response)) __osip_message_callback (OSIP_NICT_STATUS_4XX_RECEIVED, nict, nict->last_response); else if (MSG_IS_STATUS_5XX (nict->last_response)) __osip_message_callback (OSIP_NICT_STATUS_5XX_RECEIVED, nict, nict->last_response); else __osip_message_callback (OSIP_NICT_STATUS_6XX_RECEIVED, nict, nict->last_response); if (nict->state != NICT_COMPLETED) /* reset timer K */ { osip_gettimeofday (&nict->nict_context->timer_k_start, NULL); add_gettimeofday (&nict->nict_context->timer_k_start, nict->nict_context->timer_k_length); } __osip_transaction_set_state (nict, NICT_COMPLETED); }
void nist_snd_23456xx (osip_transaction_t * nist, osip_event_t * evt) { int i; if (nist->last_response != NULL) { osip_message_free (nist->last_response); } nist->last_response = evt->sip; i = __osip_transaction_snd_xxx(nist, nist->last_response); if (i != 0) { nist_handle_transport_error (nist, i); return; } else { if (EVT_IS_SND_STATUS_2XX (evt)) __osip_message_callback (OSIP_NIST_STATUS_2XX_SENT, nist, nist->last_response); else if (MSG_IS_STATUS_3XX (nist->last_response)) __osip_message_callback (OSIP_NIST_STATUS_3XX_SENT, nist, nist->last_response); else if (MSG_IS_STATUS_4XX (nist->last_response)) __osip_message_callback (OSIP_NIST_STATUS_4XX_SENT, nist, nist->last_response); else if (MSG_IS_STATUS_5XX (nist->last_response)) __osip_message_callback (OSIP_NIST_STATUS_5XX_SENT, nist, nist->last_response); else __osip_message_callback (OSIP_NIST_STATUS_6XX_SENT, nist, nist->last_response); } if (nist->state != NIST_COMPLETED) /* start J timer */ { osip_gettimeofday (&nist->nist_context->timer_j_start, NULL); add_gettimeofday (&nist->nist_context->timer_j_start, nist->nist_context->timer_j_length); } __osip_transaction_set_state (nist, NIST_COMPLETED); }
/* * PROXY_RESPONSE * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error * RFC3261 * Section 16.7: Proxy Behavior - Response Processing * 1. Find the appropriate response context * 2. Update timer C for provisional responses * 3. Remove the topmost Via * 4. Add the response to the response context * 5. Check to see if this response should be forwarded immediately * 6. When necessary, choose the best final response from the * response context * 7. Aggregate authorization header field values if necessary * 8. Optionally rewrite Record-Route header field values * 9. Forward the response * 10. Generate any necessary CANCEL requests * */ int proxy_response (sip_ticket_t *ticket) { int i; int sts; int type; struct in_addr sendto_addr; osip_via_t *via; int port; char *buffer; int buflen; osip_message_t *response; struct sockaddr_in *from; DEBUGC(DBCLASS_PROXY,"proxy_response"); if (ticket==NULL) { ERROR("proxy_response: called with NULL ticket"); return STS_FAILURE; } response=ticket->sipmsg; from=&ticket->from; /* * RFC 3261, Section 16.7 step 3 * Proxy Behavior - Response Processing - Remove my Via header field value */ /* remove my Via header line */ sts = sip_del_myvia(ticket); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY,"not addressed to my VIA, ignoring response"); return STS_FAILURE; } /* * figure out if this is an request coming from the outside * world to one of our registered clients */ /* Ahhrghh...... a response seems to have NO contact information... * so let's take FROM instead... * the TO and FROM headers are EQUAL to the request - that means * they are swapped in their meaning for a response... */ #if _OLD_DIRECTION_EVALUATION type = 0; for (i=0; i<URLMAP_SIZE; i++) { if (urlmap[i].active == 0) continue; /* incoming response ('from' == 'masq') || ('from' == 'reg') */ if ((compare_url(response->from->url, urlmap[i].reg_url)==STS_SUCCESS) || (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) { type=RESTYP_INCOMING; DEBUGC(DBCLASS_PROXY,"incoming response for %s@%s from outbound", response->from->url->username? response->from->url->username:"******", response->from->url->host? response->from->url->host : "*NULL*"); break; } /* outgoing response ('to' == 'reg') || ('to' == 'masq' ) */ if ((compare_url(response->to->url, urlmap[i].masq_url)==STS_SUCCESS) || (compare_url(response->to->url, urlmap[i].reg_url)==STS_SUCCESS)){ type=RESTYP_OUTGOING; DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound", response->from->url->username ? response->from->url->username : "******", response->from->url->host ? response->from->url->host : "*NULL*"); break; } } #else type = 0; /* * did I receive the telegram from a REGISTERED host? * -> it must be an OUTGOING response */ for (i=0; i<URLMAP_SIZE; i++) { struct in_addr tmp_addr; if (urlmap[i].active == 0) continue; if (get_ip_by_host(urlmap[i].true_url->host, &tmp_addr) == STS_FAILURE) { DEBUGC(DBCLASS_PROXY, "proxy_response: cannot resolve host [%s]", urlmap[i].true_url); } else { DEBUGC(DBCLASS_PROXY, "proxy_response: reghost:%s ip:%s", urlmap[i].true_url->host, utils_inet_ntoa(from->sin_addr)); if (memcmp(&tmp_addr, &from->sin_addr, sizeof(tmp_addr)) == 0) { type=RESTYP_OUTGOING; break; } } } /* * is the telegram directed to an internal registered host? * -> it must be an INCOMING response */ if (type == 0) { for (i=0; i<URLMAP_SIZE; i++) { if (urlmap[i].active == 0) continue; /* incoming response ('from' == 'masq') || ('from' == 'reg') */ if ((compare_url(response->from->url, urlmap[i].reg_url)==STS_SUCCESS) || (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) { type=RESTYP_INCOMING; break; } } } /* &&&& Open Issue &&&& it has been seen with cross-provider calls that the FROM may be 'garbled' (e.g [email protected] for calls made sipphone -> FWD) How can we deal with this? Should I take into consideration the 'Via' headers? This is the only clue I have, pointing to the *real* UA. Maybe I should put in a 'siproxd' ftag value to recognize it as a header inserted by myself */ if ((type == 0) && (!osip_list_eol(response->vias, 0))) { osip_via_t *via; struct in_addr addr_via, addr_myself; int port_via, port_ua; /* get the via address */ via = (osip_via_t *) osip_list_get (response->vias, 0); DEBUGC(DBCLASS_PROXY, "proxy_response: check via [%s] for " "registered UA",via->host); sts=get_ip_by_host(via->host, &addr_via); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_DNS, "proxy_response: cannot resolve VIA [%s]", via->host); } else { for (i=0; i<URLMAP_SIZE; i++) { if (urlmap[i].active == 0) continue; /* incoming response (1st via in list points to a registered UA) */ sts=get_ip_by_host(urlmap[i].true_url->host, &addr_myself); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_DNS, "proxy_response: cannot resolve " "true_url [%s]", via->host); continue; } port_via=0; if (via->port) port_via=atoi(via->port); if (port_via <= 0) port_via=SIP_PORT; port_ua=0; if (urlmap[i].true_url->port) port_ua=atoi(urlmap[i].true_url->port); if (port_ua <= 0) port_ua=SIP_PORT; DEBUGC(DBCLASS_BABBLE, "proxy_response: checking for registered " "host [%s:%i] <-> [%s:%i]", urlmap[i].true_url->host, port_ua, via->host, port_via); if ((memcmp(&addr_myself, &addr_via, sizeof(addr_myself))==0) && (port_via == port_ua)) { type=RESTYP_INCOMING; break; } } } } #endif ticket->direction=type; /* * ok, we got a response that we are allowed to process. */ switch (type) { /* * from an external host to the internal masqueraded host */ case RESTYP_INCOMING: DEBUGC(DBCLASS_PROXY,"incoming response for %s@%s from outbound", response->from->url->username? response->from->url->username:"******", response->from->url->host? response->from->url->host : "*NULL*"); /* * Response for INVITE - deal with RTP data in body and * start RTP proxy stream(s). In case * of a negative answer, stop RTP stream */ if (MSG_IS_RESPONSE_FOR(response,"INVITE")) { /* positive response, start RTP stream */ if ((MSG_IS_STATUS_1XX(response)) || (MSG_IS_STATUS_2XX(response))) { if (configuration.rtp_proxy_enable == 1) { sts = proxy_rewrite_invitation_body(response, DIR_INCOMING); } /* negative - stop a possibly started RTP stream */ } else if ((MSG_IS_STATUS_4XX(response)) || (MSG_IS_STATUS_5XX(response)) || (MSG_IS_STATUS_6XX(response))) { rtp_stop_fwd(osip_message_get_call_id(response), DIR_INCOMING); rtp_stop_fwd(osip_message_get_call_id(response), DIR_OUTGOING); } } /* if INVITE */ /* * Response for REGISTER - special handling of Contact header */ if (MSG_IS_RESPONSE_FOR(response,"REGISTER")) { /* * REGISTER returns *my* Contact header information. * Rewrite Contact header back to represent the true address. * Other responses do return the Contact header of the sender. */ sip_rewrite_contact(ticket, DIR_INCOMING); } /* * Response for SUBSCRIBE * * HACK for Grandstream SIP phones (with newer firmware like 1.0.4.40): * They send a SUBSCRIBE request to the registration server. In * case of beeing registering directly to siproxd, this request of * course will eventually be forwarded back to the same UA. * Grandstream then does reply with an '202' response (A 202 * response merely indicates that the subscription has been * understood, and that authorization may or may not have been * granted), which then of course is forwarded back to the phone. * Ans it seems that the Grandstream can *not* *handle* this * response, as it immediately sends another SUBSCRIBE request. * And this games goes on and on and on... * * As a workaround we will transform any 202 response to a * '404 unknown destination' * */ { osip_header_t *ua_hdr=NULL; osip_message_get_user_agent(response, 0, &ua_hdr); if (ua_hdr && ua_hdr->hvalue && (osip_strncasecmp(ua_hdr->hvalue,"grandstream", 11)==0) && (MSG_IS_RESPONSE_FOR(response,"SUBSCRIBE")) && (MSG_TEST_CODE(response, 202))) { DEBUGC(DBCLASS_PROXY, "proxy_response: Grandstream hack 202->404"); response->status_code=404; } } break; /* * from the internal masqueraded host to an external host */ case RESTYP_OUTGOING: DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound", response->from->url->username ? response->from->url->username : "******", response->from->url->host ? response->from->url->host : "*NULL*"); /* rewrite Contact header to represent the masqued address */ sip_rewrite_contact(ticket, DIR_OUTGOING); /* * If an 2xx OK or 1xx response, answer to an INVITE request, * rewrite body * * In case of a negative answer, stop RTP stream */ if (MSG_IS_RESPONSE_FOR(response,"INVITE")) { /* positive response, start RTP stream */ if ((MSG_IS_STATUS_1XX(response)) || (MSG_IS_STATUS_2XX(response))) { /* This is an outgoing response, therefore an outgoing stream */ sts = proxy_rewrite_invitation_body(response, DIR_OUTGOING); /* megative - stop a possibly started RTP stream */ } else if ((MSG_IS_STATUS_4XX(response)) || (MSG_IS_STATUS_5XX(response)) || (MSG_IS_STATUS_6XX(response))) { rtp_stop_fwd(osip_message_get_call_id(response), DIR_INCOMING); rtp_stop_fwd(osip_message_get_call_id(response), DIR_OUTGOING); } } /* if INVITE */ break; default: DEBUGC(DBCLASS_PROXY, "response from/to unregistered UA (%s@%s)", response->from->url->username? response->from->url->username:"******", response->from->url->host? response->from->url->host : "*NULL*"); return STS_FAILURE; } /* * for ALL incoming response include my Record-Route header. * The local UA will probably send its answer to the topmost * Route Header (8.1.2 of RFC3261) */ if (type == RESTYP_INCOMING) { DEBUGC(DBCLASS_PROXY,"Adding my Record-Route"); route_add_recordroute(ticket); } else { /* * outgoing packets must not have my record route header, as * this likely will contain a private IP address (my inbound). */ DEBUGC(DBCLASS_PROXY,"Purging Record-Routes (outgoing packet)"); route_purge_recordroute(ticket); } /* * Determine Next-Hop Address */ /*&&&& priority probably should be: * 1) Route header * 2) fixed outbound proxy * 3) SIP URI */ /* * check if we need to send to an outbound proxy */ if ((type == RESTYP_OUTGOING) && (sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) { DEBUGC(DBCLASS_PROXY, "proxy_response: have outbound proxy %s:%i", utils_inet_ntoa(sendto_addr), port); /* * Route present? * If so, fetch address from topmost Route: header and remove it. */ } else if ((type == RESTYP_OUTGOING) && (response->routes && !osip_list_eol(response->routes, 0))) { sts=route_determine_nexthop(ticket, &sendto_addr, &port); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY, "proxy_response: route_determine_nexthop failed"); return STS_FAILURE; } DEBUGC(DBCLASS_PROXY, "proxy_response: have Route header to %s:%i", utils_inet_ntoa(sendto_addr), port); } else { /* get target address and port from VIA header */ via = (osip_via_t *) osip_list_get (response->vias, 0); if (via == NULL) { ERROR("proxy_response: list_get via failed"); return STS_FAILURE; } sts = get_ip_by_host(via->host, &sendto_addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY, "proxy_response: cannot resolve VIA [%s]", via->host); return STS_FAILURE; } if (via->port) { port=atoi(via->port); } else { port=SIP_PORT; } } sts = sip_message_to_str(response, &buffer, &buflen); if (sts != 0) { ERROR("proxy_response: sip_message_to_str failed"); return STS_FAILURE; } sipsock_send(sendto_addr, port, ticket->protocol, buffer, buflen); osip_free (buffer); return STS_SUCCESS; }
void nist_snd_23456xx (osip_transaction_t * nist, osip_event_t * evt) { int i; osip_via_t *via; osip_t *osip = (osip_t *) nist->config; if (nist->last_response != NULL) { osip_message_free (nist->last_response); } nist->last_response = evt->sip; via = (osip_via_t *) osip_list_get (nist->last_response->vias, 0); if (via) { char *host; int port; osip_generic_param_t *maddr; osip_generic_param_t *received; osip_generic_param_t *rport; osip_via_param_get_byname (via, "maddr", &maddr); osip_via_param_get_byname (via, "received", &received); osip_via_param_get_byname (via, "rport", &rport); /* 1: user should not use the provided information (host and port) if they are using a reliable transport. Instead, they should use the already open socket attached to this transaction. */ /* 2: check maddr and multicast usage */ if (maddr != NULL) host = maddr->gvalue; /* we should check if this is a multicast address and use set the "ttl" in this case. (this must be done in the UDP message (not at the SIP layer) */ else if (received != NULL) host = received->gvalue; else host = via->host; if (rport == NULL || rport->gvalue == NULL) { if (via->port != NULL) port = osip_atoi (via->port); else port = 5060; } else port = osip_atoi (rport->gvalue); i = osip->cb_send_message (nist, nist->last_response, host, port, nist->out_socket); } else i = -1; if (i != 0) { nist_handle_transport_error (nist, i); return; } else { if (EVT_IS_SND_STATUS_2XX (evt)) __osip_message_callback (OSIP_NIST_STATUS_2XX_SENT, nist, nist->last_response); else if (MSG_IS_STATUS_3XX (nist->last_response)) __osip_message_callback (OSIP_NIST_STATUS_3XX_SENT, nist, nist->last_response); else if (MSG_IS_STATUS_4XX (nist->last_response)) __osip_message_callback (OSIP_NIST_STATUS_4XX_SENT, nist, nist->last_response); else if (MSG_IS_STATUS_5XX (nist->last_response)) __osip_message_callback (OSIP_NIST_STATUS_5XX_SENT, nist, nist->last_response); else __osip_message_callback (OSIP_NIST_STATUS_6XX_SENT, nist, nist->last_response); } if (nist->state != NIST_COMPLETED) /* start J timer */ nist->nist_context->timer_j_start = time (NULL); __osip_transaction_set_state (nist, NIST_COMPLETED); }
int GB_handle_messages (GB_CONNECT_STATE *gb_cons) { osip_event_t * osip_event = NULL; int ret = -1; int isDownLoad = 0; ret = gb_sip_messages_parse(&osip_event,gb_cons->buffer,gb_cons->datasize); if(ret == 0) { switch(osip_event->type) { // 请求消息 case RCV_REQINVITE: { GB_handle_RCV_REQINVITE(gb_cons, osip_event, &isDownLoad); } break; case RCV_REQACK: { GB_handle_RCV_REQACK(gb_cons, osip_event); } break; case RCV_REQUEST: { GB_handle_RCV_REQUEST(gb_cons, osip_event); } break; // 响应消息 case RCV_STATUS_1XX: { GB_handle_RCV_STATUS_1XX(gb_cons, osip_event); } break; case RCV_STATUS_2XX: { GB_handle_RCV_STATUS_2XX(gb_cons, osip_event); } break; case RCV_STATUS_3456XX: { GB_Record_Node *record = NULL; int index = -1; record = GB_Find_Record_Node_by_Call_ID(gb_cons,osip_event->sip->call_id ,&index); if(record) { if(record->info) SN_FREE(record->info); GB_Remove_Record_Node(gb_cons, index); } if(MSG_IS_STATUS_3XX(osip_event->sip)) { GB_handle_RCV_STATUS_3XX(gb_cons, osip_event); } else if(MSG_IS_STATUS_4XX(osip_event->sip)) { GB_handle_RCV_STATUS_4XX(gb_cons, osip_event); } else if(MSG_IS_STATUS_5XX(osip_event->sip)) { GB_handle_RCV_STATUS_5XX(gb_cons, osip_event); } else if(MSG_IS_STATUS_6XX(osip_event->sip)) { GB_handle_RCV_STATUS_6XX(gb_cons, osip_event); } else { } } break; default: { TRACE(SCI_TRACE_NORMAL,MOD_GB,"\n%s\n",gb_cons->buffer); } break; } } if(osip_event != NULL && isDownLoad == 0) // 若是下载,则先不释放osip_event { gb_sip_free(osip_event); osip_event = NULL; } return 0; }
void ict_rcv_3456xx(osip_transaction_t * ict, osip_event_t * evt) { osip_route_t *route; int i; osip_t *osip = (osip_t *) ict->config; /* leave this answer to the core application */ if (ict->last_response != NULL) osip_message_free(ict->last_response); ict->last_response = evt->sip; if (ict->state != ICT_COMPLETED) { /* not a retransmission */ /* automatic handling of ack! */ osip_message_t *ack = ict_create_ack(ict, evt->sip); ict->ack = ack; if (ict->ack == NULL) { __osip_transaction_set_state(ict, ICT_TERMINATED); __osip_kill_transaction_callback(OSIP_ICT_KILL_TRANSACTION, ict); return; } /* reset ict->ict_context->destination only if it is not yet set. */ if (ict->ict_context->destination == NULL) { osip_message_get_route(ack, 0, &route); if (route != NULL && route->url != NULL) { osip_uri_param_t *lr_param; osip_uri_uparam_get_byname(route->url, "lr", &lr_param); if (lr_param == NULL) { /* using uncompliant proxy: destination is the request-uri */ route = NULL; } } if (route != NULL && route->url != NULL) { int port = 5060; if (route->url->port != NULL) port = osip_atoi(route->url->port); osip_ict_set_destination(ict->ict_context, osip_strdup(route->url->host), port); } else { int port = 5060; /* search for maddr parameter */ osip_uri_param_t *maddr_param = NULL; port = 5060; if (ack->req_uri->port != NULL) port = osip_atoi(ack->req_uri->port); osip_uri_uparam_get_byname(ack->req_uri, "maddr", &maddr_param); if (maddr_param != NULL && maddr_param->gvalue != NULL) osip_ict_set_destination(ict->ict_context, osip_strdup(maddr_param->gvalue), port); else osip_ict_set_destination(ict->ict_context, osip_strdup(ack->req_uri->host), port); } } i = osip->cb_send_message(ict, ack, ict->ict_context->destination, ict->ict_context->port, ict->out_socket); if (i != 0) { ict_handle_transport_error(ict, i); return; } if (MSG_IS_STATUS_3XX(evt->sip)) __osip_message_callback(OSIP_ICT_STATUS_3XX_RECEIVED, ict, evt->sip); else if (MSG_IS_STATUS_4XX(evt->sip)) __osip_message_callback(OSIP_ICT_STATUS_4XX_RECEIVED, ict, evt->sip); else if (MSG_IS_STATUS_5XX(evt->sip)) __osip_message_callback(OSIP_ICT_STATUS_5XX_RECEIVED, ict, evt->sip); else __osip_message_callback(OSIP_ICT_STATUS_6XX_RECEIVED, ict, evt->sip); __osip_message_callback(OSIP_ICT_ACK_SENT, ict, evt->sip); } /* start timer D (length is set to MAX (64*DEFAULT_T1 or 32000) */ osip_gettimeofday(&ict->ict_context->timer_d_start, NULL); add_gettimeofday(&ict->ict_context->timer_d_start, ict->ict_context->timer_d_length); __osip_transaction_set_state(ict, ICT_COMPLETED); }
static int _eXosip_register_build_register (eXosip_reg_t * jr, osip_message_t ** _reg) { osip_message_t *reg = NULL; int i; reg = NULL; *_reg = NULL; if (jr->r_last_tr != NULL) { if (jr->r_last_tr->state != NICT_TERMINATED && jr->r_last_tr->state != NICT_COMPLETED) return -1; else { osip_message_t *last_response = NULL; osip_transaction_t *tr; osip_message_clone (jr->r_last_tr->orig_request, ®); if (reg == NULL) return -1; /* reg = jr->r_last_tr->orig_request; */ if (jr->r_last_tr->last_response != NULL) { osip_message_clone (jr->r_last_tr->last_response, &last_response); if (last_response == NULL) { osip_message_free (reg); return -1; } } __eXosip_delete_jinfo (jr->r_last_tr); tr = jr->r_last_tr; jr->r_last_tr = NULL; osip_list_add (eXosip.j_transactions, tr, 0); /* modify the REGISTER request */ { int osip_cseq_num = osip_atoi (reg->cseq->number); int length = strlen (reg->cseq->number); osip_list_special_free(®->authorizations, (void *(*)(void *)) &osip_authorization_free); osip_list_special_free(®->proxy_authorizations, (void *(*)(void *)) &osip_proxy_authorization_free); if (-1 == eXosip_update_top_via (reg)) { osip_message_free (reg); if (last_response != NULL) osip_message_free (last_response); return -1; } osip_cseq_num++; osip_free (reg->cseq->number); reg->cseq->number = (char *) osip_malloc (length + 2); /* +2 like for 9 to 10 */ sprintf (reg->cseq->number, "%i", osip_cseq_num); { osip_header_t *exp; osip_message_header_get_byname (reg, "expires", 0, &exp); if (exp!=NULL) { if (exp->hvalue!=NULL) osip_free (exp->hvalue); exp->hvalue = (char *) osip_malloc (10); snprintf (exp->hvalue, 9, "%i", jr->r_reg_period); } } osip_message_force_update (reg); } if (last_response != NULL) { if (MSG_IS_STATUS_4XX (last_response)) { eXosip_add_authentication_information (reg, last_response); } else eXosip_add_authentication_information (reg, NULL); osip_message_free (last_response); } } } if (reg == NULL) { i = generating_register (jr, ®, eXosip.transport, jr->r_aor, jr->r_registrar, jr->r_contact, jr->r_reg_period); if (i != 0) { return -2; } } *_reg = reg; return 0; }