📄 jrequest.c
字号:
/* eXosip - This is the eXtended osip library. Copyright (C) 2002,2003,2004,2005,2006,2007 Aymeric MOIZARD - jack@atosc.org eXosip is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. eXosip is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#ifdef ENABLE_MPATROL#include <mpatrol.h>#endif#include "eXosip2.h"#ifndef WIN32#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#ifdef __APPLE_CC__#include <unistd.h>#endif#else#include <windows.h>#include <iphlpapi.h>#endifextern eXosip_t eXosip;extern int ipv6_enable;/* Private functions */static int dialog_fill_route_set (osip_dialog_t * dialog, osip_message_t * request);/* should use cryptographically random identifier is RECOMMENDED.... *//* by now this should lead to identical call-id when application are started at the same time... */char *osip_call_id_new_random (){ char *tmp = (char *) osip_malloc (33); unsigned int number = osip_build_random_number (); if (tmp == NULL) return NULL; sprintf (tmp, "%u", number); return tmp;}inteXosip_generate_random (char *buf, int buf_size){ unsigned int number = osip_build_random_number (); snprintf (buf, buf_size, "%u", number); return OSIP_SUCCESS;}char *osip_from_tag_new_random (void){ return osip_call_id_new_random ();}char *osip_to_tag_new_random (void){ return osip_call_id_new_random ();}unsigned intvia_branch_new_random (void){ return osip_build_random_number ();}int_eXosip_dialog_add_contact (osip_message_t * request, osip_message_t * answer){ osip_via_t *via; osip_from_t *a_from; char *contact = NULL; char locip[65]; char firewall_ip[65]; char firewall_port[10]; int len; if (eXosip.eXtl == NULL) return OSIP_NO_NETWORK; if (request == NULL) return OSIP_BADPARAMETER; firewall_ip[0] = '\0'; firewall_port[0] = '\0'; if (eXosip.eXtl->tl_get_masquerade_contact != NULL) { eXosip.eXtl->tl_get_masquerade_contact (firewall_ip, sizeof (firewall_ip), firewall_port, sizeof (firewall_port)); } /* search for topmost Via which indicate the transport protocol */ via = (osip_via_t *) osip_list_get (&request->vias, 0); if (via == NULL || via->protocol == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via header\n")); return OSIP_SYNTAXERROR; } if (answer == NULL) a_from = request->from; else a_from = answer->to; if (a_from == NULL || a_from->url == NULL) return OSIP_SYNTAXERROR; /*guess the local ip since req uri is known */ memset (locip, '\0', sizeof (locip)); if (a_from->url->username != NULL) len = 2 + 4 + strlen (a_from->url->username) + 1 + 100 + 6 + 10 + strlen (eXosip.transport); else len = 2 + 4 + 100 + 6 + 10 + strlen (eXosip.transport); contact = (char *) osip_malloc (len + 1); if (contact == NULL) return OSIP_NOMEM; if (firewall_ip[0] != '\0') { char *c_address = request->req_uri->host; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; int i; i = eXosip_get_addrinfo (&addrinfo, request->req_uri->host, 5060, IPPROTO_TCP); 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 (eXosip_is_public_address (c_address)) { memcpy (locip, firewall_ip, sizeof (locip)); } } if (locip[0] == '\0') { eXosip_guess_ip_for_via (eXosip.eXtl->proto_family, locip, 49); if (locip[0] == '\0') { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: no default interface defined\n")); return OSIP_NO_NETWORK; } } if (eXosip.eXtl->proto_family == AF_INET6) { if (a_from->url->username != NULL) snprintf (contact, len, "<sip:%s@[%s]:%s>", a_from->url->username, locip, firewall_port); else snprintf (contact, len - strlen (eXosip.transport) - 10, "<sip:[%s]:%s>", locip, firewall_port); } else { if (a_from->url->username != NULL) snprintf (contact, len, "<sip:%s@%s:%s>", a_from->url->username, locip, firewall_port); else snprintf (contact, len - strlen (eXosip.transport) - 10, "<sip:%s:%s>", locip, firewall_port); } if (osip_strcasecmp (eXosip.transport, "UDP") != 0) { contact[strlen (contact) - 1] = '\0'; strcat (contact, ";transport="); strcat (contact, eXosip.transport); strcat (contact, ">"); } osip_message_set_contact (request, contact); osip_free (contact); return OSIP_SUCCESS;}int_eXosip_request_add_via (osip_message_t * request, const char *transport, const char *locip){ char tmp[200]; const char *ip = NULL; char firewall_ip[65]; char firewall_port[10]; if (request == NULL) return OSIP_BADPARAMETER; if (request->call_id == NULL) return OSIP_SYNTAXERROR; if (locip == NULL && request->call_id->host == NULL) return OSIP_SYNTAXERROR; if (locip != NULL) ip = locip; else if (request->call_id->host != NULL) ip = request->call_id->host; firewall_ip[0] = '\0'; firewall_port[0] = '\0'; if (eXosip.eXtl != NULL && eXosip.eXtl->tl_get_masquerade_contact != NULL) { eXosip.eXtl->tl_get_masquerade_contact (firewall_ip, sizeof (firewall_ip), firewall_port, sizeof (firewall_port)); }#ifdef MASQUERADE_VIA /* this helps to work with a server that don't handle the "received" parameter correctly. Some still exists. */ if (firewall_ip[0] != '\0') { ip = firewall_ip; }#endif if (firewall_port[0] == '\0') { snprintf (firewall_port, sizeof (firewall_port), "5060"); } if (eXosip.eXtl->proto_family == AF_INET6) snprintf (tmp, 200, "SIP/2.0/%s [%s]:%s;branch=z9hG4bK%u", eXosip.transport, ip, firewall_port, via_branch_new_random ()); else { if (eXosip.use_rport != 0) snprintf (tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", eXosip.transport, ip, firewall_port, via_branch_new_random ()); else snprintf (tmp, 200, "SIP/2.0/%s %s:%s;branch=z9hG4bK%u", eXosip.transport, ip, firewall_port, via_branch_new_random ()); } osip_message_set_via (request, tmp); return OSIP_SUCCESS;}/* prepare a minimal request (outside of a dialog) with required headers *//* method is the type of request. ("INVITE", "REGISTER"...) to is the remote target URI transport is either "TCP" or "UDP" (by now, only UDP is implemented!)*/intgenerating_request_out_of_dialog (osip_message_t ** dest, const char *method, const char *to, const char *transport, const char *from, const char *proxy){ /* Section 8.1: A valid request contains at a minimum "To, From, Call-iD, Cseq, Max-Forwards and Via */ int i; osip_message_t *request; char locip[65]; int doing_register; char *register_callid_number = NULL; *dest = NULL; if (eXosip.eXtl == NULL) return OSIP_NO_NETWORK; /*guess the local ip since req uri is known */ memset (locip, '\0', sizeof (locip)); eXosip_guess_ip_for_via (eXosip.eXtl->proto_family, locip, 49); if (locip[0] == '\0') { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: no default interface defined\n")); return OSIP_NO_NETWORK; } i = osip_message_init (&request); if (i != 0) return i; /* prepare the request-line */ osip_message_set_method (request, osip_strdup (method)); osip_message_set_version (request, osip_strdup ("SIP/2.0")); osip_message_set_status_code (request, 0); osip_message_set_reason_phrase (request, NULL); doing_register = 0 == strcmp ("REGISTER", method); if (doing_register) { osip_uri_init (&(request->req_uri)); i = osip_uri_parse (request->req_uri, proxy); if (i != 0) { osip_message_free (request); return i; } i = osip_message_set_to (request, from); if (i != 0 || request->to == NULL) { if (i >= 0) i = OSIP_SYNTAXERROR; osip_message_free (request); return i; } } else { /* in any cases except REGISTER: */ i = osip_message_set_to (request, to); if (i != 0 || request->to == NULL) { if (i >= 0) i = OSIP_SYNTAXERROR; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ERROR: callee address does not seems to be a sipurl: %s\n", to)); osip_message_free (request); return i; } /* REMOVE ALL URL PARAMETERS from to->url headers and add them as headers */ if (request->to != NULL && request->to->url != NULL) { osip_uri_t *url = request->to->url; while (osip_list_size (&url->url_headers) > 0) { osip_uri_header_t *u_header; u_header = (osip_uri_param_t *) osip_list_get (&url->url_headers, 0); if (u_header == NULL) break; if (osip_strcasecmp (u_header->gname, "from") == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -