int _eXosip_complete_answer_that_establish_a_dialog (struct eXosip_t *excontext, osip_message_t * response, osip_message_t * request) { int i; int pos = 0; char contact[1024]; char locip[65]; char firewall_ip[65]; char firewall_port[10]; firewall_ip[0] = '\0'; firewall_port[0] = '\0'; if (excontext->eXtl->tl_get_masquerade_contact != NULL) { excontext->eXtl->tl_get_masquerade_contact (excontext, firewall_ip, sizeof (firewall_ip), firewall_port, sizeof (firewall_port)); } /* 12.1.1: copy all record-route in response add a contact with global scope */ while (!osip_list_eol (&request->record_routes, pos)) { osip_record_route_t *rr; osip_record_route_t *rr2; rr = osip_list_get (&request->record_routes, pos); i = osip_record_route_clone (rr, &rr2); if (i != 0) return i; osip_list_add (&response->record_routes, rr2, -1); pos++; } memset (locip, '\0', sizeof (locip)); _eXosip_guess_ip_for_via (excontext, excontext->eXtl->proto_family, locip, 49); if (request->to->url->username == NULL) snprintf (contact, 1000, "<sip:%s:%s>", locip, firewall_port); else { char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username); snprintf (contact, 1000, "<sip:%s@%s:%s>", tmp2, locip, firewall_port); osip_free (tmp2); } if (firewall_ip[0] != '\0') { #ifdef USE_LOCALIP_WITH_LOCALPROXY /* disable this code for local testing because it adds an extra DNS */ osip_contact_t *con = (osip_contact_t *) osip_list_get (&request->contacts, 0); if (con != NULL && con->url != NULL && con->url->host != NULL) { char *c_address = con->url->host; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; i = _eXosip_get_addrinfo (excontext, &addrinfo, con->url->host, 5060, IPPROTO_UDP); if (i == 0) { memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); _eXosip_freeaddrinfo (addrinfo); c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "eXosip: here is the resolved destination host=%s\n", c_address)); } /* If c_address is a PUBLIC address, the request was coming from the PUBLIC network. */ if (_eXosip_is_public_address (c_address)) { if (request->to->url->username == NULL) snprintf (contact, 1000, "<sip:%s:%s>", firewall_ip, firewall_port); else { char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username); snprintf (contact, 1000, "<sip:%s@%s:%s>", tmp2, firewall_ip, firewall_port); osip_free (tmp2); } } } #else if (request->to->url->username == NULL) snprintf (contact, 1000, "<sip:%s:%s>", firewall_ip, firewall_port); else { char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username); snprintf (contact, 1000, "<sip:%s@%s:%s>", tmp2, firewall_ip, firewall_port); osip_free (tmp2); } #endif } { osip_via_t *via; via = (osip_via_t *) osip_list_get (&response->vias, 0); if (via == NULL || via->protocol == NULL) return OSIP_SYNTAXERROR; if (strlen (contact) + strlen (via->protocol) + strlen (";transport=>") < 1024 && 0 != osip_strcasecmp (via->protocol, "UDP")) { contact[strlen (contact) - 1] = '\0'; strcat (contact, ";transport="); strcat (contact, via->protocol); strcat (contact, ">"); } } osip_message_set_contact (response, contact); return OSIP_SUCCESS; }
int _eXosip_complete_answer_that_establish_a_dialog (struct eXosip_t *excontext, osip_message_t * response, osip_message_t * request) { int i; int route_found = 0; char contact[1024]; char scheme[10]; osip_list_iterator_t it; osip_record_route_t *rr; snprintf(scheme, sizeof(scheme), "sip"); /* 12.1.1: copy all record-route in response add a contact with global scope */ rr = (osip_record_route_t *)osip_list_get_first(&request->record_routes, &it); while (rr != NULL) { osip_record_route_t *rr2; i = osip_record_route_clone (rr, &rr2); if (i != 0) return i; osip_list_add (&response->record_routes, rr2, -1); /* rfc3261: 12.1.1 UAS behavior (check sips in top most Record-Route) */ if (it.pos==0 && rr2!=NULL && rr2->url!=NULL && rr2->url->scheme!=NULL && osip_strcasecmp(rr2->url->scheme, "sips")==0) snprintf(scheme, sizeof(scheme), "sips"); rr = (osip_record_route_t *)osip_list_get_next(&it); route_found=1; } if (MSG_IS_BYE (request)) { return OSIP_SUCCESS; } if (route_found==0) { /* rfc3261: 12.1.1 UAS behavior (check sips in Contact if no Record-Route) */ osip_contact_t *co = (osip_contact_t *) osip_list_get(&request->contacts, 0); if (co!=NULL && co->url!=NULL && co->url->scheme!=NULL && osip_strcasecmp(co->url->scheme, "sips")==0) snprintf(scheme, sizeof(scheme), "sips"); } /* rfc3261: 12.1.1 UAS behavior (check sips in Request-URI) */ if (request->req_uri->scheme!=NULL && osip_strcasecmp(request->req_uri->scheme, "sips")==0) snprintf(scheme, sizeof(scheme), "sips"); /* special values to be replaced in transport layer (eXtl_*.c files) */ if (request->to->url->username == NULL) snprintf (contact, 1000, "<%s:999.999.999.999:99999>", scheme); else { char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username); snprintf (contact, 1000, "<%s:%[email protected]:99999>", scheme, tmp2); osip_free (tmp2); } { osip_via_t *via; via = (osip_via_t *) osip_list_get (&response->vias, 0); if (via == NULL || via->protocol == NULL) return OSIP_SYNTAXERROR; if (excontext->enable_outbound==1) { contact[strlen (contact) - 1] = '\0'; strcat (contact, ";ob"); strcat (contact, ">"); } if (strlen (contact) + strlen (via->protocol) + strlen (";transport=>") < 1024 && 0 != osip_strcasecmp (via->protocol, "UDP")) { contact[strlen (contact) - 1] = '\0'; strcat (contact, ";transport="); strcat (contact, via->protocol); strcat (contact, ">"); } if (excontext->sip_instance[0] != 0 && strlen (contact) + 64 < 1024) { strcat(contact, ";+sip.instance=\"<urn:uuid:"); strcat(contact, excontext->sip_instance); strcat(contact, ">\""); } } osip_message_set_contact (response, contact); if (excontext->default_contact_displayname[0]!='\0') { osip_contact_t *new_contact; osip_message_get_contact(response, 0, &new_contact); if (new_contact!=NULL) { new_contact->displayname = osip_strdup (excontext->default_contact_displayname); } } if (excontext->eXtl_transport._tl_update_contact!=NULL) excontext->eXtl_transport._tl_update_contact(excontext, response); return OSIP_SUCCESS; }
int osip_uri_to_str (const osip_uri_t * url, char **dest) { char *buf; size_t len; size_t plen; char *tmp; const char *scheme; *dest = NULL; if (url == NULL) return -1; if (url->host == NULL && url->string == NULL) return -1; if (url->scheme == NULL && url->string != NULL) return -1; if (url->string == NULL && url->scheme == NULL) scheme = "sip"; /* default is sipurl */ else scheme = url->scheme; if (url->string != NULL) { buf = (char *) osip_malloc (strlen (scheme) + strlen (url->string) + 3); if (buf == NULL) return -1; *dest = buf; sprintf (buf, "%s:", scheme); buf = buf + strlen (scheme) + 1; sprintf (buf, "%s", url->string); buf = buf + strlen (url->string); return 0; } len = strlen (scheme) + 1 + strlen (url->host) + 5; if (url->username != NULL) len = len + (strlen (url->username) * 3) + 1; /* count escaped char */ if (url->password != NULL) len = len + (strlen (url->password) * 3) + 1; if (url->port != NULL) len = len + strlen (url->port) + 3; buf = (char *) osip_malloc (len); if (buf == NULL) return -1; tmp = buf; sprintf (tmp, "%s:", scheme); tmp = tmp + strlen (tmp); if (url->username != NULL) { char *tmp2 = __osip_uri_escape_userinfo (url->username); sprintf (tmp, "%s", tmp2); osip_free (tmp2); tmp = tmp + strlen (tmp); } if ((url->password != NULL) && (url->username != NULL)) { /* be sure that when a password is given, a username is also given */ char *tmp2 = __osip_uri_escape_password (url->password); sprintf (tmp, ":%s", tmp2); osip_free (tmp2); tmp = tmp + strlen (tmp); } if (url->username != NULL) { /* we add a '@' only when username is present... */ sprintf (tmp, "@"); tmp++; } if (strchr (url->host, ':') != NULL) { sprintf (tmp, "[%s]", url->host); tmp = tmp + strlen (tmp); } else { sprintf (tmp, "%s", url->host); tmp = tmp + strlen (tmp); } if (url->port != NULL) { sprintf (tmp, ":%s", url->port); tmp = tmp + strlen (tmp); } { int pos = 0; osip_uri_param_t *u_param; while (!osip_list_eol (&url->url_params, pos)) { char *tmp1; char *tmp2 = NULL; u_param = (osip_uri_param_t *) osip_list_get (&url->url_params, pos); tmp1 = __osip_uri_escape_uri_param (u_param->gname); if (u_param->gvalue == NULL) plen = strlen (tmp1) + 2; else { tmp2 = __osip_uri_escape_uri_param (u_param->gvalue); plen = strlen (tmp1) + strlen (tmp2) + 3; } len = len + plen; buf = (char *) osip_realloc (buf, len); tmp = buf; tmp = tmp + strlen (tmp); if (u_param->gvalue == NULL) sprintf (tmp, ";%s", tmp1); else { sprintf (tmp, ";%s=%s", tmp1, tmp2); osip_free (tmp2); } osip_free (tmp1); pos++; } } { int pos = 0; osip_uri_header_t *u_header; while (!osip_list_eol (&url->url_headers, pos)) { char *tmp1; char *tmp2; u_header = (osip_uri_header_t *) osip_list_get (&url->url_headers, pos); tmp1 = __osip_uri_escape_header_param (u_header->gname); if (tmp1 == NULL) { osip_free (buf); return -1; } tmp2 = __osip_uri_escape_header_param (u_header->gvalue); if (tmp2 == NULL) { osip_free (tmp1); osip_free (buf); return -1; } plen = strlen (tmp1) + strlen (tmp2) + 4; len = len + plen; buf = (char *) osip_realloc (buf, len); tmp = buf; tmp = tmp + strlen (tmp); if (pos == 0) sprintf (tmp, "?%s=%s", tmp1, tmp2); else sprintf (tmp, "&%s=%s", tmp1, tmp2); osip_free (tmp1); osip_free (tmp2); pos++; } } *dest = buf; return 0; }