Sat Feb 11 06:34:42 2012

Asterisk developer's documentation


chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

#include "asterisk.h"
#include <signal.h>
#include <sys/signal.h>
#include <regex.h>
#include <inttypes.h>
#include "asterisk/network.h"
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj2.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/monitor.h"
#include "asterisk/netsock2.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
#include "asterisk/ast_version.h"
#include "asterisk/event.h"
#include "asterisk/cel.h"
#include "asterisk/data.h"
#include "asterisk/aoc.h"
#include "asterisk/message.h"
#include "sip/include/sip.h"
#include "sip/include/globals.h"
#include "sip/include/config_parser.h"
#include "sip/include/reqresp_parser.h"
#include "sip/include/sip_utils.h"
#include "sip/include/srtp.h"
#include "sip/include/sdp_crypto.h"
#include "asterisk/ccss.h"
#include "asterisk/xml.h"
#include "sip/include/dialog.h"
#include "sip/include/dialplan_functions.h"
#include "sip/include/security_events.h"

Go to the source code of this file.

Data Structures

struct  ast_register_list
 The register list: Other SIP proxies we register with and receive calls from. More...
struct  ast_subscription_mwi_list
 The MWI subscription list. More...
struct  cfalias
 Structure for conversion between compressed SIP and "normal" SIP headers. More...
struct  cfsip_methods
 The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. More...
struct  cfsubscription_types
 Subscription types that we support. We support
  • dialoginfo updates (really device status, not dialog info as was the original intent of the standard)
  • SIMPLE presence used for device status
  • Voicemail notification subscriptions.
More...
struct  domain_list
struct  epa_static_data_list
struct  event_state_compositor
 The Event State Compositors. More...
struct  invstate2stringtable
 Readable descriptions of device states. More...
struct  match_req_args
struct  sip_history_head
struct  sip_reasons
 Diversion header reasons. More...

Object counters @{

Bug:
These counters are not handled in a thread-safe way ast_atomic_fetchadd_int() should be used to modify these values.


#define append_history(p, event, fmt, args...)   append_history_full(p, "%-15s " fmt, event, ## args)
 Append to SIP dialog history.
#define check_request_transport(peer, tmpl)
 generic function for determining if a correct transport is being used to contact a peer
#define CONTAINER_UNLINK(container, obj, tag)
 Unlink the given object from the container and return TRUE if it was in the container.
#define DATA_EXPORT_SIP_PEER(MEMBER)
#define FORMAT   "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n"
#define FORMAT   "%-30.30s %-12.12s %-10.10s %-10.10s\n"
#define FORMAT   "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n"
#define FORMAT   "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
#define FORMAT   "%-47.47s %-9.9s %-6.6s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT2   "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n"
#define FORMAT2   "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"
#define FORMAT2   "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-11s %-32.32s %s\n"
#define FORMAT2   "%-47.47s %9.9s %6.6s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n"
#define FORMAT4   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n"
#define sip_pvt_lock(x)   ao2_lock(x)
#define sip_pvt_trylock(x)   ao2_trylock(x)
#define sip_pvt_unlock(x)   ao2_unlock(x)
#define UNLINK(element, head, prev)
enum  match_req_res { SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_REQ_LOOP_DETECTED, SIP_REQ_FORKED }
enum  peer_unlink_flag_t { SIP_PEERS_MARKED, SIP_PEERS_ALL }
static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto,chan_local", }
static struct cfalias aliases []
static struct _map_x_s allowoverlapstr []
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static char * app_sipremoveheader = "SIPRemoveHeader"
static struct ast_module_infoast_module_info = &__mod_info
static struct sip_auth_container * authl = NULL
 Authentication container for realm authentication.
static ast_mutex_t authl_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
 Global authentication container protection while adjusting the references.
static struct _map_x_s autopeermodes []
struct ast_sockaddr bindaddr
static struct epa_static_data cc_epa_static_data
static struct ast_custom_function checksipdomain_function
static struct ast_cli_entry cli_sip []
 SIP Cli commands definition.
static struct ast_sockaddr debugaddr
static const int DEFAULT_PUBLISH_EXPIRES = 3600
static struct ast_tls_config default_tls_cfg
 Default TLS connection configuration.
static struct ao2_containerdialogs
struct ao2_containerdialogs_needdestroy
struct ao2_containerdialogs_rtpcheck
static struct _map_x_s dtmfstr []
 mapping between dtmf flags and strings
static int esc_etag_counter
static const int ESC_MAX_BUCKETS = 37
static struct
event_state_compositor 
event_state_compositors []
 The Event State Compositors.
static struct ast_sockaddr externaddr
 our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:
static time_t externexpire
static char externhost [MAXHOSTNAMELEN]
static int externrefresh = 10
static uint16_t externtcpport
static uint16_t externtlsport
static struct _map_x_s faxecmodes []
static struct ast_flags global_flags [3] = {{0}}
static int global_t38_maxdatagram
static const int HASH_DIALOG_SIZE = 563
static const int HASH_PEER_SIZE = 563
static struct _map_x_s insecurestr []
static struct ast_sockaddr internip
 our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages.
static struct io_contextio
static struct ast_halocaladdr
 List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
static struct ast_sockaddr media_address
static pthread_t monitor_thread = AST_PTHREADT_NULL
 This is the thread for the monitor which checks for input on the channels which are not currently in use.
static ast_mutex_t monlock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
static ast_mutex_t netlock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static int network_change_event_sched_id = -1
static struct ast_event_subnetwork_change_event_subscription
static struct ast_confignotify_types = NULL
static int ourport_tcp
static int ourport_tls
static struct ao2_containerpeers
 The peer list: Users, Peers and Friends.
static struct ao2_containerpeers_by_ip
static struct ast_data_handler peers_data_provider
static struct _map_x_s referstatusstrings []
static struct ast_register_list regl
 The register list: Other SIP proxies we register with and receive calls from.
static int regobjs = 0
static struct _map_x_s regstatestrings []
static int rpeerobjs = 0
struct ast_sched_contextsched
static struct
ast_cc_agent_callbacks 
sip_cc_agent_callbacks
static struct
ast_cc_monitor_callbacks 
sip_cc_monitor_callbacks
struct {
   enum sip_cc_notify_state   state
   const char *   state_string
sip_cc_notify_state_map []
struct {
   enum ast_cc_service_type   service
   const char *   service_string
sip_cc_service_map []
static struct ast_data_entry sip_data_providers []
static struct ast_custom_function sip_header_function
struct ao2_containersip_monitor_instances
static struct ast_threadstorage sip_msg_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sip_msg_buf , .custom_init = NULL , }
static struct ast_msg_tech sip_msg_tech
static ast_mutex_t sip_reload_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static int sip_reloading = FALSE
static enum channelreloadreason sip_reloadreason
static struct ast_rtp_glue sip_rtp_glue
static struct
ast_tcptls_session_args 
sip_tcp_desc
 The TCP server definition.
struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
struct ast_channel_tech sip_tech_info
 This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF.
static struct ast_tls_config sip_tls_cfg
 Working TLS connection configuration.
static struct
ast_tcptls_session_args 
sip_tls_desc
 The TCP/TLS server definition.
static struct ast_udptl_protocol sip_udptl
 Interface structure with callbacks used to connect to UDPTL module.
static struct ast_custom_function sipchaninfo_function
 Structure to declare a dialplan function: SIPCHANINFO.
static enum sip_debug_e sipdebug
static int sipdebug_text
 extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.
static struct ast_custom_function sippeer_function
 Structure to declare a dialplan function: SIPPEER.
static int sipsock = -1
 Main socket for UDP SIP communication.
static int * sipsock_read_id
static int speerobjs = 0
static struct _map_x_s stmodes []
 Report Peer status in character string.
static struct _map_x_s strefreshers []
static struct
ast_subscription_mwi_list 
submwil
 The MWI subscription list.
static struct ao2_containerthreadt
 The table of TCP threads.
static struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , }
static char used_context [AST_MAX_CONTEXT]
static const char * __get_header (const struct sip_request *req, const char *name, int *start)
static void __init_sip_msg_buf (void)
static void __init_ts_temp_pvt (void)
 A per-thread temporary pvt structure.
static void __reg_module (void)
static int __set_address_from_contact (const char *fullcontact, struct ast_sockaddr *addr, int tcp)
int __sip_ack (struct sip_pvt *p, uint32_t seqno, int resp, int sipmethod)
 Acknowledges receipt of a packet and stops retransmission called with p locked.
static int __sip_autodestruct (const void *data)
 Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref().
void __sip_destroy (struct sip_pvt *p, int lockowner, int lockdialoglist)
 Execute destruction of SIP dialog structure, release memory.
static int __sip_do_register (struct sip_registry *r)
 Register with SIP proxy.
void __sip_pretend_ack (struct sip_pvt *p)
 Pretend to ack all packets called with p locked.
static int __sip_reliable_xmit (struct sip_pvt *p, uint32_t seqno, int resp, struct ast_str *data, int fatal, int sipmethod)
int __sip_semi_ack (struct sip_pvt *p, uint32_t seqno, int resp, int sipmethod)
 Acks receipt of packet, keep it around (used for provisional responses).
static int __sip_subscribe_mwi_do (struct sip_subscription_mwi *mwi)
 Actually setup an MWI subscription or resubscribe.
static int __sip_xmit (struct sip_pvt *p, struct ast_str *data)
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function.
static void __unreg_module (void)
static char * _sip_qualify_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Send qualify message to peer from cli or manager. Mostly for debugging.
static char * _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Show one peer in detail (main function).
static char * _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Execute sip show peers command.
static void * _sip_tcp_helper_thread (struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
 SIP TCP thread management function This function reads from the socket, parses the packet into a request.
static void add_blank (struct sip_request *req)
 add a blank line if no body
static void add_cc_call_info_to_response (struct sip_pvt *p, struct sip_request *resp)
static void add_codec_to_sdp (const struct sip_pvt *p, struct ast_format *format, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_content (struct sip_request *req, const char *line)
 Add content (not header) to SIP message.
static int add_digit (struct sip_request *req, char digit, unsigned int duration, int mode)
 Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf.
static void add_diversion_header (struct sip_request *req, struct sip_pvt *pvt)
 Add "Diversion" header to outgoing message.
static int add_header (struct sip_request *req, const char *var, const char *value)
 Add header to SIP message.
static int add_header_max_forwards (struct sip_pvt *dialog, struct sip_request *req)
 Add 'Max-Forwards' header to SIP message.
static void add_msg_header (struct sip_pvt *pvt, const char *hdr_name, const char *hdr_value)
static void add_noncodec_to_sdp (const struct sip_pvt *p, int format, struct ast_str **m_buf, struct ast_str **a_buf, int debug)
 Add RFC 2833 DTMF offer to SDP.
static void add_peer_mailboxes (struct sip_peer *peer, const char *value)
static void add_peer_mwi_subs (struct sip_peer *peer)
static void add_realm_authentication (struct sip_auth_container **credentials, const char *configuration, int lineno)
static void add_route (struct sip_request *req, struct sip_route *route)
 Add route header into request per learned route.
static int add_rpid (struct sip_request *req, struct sip_pvt *p)
 Add Remote-Party-ID header to SIP message.
static enum sip_result add_sdp (struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38)
 Add Session Description Protocol message.
static int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 Add SIP domain to list of domains we are responsible for.
static int add_supported_header (struct sip_pvt *pvt, struct sip_request *req)
 Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog.
static void add_tcodec_to_sdp (const struct sip_pvt *p, struct ast_format *format, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add text codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_text (struct sip_request *req, struct sip_pvt *p)
 Add text body to SIP message.
static struct ast_variableadd_var (const char *buf, struct ast_variable *list)
 implement the setvar config line
static void add_vcodec_to_sdp (const struct sip_pvt *p, struct ast_format *format, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add video codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_vidupdate (struct sip_request *req)
 add XML encoded media control with update
static const char * allowoverlap2str (int mode)
 Convert AllowOverlap setting to printable string.
static void append_date (struct sip_request *req)
 Append date to SIP message.
static void append_history_full (struct sip_pvt *p, const char *fmt,...)
 Append to SIP dialog history with arg list.
static void append_history_va (struct sip_pvt *p, const char *fmt, va_list ap)
 Append to SIP dialog history with arg list.
static int apply_directmedia_ha (struct sip_pvt *p, const char *op)
 AST_DATA_STRUCTURE (sip_peer, DATA_EXPORT_SIP_PEER)
static void ast_quiet_chan (struct ast_channel *chan)
 Turn off generator data XXX Does this function belong in the SIP channel?
static void ast_sip_ouraddrfor (const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p)
 NAT fix - decide which IP address to use for Asterisk server?
static int ast_sockaddr_resolve_first (struct ast_sockaddr *addr, const char *name, int flag)
 Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
static int ast_sockaddr_resolve_first_af (struct ast_sockaddr *addr, const char *name, int flag, int family)
 Return the first entry from ast_sockaddr_resolve filtered by address family.
static int attempt_transfer (struct sip_dual *transferer, struct sip_dual *target)
 Attempt transfer of SIP call This fix for attended transfers on a local PBX.
static int auto_congest (const void *arg)
 Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.
static const char * autocreatepeer2str (enum autocreatepeer_mode r)
static int block_msg_header (const char *header_name)
static void build_callid_pvt (struct sip_pvt *pvt)
 Build SIP Call-ID value for a non-REGISTER transaction.
static void build_callid_registry (struct sip_registry *reg, const struct ast_sockaddr *ourip, const char *fromdomain)
 Build SIP Call-ID value for a REGISTER transaction.
static void build_contact (struct sip_pvt *p)
 Build contact header - the contact header we send out.
static struct sip_peer * build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
 Build peer from configuration (file or realtime static/dynamic).
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest.
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 Build route list from Record-Route header.
static void build_via (struct sip_pvt *p)
 Build a Via header for a request.
static int cb_extensionstate (const char *context, const char *exten, enum ast_extension_states state, void *data)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem.
static void cb_extensionstate_destroy (int id, void *data)
static void cc_epa_destructor (void *data)
static void cc_handle_publish_error (struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry)
static void change_callid_pvt (struct sip_pvt *pvt, const char *callid)
static void change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
 Change hold state for a call.
static void change_redirecting_information (struct sip_pvt *p, struct sip_request *req, struct ast_party_redirecting *redirecting, struct ast_set_party_redirecting *update_redirecting, int set_call_forward)
 update redirecting information for a channel based on headers
static void change_t38_state (struct sip_pvt *p, int state)
 Change the T38 state on a SIP dialog.
static enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, const char *uri, enum xmittype reliable, int ignore)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
static enum check_auth_result check_peer_ok (struct sip_pvt *p, char *of, struct sip_request *req, int sipmethod, struct ast_sockaddr *addr, struct sip_peer **authpeer, enum xmittype reliable, char *calleridname, char *uri2)
 Validate device authentication.
static void check_pendings (struct sip_pvt *p)
 Check pending actions on SIP call.
static int check_rtp_timeout (struct sip_pvt *dialog, time_t t)
 helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked
static int check_sip_domain (const char *domain, char *context, size_t len)
 check_sip_domain: Check if domain part of uri is local to our server
static int check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr)
 Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
static enum check_auth_result check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr, struct sip_peer **authpeer)
 Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
static void check_via (struct sip_pvt *p, struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static attribute_unused void check_via_response (struct sip_pvt *p, struct sip_request *req)
 check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/.
static void cleanup_all_regs (void)
static void cleanup_stale_contexts (char *new, char *old)
 Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
static void clear_peer_mailboxes (struct sip_peer *peer)
static void clear_sip_domains (void)
 Clear our domain list (at reload).
static char * complete_sip_peer (const char *word, int state, int flags2)
 Do completion on peer name.
static char * complete_sip_registered_peer (const char *word, int state, int flags2)
 Do completion on registered peer name.
static char * complete_sip_show_history (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show history' CLI.
static char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show peer' CLI.
static char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show user' CLI.
static char * complete_sip_unregister (const char *line, const char *word, int pos, int state)
 Support routine for 'sip unregister' CLI.
static char * complete_sip_user (const char *word, int state)
 Do completion on user name.
static char * complete_sipch (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.
static char * complete_sipnotify (const char *line, const char *word, int pos, int state)
 Support routine for 'sip notify' CLI.
static int construct_pidf_body (enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity)
static int copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy all headers from one request to another.
static int copy_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy one header field from one request to another.
static void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses)
static void copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock)
static struct ast_variablecopy_vars (struct ast_variable *src)
 duplicate a list of channel variables,
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy SIP VIA Headers from the request to the response.
static int create_addr (struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog, struct ast_sockaddr *remote_address)
 create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
static int create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer)
 Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.
static struct sip_epa_entry * create_epa_entry (const char *const event_package, const char *const destination)
static struct sip_esc_entry * create_esc_entry (struct event_state_compositor *esc, struct sip_request *req, const int expires)
static void create_new_sip_etag (struct sip_esc_entry *esc_entry, int is_linked)
static int default_sip_port (enum sip_transport type)
 The default sip port for the given transport.
static void deinit_req (struct sip_request *req)
 Deinitialize SIP response/request.
static void destroy_association (struct sip_peer *peer)
 Remove registration data from realtime database or AST/DB when registration expires.
static void destroy_escs (void)
static void destroy_mailbox (struct sip_mailbox *mailbox)
static void destroy_msg_headers (struct sip_pvt *pvt)
static void destroy_realm_authentication (void *obj)
static int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request.
static enum sip_publish_type determine_sip_publish_type (struct sip_request *req, const char *const event, const char *const etag, const char *const expires, int *expires_int)
static int dialog_checkrtp_cb (void *dialogobj, void *arg, int flags)
 Check RTP Timeout on dialogs.
static int dialog_cmp_cb (void *obj, void *arg, int flags)
static int dialog_dump_func (void *userobj, void *arg, int flags)
static int dialog_find_multiple (void *obj, void *arg, int flags)
static int dialog_hash_cb (const void *obj, const int flags)
static int dialog_initialize_rtp (struct sip_pvt *dialog)
 Initialize RTP portion of a dialog.
static int dialog_needdestroy (void *dialogobj, void *arg, int flags)
 Match dialogs that need to be destroyed.
struct sip_pvt * dialog_ref_debug (struct sip_pvt *p, const char *tag, char *file, int line, const char *func)
void dialog_unlink_all (struct sip_pvt *dialog)
 Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.
struct sip_pvt * dialog_unref_debug (struct sip_pvt *p, const char *tag, char *file, int line, const char *func)
static void disable_dsp_detect (struct sip_pvt *p)
static void display_nat_warning (const char *cat, int reason, struct ast_flags *flags)
static int do_magic_pickup (struct ast_channel *channel, const char *extension, const char *context)
static int do_message_auth (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
static void * do_monitor (void *data)
 The SIP monitoring thread.
static int do_proxy_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init)
 Add authentication on outbound SIP packet.
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code)
 Authenticate for outbound registration.
static void do_setnat (struct sip_pvt *p)
 Set nat mode on the various data sockets.
static const char * domain_mode_to_text (const enum domain_mode mode)
 Print domain mode to cli.
static const char * dtmfmode2str (int mode)
 Convert DTMF mode to printable string.
static void enable_dsp_detect (struct sip_pvt *p)
static int esc_cmp_fn (void *obj, void *arg, int flags)
static void esc_entry_destructor (void *obj)
static int esc_hash_fn (const void *obj, const int flags)
static int expire_register (const void *data)
 Expire registration of SIP peer.
static void extract_host_from_hostport (char **hostport)
 Terminate a host:port at the ':'.
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 Check Contact: URI of SIP message.
static const char * faxec2str (int faxec)
static int finalize_content (struct sip_request *req)
 Add 'Content-Length' header and content to SIP message.
static const char * find_alias (const char *name, const char *_default)
 Find compressed SIP alias.
static int find_by_callid_helper (void *obj, void *arg, int flags)
static int find_by_name (void *obj, void *arg, void *data, int flags)
static int find_by_notify_uri_helper (void *obj, void *arg, int flags)
static int find_by_subscribe_uri_helper (void *obj, void *arg, int flags)
static struct sip_pvt * find_call (struct sip_request *req, struct ast_sockaddr *addr, const int intended_method)
 find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_request_do
static int find_calling_channel (void *obj, void *arg, void *data, int flags)
 Find the channel that is causing the RINGING update.
const char * find_closing_quote (const char *start, const char *lim)
 Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
static const char * find_full_alias (const char *name, const char *_default)
 Find full SIP alias.
static struct sip_auth * find_realm_authentication (struct sip_auth_container *credentials, const char *realm)
static int find_sdp (struct sip_request *req)
 Determine whether a SIP message contains an SDP in its body.
static struct ast_cc_agentfind_sip_cc_agent_by_notify_uri (const char *const uri)
static struct ast_cc_agentfind_sip_cc_agent_by_original_callid (struct sip_pvt *pvt)
static struct ast_cc_agentfind_sip_cc_agent_by_subscribe_uri (const char *const uri)
static int find_sip_method (const char *msg)
 find_sip_method: Find SIP method from header
static int find_sip_monitor_instance_by_subscription_pvt (void *obj, void *arg, int flags)
static int find_sip_monitor_instance_by_suspension_entry (void *obj, void *arg, int flags)
static struct epa_static_data * find_static_data (const char *const event_package)
static struct
cfsubscription_types
find_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array.
static void forked_invite_init (struct sip_request *req, const char *new_theirtag, struct sip_pvt *original, struct ast_sockaddr *addr)
 This function creates a dialog to handle a forked request. This dialog exists only to properly terminiate the the forked request immediately.
static void free_old_route (struct sip_route *route)
 Remove route from route list.
static int func_check_sipdomain (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 Dial plan function to check if domain is local.
static int func_header_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
 Read SIP header (dialplan function).
static int function_sipchaninfo_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${SIPCHANINFO()} Dialplan function - reads sip channel data
static int function_sippeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${SIPPEER()} Dialplan function - reads peer data
static char * generate_random_string (char *buf, size_t size)
 Generate 32 byte random string for callid's etc.
static char * generate_uri (struct sip_pvt *pvt, char *buf, size_t size)
static int get_address_family_filter (const struct ast_sockaddr *addr)
 Helper for dns resolution to filter by address family.
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 Call transfer support (old way, deprecated by the IETF).
static char * get_body (struct sip_request *req, char *name, char delimiter)
 Get a specific line from the message body.
static char * get_body_by_line (const char *line, const char *name, int nameLen, char delimiter)
 Reads one line of SIP message body.
static int get_cached_mwi (struct sip_peer *peer, int *new, int *old)
 Get cached MWI info.
static void get_crypto_attrib (struct sip_pvt *p, struct sip_srtp *srtp, const char **a_crypto)
static enum sip_get_dest_result get_destination (struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id)
 Find out who the call is for.
static int get_domain (const char *str, char *domain, int len)
 Extract domain from SIP To/From header.
static struct
event_state_compositor
get_esc (const char *const event_package)
static struct sip_esc_entry * get_esc_entry (const char *entity_tag, struct event_state_compositor *esc)
static struct ast_variableget_insecure_variable_from_config (struct ast_config *config)
static struct ast_variableget_insecure_variable_from_sippeers (const char *column, const char *value)
static struct ast_variableget_insecure_variable_from_sipregs (const char *column, const char *value, struct ast_variable **var)
static int get_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct ast_sockaddr *addr)
static int get_msg_text (char *buf, int len, struct sip_request *req)
 Get message body from a SIP request.
static int get_msg_text2 (struct ast_str **buf, struct sip_request *req)
static const char * get_name_from_variable (const struct ast_variable *var)
static void get_our_media_address (struct sip_pvt *p, int needvideo, int needtext, struct ast_sockaddr *addr, struct ast_sockaddr *vaddr, struct ast_sockaddr *taddr, struct ast_sockaddr *dest, struct ast_sockaddr *vdest, struct ast_sockaddr *tdest)
 Set all IP media addresses for this call.
static int get_pai (struct sip_pvt *p, struct sip_request *req)
 Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id.
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason)
 Get referring dnis.
static void get_realm (struct sip_pvt *p, const struct sip_request *req)
 Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=...
static int get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req)
 Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
static int get_rpid (struct sip_pvt *p, struct sip_request *oreq)
 Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id.
static const char * get_sdp_iterate (int *start, struct sip_request *req, const char *name)
 Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
static char get_sdp_line (int *start, int stop, struct sip_request *req, const char **value)
 Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.
static struct sip_pvt * get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag)
 Lock dialog lock and find matching pvt lock.
static const char * get_srv_protocol (enum sip_transport t)
 Return protocol string for srv dns query.
static const char * get_srv_service (enum sip_transport t)
 Return service string for srv dns query.
static const char * get_transport_list (unsigned int transports)
 Return configuration of transports for a device.
static const char * get_transport_pvt (struct sip_pvt *p)
 Return transport of dialog.
static int get_transport_str2enum (const char *transport)
 Return int representing a bit field of transport types found in const char *transport.
static const char * gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
 Get tag from packet.
static int handle_cc_notify (struct sip_pvt *pvt, struct sip_request *req)
static int handle_cc_subscribe (struct sip_pvt *p, struct sip_request *req)
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 Handle flag-type options common to configuration of devices - peers.
static int handle_incoming (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int *recount, int *nounlock)
 Handle incoming SIP requests (methods).
static int handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, struct ast_sockaddr *addr, int *nounlock)
 Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req)
 Handle incoming BYE request.
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req)
 Handle incoming CANCEL request.
static int handle_request_do (struct sip_request *req, struct ast_sockaddr *addr)
 Handle incoming SIP message - request or response.
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 Receive SIP INFO Message.
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, struct ast_sockaddr *addr, int *recount, const char *e, int *nounlock)
 Handle incoming INVITE request.
static int handle_request_message (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
 Handle incoming MESSAGE request.
static int handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, const char *e)
 Handle incoming notifications.
static int handle_request_options (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
 Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.
static int handle_request_publish (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const uint32_t seqno, const char *uri)
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, uint32_t seqno, int *nounlock)
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
 Handle incoming REGISTER request.
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, const char *e)
 Handle incoming SUBSCRIBE request.
static int handle_request_update (struct sip_pvt *p, struct sip_request *req)
 bare-bones support for SIP UPDATE
static void handle_response (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
 Handle SIP response in dialogue.
static void handle_response_info (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
static void handle_response_invite (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
 Handle SIP response to INVITE dialogue.
static void handle_response_message (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
static void handle_response_notify (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
static void handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req)
 Handle qualification responses (OPTIONS).
static void handle_response_publish (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
static void handle_response_refer (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
static int handle_response_register (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
 Handle responses on REGISTER to services.
static void handle_response_subscribe (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
static void handle_response_update (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)
 Handle authentication challenge for SIP UPDATE.
static int handle_sip_publish_initial (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const int expires)
static int handle_sip_publish_modify (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires)
static int handle_sip_publish_refresh (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires)
static int handle_sip_publish_remove (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag)
static int handle_t38_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v, int *maxdatagram)
 Handle T.38 configuration options common to users and peers.
const char * hangup_cause2sip (int cause)
 Convert Asterisk hangup causes to SIP codes.
int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes.
static int init_req (struct sip_request *req, int sipmethod, const char *recip)
 Initialize SIP request.
static int init_resp (struct sip_request *resp, const char *msg)
 Initialize SIP response, based on SIP request.
static int initialize_escs (void)
static void initialize_initreq (struct sip_pvt *p, struct sip_request *req)
 Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
static int initialize_udptl (struct sip_pvt *p)
static void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, const char *const explicit_uri)
 Initiate new SIP request to peer/user.
static const char * insecure2str (int mode)
 Convert Insecure setting to printable string.
static int interpret_t38_parameters (struct sip_pvt *p, const struct ast_control_t38_parameters *parameters)
 Helper function which updates T.38 capability information and triggers a reinvite.
static int is_method_allowed (unsigned int *allowed_methods, enum sipmethod method)
 Check if method is allowed for a device or a dialog.
static void list_route (struct sip_route *route)
 List all routes - mostly for debugging.
static int load_module (void)
 PBX load module - initialization.
static int local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, uint32_t seqno, int *nounlock)
 Find all call legs and bridge transferee with target called from handle_request_refer.
static void lws2sws (struct ast_str *data)
 Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
static void make_our_tag (char *tagbuf, size_t len)
 Make our SIP dialog tag.
static int manager_show_registry (struct mansession *s, const struct message *m)
 Show SIP registrations in the manager API.
static int manager_sip_qualify_peer (struct mansession *s, const struct message *m)
 Qualify SIP peers in the manager API.
static int manager_sip_show_peer (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sip_show_peers (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sipnotify (struct mansession *s, const struct message *m)
static int map_s_x (const struct _map_x_s *table, const char *s, int errorvalue)
 map from a string to an integer value, case insensitive. If no match is found, return errorvalue.
static const char * map_x_s (const struct _map_x_s *table, int x, const char *errorstring)
 map from an integer value to a string. If no match is found, return errorstring
static void mark_method_allowed (unsigned int *allowed_methods, enum sipmethod method)
static void mark_method_unallowed (unsigned int *allowed_methods, enum sipmethod method)
static void mark_parsed_methods (unsigned int *methods, char *methods_str)
static int match_and_cleanup_peer_sched (void *peerobj, void *arg, int flags)
static enum match_req_res match_req_to_dialog (struct sip_pvt *sip_pvt_ptr, struct match_req_args *arg)
static int method_match (enum sipmethod id, const char *name)
 returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
static void mwi_event_cb (const struct ast_event *event, void *userdata)
 Receive MWI events that we have subscribed to.
static void network_change_event_cb (const struct ast_event *, void *)
static int network_change_event_sched_cb (const void *data)
static void network_change_event_subscribe (void)
static void network_change_event_unsubscribe (void)
static struct sip_proxy * obproxy_get (struct sip_pvt *dialog, struct sip_peer *peer)
 Get default outbound proxy or global proxy.
static void on_dns_update_mwi (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
static void on_dns_update_peer (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
static void on_dns_update_registry (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
static unsigned int parse_allowed_methods (struct sip_request *req)
 parse the Allow header to see what methods the endpoint we are communicating with allows.
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, parse it.
static int parse_minse (const char *p_hdrval, int *const p_interval)
 Session-Timers: Function for parsing Min-SE header.
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req, char **name, char **number, int set_call_forward)
 Parse 302 Moved temporalily response.
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 Save contact header for 200 OK on INVITE.
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
 Parse contact header and save registration (peer registration).
static int parse_request (struct sip_request *req)
 Parse a SIP message.
static int parse_session_expires (const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref)
 Session-Timers: Function for parsing Session-Expires header.
static int parse_uri_legacy_check (char *uri, const char *scheme, char **user, char **pass, char **hostport, char **transport)
 parse uri in a way that allows semicolon stripping if legacy mode is enabled
static int peer_cmp_cb (void *obj, void *arg, int flags)
static int peer_dump_func (void *userobj, void *arg, int flags)
static int peer_hash_cb (const void *obj, const int flags)
static int peer_ipcmp_cb (void *obj, void *arg, int flags)
static int peer_ipcmp_cb_full (void *obj, void *arg, void *data, int flags)
static int peer_iphash_cb (const void *obj, const int flags)
static void peer_mailboxes_to_str (struct ast_str **mailbox_str, struct sip_peer *peer)
 list peer mailboxes to CLI
static int peer_markall_func (void *device, void *arg, int flags)
static void peer_sched_cleanup (struct sip_peer *peer)
static int peer_status (struct sip_peer *peer, char *status, int statuslen)
int peercomparefunc (const void *a, const void *b)
static int peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
unsigned int port_str2int (const char *pt, unsigned int standard)
 converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used.
static void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
 Print codec list from preference to CLI/manager.
static void print_group (int fd, ast_group_t group, int crlf)
 Print call group and pickup group.
static void proc_422_rsp (struct sip_pvt *p, struct sip_request *rsp)
 Handle 422 response to INVITE with session-timer requested.
static int proc_session_timer (const void *vp)
 Session-Timers: Process session refresh timeout event.
static int process_crypto (struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a)
static int process_sdp (struct sip_pvt *p, struct sip_request *req, int t38action)
 Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
static int process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec)
static int process_sdp_a_image (const char *a, struct sip_pvt *p)
static int process_sdp_a_sendonly (const char *a, int *sendonly)
static int process_sdp_a_text (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec)
static int process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec)
static int process_sdp_c (const char *c, struct ast_sockaddr *addr)
static int process_sdp_o (const char *o, struct sip_pvt *p)
static int process_via (struct sip_pvt *p, const struct sip_request *req)
 Process the Via header according to RFC 3261 section 18.2.2.
static int proxy_update (struct sip_proxy *proxy)
static int publish_expire (const void *data)
static void pvt_set_needdestroy (struct sip_pvt *pvt, const char *reason)
static struct sip_peer * realtime_peer (const char *newpeername, struct ast_sockaddr *addr, char *callbackexten, int devstate_only, int which_objects)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped.
static int realtime_peer_by_addr (const char **name, struct ast_sockaddr *addr, const char *ipaddr, const char *callbackexten, struct ast_variable **var, struct ast_variable **varregs)
static int realtime_peer_by_name (const char *const *name, struct ast_sockaddr *addr, const char *ipaddr, struct ast_variable **var, struct ast_variable **varregs)
static struct ast_variablerealtime_peer_get_sippeer_helper (const char **name, struct ast_variable **varregs)
static void realtime_update_peer (const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms)
 Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
static void receive_message (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
 Receive SIP MESSAGE method messages.
static void ref_proxy (struct sip_pvt *pvt, struct sip_proxy *proxy)
 maintain proper refcounts for a sip_pvt's outboundproxy
static const char * referstatus2str (enum referstatus rstatus)
 Convert transfer status to string.
static void reg_source_db (struct sip_peer *peer)
 Get registration details from Asterisk DB.
static void register_peer_exten (struct sip_peer *peer, int onoff)
 Automatically add peer extension to dial plan.
static int register_realtime_peers_with_callbackextens (void)
static enum check_auth_result register_verify (struct sip_pvt *p, struct ast_sockaddr *addr, struct sip_request *req, const char *uri)
 Verify registration of user
  • Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth
  • Registration requests are only matched with peers that are marked as "dynamic".

static struct sip_registry * registry_addref (struct sip_registry *reg, char *tag)
 Add object reference to SIP registry.
static void * registry_unref (struct sip_registry *reg, char *tag)
static const char * regstate2str (enum sipregistrystate regstate)
 Convert registration state status to string.
static int reload (void)
 Part of Asterisk module interface.
static int reload_config (enum channelreloadreason reason)
 Re-read SIP.conf config file.
static char * remove_uri_parameters (char *uri)
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply to authentication for outbound registrations
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, uint32_t seqno, int newbranch)
 Initialize a SIP request message (not the initial one in a dialog).
static int resp_needs_contact (const char *msg, enum sipmethod method)
 Test if this response needs a contact header.
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet.
static int restart_monitor (void)
 Start the channel monitor thread.
static void restart_session_timer (struct sip_pvt *p)
 Session-Timers: Restart session timer.
static int retrans_pkt (const void *data)
 Retransmit SIP message if no answer (Called from scheduler).
static int send_provisional_keepalive (const void *data)
static int send_provisional_keepalive_full (struct sip_pvt *pvt, int with_sdp)
static int send_provisional_keepalive_with_sdp (const void *data)
static int send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
static int send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
 Transmit response on SIP request.
static enum ast_cc_service_type service_string_to_service_type (const char *const service_string)
static int set_address_from_contact (struct sip_pvt *pvt)
 Change the other partys IP address based on given contact.
static void set_destination (struct sip_pvt *p, char *uri)
 Set destination from SIP URI.
static void set_insecure_flags (struct ast_flags *flags, const char *value, int lineno)
 Parse insecure= setting in sip.conf and set flags according to setting.
static int set_message_vars_from_req (struct ast_msg *msg, struct sip_request *req)
static void set_nonce_randdata (struct sip_pvt *p, int forceupdate)
 builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
static void set_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations.
static unsigned int set_pvt_allowed_methods (struct sip_pvt *pvt, struct sip_request *req)
static void set_socket_transport (struct sip_socket *socket, int transport)
static void set_t38_capabilities (struct sip_pvt *p)
 Set the global T38 capabilities on a SIP dialog structure.
static int setup_srtp (struct sip_srtp **srtp)
static int show_channels_cb (void *__cur, void *__arg, int flags)
 callback for show channel|subscription
static int show_chanstats_cb (void *__cur, void *__arg, int flags)
 Callback for show_chanstats.
static int sip_addheader (struct ast_channel *chan, const char *data)
 Add a SIP header to an outbound INVITE.
struct sip_pvt * sip_alloc (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, struct sip_request *req)
 Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference.
static void sip_alreadygone (struct sip_pvt *dialog)
 Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
void sip_auth_headers (enum sip_auth_type code, char **header, char **respheader)
 return the request and response header for a 401 or 407 code
static int sip_call (struct ast_channel *ast, const char *dest, int timeout)
 Initiate SIP call from PBX used from the dial() application.
int sip_cancel_destroy (struct sip_pvt *p)
 Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference.
static void sip_cc_agent_destructor (struct ast_cc_agent *agent)
static int sip_cc_agent_init (struct ast_cc_agent *agent, struct ast_channel *chan)
static int sip_cc_agent_recall (struct ast_cc_agent *agent)
static void sip_cc_agent_respond (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
static int sip_cc_agent_start_monitoring (struct ast_cc_agent *agent)
static int sip_cc_agent_start_offer_timer (struct ast_cc_agent *agent)
static int sip_cc_agent_status_request (struct ast_cc_agent *agent)
static int sip_cc_agent_stop_offer_timer (struct ast_cc_agent *agent)
static int sip_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id)
static void sip_cc_monitor_destructor (void *private_data)
static int sip_cc_monitor_request_cc (struct ast_cc_monitor *monitor, int *available_timer_id)
static int sip_cc_monitor_suspend (struct ast_cc_monitor *monitor)
static int sip_cc_monitor_unsuspend (struct ast_cc_monitor *monitor)
static int sip_check_authtimeout (time_t start)
 Check if the authtimeout has expired.
static char * sip_cli_notify (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Cli command to send SIP notify to peer.
static int sip_debug_test_addr (const struct ast_sockaddr *addr)
 See if we pass debug IP filter.
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output.
struct sip_pvt * sip_destroy (struct sip_pvt *p)
 Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers.
static void sip_destroy_fn (void *p)
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory.
static void sip_destroy_peer_fn (void *peer)
static int sip_devicestate (const char *data)
 Part of PBX channel interface.
void sip_digest_parser (char *c, struct digestkeys *keys)
 Takes the digest response and parses it.
static char * sip_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Turn on SIP debugging (CLI command).
static char * sip_do_debug_ip (int fd, const char *arg)
 Enable SIP Debugging for a single IP.
static char * sip_do_debug_peer (int fd, const char *arg)
 Turn on SIP debugging for a given peer.
static int sip_do_reload (enum channelreloadreason reason)
 Reload module.
static int sip_dtmfmode (struct ast_channel *chan, const char *data)
 Set the DTMFmode for an outbound SIP call (application).
static void sip_dump_history (struct sip_pvt *dialog)
 Dump SIP history to debug log file at end of lifespan for SIP dialog.
static int sip_epa_register (const struct epa_static_data *static_data)
static void sip_epa_unregister_all (void)
struct sip_peer * sip_find_peer (const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport)
 Locate device by name or ip address.
static struct sip_peer * sip_find_peer_by_ip_and_exten (struct ast_sockaddr *addr, char *callbackexten, int transport)
static struct sip_peer * sip_find_peer_full (const char *peer, struct ast_sockaddr *addr, char *callbackexten, int realtime, int which_objects, int devstate_only, int transport)
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
static const char * sip_get_callid (struct ast_channel *chan)
 Deliver SIP call ID for the call.
static int sip_get_cc_information (struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service)
static void sip_get_codec (struct ast_channel *chan, struct ast_format_cap *result)
const char * sip_get_header (const struct sip_request *req, const char *name)
 Get header from SIP request.
static enum ast_rtp_glue_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
const char * sip_get_transport (enum sip_transport t)
 Return transport as string.
static enum ast_rtp_glue_result sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
static struct ast_udptlsip_get_udptl_peer (struct ast_channel *chan)
static enum ast_rtp_glue_result sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
static void sip_handle_cc (struct sip_pvt *pvt, struct sip_request *req, enum ast_cc_service_type service)
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
static int sip_is_xml_parsable (void)
static int sip_monitor_instance_cmp_fn (void *obj, void *arg, int flags)
static void sip_monitor_instance_destructor (void *data)
static int sip_monitor_instance_hash_fn (const void *obj, const int flags)
static struct
sip_monitor_instance * 
sip_monitor_instance_init (int core_id, const char *const subscribe_uri, const char *const peername, const char *const device_name)
static int sip_msg_send (const struct ast_msg *msg, const char *to, const char *from)
static const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode.
static struct ast_channelsip_new (struct sip_pvt *i, int state, const char *title, const char *linkedid)
 Initiate a call in the SIP channel.
static int sip_notify_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_offer_timer_expire (const void *data)
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, uint32_t seqno, const char *park_exten, const char *park_context)
static void * sip_park_thread (void *stuff)
 Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure.
static int sip_pickup (struct ast_channel *chan)
 Pickup a call using the subsystem in features.c This is executed in a separate thread.
static void * sip_pickup_thread (void *stuff)
 SIP pickup support function Starts in a new thread, then pickup the call.
static void sip_poke_all_peers (void)
 Send a poke to all known peers.
static int sip_poke_noanswer (const void *data)
 React to lack of answer to Qualify poke.
static int sip_poke_peer (struct sip_peer *peer, int force)
 Check availability of peer, also keep NAT open.
static int sip_poke_peer_s (const void *data)
 Poke peer (send qualify to check if peer is alive and well).
static int sip_prepare_socket (struct sip_pvt *p)
static char * sip_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Remove temporary realtime objects from memory (CLI).
static struct ast_channelsip_pvt_lock_full (struct sip_pvt *pvt)
static char * sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Send an OPTIONS packet to a SIP peer.
static int sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen)
 Query an option on a SIP dialog.
static struct ast_framesip_read (struct ast_channel *ast)
 Read SIP RTP from channel.
static struct ast_sockaddrsip_real_dst (const struct sip_pvt *p)
 The real destination address for a write.
static const char * sip_reason_code_to_str (enum AST_REDIRECTING_REASON code)
static enum AST_REDIRECTING_REASON sip_reason_str_to_code (const char *text)
struct sip_peer * sip_ref_peer (struct sip_peer *peer, char *tag)
static int sip_refer_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_reg_timeout (const void *data)
 Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called.
static int sip_register (const char *value, int lineno)
 create sip_registry object from register=> line in sip.conf and link into reg container
static void sip_register_tests (void)
 SIP test registration.
static void sip_registry_destroy (struct sip_registry *reg)
 Destroy registry object Objects created with the register= statement in static configuration.
static int sip_reinvite_retry (const void *data)
 Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
static char * sip_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Force reload of module from cli.
static int sip_removeheader (struct ast_channel *chan, const char *data)
 Remove SIP headers added previously with SipAddHeader application.
static struct ast_channelsip_request_call (const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
static int sip_reregister (const void *data)
 Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways.
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
static const char * sip_sanitized_host (const char *host)
void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
void sip_scheddestroy_final (struct sip_pvt *p, int ms)
 Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits.
static void sip_send_all_mwi_subscriptions (void)
 Send all MWI subscriptions.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer, int cache_only)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
 Send message with Access-URL header, if this is an HTML URL only!
static int sip_sendtext (struct ast_channel *ast, const char *text)
static void sip_set_default_format_capabilities (struct ast_format_cap *cap)
static char * sip_set_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Enable/Disable SIP History logging (CLI).
static void sip_set_redirstr (struct sip_pvt *p, char *reason)
 Translate referring cause.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active)
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static int sip_setoption (struct ast_channel *chan, int option, void *data, int datalen)
 Set an option on a SIP dialog.
static char * sip_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show details of one active dialog.
static char * sip_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command.
static char * sip_show_channelstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 SIP show channelstats CLI (main function).
static char * sip_show_domains (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list local domains.
static char * sip_show_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show history details of one dialog.
static char * sip_show_inuse (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Command to show calls within limits set by call_limit.
static char * sip_show_mwi (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * sip_show_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 List all allocated SIP Objects (realtime or static).
static char * sip_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail.
static char * sip_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Show Peers command.
static char * sip_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show SIP Registry (registrations with other SIP proxies.
static char * sip_show_sched (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * sip_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 List global settings for the SIP channel.
static char * sip_show_tcp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show active TCP connections.
static char * sip_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one user in detail.
static char * sip_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static struct sip_st_dlg * sip_st_alloc (struct sip_pvt *const p)
 Allocate Session-Timers struct w/in dialog.
static int sip_standard_port (enum sip_transport type, int port)
 Returns the port to use for this socket.
static int sip_subscribe_mwi (const char *value, int lineno)
 Parse mwi=> line in sip.conf and add to list.
static void sip_subscribe_mwi_destroy (struct sip_subscription_mwi *mwi)
 Destroy MWI subscription object.
static int sip_subscribe_mwi_do (const void *data)
 Send a subscription or resubscription for MWI.
static int sip_t38_abort (const void *data)
 Called to deny a T38 reinvite if the core does not respond to our request.
static struct
ast_tcptls_session_instance
sip_tcp_locate (struct ast_sockaddr *s)
 Find thread for TCP/TLS session (based on IP/Port.
static void * sip_tcp_worker_fn (void *data)
 SIP TCP connection handler.
static void sip_tcptls_client_args_destructor (void *obj)
static int sip_tcptls_write (struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len)
 used to indicate to a tcptls thread that data is ready to be written
static struct sip_threadinfo * sip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport)
 creates a sip_threadinfo object and links it into the threadt table.
static void sip_threadinfo_destructor (void *obj)
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
void * sip_unref_peer (struct sip_peer *peer, char *tag)
static char * sip_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Unregister (force expiration) a SIP peer in the registry via CLI.
static void sip_unregister_tests (void)
 SIP test registration.
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP UDP socket.
static int sockaddr_is_null_or_any (const struct ast_sockaddr *addr)
static enum st_mode st_get_mode (struct sip_pvt *p, int no_cached)
 Get the session-timer mode.
static enum st_refresher st_get_refresher (struct sip_pvt *p)
 Get the entity (UAC or UAS) that's acting as the session-timer refresher.
static int st_get_se (struct sip_pvt *p, int max)
 Get Max or Min SE (session timer expiry).
static void start_session_timer (struct sip_pvt *p)
 Session-Timers: Start session timer.
static void state_notify_build_xml (int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto)
 Builds XML portion of NOTIFY messages for presence or dialog updates.
static const char * stmode2str (enum st_mode m)
static void stop_media_flows (struct sip_pvt *p)
 Immediately stop RTP, VRTP and UDPTL as applicable.
static void stop_session_timer (struct sip_pvt *p)
 Session-Timers: Stop session timer.
static int str2dtmfmode (const char *str)
 maps a string to dtmfmode, returns -1 on error
static enum st_mode str2stmode (const char *s)
static enum st_refresher str2strefresher (const char *s)
static const char * strefresher2str (enum st_refresher r)
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
static unsigned int t38_get_rate (enum ast_control_t38_rate rate)
 Get Max T.38 Transmission rate from T38 capabilities.
static void tcptls_packet_destructor (void *obj)
static struct sip_peer * temp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode).
static void temp_pvt_cleanup (void *)
static int temp_pvt_init (void *)
static char * terminate_uri (char *uri)
static int threadinfo_locate_cb (void *obj, void *arg, int flags)
static int threadt_cmp_cb (void *obj, void *arg, int flags)
static int threadt_hash_cb (const void *obj, const int flags)
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static int transmit_cc_notify (struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state)
static void transmit_fake_auth_response (struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.
static int transmit_info_with_aoc (struct sip_pvt *p, struct ast_aoc_decoded *decoded)
 Send SIP INFO advice of charge message.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init, const char *const explicit_uri)
 Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.
static int transmit_message (struct sip_pvt *p, int init, int auth)
 Transmit with SIP MESSAGE method.
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, const char *vmexten)
 Notify user of messages waiting in voicemail (RFC3842).
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
 Notify a transferring party of the status of transfer (RFC3515).
static int transmit_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp)
static int transmit_publish (struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri)
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()).
static int transmit_reinvite_with_sdp (struct sip_pvt *p, int t38version, int oldsdp)
 Transmit reinvite with SDP.
static int transmit_request (struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_minexpires (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append Min-Expires header, content length before transmitting response.
static int transmit_response_with_minse (struct sip_pvt *p, const char *msg, const struct sip_request *req, int minse_int)
 Transmit 422 response with Min-SE header (Session-Timers).
static int transmit_response_with_retry_after (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *seconds)
 Append Retry-After header field when transmitting response.
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp, int rpid)
 Used for 200 OK and 183 early media.
static int transmit_response_with_sip_etag (struct sip_pvt *p, const char *msg, const struct sip_request *req, struct sip_esc_entry *esc_entry, int need_new_etag)
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem (RFC3265).
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static void unlink_all_peers_from_tables (void)
static void unlink_marked_peers_from_tables (void)
static void unlink_peer_from_tables (struct sip_peer *peer)
static void unlink_peers_from_tables (peer_unlink_flag_t flag)
static int unload_module (void)
 PBX unload module API.
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.
static void update_connectedline (struct sip_pvt *p, const void *data, size_t datalen)
 Notify peer that the connected line has changed.
static void update_peer (struct sip_peer *p, int expire)
 Update peer data in database (if used).
static void update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp)
static void update_redirecting (struct sip_pvt *p, const void *data, size_t datalen)
 Send a provisional response indicating that a call was redirected.

Defines

#define SIP_PEDANTIC_DECODE(str)

Variables

static int authlimit = DEFAULT_AUTHLIMIT
static int authtimeout = DEFAULT_AUTHTIMEOUT
static int can_parse_xml
static unsigned int chan_idx
static const char config [] = "sip.conf"
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static unsigned int dumphistory
static int global_authfailureevents
static unsigned int global_autoframing
static int global_callcounter
static unsigned int global_cos_audio
static unsigned int global_cos_sip
static unsigned int global_cos_text
static unsigned int global_cos_video
static int global_dynamic_exclude_static = 0
static struct ast_jb_conf global_jbconf
static int global_match_auth_username
static int global_max_se
static int global_min_se
static int global_prematuremediafilter
static int global_qualify_gap
static int global_qualify_peers
static int global_qualifyfreq
static int global_reg_timeout
static int global_regattempts_max
static int global_relaxdtmf
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static char global_sdpowner [AST_MAX_EXTENSION]
static char global_sdpsession [AST_MAX_EXTENSION]
static int global_shrinkcallerid
static enum st_mode global_st_mode
static enum st_refresher global_st_refresher
static int global_store_sip_cause
static int global_t1
static int global_t1min
static int global_timer_b
static unsigned int global_tos_audio
static unsigned int global_tos_sip
static unsigned int global_tos_text
static unsigned int global_tos_video
static char global_useragent [AST_MAX_EXTENSION]
static struct invstate2stringtable invitestate2string []
 Readable descriptions of device states.
static int max_expiry = DEFAULT_MAX_EXPIRY
static int min_expiry = DEFAULT_MIN_EXPIRY
static int mwi_expiry = DEFAULT_MWI_EXPIRY
static const char notify_config [] = "sip_notify.conf"
static unsigned int recordhistory
static struct sip_settings sip_cfg
static struct cfsip_methods sip_methods []
 The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type.
static struct sip_reasons sip_reason_table []
 Diversion header reasons.
static struct cfsubscription_types subscription_types []
 Subscription types that we support. We support
  • dialoginfo updates (really device status, not dialog info as was the original intent of the standard)
  • SIMPLE presence used for device status
  • Voicemail notification subscriptions.

static int unauth_sessions = 0
DefaultSettings
Default setttings are used as a channel setting and as a default when configuring devices

static char default_callerid [AST_MAX_EXTENSION]
static char default_engine [256]
static char default_fromdomain [AST_MAX_EXTENSION]
static int default_fromdomainport
static char default_language [MAX_LANGUAGE]
static int default_maxcallbitrate
static char default_mohinterpret [MAX_MUSICCLASS]
static char default_mohsuggest [MAX_MUSICCLASS]
static char default_mwi_from [80]
static char default_notifymime [AST_MAX_EXTENSION]
static char default_parkinglot [AST_MAX_CONTEXT]
static struct ast_codec_pref default_prefs
static unsigned int default_primary_transport
static int default_qualify
static unsigned int default_transports
static char default_vmexten [AST_MAX_EXTENSION]
static char default_zone [MAX_TONEZONE_COUNTRY]


Detailed Description

Implementation of Session Initiation Protocol.

Author:
Mark Spencer <markster@digium.com>
See Also: Implementation of RFC 3261 - without S/MIME, and experimental TCP and TLS support Configuration file sip.conf

********** IMPORTANT *

Note:
TCP/TLS support is EXPERIMENTAL and WILL CHANGE. This applies to configuration settings, dialplan commands and dialplans apps/functions See SIP TCP and TLS support
******** General TODO:s
Todo:
Better support of forking
Todo:
VIA branch tag transaction checking
Todo:
Transaction support
******** Wishlist: Improvements

Overview of the handling of SIP sessions
The SIP channel handles several types of SIP sessions, or dialogs, not all of them being "telephone calls".
  • Incoming calls that will be sent to the PBX core
  • Outgoing calls, generated by the PBX
  • SIP subscriptions and notifications of states and voicemail messages
  • SIP registrations, both inbound and outbound
  • SIP peer management (peerpoke, OPTIONS)
  • SIP text messages
In the SIP channel, there's a list of active SIP dialogs, which includes all of these when they are active. "sip show channels" in the CLI will show most of these, excluding subscriptions which are shown by "sip show subscriptions"

incoming packets
Incoming packets are received in the monitoring thread, then handled by sipsock_read() for udp only. In tcp, packets are read by the tcp_helper thread. sipsock_read() function parses the packet and matches an existing dialog or starts a new SIP dialog.
sipsock_read sends the packet to handle_incoming(), that parses a bit more. If it is a response to an outbound request, the packet is sent to handle_response(). If it is a request, handle_incoming() sends it to one of a list of functions depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc sipsock_read locks the ast_channel if it exists (an active call) and unlocks it after we have processed the SIP message.

A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.

The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c

Outbound calls
Outbound calls are set up by the PBX through the sip_request_call() function. After that, they are activated by sip_call().
Hanging up
The PBX issues a hangup on both incoming and outgoing calls through the sip_hangup() function

Definition in file chan_sip.c.


Define Documentation

#define append_history ( p,
event,
fmt,
args...   )     append_history_full(p, "%-15s " fmt, event, ## args)

#define check_request_transport ( peer,
tmpl   ) 

generic function for determining if a correct transport is being used to contact a peer

this is done as a macro so that the "tmpl" var can be passed either a sip_request or a sip_peer

Definition at line 2321 of file chan_sip.c.

Referenced by create_addr_from_peer(), and register_verify().

#define CONTAINER_UNLINK ( container,
obj,
tag   ) 

Unlink the given object from the container and return TRUE if it was in the container.

Definition at line 7699 of file chan_sip.c.

Referenced by change_callid_pvt().

#define DATA_EXPORT_SIP_PEER ( MEMBER   ) 

Definition at line 31228 of file chan_sip.c.

#define FORMAT   "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n"

Definition at line 19016 of file chan_sip.c.

#define FORMAT   "%-30.30s %-12.12s %-10.10s %-10.10s\n"

Definition at line 19016 of file chan_sip.c.

#define FORMAT   "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n"

Definition at line 19016 of file chan_sip.c.

#define FORMAT   "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"

Definition at line 19016 of file chan_sip.c.

#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"

Definition at line 19016 of file chan_sip.c.

#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"

Definition at line 19016 of file chan_sip.c.

#define FORMAT   "%-47.47s %-9.9s %-6.6s\n"

Definition at line 19016 of file chan_sip.c.

#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"

Definition at line 19016 of file chan_sip.c.

#define FORMAT2   "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n"

Definition at line 19015 of file chan_sip.c.

#define FORMAT2   "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"

Definition at line 19015 of file chan_sip.c.

#define FORMAT2   "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"

Definition at line 19015 of file chan_sip.c.

#define FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-11s %-32.32s %s\n"

Definition at line 19015 of file chan_sip.c.

#define FORMAT2   "%-47.47s %9.9s %6.6s\n"

Definition at line 19015 of file chan_sip.c.

#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"

Definition at line 19015 of file chan_sip.c.

#define FORMAT3   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n"

Definition at line 19014 of file chan_sip.c.

Referenced by sip_show_channels().

#define FORMAT4   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n"

Definition at line 19013 of file chan_sip.c.

Referenced by show_channels_cb().

#define SIP_PEDANTIC_DECODE ( str   ) 

Value:

if (sip_cfg.pedanticsipchecking && !ast_strlen_zero(str)) { \
      ast_uri_decode(str, ast_uri_sip_user); \
   }  \

Definition at line 707 of file chan_sip.c.

Referenced by check_user_full(), get_also_info(), get_destination(), get_refer_info(), register_verify(), and sip_msg_send().

#define sip_pvt_lock (  )     ao2_lock(x)

#define sip_pvt_trylock (  )     ao2_trylock(x)

Definition at line 1119 of file chan_sip.c.

Referenced by dialog_checkrtp_cb(), dialog_needdestroy(), and sip_hangup().

#define sip_pvt_unlock (  )     ao2_unlock(x)

#define UNLINK ( element,
head,
prev   ) 

some list management macros.

Definition at line 1218 of file chan_sip.c.

Referenced by __sip_ack(), handle_request_cancel(), and retrans_pkt().


Enumeration Type Documentation

Enumerator:
SIP_REQ_MATCH 
SIP_REQ_NOT_MATCH 
SIP_REQ_LOOP_DETECTED 
SIP_REQ_FORKED 

Definition at line 8000 of file chan_sip.c.

08000                    {
08001    SIP_REQ_MATCH,
08002    SIP_REQ_NOT_MATCH,
08003    SIP_REQ_LOOP_DETECTED, /* multiple incoming requests with same call-id but different branch parameters have been detected */
08004    SIP_REQ_FORKED, /* An outgoing request has been forked as result of receiving two differing 200ok responses. */
08005 };

Enumerator:
SIP_PEERS_MARKED 
SIP_PEERS_ALL 

Definition at line 2886 of file chan_sip.c.

02886              {
02887    SIP_PEERS_MARKED,
02888    SIP_PEERS_ALL,
02889 } peer_unlink_flag_t;


Function Documentation

static const char * __get_header ( const struct sip_request *  req,
const char *  name,
int *  start 
) [static]

Definition at line 7460 of file chan_sip.c.

References ast_skip_blanks(), find_alias(), len(), match(), and sip_cfg.

07461 {
07462    /*
07463     * Technically you can place arbitrary whitespace both before and after the ':' in
07464     * a header, although RFC3261 clearly says you shouldn't before, and place just
07465     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was
07466     * a good idea to say you can do it, and if you can do it, why in the hell would.
07467     * you say you shouldn't.
07468     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
07469     * and we always allow spaces after that for compatibility.
07470     */
07471    const char *sname = find_alias(name, NULL);
07472    int x, len = strlen(name), slen = (sname ? 1 : 0);
07473    for (x = *start; x < req->headers; x++) {
07474       const char *header = REQ_OFFSET_TO_STR(req, header[x]);
07475       int smatch = 0, match = !strncasecmp(header, name, len);
07476       if (slen) {
07477          smatch = !strncasecmp(header, sname, slen);
07478       }
07479       if (match || smatch) {
07480          /* skip name */
07481          const char *r = header + (match ? len : slen );
07482          if (sip_cfg.pedanticsipchecking) {
07483             r = ast_skip_blanks(r);
07484          }
07485 
07486          if (*r == ':') {
07487             *start = x+1;
07488             return ast_skip_blanks(r+1);
07489          }
07490       }
07491    }
07492 
07493    /* Don't return NULL, so sip_get_header is always a valid pointer */
07494    return "";
07495 }

static void __init_sip_msg_buf ( void   )  [static]

Definition at line 16819 of file chan_sip.c.

16823 : RFC 3428 */

static void __init_ts_temp_pvt ( void   )  [static]

A per-thread temporary pvt structure.

Definition at line 1143 of file chan_sip.c.

01168 : The address we bind to */

static void __reg_module ( void   )  [static]

Definition at line 31726 of file chan_sip.c.

static int __set_address_from_contact ( const char *  fullcontact,
struct ast_sockaddr addr,
int  tcp 
) [static]

Definition at line 14335 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_strlen_zero(), get_transport_str2enum(), LOG_WARNING, and parse_uri_legacy_check().

Referenced by build_peer(), and set_address_from_contact().

14336 {
14337    char *hostport, *transport;
14338    char contact_buf[256];
14339    char *contact;
14340 
14341    /* Work on a copy */
14342    ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
14343    contact = contact_buf;
14344 
14345    /* 
14346     * We have only the part in <brackets> here so we just need to parse a SIP URI.
14347     *
14348     * Note: The outbound proxy could be using UDP between the proxy and Asterisk.
14349     * We still need to be able to send to the remote agent through the proxy.
14350     */
14351 
14352    if (parse_uri_legacy_check(contact, "sip:,sips:", &contact, NULL, &hostport,
14353             &transport)) {
14354       ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact);
14355    }
14356 
14357    /* XXX This could block for a long time XXX */
14358    /* We should only do this if it's a name, not an IP */
14359    /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records
14360       to find transport, port address and hostname. If there's a port number, we have to
14361       assume that the hostport part is a host name and only look for an A/AAAA record in DNS.
14362    */
14363 
14364    /* If we took in an invalid URI, hostport may not have been initialized */
14365    /* ast_sockaddr_resolve requires an initialized hostport string. */
14366    if (ast_strlen_zero(hostport)) {
14367       ast_log(LOG_WARNING, "Invalid URI: parse_uri failed to acquire hostport\n");
14368       return -1;
14369    }
14370 
14371    if (ast_sockaddr_resolve_first(addr, hostport, 0)) {
14372       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't "
14373          "resolve in DNS) : '%s'\n", hostport);
14374       return -1;
14375    }
14376 
14377    /* set port */
14378    if (!ast_sockaddr_port(addr)) {
14379       ast_sockaddr_set_port(addr,
14380                   (get_transport_str2enum(transport) ==
14381                    SIP_TRANSPORT_TLS ||
14382                    !strncasecmp(fullcontact, "sips", 4)) ?
14383                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
14384    }
14385 
14386    return 0;
14387 }

int __sip_ack ( struct sip_pvt *  p,
uint32_t  seqno,
int  resp,
int  sipmethod 
)

Acknowledges receipt of a packet and stops retransmission called with p locked.

Definition at line 3993 of file chan_sip.c.

References ast_debug, ast_free, ast_sched_del(), FALSE, ref_proxy(), sip_pvt_lock, sip_pvt_unlock, TRUE, and UNLINK.

Referenced by __sip_pretend_ack(), handle_incoming(), handle_request_invite(), handle_request_publish(), and handle_response().

03994 {
03995    struct sip_pkt *cur, *prev = NULL;
03996    const char *msg = "Not Found";   /* used only for debugging */
03997    int res = FALSE;
03998 
03999    /* If we have an outbound proxy for this dialog, then delete it now since
04000      the rest of the requests in this dialog needs to follow the routing.
04001      If obforcing is set, we will keep the outbound proxy during the whole
04002      dialog, regardless of what the SIP rfc says
04003    */
04004    if (p->outboundproxy && !p->outboundproxy->force){
04005       ref_proxy(p, NULL);
04006    }
04007 
04008    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
04009       if (cur->seqno != seqno || cur->is_resp != resp) {
04010          continue;
04011       }
04012       if (cur->is_resp || cur->method == sipmethod) {
04013          res = TRUE;
04014          msg = "Found";
04015          if (!resp && (seqno == p->pendinginvite)) {
04016             ast_debug(1, "Acked pending invite %u\n", p->pendinginvite);
04017             p->pendinginvite = 0;
04018          }
04019          if (cur->retransid > -1) {
04020             if (sipdebug)
04021                ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
04022          }
04023          /* This odd section is designed to thwart a
04024           * race condition in the packet scheduler. There are
04025           * two conditions under which deleting the packet from the
04026           * scheduler can fail.
04027           *
04028           * 1. The packet has been removed from the scheduler because retransmission
04029           * is being attempted. The problem is that if the packet is currently attempting
04030           * retransmission and we are at this point in the code, then that MUST mean
04031           * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
04032           * lock temporarily to allow retransmission.
04033           *
04034           * 2. The packet has reached its maximum number of retransmissions and has
04035           * been permanently removed from the packet scheduler. If this is the case, then
04036           * the packet's retransid will be set to -1. The atomicity of the setting and checking
04037           * of the retransid to -1 is ensured since in both cases p's lock is held.
04038           */
04039          while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
04040             sip_pvt_unlock(p);
04041             usleep(1);
04042             sip_pvt_lock(p);
04043          }
04044          UNLINK(cur, p->packets, prev);
04045          dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt");
04046          if (cur->data) {
04047             ast_free(cur->data);
04048          }
04049          ast_free(cur);
04050          break;
04051       }
04052    }
04053    ast_debug(1, "Stopping retransmission on '%s' of %s %u: Match %s\n",
04054       p->callid, resp ? "Response" : "Request", seqno, msg);
04055    return res;
04056 }

static int __sip_autodestruct ( const void *  data  )  [static]

Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref().

Definition at line 3857 of file chan_sip.c.

References __sip_pretend_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, ast_channel_unlock, ast_channel_unref, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup_with_cause(), dialog_unlink_all(), LOG_WARNING, method_match(), NONE, pvt_set_needdestroy(), sip_methods, sip_pvt_lock, sip_pvt_lock_full(), sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), and TRUE.

Referenced by sip_scheddestroy(), and sip_show_sched().

03858 {
03859    struct sip_pvt *p = (struct sip_pvt *)data;
03860    struct ast_channel *owner;
03861 
03862    /* If this is a subscription, tell the phone that we got a timeout */
03863    if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) {
03864       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
03865       p->subscribed = NONE;
03866       append_history(p, "Subscribestatus", "timeout");
03867       ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>");
03868       return 10000;  /* Reschedule this destruction so that we know that it's gone */
03869    }
03870 
03871    /* If there are packets still waiting for delivery, delay the destruction */
03872    if (p->packets) {
03873       if (!p->needdestroy) {
03874          char method_str[31];
03875          ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
03876          append_history(p, "ReliableXmit", "timeout");
03877          if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
03878             if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
03879                pvt_set_needdestroy(p, "autodestruct");
03880             }
03881          }
03882          return 10000;
03883       } else {
03884          /* They've had their chance to respond. Time to bail */
03885          __sip_pretend_ack(p);
03886       }
03887    }
03888 
03889    /* Reset schedule ID */
03890    p->autokillid = -1;
03891 
03892 
03893    /*
03894     * Lock both the pvt and the channel safely so that we can queue up a frame.
03895     */
03896    owner = sip_pvt_lock_full(p);
03897    if (owner) {
03898       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
03899       ast_queue_hangup_with_cause(owner, AST_CAUSE_PROTOCOL_ERROR);
03900       ast_channel_unlock(owner);
03901       ast_channel_unref(owner);
03902    } else if (p->refer && !p->alreadygone) {
03903       ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
03904       stop_media_flows(p);
03905       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
03906       append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid);
03907       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03908    } else {
03909       append_history(p, "AutoDestroy", "%s", p->callid);
03910       ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid);
03911       sip_pvt_unlock(p);
03912       dialog_unlink_all(p); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */
03913       sip_pvt_lock(p);
03914       /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */
03915       /* sip_destroy(p); */      /* Go ahead and destroy dialog. All attempts to recover is done */
03916       /* sip_destroy also absorbs the reference */
03917    }
03918 
03919    sip_pvt_unlock(p);
03920 
03921    dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
03922 
03923    return 0;
03924 }

void __sip_destroy ( struct sip_pvt *  p,
int  lockowner,
int  lockdialoglist 
)

Execute destruction of SIP dialog structure, release memory.

Definition at line 5821 of file chan_sip.c.

References ao2_ref, ao2_t_ref, ast_cc_config_params_destroy(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, ast_format_cap_destroy(), ast_free, ast_free_ha(), AST_LIST_REMOVE_HEAD, ast_rtp_instance_destroy(), AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose, deinit_req(), destroy_msg_headers(), free_old_route(), registry_unref(), sip_debug_test_pvt(), sip_dump_history(), sip_methods, sip_srtp_destroy(), sip_unref_peer(), stop_session_timer(), cfsip_methods::text, and update_call_counter().

Referenced by sip_destroy().

05822 {
05823    struct sip_request *req;
05824 
05825    /* Destroy Session-Timers if allocated */
05826    if (p->stimer) {
05827       p->stimer->quit_flag = 1;
05828       stop_session_timer(p);
05829       ast_free(p->stimer);
05830       p->stimer = NULL;
05831    }
05832 
05833    if (sip_debug_test_pvt(p))
05834       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
05835 
05836    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05837       update_call_counter(p, DEC_CALL_LIMIT);
05838       ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
05839    }
05840 
05841    /* Unlink us from the owner if we have one */
05842    if (p->owner) {
05843       if (lockowner)
05844          ast_channel_lock(p->owner);
05845       ast_debug(1, "Detaching from %s\n", ast_channel_name(p->owner));
05846       p->owner->tech_pvt = NULL;
05847       /* Make sure that the channel knows its backend is going away */
05848       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05849       if (lockowner)
05850          ast_channel_unlock(p->owner);
05851       /* Give the channel a chance to react before deallocation */
05852       usleep(1);
05853    }
05854 
05855    /* Remove link from peer to subscription of MWI */
05856    if (p->relatedpeer && p->relatedpeer->mwipvt)
05857       p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
05858    if (p->relatedpeer && p->relatedpeer->call == p)
05859       p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
05860    
05861    if (p->relatedpeer)
05862       p->relatedpeer = sip_unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy");
05863    
05864    if (p->registry) {
05865       if (p->registry->call == p)
05866          p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all");
05867       p->registry = registry_unref(p->registry, "delete p->registry");
05868    }
05869    
05870    if (p->mwi) {
05871       p->mwi->call = NULL;
05872    }
05873 
05874    if (dumphistory)
05875       sip_dump_history(p);
05876 
05877    if (p->options)
05878       ast_free(p->options);
05879 
05880    if (p->notify) {
05881       ast_variables_destroy(p->notify->headers);
05882       ast_free(p->notify->content);
05883       ast_free(p->notify);
05884    }
05885    if (p->rtp) {
05886       ast_rtp_instance_destroy(p->rtp);
05887    }
05888    if (p->vrtp) {
05889       ast_rtp_instance_destroy(p->vrtp);
05890    }
05891    if (p->trtp) {
05892       ast_rtp_instance_destroy(p->trtp);
05893    }
05894    if (p->udptl)
05895       ast_udptl_destroy(p->udptl);
05896    if (p->refer)
05897       ast_free(p->refer);
05898    if (p->route) {
05899       free_old_route(p->route);
05900       p->route = NULL;
05901    }
05902    deinit_req(&p->initreq);
05903 
05904    /* Clear history */
05905    if (p->history) {
05906       struct sip_history *hist;
05907       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
05908          ast_free(hist);
05909          p->history_entries--;
05910       }
05911       ast_free(p->history);
05912       p->history = NULL;
05913    }
05914 
05915    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
05916       ast_free(req);
05917    }
05918 
05919    if (p->chanvars) {
05920       ast_variables_destroy(p->chanvars);
05921       p->chanvars = NULL;
05922    }
05923 
05924    destroy_msg_headers(p);
05925 
05926    if (p->srtp) {
05927       sip_srtp_destroy(p->srtp);
05928       p->srtp = NULL;
05929    }
05930 
05931    if (p->vsrtp) {
05932       sip_srtp_destroy(p->vsrtp);
05933       p->vsrtp = NULL;
05934    }
05935 
05936    if (p->tsrtp) {
05937       sip_srtp_destroy(p->tsrtp);
05938       p->tsrtp = NULL;
05939    }
05940 
05941    if (p->directmediaha) {
05942       ast_free_ha(p->directmediaha);
05943       p->directmediaha = NULL;
05944    }
05945 
05946    ast_string_field_free_memory(p);
05947 
05948    ast_cc_config_params_destroy(p->cc_params);
05949 
05950    if (p->epa_entry) {
05951       ao2_ref(p->epa_entry, -1);
05952       p->epa_entry = NULL;
05953    }
05954 
05955    if (p->socket.tcptls_session) {
05956       ao2_ref(p->socket.tcptls_session, -1);
05957       p->socket.tcptls_session = NULL;
05958    }
05959 
05960    if (p->peerauth) {
05961       ao2_t_ref(p->peerauth, -1, "Removing active peer authentication");
05962       p->peerauth = NULL;
05963    }
05964 
05965    p->caps = ast_format_cap_destroy(p->caps);
05966    p->jointcaps = ast_format_cap_destroy(p->jointcaps);
05967    p->peercaps = ast_format_cap_destroy(p->peercaps);
05968    p->redircaps = ast_format_cap_destroy(p->redircaps);
05969    p->prefcaps = ast_format_cap_destroy(p->prefcaps);
05970 }

static int __sip_do_register ( struct sip_registry *  r  )  [static]

Register with SIP proxy.

Returns:
see __sip_xmit

Definition at line 13521 of file chan_sip.c.

References transmit_register().

Referenced by sip_reregister().

13522 {
13523    int res;
13524 
13525    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
13526    return res;
13527 }

void __sip_pretend_ack ( struct sip_pvt *  p  ) 

Pretend to ack all packets called with p locked.

Definition at line 4060 of file chan_sip.c.

References __sip_ack(), ast_log(), find_sip_method(), LOG_WARNING, sip_methods, and cfsip_methods::text.

Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), and sip_reg_timeout().

04061 {
04062    struct sip_pkt *cur = NULL;
04063 
04064    while (p->packets) {
04065       int method;
04066       if (cur == p->packets) {
04067          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
04068          return;
04069       }
04070       cur = p->packets;
04071       method = (cur->method) ? cur->method : find_sip_method(cur->data->str);
04072       __sip_ack(p, cur->seqno, cur->is_resp, method);
04073    }
04074 }

static enum sip_result __sip_reliable_xmit ( struct sip_pvt *  p,
uint32_t  seqno,
int  resp,
struct ast_str data,
int  fatal,
int  sipmethod 
) [static]

Todo:
According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited

Definition at line 3766 of file chan_sip.c.

References __sip_xmit(), append_history, ast_calloc, ast_debug, ast_free, ast_log(), AST_PTHREADT_NULL, AST_SCHED_DEL, AST_SCHED_REPLACE_VARIABLE, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_str_strlen(), ast_tvnow(), DEFAULT_RETRANS, LOG_ERROR, and retrans_pkt().

Referenced by send_request(), and send_response().

03767 {
03768    struct sip_pkt *pkt = NULL;
03769    int siptimer_a = DEFAULT_RETRANS;
03770    int xmitres = 0;
03771    int respid;
03772 
03773    if (sipmethod == SIP_INVITE) {
03774       /* Note this is a pending invite */
03775       p->pendinginvite = seqno;
03776    }
03777 
03778    /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */
03779    /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */
03780    /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */
03781    if (!(p->socket.type & SIP_TRANSPORT_UDP)) {
03782       xmitres = __sip_xmit(p, data);   /* Send packet */
03783       if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03784          append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)");
03785          return AST_FAILURE;
03786       } else {
03787          return AST_SUCCESS;
03788       }
03789    }
03790 
03791    if (!(pkt = ast_calloc(1, sizeof(*pkt)))) {
03792       return AST_FAILURE;
03793    }
03794    /* copy data, add a terminator and save length */
03795    if (!(pkt->data = ast_str_create(ast_str_strlen(data)))) {
03796       ast_free(pkt);
03797       return AST_FAILURE;
03798    }
03799    ast_str_set(&pkt->data, 0, "%s%s", data->str, "\0");
03800    /* copy other parameters from the caller */
03801    pkt->method = sipmethod;
03802    pkt->seqno = seqno;
03803    pkt->is_resp = resp;
03804    pkt->is_fatal = fatal;
03805    pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner");
03806    pkt->next = p->packets;
03807    p->packets = pkt; /* Add it to the queue */
03808    if (resp) {
03809       /* Parse out the response code */
03810       if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) {
03811          pkt->response_code = respid;
03812       }
03813    }
03814    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
03815    pkt->retransid = -1;
03816    if (pkt->timer_t1) {
03817       siptimer_a = pkt->timer_t1;
03818    }
03819 
03820    pkt->time_sent = ast_tvnow(); /* time packet was sent */
03821    pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */
03822 
03823    /* Schedule retransmission */
03824    AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1);
03825    if (sipdebug) {
03826       ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
03827    }
03828 
03829    xmitres = __sip_xmit(pkt->owner, pkt->data); /* Send packet */
03830 
03831    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03832       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03833       ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n");
03834       AST_SCHED_DEL(sched, pkt->retransid);
03835       p->packets = pkt->next;
03836       pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03837       ast_free(pkt->data);
03838       ast_free(pkt);
03839       return AST_FAILURE;
03840    } else {
03841       /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread
03842        * only wakes up every 1000ms by default, we have to poke the thread here to make
03843        * sure it successfully detects this must be retransmitted in less time than
03844        * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */
03845       if (monitor_thread != AST_PTHREADT_NULL) {
03846          pthread_kill(monitor_thread, SIGURG);
03847       }
03848       return AST_SUCCESS;
03849    }
03850 }

int __sip_semi_ack ( struct sip_pvt *  p,
uint32_t  seqno,
int  resp,
int  sipmethod 
)

Acks receipt of packet, keep it around (used for provisional responses).

Definition at line 4077 of file chan_sip.c.

References ast_debug, AST_SCHED_DEL, FALSE, method_match(), sip_methods, cfsip_methods::text, and TRUE.

Referenced by handle_response(), and sip_hangup().

04078 {
04079    struct sip_pkt *cur;
04080    int res = FALSE;
04081 
04082    for (cur = p->packets; cur; cur = cur->next) {
04083       if (cur->seqno == seqno && cur->is_resp == resp &&
04084          (cur->is_resp || method_match(sipmethod, cur->data->str))) {
04085          /* this is our baby */
04086          if (cur->retransid > -1) {
04087             if (sipdebug)
04088                ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
04089          }
04090          AST_SCHED_DEL(sched, cur->retransid);
04091          res = TRUE;
04092          break;
04093       }
04094    }
04095    ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %u: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found");
04096    return res;
04097 }

static int __sip_subscribe_mwi_do ( struct sip_subscription_mwi *  mwi  )  [static]

Actually setup an MWI subscription or resubscribe.

Definition at line 12855 of file chan_sip.c.

References ast_dnsmgr_lookup_cb(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, ASTOBJ_UNREF, bindaddr, build_contact(), build_via(), change_callid_pvt(), create_addr(), dialog_unlink_all(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), MAXHOSTNAMELEN, obproxy_get(), on_dns_update_mwi(), ref_proxy(), set_socket_transport(), sip_alloc(), sip_cfg, sip_subscribe_mwi_destroy(), and transmit_invite().

Referenced by sip_subscribe_mwi_do().

12856 {
12857    /* If we have no DNS manager let's do a lookup */
12858    if (!mwi->dnsmgr) {
12859       char transport[MAXHOSTNAMELEN];
12860       snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport));
12861 
12862       mwi->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
12863       ASTOBJ_REF(mwi); /* Add a ref for storing the mwi on the dnsmgr for updates */
12864       ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, mwi);
12865       if (!mwi->dnsmgr) {
12866          ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); /* dnsmgr disabled, remove reference */
12867       }
12868    }
12869 
12870    /* If we already have a subscription up simply send a resubscription */
12871    if (mwi->call) {
12872       transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL);
12873       return 0;
12874    }
12875    
12876    /* Create a dialog that we will use for the subscription */
12877    if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) {
12878       return -1;
12879    }
12880 
12881    ref_proxy(mwi->call, obproxy_get(mwi->call, NULL));
12882 
12883    if (!ast_sockaddr_port(&mwi->us) && mwi->portno) {
12884       ast_sockaddr_set_port(&mwi->us, mwi->portno);
12885    }
12886    
12887    /* Setup the destination of our subscription */
12888    if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0, NULL)) {
12889       dialog_unlink_all(mwi->call);
12890       mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all");
12891       return 0;
12892    }
12893 
12894    mwi->call->expiry = mwi_expiry;
12895    
12896    if (!mwi->dnsmgr && mwi->portno) {
12897       ast_sockaddr_set_port(&mwi->call->sa, mwi->portno);
12898       ast_sockaddr_set_port(&mwi->call->recv, mwi->portno);
12899    } else {
12900       mwi->portno = ast_sockaddr_port(&mwi->call->sa);
12901    }
12902    
12903    /* Set various other information */
12904    if (!ast_strlen_zero(mwi->authuser)) {
12905       ast_string_field_set(mwi->call, peername, mwi->authuser);
12906       ast_string_field_set(mwi->call, authname, mwi->authuser);
12907       ast_string_field_set(mwi->call, fromuser, mwi->authuser);
12908    } else {
12909       ast_string_field_set(mwi->call, peername, mwi->username);
12910       ast_string_field_set(mwi->call, authname, mwi->username);
12911       ast_string_field_set(mwi->call, fromuser, mwi->username);
12912    }
12913    ast_string_field_set(mwi->call, username, mwi->username);
12914    if (!ast_strlen_zero(mwi->secret)) {
12915       ast_string_field_set(mwi->call, peersecret, mwi->secret);
12916    }
12917    set_socket_transport(&mwi->call->socket, mwi->transport);
12918    mwi->call->socket.port = htons(mwi->portno);
12919    ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call);
12920    build_contact(mwi->call);
12921    build_via(mwi->call);
12922 
12923    /* Change the dialog callid. */
12924    change_callid_pvt(mwi->call, NULL);
12925 
12926    ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING);
12927    
12928    /* Associate the call with us */
12929    mwi->call->mwi = ASTOBJ_REF(mwi);
12930 
12931    mwi->call->subscribed = MWI_NOTIFICATION;
12932 
12933    /* Actually send the packet */
12934    transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL);
12935 
12936    return 0;
12937 }

static int __sip_xmit ( struct sip_pvt *  p,
struct ast_str data 
) [static]

Definition at line 3364 of file chan_sip.c.

References ast_debug, ast_log(), ast_sendto(), ast_sockaddr_stringify(), ast_str_strlen(), errno, get_transport_pvt(), LOG_WARNING, sip_prepare_socket(), sip_real_dst(), and sip_tcptls_write().

Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().

03365 {
03366    int res = 0;
03367    const struct ast_sockaddr *dst = sip_real_dst(p);
03368 
03369    ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", data->str, get_transport_pvt(p), ast_sockaddr_stringify(dst));
03370 
03371    if (sip_prepare_socket(p) < 0) {
03372       return XMIT_ERROR;
03373    }
03374 
03375    if (p->socket.type == SIP_TRANSPORT_UDP) {
03376       res = ast_sendto(p->socket.fd, data->str, ast_str_strlen(data), 0, dst);
03377    } else if (p->socket.tcptls_session) {
03378       res = sip_tcptls_write(p->socket.tcptls_session, data->str, ast_str_strlen(data));
03379    } else {
03380       ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n");
03381       return XMIT_ERROR;
03382    }
03383 
03384    if (res == -1) {
03385       switch (errno) {
03386       case EBADF:    /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
03387       case EHOSTUNREACH:   /* Host can't be reached */
03388       case ENETDOWN:    /* Interface down */
03389       case ENETUNREACH: /* Network failure */
03390       case ECONNREFUSED:      /* ICMP port unreachable */
03391          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
03392       }
03393    }
03394    if (res != ast_str_strlen(data)) {
03395       ast_log(LOG_WARNING, "sip_xmit of %p (len %zu) to %s returned %d: %s\n", data, ast_str_strlen(data), ast_sockaddr_stringify(dst), res, strerror(errno));
03396    }
03397 
03398    return res;
03399 }

static int __transmit_response ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
enum xmittype  reliable 
) [static]

Base transmit response function.

Definition at line 10732 of file chan_sip.c.

References add_cc_call_info_to_response(), add_diversion_header(), add_header(), add_rpid(), ast_cause2str(), ast_clear_flag, ast_log(), ast_test_flag, hangup_sip2cause(), LOG_WARNING, respprep(), send_response(), and sip_get_header().

Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().

10733 {
10734    struct sip_request resp;
10735    uint32_t seqno = 0;
10736 
10737    if (reliable && (sscanf(sip_get_header(req, "CSeq"), "%30u ", &seqno) != 1)) {
10738       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", sip_get_header(req, "CSeq"));
10739       return -1;
10740    }
10741    respprep(&resp, p, msg, req);
10742 
10743    if (ast_test_flag(&p->flags[0], SIP_SENDRPID)
10744          && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND)
10745          && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) {
10746       ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND);
10747       add_rpid(&resp, p);
10748    }
10749    if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) {
10750       add_cc_call_info_to_response(p, &resp);
10751    }
10752 
10753    /* If we are sending a 302 Redirect we can add a diversion header if the redirect information is set */
10754    if (!strncmp(msg, "302", 3)) {
10755       add_diversion_header(&resp, p);
10756    }
10757 
10758    /* If we are cancelling an incoming invite for some reason, add information
10759       about the reason why we are doing this in clear text */
10760    if (p->method == SIP_INVITE && msg[0] != '1') {
10761       char buf[20];
10762 
10763       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) {
10764          int hangupcause = 0;
10765 
10766          if (p->owner && p->owner->hangupcause) {
10767             hangupcause = p->owner->hangupcause;
10768          } else if (p->hangupcause) {
10769             hangupcause = p->hangupcause;
10770          } else {
10771             int respcode;
10772             if (sscanf(msg, "%30d ", &respcode))
10773                hangupcause = hangup_sip2cause(respcode);
10774          }
10775 
10776          if (hangupcause) {
10777             sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f);
10778             add_header(&resp, "Reason", buf);
10779          }
10780       }
10781 
10782       if (p->owner && p->owner->hangupcause) {
10783          add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
10784          snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
10785          add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
10786       }
10787    }
10788    return send_response(p, &resp, reliable, seqno);
10789 }

static void __unreg_module ( void   )  [static]

Definition at line 31726 of file chan_sip.c.

static char * _sip_qualify_peer ( int  type,
int  fd,
struct mansession s,
const struct message m,
int  argc,
const char *  argv[] 
) [static]

Send qualify message to peer from cli or manager. Mostly for debugging.

Definition at line 18009 of file chan_sip.c.

References ast_cli(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, sip_find_peer(), sip_poke_peer(), sip_unref_peer(), and TRUE.

Referenced by manager_sip_qualify_peer(), and sip_qualify_peer().

18010 {
18011    struct sip_peer *peer;
18012    int load_realtime;
18013 
18014    if (argc < 4)
18015       return CLI_SHOWUSAGE;
18016 
18017    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
18018    if ((peer = sip_find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) {
18019       sip_poke_peer(peer, 1);
18020       sip_unref_peer(peer, "qualify: done with peer");
18021    } else if (type == 0) {
18022       ast_cli(fd, "Peer '%s' not found\n", argv[3]);
18023    } else {
18024       astman_send_error(s, m, "Peer not found");
18025    }
18026    return CLI_SUCCESS;
18027 }

static char * _sip_show_peer ( int  type,
int  fd,
struct mansession s,
const struct message m,
int  argc,
const char *  argv[] 
) [static]

Show one peer in detail (main function).

Definition at line 18094 of file chan_sip.c.

References allowoverlap2str(), ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), AST_CLI_YESNO, ast_codec_pref_index(), AST_CODEC_PREF_SIZE, ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_TRAVERSE, ast_print_group(), ast_sched_when(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, comedia_string(), dtmfmode2str(), FALSE, faxec2str(), force_rport_string(), get_transport_list(), insecure2str(), ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), print_codec_to_cli(), print_group(), S_OR, sip_cfg, sip_find_peer(), sip_get_transport(), sip_unref_peer(), status, stmode2str(), strefresher2str(), text, transfermode2str(), TRUE, and ast_variable::value.

Referenced by manager_sip_show_peer(), and sip_show_peer().

18095 {
18096    char status[30] = "";
18097    char cbuf[256];
18098    struct sip_peer *peer;
18099    char codec_buf[512];
18100    struct ast_codec_pref *pref;
18101    struct ast_variable *v;
18102    int x = 0, load_realtime;
18103    struct ast_format codec;
18104    int realtimepeers;
18105 
18106    realtimepeers = ast_check_realtime("sippeers");
18107 
18108    if (argc < 4)
18109       return CLI_SHOWUSAGE;
18110 
18111    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
18112    peer = sip_find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0);
18113 
18114    if (s) {    /* Manager */
18115       if (peer) {
18116          const char *id = astman_get_header(m, "ActionID");
18117 
18118          astman_append(s, "Response: Success\r\n");
18119          if (!ast_strlen_zero(id))
18120             astman_append(s, "ActionID: %s\r\n", id);
18121       } else {
18122          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]);
18123          astman_send_error(s, m, cbuf);
18124          return CLI_SUCCESS;
18125       }
18126    }
18127    if (peer && type==0 ) { /* Normal listing */
18128       struct ast_str *mailbox_str = ast_str_alloca(512);
18129       struct sip_auth_container *credentials;
18130 
18131       ao2_lock(peer);
18132       credentials = peer->auth;
18133       if (credentials) {
18134          ao2_t_ref(credentials, +1, "Ref peer auth for show");
18135       }
18136       ao2_unlock(peer);
18137 
18138       ast_cli(fd, "\n\n");
18139       ast_cli(fd, "  * Name       : %s\n", peer->name);
18140       ast_cli(fd, "  Description  : %s\n", peer->description);
18141       if (realtimepeers) { /* Realtime is enabled */
18142          ast_cli(fd, "  Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No");
18143       }
18144       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
18145       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
18146       ast_cli(fd, "  Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>");
18147       if (credentials) {
18148          struct sip_auth *auth;
18149 
18150          AST_LIST_TRAVERSE(&credentials->list, auth, node) {
18151             ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s %s\n",
18152                auth->realm,
18153                auth->username,
18154                !ast_strlen_zero(auth->secret)
18155                   ? "<Secret set>"
18156                   : (!ast_strlen_zero(auth->md5secret)
18157                      ? "<MD5secret set>" : "<Not set>"));
18158          }
18159          ao2_t_ref(credentials, -1, "Unref peer auth for show");
18160       }
18161       ast_cli(fd, "  Context      : %s\n", peer->context);
18162       ast_cli(fd, "  Record On feature : %s\n", peer->record_on_feature);
18163       ast_cli(fd, "  Record Off feature : %s\n", peer->record_off_feature);
18164       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
18165       ast_cli(fd, "  Language     : %s\n", peer->language);
18166       ast_cli(fd, "  Tonezone     : %s\n", peer->zone[0] != '\0' ? peer->zone : "<Not set>");
18167       if (!ast_strlen_zero(peer->accountcode))
18168          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
18169       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
18170       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
18171       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
18172       if (!ast_strlen_zero(peer->fromuser))
18173          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
18174       if (!ast_strlen_zero(peer->fromdomain))
18175          ast_cli(fd, "  FromDomain   : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
18176       ast_cli(fd, "  Callgroup    : ");
18177       print_group(fd, peer->callgroup, 0);
18178       ast_cli(fd, "  Pickupgroup  : ");
18179       print_group(fd, peer->pickupgroup, 0);
18180       peer_mailboxes_to_str(&mailbox_str, peer);
18181       ast_cli(fd, "  MOH Suggest  : %s\n", peer->mohsuggest);
18182       ast_cli(fd, "  Mailbox      : %s\n", mailbox_str->str);
18183       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
18184       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
18185       ast_cli(fd, "  Max forwards : %d\n", peer->maxforwards);
18186       if (peer->busy_level)
18187          ast_cli(fd, "  Busy level   : %d\n", peer->busy_level);
18188       ast_cli(fd, "  Dynamic      : %s\n", AST_CLI_YESNO(peer->host_dynamic));
18189       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
18190       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
18191       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
18192       ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
18193       ast_cli(fd, "  Force rport  : %s\n", force_rport_string(peer->flags));
18194       ast_cli(fd, "  Symmetric RTP: %s\n", comedia_string(peer->flags));
18195       ast_cli(fd, "  ACL          : %s\n", AST_CLI_YESNO(peer->ha != NULL));
18196       ast_cli(fd, "  DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL));
18197       ast_cli(fd, "  T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
18198       ast_cli(fd, "  T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
18199       ast_cli(fd, "  T.38 MaxDtgrm: %d\n", peer->t38_maxdatagram);
18200       ast_cli(fd, "  DirectMedia  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)));
18201       ast_cli(fd, "  PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)));
18202       ast_cli(fd, "  User=Phone   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)));
18203       ast_cli(fd, "  Video Support: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) || ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS)));
18204       ast_cli(fd, "  Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)));
18205       ast_cli(fd, "  Ign SDP ver  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION)));
18206       ast_cli(fd, "  Trust RPID   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID)));
18207       ast_cli(fd, "  Send RPID    : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID)));
18208       ast_cli(fd, "  Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
18209       ast_cli(fd, "  Overlap dial : %s\n", allowoverlap2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP)));
18210       if (peer->outboundproxy)
18211          ast_cli(fd, "  Outb. proxy  : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name,
18212                      peer->outboundproxy->force ? "(forced)" : "");
18213 
18214       /* - is enumerated */
18215       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
18216       ast_cli(fd, "  Timer T1     : %d\n", peer->timer_t1);
18217       ast_cli(fd, "  Timer B      : %d\n", peer->timer_b);
18218       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
18219       ast_cli(fd, "  Addr->IP     : %s\n", ast_sockaddr_stringify(&peer->addr));
18220       ast_cli(fd, "  Defaddr->IP  : %s\n", ast_sockaddr_stringify(&peer->defaddr));
18221       ast_cli(fd, "  Prim.Transp. : %s\n", sip_get_transport(peer->socket.type));
18222       ast_cli(fd, "  Allowed.Trsp : %s\n", get_transport_list(peer->transports));
18223       if (!ast_strlen_zero(sip_cfg.regcontext))
18224          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
18225       ast_cli(fd, "  Def. Username: %s\n", peer->username);
18226       ast_cli(fd, "  SIP Options  : ");
18227       if (peer->sipoptions) {
18228          int lastoption = -1;
18229          for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
18230             if (sip_options[x].id != lastoption) {
18231                if (peer->sipoptions & sip_options[x].id)
18232                   ast_cli(fd, "%s ", sip_options[x].text);
18233                lastoption = x;
18234             }
18235          }
18236       } else
18237          ast_cli(fd, "(none)");
18238 
18239       ast_cli(fd, "\n");
18240       ast_cli(fd, "  Codecs       : ");
18241       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->caps);
18242       ast_cli(fd, "%s\n", codec_buf);
18243       ast_cli(fd, "  Codec Order  : (");
18244       print_codec_to_cli(fd, &peer->prefs);
18245       ast_cli(fd, ")\n");
18246 
18247       ast_cli(fd, "  Auto-Framing :  %s \n", AST_CLI_YESNO(peer->autoframing));
18248       ast_cli(fd, "  Status       : ");
18249       peer_status(peer, status, sizeof(status));
18250       ast_cli(fd, "%s\n", status);
18251       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
18252       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
18253       ast_cli(fd, "  Qualify Freq : %d ms\n", peer->qualifyfreq);
18254       if (peer->chanvars) {
18255          ast_cli(fd, "  Variables    :\n");
18256          for (v = peer->chanvars ; v ; v = v->next)
18257             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
18258       }
18259 
18260       ast_cli(fd, "  Sess-Timers  : %s\n", stmode2str(peer->stimer.st_mode_oper));
18261       ast_cli(fd, "  Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref));
18262       ast_cli(fd, "  Sess-Expires : %d secs\n", peer->stimer.st_max_se);
18263       ast_cli(fd, "  Min-Sess     : %d secs\n", peer->stimer.st_min_se);
18264       ast_cli(fd, "  RTP Engine   : %s\n", peer->engine);
18265       ast_cli(fd, "  Parkinglot   : %s\n", peer->parkinglot);
18266       ast_cli(fd, "  Use Reason   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)));
18267       ast_cli(fd, "  Encryption   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP)));
18268       ast_cli(fd, "\n");
18269       peer = sip_unref_peer(peer, "sip_show_peer: sip_unref_peer: done with peer ptr");
18270    } else  if (peer && type == 1) { /* manager listing */
18271       char buffer[256];
18272       struct ast_str *mailbox_str = ast_str_alloca(512);
18273       astman_append(s, "Channeltype: SIP\r\n");
18274       astman_append(s, "ObjectName: %s\r\n", peer->name);
18275       astman_append(s, "ChanObjectType: peer\r\n");
18276       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
18277       astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y");
18278       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
18279       astman_append(s, "Context: %s\r\n", peer->context);
18280       astman_append(s, "Language: %s\r\n", peer->language);
18281       astman_append(s, "ToneZone: %s\r\n", peer->zone[0] != '\0' ? peer->zone : "<Not set>");
18282       if (!ast_strlen_zero(peer->accountcode))
18283          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
18284       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
18285       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
18286       if (!ast_strlen_zero(peer->fromuser))
18287          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
18288       if (!ast_strlen_zero(peer->fromdomain))
18289          astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
18290       astman_append(s, "Callgroup: ");
18291       astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup));
18292       astman_append(s, "Pickupgroup: ");
18293       astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup));
18294       astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest);
18295       peer_mailboxes_to_str(&mailbox_str, peer);
18296       astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str);
18297       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
18298       astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards);
18299       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
18300       astman_append(s, "Busy-level: %d\r\n", peer->busy_level);
18301       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
18302       astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N");
18303       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
18304       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire));
18305       astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
18306       astman_append(s, "SIP-Forcerport: %s\r\n", ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT) ?
18307             (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "A" : "a") :
18308             (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "Y" : "N"));
18309       astman_append(s, "SIP-Comedia: %s\r\n", ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA) ?
18310             (ast_test_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP) ? "A" : "a") :
18311             (ast_test_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP) ? "Y" : "N"));
18312       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
18313       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N"));
18314       astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N"));
18315       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
18316       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
18317       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
18318       astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N"));
18319       astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N"));
18320       astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
18321       astman_append(s, "SIP-T.38MaxDtgrm: %d\r\n", peer->t38_maxdatagram);
18322       astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper));
18323       astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref));
18324       astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se);
18325       astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se);
18326       astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine);
18327       astman_append(s, "SIP-Encryption: %s\r\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP) ? "Y" : "N");
18328 
18329       /* - is enumerated */
18330       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
18331       astman_append(s, "ToHost: %s\r\n", peer->tohost);
18332       astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr));
18333       astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_sockaddr_stringify_addr(&peer->defaddr), ast_sockaddr_port(&peer->defaddr));
18334       astman_append(s, "Default-Username: %s\r\n", peer->username);
18335       if (!ast_strlen_zero(sip_cfg.regcontext))
18336          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
18337       astman_append(s, "Codecs: ");
18338       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->caps);
18339       astman_append(s, "%s\r\n", codec_buf);
18340       astman_append(s, "CodecOrder: ");
18341       pref = &peer->prefs;
18342       for(x = 0; x < AST_CODEC_PREF_SIZE ; x++) {
18343          if (!(ast_codec_pref_index(pref, x, &codec))) {
18344             break;
18345          }
18346          astman_append(s, "%s", ast_getformatname(&codec));
18347          if ((x < (AST_CODEC_PREF_SIZE - 1)) && ast_codec_pref_index(pref, x+1, &codec))
18348             astman_append(s, ",");
18349       }
18350 
18351       astman_append(s, "\r\n");
18352       astman_append(s, "Status: ");
18353       peer_status(peer, status, sizeof(status));
18354       astman_append(s, "%s\r\n", status);
18355       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
18356       astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact);
18357       astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq);
18358       astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot);
18359       if (peer->chanvars) {
18360          for (v = peer->chanvars ; v ; v = v->next) {
18361             astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value);
18362          }
18363       }
18364       astman_append(s, "SIP-Use-Reason-Header: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N");
18365       astman_append(s, "Description: %s\r\n", peer->description);
18366 
18367       peer = sip_unref_peer(peer, "sip_show_peer: sip_unref_peer: done with peer");
18368 
18369    } else {
18370       ast_cli(fd, "Peer %s not found.\n", argv[3]);
18371       ast_cli(fd, "\n");
18372    }
18373 
18374    return CLI_SUCCESS;
18375 }

static char * _sip_show_peers ( int  fd,
int *  total,
struct mansession s,
const struct message m,
int  argc,
const char *  argv[] 
) [static]

Execute sip show peers command.

Definition at line 17355 of file chan_sip.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_calloc, ast_check_realtime(), ast_cli(), ast_copy_string(), ast_free, ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, FORMAT2, id, name, peer_status(), peercomparefunc(), sip_unref_peer(), status, and TRUE.

Referenced by manager_sip_show_peers(), and sip_show_peers().

17356 {
17357    regex_t regexbuf;
17358    int havepattern = FALSE;
17359    struct sip_peer *peer;
17360    struct ao2_iterator i;
17361 
17362 /* the last argument is left-aligned, so we don't need a size anyways */
17363 #define FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-11s %-32.32s %s\n"
17364 
17365    char name[256];
17366    int total_peers = 0;
17367    int peers_mon_online = 0;
17368    int peers_mon_offline = 0;
17369    int peers_unmon_offline = 0;
17370    int peers_unmon_online = 0;
17371    const char *id;
17372    char idtext[256] = "";
17373    int realtimepeers;
17374    int objcount = ao2_container_count(peers);
17375    struct sip_peer **peerarray;
17376    int k;
17377 
17378    realtimepeers = ast_check_realtime("sippeers");
17379    peerarray = ast_calloc(sizeof(struct sip_peer *), objcount);
17380 
17381    if (s) { /* Manager - get ActionID */
17382       id = astman_get_header(m, "ActionID");
17383       if (!ast_strlen_zero(id))
17384          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
17385    }
17386 
17387    switch (argc) {
17388    case 5:
17389       if (!strcasecmp(argv[3], "like")) {
17390          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
17391             return CLI_SHOWUSAGE;
17392          havepattern = TRUE;
17393       } else
17394          return CLI_SHOWUSAGE;
17395    case 3:
17396       break;
17397    default:
17398       return CLI_SHOWUSAGE;
17399    }
17400 
17401    if (!s) /* Normal list */
17402       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", "Description", (realtimepeers ? "Realtime" : ""));
17403 
17404    i = ao2_iterator_init(peers, 0);
17405    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
17406       ao2_lock(peer);
17407 
17408       if (!(peer->type & SIP_TYPE_PEER)) {
17409          ao2_unlock(peer);
17410          sip_unref_peer(peer, "unref peer because it's actually a user");
17411          continue;
17412       }
17413 
17414       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
17415          objcount--;
17416          ao2_unlock(peer);
17417          sip_unref_peer(peer, "toss iterator peer ptr before continue");
17418          continue;
17419       }
17420 
17421       peerarray[total_peers++] = peer;
17422       ao2_unlock(peer);
17423    }
17424    ao2_iterator_destroy(&i);
17425 
17426    qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc);
17427 
17428    for(k=0; k < total_peers; k++) {
17429       char status[20] = "";
17430       char srch[2000];
17431       char pstatus;
17432 
17433       /*
17434        * tmp_port and tmp_host store copies of ast_sockaddr_stringify strings since the
17435        * string pointers for that function aren't valid between subsequent calls to
17436        * ast_sockaddr_stringify functions
17437        */
17438       char *tmp_port;
17439       char *tmp_host;
17440 
17441       peer = peerarray[k];
17442 
17443       tmp_port = ast_sockaddr_isnull(&peer->addr) ?
17444          "0" : ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
17445 
17446       tmp_host = ast_sockaddr_isnull(&peer->addr) ?
17447          "(Unspecified)" : ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
17448 
17449       ao2_lock(peer);
17450       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
17451          ao2_unlock(peer);
17452          peer = peerarray[k] = sip_unref_peer(peer, "toss iterator peer ptr before continue");
17453          continue;
17454       }
17455 
17456       if (!ast_strlen_zero(peer->username) && !s)
17457          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
17458       else
17459          ast_copy_string(name, peer->name, sizeof(name));
17460 
17461       pstatus = peer_status(peer, status, sizeof(status));
17462       if (pstatus == 1)
17463          peers_mon_online++;
17464       else if (pstatus == 0)
17465          peers_mon_offline++;
17466       else {
17467          if (ast_sockaddr_isnull(&peer->addr) ||
17468              !ast_sockaddr_port(&peer->addr)) {
17469             peers_unmon_offline++;
17470          } else {
17471             peers_unmon_online++;
17472          }
17473       }
17474 
17475       snprintf(srch, sizeof(srch), FORMAT2, name,
17476          tmp_host,
17477          peer->host_dynamic ? " D " : "   ", /* Dynamic or not? */
17478          ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT) ?
17479             ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " A " : " a " :
17480             ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : "   ", /* NAT=yes? */
17481          peer->ha ? " A " : "   ",  /* permit/deny */
17482          tmp_port, status,
17483          peer->description ? peer->description : "",
17484          realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
17485 
17486       if (!s)  {/* Normal CLI list */
17487          ast_cli(fd, FORMAT2, name,
17488          tmp_host,
17489          peer->host_dynamic ? " D " : "   ", /* Dynamic or not? */
17490          ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT) ?
17491             ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " A " : " a " :
17492             ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : "   ", /* NAT=yes? */
17493          peer->ha ? " A " : "   ",       /* permit/deny */
17494          tmp_port, status,
17495          peer->description ? peer->description : "",
17496          realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
17497       } else { /* Manager format */
17498          /* The names here need to be the same as other channels */
17499          astman_append(s,
17500          "Event: PeerEntry\r\n%s"
17501          "Channeltype: SIP\r\n"
17502          "ObjectName: %s\r\n"
17503          "ChanObjectType: peer\r\n" /* "peer" or "user" */
17504          "IPaddress: %s\r\n"
17505          "IPport: %s\r\n"
17506          "Dynamic: %s\r\n"
17507          "AutoForcerport: %s\r\n"
17508          "Forcerport: %s\r\n"
17509          "AutoComedia: %s\r\n"
17510          "Comedia: %s\r\n"
17511          "VideoSupport: %s\r\n"
17512          "TextSupport: %s\r\n"
17513          "ACL: %s\r\n"
17514          "Status: %s\r\n"
17515          "RealtimeDevice: %s\r\n"
17516          "Description: %s\r\n\r\n",
17517          idtext,
17518          peer->name,
17519          ast_sockaddr_isnull(&peer->addr) ? "-none-" : tmp_host,
17520          ast_sockaddr_isnull(&peer->addr) ? "0" : tmp_port,
17521          peer->host_dynamic ? "yes" : "no",  /* Dynamic or not? */
17522          ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT) ? "yes" : "no",
17523          ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no",  /* NAT=yes? */
17524          ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA) ? "yes" : "no",
17525          ast_test_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP) ? "yes" : "no",
17526          ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no",  /* VIDEOSUPPORT=yes? */
17527          ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no",   /* TEXTSUPPORT=yes? */
17528          peer->ha ? "yes" : "no",       /* permit/deny */
17529          status,
17530          realtimepeers ? (peer->is_realtime ? "yes":"no") : "no",
17531          peer->description);
17532       }
17533       ao2_unlock(peer);
17534       peer = peerarray[k] = sip_unref_peer(peer, "toss iterator peer ptr");
17535    }
17536 
17537    if (!s)
17538       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
17539               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
17540 
17541    if (havepattern)
17542       regfree(&regexbuf);
17543 
17544    if (total)
17545       *total = total_peers;
17546 
17547    ast_free(peerarray);
17548 
17549    return CLI_SUCCESS;
17550 #undef FORMAT2
17551 }

static void * _sip_tcp_helper_thread ( struct sip_pvt *  pvt,
struct ast_tcptls_session_instance tcptls_session 
) [static]

SIP TCP thread management function This function reads from the socket, parses the packet into a request.

Todo:
XXX If there's no Content-Length or if the content-length and what we receive is not the same - we should generate an error

Definition at line 2522 of file chan_sip.c.

References ao2_lock, ao2_ref, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, ast_atomic_fetchadd_int(), ast_debug, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_poll, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_tcptls_client_start(), ast_tcptls_close_session_file(), ast_tcptls_server_write(), ast_wait_for_input(), cleanup(), ast_tcptls_session_instance::client, copy_request(), deinit_req(), errno, ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, handle_request_do(), ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, MIN, OBJ_POINTER, ast_tcptls_session_instance::parent, parse_request(), ast_tcptls_session_instance::remote_address, set_socket_transport(), sip_check_authtimeout(), sip_get_header(), sip_threadinfo_create(), and ast_tcptls_session_instance::ssl.

Referenced by sip_tcp_worker_fn().

02523 {
02524    int res, cl, timeout = -1, authenticated = 0, flags, after_poll = 0, need_poll = 1;
02525    time_t start;
02526    struct sip_request req = { 0, } , reqcpy = { 0, };
02527    struct sip_threadinfo *me = NULL;
02528    char buf[1024] = "";
02529    struct pollfd fds[2] = { { 0 }, { 0 }, };
02530    struct ast_tcptls_session_args *ca = NULL;
02531 
02532    /* If this is a server session, then the connection has already been
02533     * setup. Check if the authlimit has been reached and if not create the
02534     * threadinfo object so we can access this thread for writing.
02535     *
02536     * if this is a client connection more work must be done.
02537     * 1. We own the parent session args for a client connection.  This pointer needs
02538     *    to be held on to so we can decrement it's ref count on thread destruction.
02539     * 2. The threadinfo object was created before this thread was launched, however
02540     *    it must be found within the threadt table.
02541     * 3. Last, the tcptls_session must be started.
02542     */
02543    if (!tcptls_session->client) {
02544       if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
02545          /* unauth_sessions is decremented in the cleanup code */
02546          goto cleanup;
02547       }
02548 
02549       if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) {
02550          ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
02551          goto cleanup;
02552       }
02553 
02554       flags |= O_NONBLOCK;
02555       if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) {
02556          ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
02557          goto cleanup;
02558       }
02559 
02560       if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) {
02561          goto cleanup;
02562       }
02563       ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread");
02564    } else {
02565       struct sip_threadinfo tmp = {
02566          .tcptls_session = tcptls_session,
02567       };
02568 
02569       if ((!(ca = tcptls_session->parent)) ||
02570          (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) ||
02571          (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) {
02572          goto cleanup;
02573       }
02574    }
02575 
02576    flags = 1;
02577    if (setsockopt(tcptls_session->fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) {
02578       ast_log(LOG_ERROR, "error enabling TCP keep-alives on sip socket: %s\n", strerror(errno));
02579       goto cleanup;
02580    }
02581 
02582    me->threadid = pthread_self();
02583    ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
02584 
02585    /* set up pollfd to watch for reads on both the socket and the alert_pipe */
02586    fds[0].fd = tcptls_session->fd;
02587    fds[1].fd = me->alert_pipe[0];
02588    fds[0].events = fds[1].events = POLLIN | POLLPRI;
02589 
02590    if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
02591       goto cleanup;
02592    }
02593    if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) {
02594       goto cleanup;
02595    }
02596 
02597    if(time(&start) == -1) {
02598       ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
02599       goto cleanup;
02600    }
02601 
02602    for (;;) {
02603       struct ast_str *str_save;
02604 
02605       if (!tcptls_session->client && req.authenticated && !authenticated) {
02606          authenticated = 1;
02607          ast_atomic_fetchadd_int(&unauth_sessions, -1);
02608       }
02609 
02610       /* calculate the timeout for unauthenticated server sessions */
02611       if (!tcptls_session->client && !authenticated ) {
02612          if ((timeout = sip_check_authtimeout(start)) < 0) {
02613             goto cleanup;
02614          }
02615 
02616          if (timeout == 0) {
02617             ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
02618             goto cleanup;
02619          }
02620       } else {
02621          timeout = -1;
02622       }
02623 
02624       res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */
02625       if (res < 0) {
02626          ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
02627          goto cleanup;
02628       } else if (res == 0) {
02629          /* timeout */
02630          ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
02631          goto cleanup;
02632       }
02633 
02634       /* handle the socket event, check for both reads from the socket fd,
02635        * and writes from alert_pipe fd */
02636       if (fds[0].revents) { /* there is data on the socket to be read */
02637          after_poll = 1;
02638 
02639          fds[0].revents = 0;
02640 
02641          /* clear request structure */
02642          str_save = req.data;
02643          memset(&req, 0, sizeof(req));
02644          req.data = str_save;
02645          ast_str_reset(req.data);
02646 
02647          str_save = reqcpy.data;
02648          memset(&reqcpy, 0, sizeof(reqcpy));
02649          reqcpy.data = str_save;
02650          ast_str_reset(reqcpy.data);
02651 
02652          memset(buf, 0, sizeof(buf));
02653 
02654          if (tcptls_session->ssl) {
02655             set_socket_transport(&req.socket, SIP_TRANSPORT_TLS);
02656             req.socket.port = htons(ourport_tls);
02657          } else {
02658             set_socket_transport(&req.socket, SIP_TRANSPORT_TCP);
02659             req.socket.port = htons(ourport_tcp);
02660          }
02661          req.socket.fd = tcptls_session->fd;
02662 
02663          /* Read in headers one line at a time */
02664          while (ast_str_strlen(req.data) < 4 || strncmp(REQ_OFFSET_TO_STR(&req, data->used - 4), "\r\n\r\n", 4)) {
02665             if (!tcptls_session->client && !authenticated ) {
02666                if ((timeout = sip_check_authtimeout(start)) < 0) {
02667                   goto cleanup;
02668                }
02669 
02670                if (timeout == 0) {
02671                   ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
02672                   goto cleanup;
02673                }
02674             } else {
02675                timeout = -1;
02676             }
02677 
02678             /* special polling behavior is required for TLS
02679              * sockets because of the buffering done in the
02680              * TLS layer */
02681             if (!tcptls_session->ssl || need_poll) {
02682                need_poll = 0;
02683                after_poll = 1;
02684                res = ast_wait_for_input(tcptls_session->fd, timeout);
02685                if (res < 0) {
02686                   ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
02687                   goto cleanup;
02688                } else if (res == 0) {
02689                   /* timeout */
02690                   ast_debug(2, "SIP TCP server timed out\n");
02691                   goto cleanup;
02692                }
02693             }
02694 
02695             ast_mutex_lock(&tcptls_session->lock);
02696             if (!fgets(buf, sizeof(buf), tcptls_session->f)) {
02697                ast_mutex_unlock(&tcptls_session->lock);
02698                if (after_poll) {
02699                   goto cleanup;
02700                } else {
02701                   need_poll = 1;
02702                   continue;
02703                }
02704             }
02705             ast_mutex_unlock(&tcptls_session->lock);
02706             after_poll = 0;
02707             if (me->stop) {
02708                 goto cleanup;
02709             }
02710             ast_str_append(&req.data, 0, "%s", buf);
02711          }
02712          copy_request(&reqcpy, &req);
02713          parse_request(&reqcpy);
02714          /* In order to know how much to read, we need the content-length header */
02715          if (sscanf(sip_get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
02716             while (cl > 0) {
02717                size_t bytes_read;
02718                if (!tcptls_session->client && !authenticated ) {
02719                   if ((timeout = sip_check_authtimeout(start)) < 0) {
02720                      goto cleanup;
02721                   }
02722 
02723                   if (timeout == 0) {
02724                      ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
02725                      goto cleanup;
02726                   }
02727                } else {
02728                   timeout = -1;
02729                }
02730 
02731                if (!tcptls_session->ssl || need_poll) {
02732                   need_poll = 0;
02733                   after_poll = 1;
02734                   res = ast_wait_for_input(tcptls_session->fd, timeout);
02735                   if (res < 0) {
02736                      ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
02737                      goto cleanup;
02738                   } else if (res == 0) {
02739                      /* timeout */
02740                      ast_debug(2, "SIP TCP server timed out\n");
02741                      goto cleanup;
02742                   }
02743                }
02744 
02745                ast_mutex_lock(&tcptls_session->lock);
02746                if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
02747                   ast_mutex_unlock(&tcptls_session->lock);
02748                   if (after_poll) {
02749                      goto cleanup;
02750                   } else {
02751                      need_poll = 1;
02752                      continue;
02753                   }
02754                }
02755                buf[bytes_read] = '\0';
02756                ast_mutex_unlock(&tcptls_session->lock);
02757                after_poll = 0;
02758                if (me->stop) {
02759                   goto cleanup;
02760                }
02761                cl -= strlen(buf);
02762                ast_str_append(&req.data, 0, "%s", buf);
02763             }
02764          }
02765          /*! \todo XXX If there's no Content-Length or if the content-length and what
02766                we receive is not the same - we should generate an error */
02767 
02768          req.socket.tcptls_session = tcptls_session;
02769          handle_request_do(&req, &tcptls_session->remote_address);
02770       }
02771 
02772       if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */
02773          enum sip_tcptls_alert alert;
02774          struct tcptls_packet *packet;
02775 
02776          fds[1].revents = 0;
02777 
02778          if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) {
02779             ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02780             continue;
02781          }
02782 
02783          switch (alert) {
02784          case TCPTLS_ALERT_STOP:
02785             goto cleanup;
02786          case TCPTLS_ALERT_DATA:
02787             ao2_lock(me);
02788             if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) {
02789                ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty");
02790             }
02791             ao2_unlock(me);
02792 
02793             if (packet) {
02794                if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) {
02795                   ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n");
02796                }
02797                ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed");
02798             }
02799             break;
02800          default:
02801             ast_log(LOG_ERROR, "Unknown tcptls thread alert '%d'\n", alert);
02802          }
02803       }
02804    }
02805 
02806    ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
02807 
02808 cleanup:
02809    if (tcptls_session && !tcptls_session->client && !authenticated) {
02810       ast_atomic_fetchadd_int(&unauth_sessions, -1);
02811    }
02812 
02813    if (me) {
02814       ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
02815       ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
02816    }
02817    deinit_req(&reqcpy);
02818    deinit_req(&req);
02819 
02820    /* if client, we own the parent session arguments and must decrement ref */
02821    if (ca) {
02822       ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments");
02823    }
02824 
02825    if (tcptls_session) {
02826       ast_mutex_lock(&tcptls_session->lock);
02827       ast_tcptls_close_session_file(tcptls_session);
02828       tcptls_session->parent = NULL;
02829       ast_mutex_unlock(&tcptls_session->lock);
02830 
02831       ao2_ref(tcptls_session, -1);
02832       tcptls_session = NULL;
02833    }
02834    return NULL;
02835 }

static void add_blank ( struct sip_request *  req  )  [static]

add a blank line if no body

Definition at line 4108 of file chan_sip.c.

References ast_str_append().

Referenced by send_request(), and send_response().

04109 {
04110    if (!req->lines) {
04111       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
04112       ast_str_append(&req->data, 0, "\r\n");
04113    }
04114 }

static void add_cc_call_info_to_response ( struct sip_pvt *  p,
struct sip_request *  resp 
) [static]

Definition at line 12125 of file chan_sip.c.

References add_header(), ao2_ref, ast_copy_string(), ast_log(), ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), find_sip_cc_agent_by_original_callid(), generate_uri(), LOG_WARNING, and ast_cc_agent::private_data.

Referenced by __transmit_response(), and transmit_response_with_sdp().

12126 {
12127    char uri[SIPBUFSIZE];
12128    struct ast_str *header = ast_str_alloca(SIPBUFSIZE);
12129    struct ast_cc_agent *agent = find_sip_cc_agent_by_original_callid(p);
12130    struct sip_cc_agent_pvt *agent_pvt;
12131 
12132    if (!agent) {
12133       /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an
12134        * agent? Oh well, we'll just warn and return without adding the header.
12135        */
12136       ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid);
12137       return;
12138    }
12139 
12140    agent_pvt = agent->private_data;
12141 
12142    if (!ast_strlen_zero(agent_pvt->subscribe_uri)) {
12143       ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri));
12144    } else {
12145       generate_uri(p, uri, sizeof(uri));
12146       ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri));
12147    }
12148    /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed
12149     * to be more accurate. This parameter has no bearing on the actual operation
12150     * of the feature; it's just there for informational purposes.
12151     */
12152    ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR");
12153    add_header(resp, "Call-Info", ast_str_buffer(header));
12154    ao2_ref(agent, -1);
12155 }

static void add_codec_to_sdp ( const struct sip_pvt *  p,
struct ast_format codec,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

Add codec offer to SDP offer/answer body in INVITE or 200 OK.

Definition at line 11313 of file chan_sip.c.

References ast_codec_pref_getsize(), AST_FORMAT_CELT, AST_FORMAT_G719, AST_FORMAT_G723_1, AST_FORMAT_G729A, ast_format_get_value(), AST_FORMAT_ILBC, AST_FORMAT_SILK, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), AST_RTP_OPT_G726_NONSTANDARD, ast_str_append(), ast_test_flag, ast_verbose, CELT_ATTR_KEY_FRAME_SIZE, ast_format_list::cur_ms, ast_format::id, ast_rtp_codecs::pref, SILK_ATTR_KEY_DTX, SILK_ATTR_KEY_FEC, and SILK_ATTR_KEY_MAX_BITRATE.

Referenced by add_sdp().

11319 {
11320    int rtp_code;
11321    struct ast_format_list fmt;
11322    int val = 0;
11323 
11324    if (debug)
11325       ast_verbose("Adding codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
11326    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, format, 0)) == -1)
11327       return;
11328 
11329    if (p->rtp) {
11330       struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
11331       fmt = ast_codec_pref_getsize(pref, format);
11332    } else /* I don't see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
11333       return;
11334    ast_str_append(m_buf, 0, " %d", rtp_code);
11335    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n",
11336       rtp_code,
11337       ast_rtp_lookup_mime_subtype2(1, format, 0, ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
11338       ast_rtp_lookup_sample_rate2(1, format, 0));
11339 
11340    switch ((int) format->id) {
11341    case AST_FORMAT_G729A:
11342       /* Indicate that we don't support VAD (G.729 annex B) */
11343       ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
11344       break;
11345    case AST_FORMAT_G723_1:
11346       /* Indicate that we don't support VAD (G.723.1 annex A) */
11347       ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
11348       break;
11349    case AST_FORMAT_ILBC:
11350       /* Add information about us using only 20/30 ms packetization */
11351       ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
11352       break;
11353    case AST_FORMAT_SIREN7:
11354       /* Indicate that we only expect 32Kbps */
11355       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code);
11356       break;
11357    case AST_FORMAT_SIREN14:
11358       /* Indicate that we only expect 48Kbps */
11359       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code);
11360       break;
11361    case AST_FORMAT_G719:
11362       /* Indicate that we only expect 64Kbps */
11363       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code);
11364       break;
11365    case AST_FORMAT_CELT:
11366       if (!ast_format_get_value(format, CELT_ATTR_KEY_FRAME_SIZE, &val) && val > 0) {
11367          ast_str_append(a_buf, 0, "a=fmtp:%d framesize=%u\r\n", rtp_code, val);
11368       }
11369       break;
11370    case AST_FORMAT_SILK:
11371       if (!ast_format_get_value(format, SILK_ATTR_KEY_MAX_BITRATE, &val) && val > 5000 && val < 40000) {
11372          ast_str_append(a_buf, 0, "a=fmtp:%d maxaveragebitrate=%u\r\n", rtp_code, val);
11373       }
11374       if (!ast_format_get_value(format, SILK_ATTR_KEY_DTX, &val)) {
11375          ast_str_append(a_buf, 0, "a=fmtp:%d usedtx=%u\r\n", rtp_code, val ? 1 : 0);
11376       }
11377       if (!ast_format_get_value(format, SILK_ATTR_KEY_FEC, &val)) {
11378          ast_str_append(a_buf, 0, "a=fmtp:%d useinbandfec=%u\r\n", rtp_code, val ? 1 : 0);
11379       }
11380       break;
11381    }
11382 
11383    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
11384       *min_packet_size = fmt.cur_ms;
11385 
11386    /* Our first codec packetization processed cannot be zero */
11387    if ((*min_packet_size)==0 && fmt.cur_ms)
11388       *min_packet_size = fmt.cur_ms;
11389 }

static int add_content ( struct sip_request *  req,
const char *  line 
) [static]

Add content (not header) to SIP message.

Definition at line 10185 of file chan_sip.c.

References ast_log(), ast_str_append(), and LOG_WARNING.

Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_cc_notify(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().

10186 {
10187    if (req->lines) {
10188       ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n");
10189       return -1;
10190    }
10191 
10192    ast_str_append(&req->content, 0, "%s", line);
10193    return 0;
10194 }

static int add_digit ( struct sip_request *  req,
char  digit,
unsigned int  duration,
int  mode 
) [static]

Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf.

Definition at line 11171 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_info_with_digit().

11172 {
11173    char tmp[256];
11174    int event;
11175    if (mode) {
11176       /* Application/dtmf short version used by some implementations */
11177       if ('0' <= digit && digit <= '9') {
11178          event = digit - '0';
11179       } else if (digit == '*') {
11180          event = 10;
11181       } else if (digit == '#') {
11182          event = 11;
11183       } else if ('A' <= digit && digit <= 'D') {
11184          event = 12 + digit - 'A';
11185       } else if ('a' <= digit && digit <= 'd') {
11186          event = 12 + digit - 'a';
11187       } else {
11188          /* Unknown digit */
11189          event = 0;
11190       }
11191       snprintf(tmp, sizeof(tmp), "%d\r\n", event);
11192       add_header(req, "Content-Type", "application/dtmf");
11193       add_content(req, tmp);
11194    } else {
11195       /* Application/dtmf-relay as documented by Cisco */
11196       snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
11197       add_header(req, "Content-Type", "application/dtmf-relay");
11198       add_content(req, tmp);
11199    }
11200    return 0;
11201 }

static void add_diversion_header ( struct sip_request *  req,
struct sip_pvt *  pvt 
) [static]

Add "Diversion" header to outgoing message.

We need to add a Diversion header if the owner channel of this dialog has redirecting information associated with it.

Parameters:
req The request/response to which we will add the header
pvt The sip_pvt which represents the call-leg

Definition at line 12528 of file chan_sip.c.

References add_header(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), and sip_reason_code_to_str().

Referenced by __transmit_response(), transmit_invite(), and update_redirecting().

12529 {
12530    const char *diverting_number;
12531    const char *diverting_name;
12532    const char *reason;
12533    char header_text[256];
12534 
12535    if (!pvt->owner) {
12536       return;
12537    }
12538 
12539    diverting_number = pvt->owner->redirecting.from.number.str;
12540    if (!pvt->owner->redirecting.from.number.valid
12541       || ast_strlen_zero(diverting_number)) {
12542       return;
12543    }
12544 
12545    reason = sip_reason_code_to_str(pvt->owner->redirecting.reason);
12546 
12547    /* We at least have a number to place in the Diversion header, which is enough */
12548    diverting_name = pvt->owner->redirecting.from.name.str;
12549    if (!pvt->owner->redirecting.from.name.valid
12550       || ast_strlen_zero(diverting_name)) {
12551       snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number,
12552             ast_sockaddr_stringify_host_remote(&pvt->ourip), reason);
12553    } else {
12554       snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s",
12555             diverting_name, diverting_number,
12556             ast_sockaddr_stringify_host_remote(&pvt->ourip), reason);
12557    }
12558 
12559    add_header(req, "Diversion", header_text);
12560 }

static int add_header ( struct sip_request *  req,
const char *  var,
const char *  value 
) [static]

Add header to SIP message.

Definition at line 10127 of file chan_sip.c.

References ast_log(), ast_str_append(), ast_str_strlen(), find_alias(), LOG_WARNING, and sip_cfg.

10128 {
10129    if (req->headers == SIP_MAX_HEADERS) {
10130       ast_log(LOG_WARNING, "Out of SIP header space\n");
10131       return -1;
10132    }
10133 
10134    if (req->lines) {
10135       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
10136       return -1;
10137    }
10138 
10139    if (sip_cfg.compactheaders) {
10140       var = find_alias(var, var);
10141    }
10142 
10143    ast_str_append(&req->data, 0, "%s: %s\r\n", var, value);
10144    req->header[req->headers] = ast_str_strlen(req->data);
10145 
10146    req->headers++;
10147 
10148    return 0;   
10149 }

static int add_header_max_forwards ( struct sip_pvt *  dialog,
struct sip_request *  req 
) [static]

Add 'Max-Forwards' header to SIP message.

Precondition:
dialog is assumed to be locked while calling this function

Definition at line 10155 of file chan_sip.c.

References add_header().

Referenced by initreqprep(), reqprep(), and transmit_register().

10156 {
10157    char clen[10];
10158 
10159    snprintf(clen, sizeof(clen), "%d", dialog->maxforwards);
10160 
10161    return add_header(req, "Max-Forwards", clen);
10162 }

static void add_msg_header ( struct sip_pvt *  pvt,
const char *  hdr_name,
const char *  hdr_value 
) [static]

Definition at line 11117 of file chan_sip.c.

References ast_calloc, and AST_LIST_INSERT_TAIL.

Referenced by sip_msg_send().

11118 {
11119    size_t hdr_len_name;
11120    size_t hdr_len_value;
11121    struct sip_msg_hdr *node;
11122    char *pos;
11123 
11124    hdr_len_name = strlen(hdr_name) + 1;
11125    hdr_len_value = strlen(hdr_value) + 1;
11126 
11127    node = ast_calloc(1, sizeof(*node) + hdr_len_name + hdr_len_value);
11128    if (!node) {
11129       return;
11130    }
11131    pos = node->stuff;
11132    node->name = pos;
11133    strcpy(pos, hdr_name);
11134    pos += hdr_len_name;
11135    node->value = pos;
11136    strcpy(pos, hdr_value);
11137 
11138    AST_LIST_INSERT_TAIL(&pvt->msg_headers, node, next);
11139 }

static void add_noncodec_to_sdp ( const struct sip_pvt *  p,
int  format,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug 
) [static]

Add RFC 2833 DTMF offer to SDP.

Definition at line 11471 of file chan_sip.c.

References ast_rtp_codecs_payload_code(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.

Referenced by add_sdp().

11474 {
11475    int rtp_code;
11476 
11477    if (debug)
11478       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, NULL, format, 0));
11479    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, NULL, format)) == -1)
11480       return;
11481 
11482    ast_str_append(m_buf, 0, " %d", rtp_code);
11483    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
11484              ast_rtp_lookup_mime_subtype2(0, NULL, format, 0),
11485              ast_rtp_lookup_sample_rate2(0, NULL, format));
11486    if (format == AST_RTP_DTMF)   /* Indicate we support DTMF and FLASH... */
11487       ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
11488 }

static void add_peer_mailboxes ( struct sip_peer *  peer,
const char *  value 
) [static]

Todo:
document this function

Definition at line 28192 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdupa, ast_strip(), ast_strlen_zero(), context, mailbox, mbox(), S_OR, and strsep().

Referenced by build_peer().

28193 {
28194    char *next, *mbox, *context;
28195 
28196    next = ast_strdupa(value);
28197 
28198    while ((mbox = context = strsep(&next, ","))) {
28199       struct sip_mailbox *mailbox;
28200       int duplicate = 0;
28201       /* remove leading/trailing whitespace from mailbox string */
28202       mbox = ast_strip(mbox);
28203       strsep(&context, "@");
28204 
28205       if (ast_strlen_zero(mbox)) {
28206          continue;
28207       }
28208 
28209       /* Check whether the mailbox is already in the list */
28210       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
28211          if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) {
28212             duplicate = 1;
28213             break;
28214          }
28215       }
28216       if (duplicate) {
28217          continue;
28218       }
28219 
28220       if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) {
28221          continue;
28222       }
28223 
28224       if (!ast_strlen_zero(context)) {
28225          mailbox->context = mailbox->mailbox + strlen(mbox) + 1;
28226          strcpy(mailbox->context, context); /* SAFE */
28227       }
28228       strcpy(mailbox->mailbox, mbox); /* SAFE */
28229 
28230       AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
28231    }
28232 }

static void add_peer_mwi_subs ( struct sip_peer *  peer  )  [static]

Definition at line 25437 of file chan_sip.c.

References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), AST_LIST_TRAVERSE, mailbox, mwi_event_cb(), and S_OR.

Referenced by build_peer(), and handle_request_subscribe().

25438 {
25439    struct sip_mailbox *mailbox;
25440 
25441    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
25442       if (mailbox->event_sub) {
25443          ast_event_unsubscribe(mailbox->event_sub);
25444       }
25445 
25446       mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer,
25447          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
25448          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
25449          AST_EVENT_IE_END);
25450    }
25451 }

static void add_realm_authentication ( struct sip_auth_container **  credentials,
const char *  configuration,
int  lineno 
) [static]

Definition at line 27986 of file chan_sip.c.

References ao2_t_alloc, ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, ast_log(), ast_strdupa, ast_strlen_zero(), ast_verb, destroy_realm_authentication(), LOG_WARNING, and secret.

Referenced by build_peer(), and reload_config().

27987 {
27988    char *authcopy;
27989    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
27990    struct sip_auth *auth;
27991 
27992    if (ast_strlen_zero(configuration)) {
27993       /* Nothing to add */
27994       return;
27995    }
27996 
27997    ast_debug(1, "Auth config ::  %s\n", configuration);
27998 
27999    authcopy = ast_strdupa(configuration);
28000    username = authcopy;
28001 
28002    /* split user[:secret] and relm */
28003    realm = strrchr(username, '@');
28004    if (realm)
28005       *realm++ = '\0';
28006    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
28007       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
28008       return;
28009    }
28010 
28011    /* parse username at ':' for secret, or '#" for md5secret */
28012    if ((secret = strchr(username, ':'))) {
28013       *secret++ = '\0';
28014    } else if ((md5secret = strchr(username, '#'))) {
28015       *md5secret++ = '\0';
28016    }
28017 
28018    /* Create the continer if needed. */
28019    if (!*credentials) {
28020       *credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication,
28021          "Create realm auth container.");
28022       if (!*credentials) {
28023          /* Failed to create the credentials container. */
28024          return;
28025       }
28026    }
28027 
28028    /* Create the authentication credential entry. */
28029    auth = ast_calloc(1, sizeof(*auth));
28030    if (!auth) {
28031       return;
28032    }
28033    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
28034    ast_copy_string(auth->username, username, sizeof(auth->username));
28035    if (secret)
28036       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
28037    if (md5secret)
28038       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
28039 
28040    /* Add credential to container list. */
28041    AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node);
28042 
28043    ast_verb(3, "Added authentication for realm %s\n", realm);
28044 }

static void add_route ( struct sip_request *  req,
struct sip_route *  route 
) [static]

Add route header into request per learned route.

Definition at line 10296 of file chan_sip.c.

References add_header(), and ast_copy_string().

Referenced by initreqprep(), and reqprep().

10297 {
10298    char r[SIPBUFSIZE*2], *p;
10299    int n, rem = sizeof(r);
10300 
10301    if (!route)
10302       return;
10303 
10304    p = r;
10305    for (;route ; route = route->next) {
10306       n = strlen(route->hop);
10307       if (rem < n+3) /* we need room for ",<route>" */
10308          break;
10309       if (p != r) {  /* add a separator after fist route */
10310          *p++ = ',';
10311          --rem;
10312       }
10313       *p++ = '<';
10314       ast_copy_string(p, route->hop, rem); /* cannot fail */
10315       p += n;
10316       *p++ = '>';
10317       rem -= (n+2);
10318    }
10319    *p = '\0';
10320    add_header(req, "Route", r);
10321 }

static int add_rpid ( struct sip_request *  req,
struct sip_pvt *  p 
) [static]

Add Remote-Party-ID header to SIP message.

Precondition:
if p->owner exists, it must be locked

Definition at line 11207 of file chan_sip.c.

References add_header(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_test_flag, ast_uri_encode(), ast_uri_sip_user, and S_OR.

Referenced by __transmit_response(), transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), and update_connectedline().

11208 {
11209    struct ast_str *tmp = ast_str_alloca(256);
11210    char tmp2[256];
11211    char *lid_num = NULL;
11212    char *lid_name = NULL;
11213    int lid_pres;
11214    const char *fromdomain;
11215    const char *privacy = NULL;
11216    const char *screen = NULL;
11217    const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>";
11218 
11219    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
11220       return 0;
11221    }
11222 
11223    if (p->owner && p->owner->connected.id.number.valid
11224       && p->owner->connected.id.number.str) {
11225       lid_num = p->owner->connected.id.number.str;
11226    }
11227    if (p->owner && p->owner->connected.id.name.valid
11228       && p->owner->connected.id.name.str) {
11229       lid_name = p->owner->connected.id.name.str;
11230    }
11231    lid_pres = (p->owner) ? ast_party_id_presentation(&p->owner->connected.id) : AST_PRES_NUMBER_NOT_AVAILABLE;
11232 
11233    if (ast_strlen_zero(lid_num))
11234       return 0;
11235    if (ast_strlen_zero(lid_name))
11236       lid_name = lid_num;
11237    fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip));
11238 
11239    lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), ast_uri_sip_user);
11240 
11241    if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) {
11242       if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
11243          ast_str_set(&tmp, -1, "%s", anonymous_string);
11244       } else {
11245          ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name, lid_num, fromdomain);
11246       }
11247       add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp));
11248    } else {
11249       ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name, lid_num, fromdomain, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "calling" : "called");
11250 
11251       switch (lid_pres) {
11252       case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
11253       case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
11254          privacy = "off";
11255          screen = "no";
11256          break;
11257       case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
11258       case AST_PRES_ALLOWED_NETWORK_NUMBER:
11259          privacy = "off";
11260          screen = "yes";
11261          break;
11262       case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
11263       case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
11264          privacy = "full";
11265          screen = "no";
11266          break;
11267       case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
11268       case AST_PRES_PROHIB_NETWORK_NUMBER:
11269          privacy = "full";
11270          screen = "yes";
11271          break;
11272       case AST_PRES_NUMBER_NOT_AVAILABLE:
11273          break;
11274       default:
11275          if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
11276             privacy = "full";
11277          }
11278          else
11279             privacy = "off";
11280          screen = "no";
11281          break;
11282       }
11283 
11284       if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) {
11285          ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen);
11286       }
11287 
11288       add_header(req, "Remote-Party-ID", ast_str_buffer(tmp));
11289    }
11290    return 0;
11291 }

static enum sip_result add_sdp ( struct sip_request *  resp,
struct sip_pvt *  p,
int  oldsdp,
int  add_audio,
int  add_t38 
) [static]

Add Session Description Protocol message.

If oldsdp is TRUE, then the SDP version number is not incremented. This mechanism is used in Session-Timers where RE-INVITEs are used for refreshing SIP sessions without modifying the media session in any way.

Definition at line 11620 of file chan_sip.c.

References add_codec_to_sdp(), add_content(), add_header(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ao2_lock, ao2_t_link, ao2_t_unlink, ao2_unlock, ast_codec_pref_index(), AST_CODEC_PREF_SIZE, ast_debug, ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_has_joint(), ast_format_cap_has_type(), ast_format_cap_is_empty(), ast_format_cap_iscompatible(), ast_format_cap_iter_end(), ast_format_cap_iter_next(), ast_format_cap_iter_start(), ast_format_cap_joint_copy(), AST_FORMAT_GET_TYPE, AST_FORMAT_TYPE_AUDIO, AST_FORMAT_TYPE_TEXT, AST_FORMAT_TYPE_VIDEO, ast_getformatname_multiple(), ast_internal_timing_enabled(), ast_log(), ast_random(), AST_RTP_MAX, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_addr_remote(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_append(), ast_strlen_zero(), AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose, debug, FALSE, get_crypto_attrib(), get_our_media_address(), ast_format::id, LOG_WARNING, sip_debug_test_pvt(), t38_get_rate(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and version.

11621 {
11622    struct ast_format_cap *alreadysent = ast_format_cap_alloc_nolock();
11623    struct ast_format_cap *tmpcap = ast_format_cap_alloc_nolock();
11624    int res = AST_SUCCESS;
11625    int doing_directmedia = FALSE;
11626    struct ast_sockaddr addr = { {0,} };
11627    struct ast_sockaddr vaddr = { {0,} };
11628    struct ast_sockaddr taddr = { {0,} };
11629    struct ast_sockaddr udptladdr = { {0,} };
11630    struct ast_sockaddr dest = { {0,} };
11631    struct ast_sockaddr vdest = { {0,} };
11632    struct ast_sockaddr tdest = { {0,} };
11633    struct ast_sockaddr udptldest = { {0,} };
11634 
11635    /* SDP fields */
11636    char *version =   "v=0\r\n";     /* Protocol version */
11637    char subject[256];            /* Subject of the session */
11638    char owner[256];           /* Session owner/creator */
11639    char connection[256];            /* Connection data */
11640    char *session_time = "t=0 0\r\n";         /* Time the session is active */
11641    char bandwidth[256] = "";        /* Max bitrate */
11642    char *hold = "";
11643    struct ast_str *m_audio = ast_str_alloca(256);  /* Media declaration line for audio */
11644    struct ast_str *m_video = ast_str_alloca(256);  /* Media declaration line for video */
11645    struct ast_str *m_text = ast_str_alloca(256);   /* Media declaration line for text */
11646    struct ast_str *m_modem = ast_str_alloca(256);  /* Media declaration line for modem */
11647    struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */
11648    struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */
11649    struct ast_str *a_text = ast_str_alloca(1024);  /* Attributes for text */
11650    struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */
11651    const char *a_crypto = NULL;
11652    const char *v_a_crypto = NULL;
11653    const char *t_a_crypto = NULL;
11654 
11655    int x;
11656    struct ast_format tmp_fmt;
11657    int needaudio = FALSE;
11658    int needvideo = FALSE;
11659    int needtext = FALSE;
11660    int debug = sip_debug_test_pvt(p);
11661    int min_audio_packet_size = 0;
11662    int min_video_packet_size = 0;
11663    int min_text_packet_size = 0;
11664 
11665    char codecbuf[SIPBUFSIZE];
11666    char buf[SIPBUFSIZE];
11667    char dummy_answer[256];
11668 
11669    /* Set the SDP session name */
11670    snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
11671 
11672    if (!alreadysent || !tmpcap) {
11673       res = AST_FAILURE;
11674       goto add_sdp_cleanup;
11675    }
11676    if (!p->rtp) {
11677       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
11678       res = AST_FAILURE;
11679       goto add_sdp_cleanup;
11680 
11681    }
11682    /* XXX We should not change properties in the SIP dialog until
11683       we have acceptance of the offer if this is a re-invite */
11684 
11685    /* Set RTP Session ID and version */
11686    if (!p->sessionid) {
11687       p->sessionid = (int)ast_random();
11688       p->sessionversion = p->sessionid;
11689    } else {
11690       if (oldsdp == FALSE)
11691          p->sessionversion++;
11692    }
11693 
11694    if (add_audio) {
11695       doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && !(ast_format_cap_is_empty(p->redircaps))) ? TRUE : FALSE;
11696       /* Check if we need video in this call */
11697       if ((ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_VIDEO)) && !p->novideo) {
11698          ast_format_cap_joint_copy(p->jointcaps, p->redircaps, tmpcap);
11699          if (doing_directmedia && !ast_format_cap_has_type(tmpcap, AST_FORMAT_TYPE_VIDEO)) {
11700             ast_debug(2, "This call needs video offers, but caller probably did not offer it!\n");
11701          } else if (p->vrtp) {
11702             needvideo = TRUE;
11703             ast_debug(2, "This call needs video offers!\n");
11704          } else {
11705             ast_debug(2, "This call needs video offers, but there's no video support enabled!\n");
11706          }
11707       }
11708       /* Check if we need text in this call */
11709       if ((ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_TEXT)) && !p->notext) {
11710          if (sipdebug_text)
11711             ast_verbose("We think we can do text\n");
11712          if (p->trtp) {
11713             if (sipdebug_text) {
11714                ast_verbose("And we have a text rtp object\n");
11715             }
11716             needtext = TRUE;
11717             ast_debug(2, "This call needs text offers! \n");
11718          } else {
11719             ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n");
11720          }
11721       }
11722    }
11723 
11724    get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest);
11725 
11726    snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n",
11727        ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner,
11728        p->sessionid, p->sessionversion,
11729        (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
11730          "IP6" : "IP4",
11731        ast_sockaddr_stringify_addr_remote(&dest));
11732 
11733    snprintf(connection, sizeof(connection), "c=IN %s %s\r\n",
11734        (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
11735          "IP6" : "IP4",
11736        ast_sockaddr_stringify_addr_remote(&dest));
11737 
11738    if (add_audio) {
11739       if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) {
11740          hold = "a=recvonly\r\n";
11741          doing_directmedia = FALSE;
11742       } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) {
11743          hold = "a=inactive\r\n";
11744          doing_directmedia = FALSE;
11745       } else {
11746          hold = "a=sendrecv\r\n";
11747       }
11748 
11749       ast_format_cap_copy(tmpcap, p->jointcaps);
11750 
11751       /* XXX note, Video and Text are negated - 'true' means 'no' */
11752       ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), tmpcap),
11753            p->novideo ? "True" : "False", p->notext ? "True" : "False");
11754       ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcaps));
11755 
11756       if (doing_directmedia) {
11757          ast_format_cap_joint_copy(p->jointcaps, p->redircaps, tmpcap);
11758          ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), tmpcap));
11759       }
11760 
11761       /* Check if we need audio */
11762       if (ast_format_cap_has_type(tmpcap, AST_FORMAT_TYPE_AUDIO))
11763          needaudio = TRUE;
11764 
11765       if (debug) {
11766          ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&addr));
11767       }
11768 
11769       /* Ok, we need video. Let's add what we need for video and set codecs.
11770          Video is handled differently than audio since we can not transcode. */
11771       if (needvideo) {
11772          get_crypto_attrib(p, p->vsrtp, &v_a_crypto);
11773          ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest),
11774             v_a_crypto ? "SAVP" : "AVP");
11775 
11776          /* Build max bitrate string */
11777          if (p->maxcallbitrate)
11778             snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
11779          if (debug) {
11780             ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest));
11781          }
11782       }
11783 
11784       /* Ok, we need text. Let's add what we need for text and set codecs.
11785          Text is handled differently than audio since we can not transcode. */
11786       if (needtext) {
11787          if (sipdebug_text)
11788             ast_verbose("Lets set up the text sdp\n");
11789          get_crypto_attrib(p, p->tsrtp, &t_a_crypto);
11790          ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest),
11791             t_a_crypto ? "SAVP" : "AVP");
11792          if (debug) {  /* XXX should I use tdest below ? */
11793             ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr));
11794          }
11795       }
11796 
11797       /* Start building generic SDP headers */
11798 
11799       /* We break with the "recommendation" and send our IP, in order that our
11800          peer doesn't have to ast_gethostbyname() us */
11801 
11802       get_crypto_attrib(p, p->srtp, &a_crypto);
11803       ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest),
11804          a_crypto ? "SAVP" : "AVP");
11805 
11806       /* Now, start adding audio codecs. These are added in this order:
11807          - First what was requested by the calling channel
11808          - Then preferences in order from sip.conf device config for this peer/user
11809          - Then other codecs in capabilities, including video
11810       */
11811 
11812       /* Prefer the audio codec we were requested to use, first, no matter what
11813          Note that p->prefcodec can include video codecs, so mask them out
11814       */
11815       if (ast_format_cap_has_joint(tmpcap, p->prefcaps)) {
11816          ast_format_cap_iter_start(p->prefcaps);
11817          while (!(ast_format_cap_iter_next(p->prefcaps, &tmp_fmt))) {
11818             if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_AUDIO) {
11819                continue;
11820             }
11821             add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size);
11822             ast_format_cap_add(alreadysent, &tmp_fmt);
11823          }
11824          ast_format_cap_iter_end(p->prefcaps);
11825       }
11826 
11827       /* Start by sending our preferred audio/video codecs */
11828       for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
11829          if (!(ast_codec_pref_index(&p->prefs, x, &tmp_fmt)))
11830             break;
11831 
11832          if (!(ast_format_cap_iscompatible(tmpcap, &tmp_fmt)))
11833             continue;
11834 
11835          if (ast_format_cap_iscompatible(alreadysent, &tmp_fmt))
11836             continue;
11837 
11838          if (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_AUDIO) {
11839             add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size);
11840          } else if (needvideo && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_VIDEO)) {
11841             add_vcodec_to_sdp(p, &tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
11842          } else if (needtext && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_TEXT)) {
11843             add_tcodec_to_sdp(p, &tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
11844          }
11845 
11846          ast_format_cap_add(alreadysent, &tmp_fmt);
11847       }
11848 
11849       /* Now send any other common audio and video codecs, and non-codec formats: */
11850       ast_format_cap_iter_start(tmpcap);
11851       while (!(ast_format_cap_iter_next(tmpcap, &tmp_fmt))) {
11852          if (ast_format_cap_iscompatible(alreadysent, &tmp_fmt))
11853             continue;
11854 
11855          if (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_AUDIO) {
11856             add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size);
11857          } else if (needvideo && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_VIDEO)) {
11858             add_vcodec_to_sdp(p, &tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
11859          } else if (needtext && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_TEXT)) {
11860             add_tcodec_to_sdp(p, &tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
11861          }
11862       }
11863       ast_format_cap_iter_end(tmpcap);
11864 
11865       /* Now add DTMF RFC2833 telephony-event as a codec */
11866       for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
11867          if (!(p->jointnoncodeccapability & x))
11868             continue;
11869 
11870          add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug);
11871       }
11872 
11873       ast_debug(3, "-- Done with adding codecs to SDP\n");
11874 
11875       if (!p->owner || !ast_internal_timing_enabled(p->owner))
11876          ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n");
11877 
11878       if (min_audio_packet_size)
11879          ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size);
11880 
11881       /* XXX don't think you can have ptime for video */
11882       if (min_video_packet_size)
11883          ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size);
11884 
11885       /* XXX don't think you can have ptime for text */
11886       if (min_text_packet_size)
11887          ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size);
11888 
11889       if (m_audio->len - m_audio->used < 2 || m_video->len - m_video->used < 2 ||
11890           m_text->len - m_text->used < 2 || a_text->len - a_text->used < 2 ||
11891           a_audio->len - a_audio->used < 2 || a_video->len - a_video->used < 2)
11892          ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
11893    }
11894 
11895    if (add_t38) {
11896       /* Our T.38 end is */
11897       ast_udptl_get_us(p->udptl, &udptladdr);
11898 
11899       /* Determine T.38 UDPTL destination */
11900       if (!ast_sockaddr_isnull(&p->udptlredirip)) {
11901          ast_sockaddr_copy(&udptldest, &p->udptlredirip);
11902       } else {
11903          ast_sockaddr_copy(&udptldest, &p->ourip);
11904          ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr));
11905       }
11906 
11907       if (debug) {
11908          ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr));
11909       }
11910 
11911       /* We break with the "recommendation" and send our IP, in order that our
11912          peer doesn't have to ast_gethostbyname() us */
11913 
11914       ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest));
11915 
11916       if (!ast_sockaddr_cmp(&udptldest, &dest)) {
11917          ast_str_append(&m_modem, 0, "c=IN %s %s\r\n",
11918                (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
11919                "IP6" : "IP4", ast_sockaddr_stringify_addr_remote(&udptldest));
11920       }
11921 
11922       ast_str_append(&a_modem, 0, "a=T38FaxVersion:%d\r\n", p->t38.our_parms.version);
11923       ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", t38_get_rate(p->t38.our_parms.rate));
11924       if (p->t38.our_parms.fill_bit_removal) {
11925          ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n");
11926       }
11927       if (p->t38.our_parms.transcoding_mmr) {
11928          ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n");
11929       }
11930       if (p->t38.our_parms.transcoding_jbig) {
11931          ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n");
11932       }
11933       switch (p->t38.our_parms.rate_management) {
11934       case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF:
11935          ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n");
11936          break;
11937       case AST_T38_RATE_MANAGEMENT_LOCAL_TCF:
11938          ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n");
11939          break;
11940       }
11941       ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl));
11942       switch (ast_udptl_get_error_correction_scheme(p->udptl)) {
11943       case UDPTL_ERROR_CORRECTION_NONE:
11944          break;
11945       case UDPTL_ERROR_CORRECTION_FEC:
11946          ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n");
11947          break;
11948       case UDPTL_ERROR_CORRECTION_REDUNDANCY:
11949          ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n");
11950          break;
11951       }
11952    }
11953 
11954    if (needaudio)
11955       ast_str_append(&m_audio, 0, "\r\n");
11956    if (needvideo)
11957       ast_str_append(&m_video, 0, "\r\n");
11958    if (needtext)
11959       ast_str_append(&m_text, 0, "\r\n");
11960 
11961    add_header(resp, "Content-Type", "application/sdp");
11962    add_content(resp, version);
11963    add_content(resp, owner);
11964    add_content(resp, subject);
11965    add_content(resp, connection);
11966    /* only if video response is appropriate */
11967    if (needvideo) {
11968       add_content(resp, bandwidth);
11969    }
11970    add_content(resp, session_time);
11971    /* if this is a response to an invite, order our offers properly */
11972    if (p->offered_media[SDP_AUDIO].order_offered ||
11973       p->offered_media[SDP_VIDEO].order_offered ||
11974       p->offered_media[SDP_TEXT].order_offered ||
11975       p->offered_media[SDP_IMAGE].order_offered) {
11976       int i;
11977       /* we have up to 3 streams as limited by process_sdp */
11978       for (i = 1; i <= 3; i++) {
11979          if (p->offered_media[SDP_AUDIO].order_offered == i) {
11980             if (needaudio) {
11981                add_content(resp, m_audio->str);
11982                add_content(resp, a_audio->str);
11983                add_content(resp, hold);
11984                if (a_crypto) {
11985                   add_content(resp, a_crypto);
11986                }
11987             } else {
11988                snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs);
11989                add_content(resp, dummy_answer);
11990             }
11991          } else if (p->offered_media[SDP_VIDEO].order_offered == i) {
11992             if (needvideo) { /* only if video response is appropriate */
11993                add_content(resp, m_video->str);
11994                add_content(resp, a_video->str);
11995                add_content(resp, hold);   /* Repeat hold for the video stream */
11996                if (v_a_crypto) {
11997                   add_content(resp, v_a_crypto);
11998                }
11999             } else {
12000                snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs);
12001                add_content(resp, dummy_answer);
12002             }
12003          } else if (p->offered_media[SDP_TEXT].order_offered == i) {
12004             if (needtext) { /* only if text response is appropriate */
12005                add_content(resp, m_text->str);
12006                add_content(resp, a_text->str);
12007                add_content(resp, hold);   /* Repeat hold for the text stream */
12008                if (t_a_crypto) {
12009                   add_content(resp, t_a_crypto);
12010                }
12011             } else {
12012                snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs);
12013                add_content(resp, dummy_answer);
12014             }
12015          } else if (p->offered_media[SDP_IMAGE].order_offered == i) {
12016             if (add_t38) {
12017                add_content(resp, m_modem->str);
12018                add_content(resp, a_modem->str);
12019             } else {
12020                add_content(resp, "m=image 0 udptl t38\r\n");
12021             }
12022          }
12023       }
12024    } else {
12025       /* generate new SDP from scratch, no offers */
12026       if (needaudio) {
12027          add_content(resp, m_audio->str);
12028          add_content(resp, a_audio->str);
12029          add_content(resp, hold);
12030          if (a_crypto) {
12031             add_content(resp, a_crypto);
12032          }
12033       }
12034       if (needvideo) { /* only if video response is appropriate */
12035          add_content(resp, m_video->str);
12036          add_content(resp, a_video->str);
12037          add_content(resp, hold);   /* Repeat hold for the video stream */
12038          if (v_a_crypto) {
12039             add_content(resp, v_a_crypto);
12040          }
12041       }
12042       if (needtext) { /* only if text response is appropriate */
12043          add_content(resp, m_text->str);
12044          add_content(resp, a_text->str);
12045          add_content(resp, hold);   /* Repeat hold for the text stream */
12046          if (t_a_crypto) {
12047             add_content(resp, t_a_crypto);
12048          }
12049       }
12050       if (add_t38) {
12051          add_content(resp, m_modem->str);
12052          add_content(resp, a_modem->str);
12053       }
12054    }
12055 
12056    /* Update lastrtprx when we send our SDP */
12057    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
12058 
12059    /*
12060     * We unlink this dialog and link again into the
12061     * dialogs_rtpcheck container so its not in there twice.
12062     */
12063    ao2_lock(dialogs_rtpcheck);
12064    ao2_t_unlink(dialogs_rtpcheck, p, "unlink pvt into dialogs_rtpcheck container");
12065    ao2_t_link(dialogs_rtpcheck, p, "link pvt into dialogs_rtpcheck container");
12066    ao2_unlock(dialogs_rtpcheck);
12067 
12068    ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmpcap));
12069 
12070 add_sdp_cleanup:
12071    alreadysent = ast_format_cap_destroy(alreadysent);
12072    tmpcap = ast_format_cap_destroy(tmpcap);
12073 
12074    return res;
12075 }

static int add_sip_domain ( const char *  domain,
const enum domain_mode  mode,
const char *  context 
) [static]

Add SIP domain to list of domains we are responsible for.

Definition at line 27895 of file chan_sip.c.

References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), and LOG_WARNING.

Referenced by reload_config().

27896 {
27897    struct domain *d;
27898 
27899    if (ast_strlen_zero(domain)) {
27900       ast_log(LOG_WARNING, "Zero length domain.\n");
27901       return 1;
27902    }
27903 
27904    if (!(d = ast_calloc(1, sizeof(*d))))
27905       return 0;
27906 
27907    ast_copy_string(d->domain, domain, sizeof(d->domain));
27908 
27909    if (!ast_strlen_zero(context))
27910       ast_copy_string(d->context, context, sizeof(d->context));
27911 
27912    d->mode = mode;
27913 
27914    AST_LIST_LOCK(&domain_list);
27915    AST_LIST_INSERT_TAIL(&domain_list, d, list);
27916    AST_LIST_UNLOCK(&domain_list);
27917 
27918    if (sipdebug)
27919       ast_debug(1, "Added local SIP domain '%s'\n", domain);
27920 
27921    return 1;
27922 }

static int add_supported_header ( struct sip_pvt *  pvt,
struct sip_request *  req 
) [static]

Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog.

Definition at line 10115 of file chan_sip.c.

References add_header(), and st_get_mode().

Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and update_connectedline().

10116 {
10117    int res;
10118    if (st_get_mode(pvt, 0) != SESSION_TIMER_MODE_REFUSE) {
10119       res = add_header(req, "Supported", "replaces, timer");
10120    } else {
10121       res = add_header(req, "Supported", "replaces");
10122    }
10123    return res;
10124 }

static void add_tcodec_to_sdp ( const struct sip_pvt *  p,
struct ast_format format,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

Add text codec offer to SDP offer/answer body in INVITE or 200 OK.

Definition at line 11416 of file chan_sip.c.

References ast_format_set(), AST_FORMAT_T140, AST_FORMAT_T140RED, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), ast_verbose, and ast_format::id.

Referenced by add_sdp().

11419 {
11420    int rtp_code;
11421 
11422    if (!p->trtp)
11423       return;
11424 
11425    if (debug)
11426       ast_verbose("Adding text codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
11427 
11428    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, format, 0)) == -1)
11429       return;
11430 
11431    ast_str_append(m_buf, 0, " %d", rtp_code);
11432    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
11433              ast_rtp_lookup_mime_subtype2(1, format, 0, 0),
11434              ast_rtp_lookup_sample_rate2(1, format, 0));
11435    /* Add fmtp code here */
11436 
11437    if (format->id == AST_FORMAT_T140RED) {
11438       struct ast_format tmp_fmt;
11439       int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, ast_format_set(&tmp_fmt, AST_FORMAT_T140, 0), 0);
11440       ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
11441           t140code,
11442           t140code,
11443           t140code);
11444 
11445    }
11446 }

static int add_text ( struct sip_request *  req,
struct sip_pvt *  p 
) [static]

Add text body to SIP message.

Definition at line 11142 of file chan_sip.c.

References add_content(), add_header(), AST_LIST_TRAVERSE, and ast_strlen_zero().

Referenced by transmit_message(), and transmit_request_with_auth().

11143 {
11144    const char *content_type = NULL;
11145    struct sip_msg_hdr *node;
11146 
11147    /* Add any additional MESSAGE headers. */
11148    AST_LIST_TRAVERSE(&p->msg_headers, node, next) {
11149       if (!strcasecmp(node->name, "Content-Type")) {
11150          /* Save content type */
11151          content_type = node->value;
11152       } else {
11153          add_header(req, node->name, node->value);
11154       }
11155    }
11156    if (ast_strlen_zero(content_type)) {
11157       /* "Content-Type" not set - use default value */
11158       content_type = "text/plain;charset=UTF-8";
11159    }
11160    add_header(req, "Content-Type", content_type);
11161 
11162    /* XXX Convert \n's to \r\n's XXX */
11163    add_content(req, p->msg_body);
11164    return 0;
11165 }

static struct ast_variable* add_var ( const char *  buf,
struct ast_variable list 
) [static, read]

implement the setvar config line

Definition at line 28075 of file chan_sip.c.

References ast_strdupa, ast_variable_new(), and ast_variable::next.

28076 {
28077    struct ast_variable *tmpvar = NULL;
28078    char *varname = ast_strdupa(buf), *varval = NULL;
28079    
28080    if ((varval = strchr(varname, '='))) {
28081       *varval++ = '\0';
28082       if ((tmpvar = ast_variable_new(varname, varval, ""))) {
28083          tmpvar->next = list;
28084          list = tmpvar;
28085       }
28086    }
28087    return list;
28088 }

static void add_vcodec_to_sdp ( const struct sip_pvt *  p,
struct ast_format format,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

Add video codec offer to SDP offer/answer body in INVITE or 200 OK.

Definition at line 11393 of file chan_sip.c.

References ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), ast_verbose, and ast_format::id.

Referenced by add_sdp().

11396 {
11397    int rtp_code;
11398 
11399    if (!p->vrtp)
11400       return;
11401 
11402    if (debug)
11403       ast_verbose("Adding video codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
11404 
11405    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, format, 0)) == -1)
11406       return;
11407 
11408    ast_str_append(m_buf, 0, " %d", rtp_code);
11409    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
11410              ast_rtp_lookup_mime_subtype2(1, format, 0, 0),
11411              ast_rtp_lookup_sample_rate2(1, format, 0));
11412    /* Add fmtp code here */
11413 }

static int add_vidupdate ( struct sip_request *  req  )  [static]

add XML encoded media control with update

Note:
XML: The only way to turn 0 bits of information into a few hundred. (markster)

Definition at line 11295 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_info_with_vidupdate().

11296 {
11297    const char *xml_is_a_huge_waste_of_space =
11298       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
11299       " <media_control>\r\n"
11300       "  <vc_primitive>\r\n"
11301       "   <to_encoder>\r\n"
11302       "    <picture_fast_update>\r\n"
11303       "    </picture_fast_update>\r\n"
11304       "   </to_encoder>\r\n"
11305       "  </vc_primitive>\r\n"
11306       " </media_control>\r\n";
11307    add_header(req, "Content-Type", "application/media_control+xml");
11308    add_content(req, xml_is_a_huge_waste_of_space);
11309    return 0;
11310 }

static const char * allowoverlap2str ( int  mode  )  [static]

Convert AllowOverlap setting to printable string.

Definition at line 17655 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

17656 {
17657    return map_x_s(allowoverlapstr, mode, "<error>");
17658 }

static void append_date ( struct sip_request *  req  )  [static]

Append date to SIP message.

Definition at line 10914 of file chan_sip.c.

References add_header().

10915 {
10916    char tmpdat[256];
10917    struct tm tm;
10918    time_t t = time(NULL);
10919 
10920    gmtime_r(&t, &tm);
10921    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
10922    add_header(req, "Date", tmpdat);
10923 }

static void append_history_full ( struct sip_pvt *  p,
const char *  fmt,
  ... 
) [static]

Append to SIP dialog history with arg list.

Definition at line 3555 of file chan_sip.c.

References append_history_va().

03556 {
03557    va_list ap;
03558 
03559    if (!p) {
03560       return;
03561    }
03562 
03563    if (!p->do_history && !recordhistory && !dumphistory) {
03564       return;
03565    }
03566 
03567    va_start(ap, fmt);
03568    append_history_va(p, fmt, ap);
03569    va_end(ap);
03570 
03571    return;
03572 }

static void append_history_va ( struct sip_pvt *  p,
const char *  fmt,
va_list  ap 
) [static]

Append to SIP dialog history with arg list.

Definition at line 3527 of file chan_sip.c.

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, and strsep().

Referenced by append_history_full().

03528 {
03529    char buf[80], *c = buf; /* max history length */
03530    struct sip_history *hist;
03531    int l;
03532 
03533    vsnprintf(buf, sizeof(buf), fmt, ap);
03534    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
03535    l = strlen(buf) + 1;
03536    if (!(hist = ast_calloc(1, sizeof(*hist) + l))) {
03537       return;
03538    }
03539    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
03540       ast_free(hist);
03541       return;
03542    }
03543    memcpy(hist->event, buf, l);
03544    if (p->history_entries == MAX_HISTORY_ENTRIES) {
03545       struct sip_history *oldest;
03546       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
03547       p->history_entries--;
03548       ast_free(oldest);
03549    }
03550    AST_LIST_INSERT_TAIL(p->history, hist, list);
03551    p->history_entries++;
03552 }

static int apply_directmedia_ha ( struct sip_pvt *  p,
const char *  op 
) [static]

Definition at line 30109 of file chan_sip.c.

References ast_apply_ha(), ast_debug, ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address(), AST_SENSE_ALLOW, AST_SENSE_DENY, ast_sockaddr_stringify(), and ast_strdupa.

Referenced by sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), and sip_get_vrtp_peer().

30110 {
30111    struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
30112    int res = AST_SENSE_ALLOW;
30113 
30114    ast_rtp_instance_get_remote_address(p->rtp, &them);
30115    ast_rtp_instance_get_local_address(p->rtp, &us);
30116 
30117    if ((res = ast_apply_ha(p->directmediaha, &them)) == AST_SENSE_DENY) {
30118       const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us));
30119       const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them));
30120 
30121       ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
30122          op, them_addr, us_addr);
30123    }
30124 
30125    return res;
30126 }

AST_DATA_STRUCTURE ( sip_peer  ,
DATA_EXPORT_SIP_PEER   
)

static void ast_quiet_chan ( struct ast_channel chan  )  [static]

Turn off generator data XXX Does this function belong in the SIP channel?

Definition at line 22382 of file chan_sip.c.

References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, ast_test_flag, and ast_channel::generatordata.

Referenced by attempt_transfer(), and handle_invite_replaces().

22383 {
22384    if (chan && chan->_state == AST_STATE_UP) {
22385       if (ast_test_flag(chan, AST_FLAG_MOH))
22386          ast_moh_stop(chan);
22387       else if (chan->generatordata)
22388          ast_deactivate_generator(chan);
22389    }
22390 }

static void ast_sip_ouraddrfor ( const struct ast_sockaddr them,
struct ast_sockaddr us,
struct sip_pvt *  p 
) [static]

NAT fix - decide which IP address to use for Asterisk server?

Using the localaddr structure built up with localnet statements in sip.conf apply it to their address to see if we need to substitute our externaddr or can get away with our internal bindaddr 'us' is always overwritten.

Definition at line 3421 of file chan_sip.c.

References ast_apply_ha(), ast_debug, ast_log(), ast_ouraddrfor(), AST_SENSE_ALLOW, ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), bindaddr, externaddr, internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, sip_cfg, and sip_get_transport().

Referenced by __sip_subscribe_mwi_do(), sip_alloc(), sip_cc_monitor_request_cc(), sip_msg_send(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and transmit_response_using_temp().

03422 {
03423    struct ast_sockaddr theirs;
03424 
03425    /* Set want_remap to non-zero if we want to remap 'us' to an externally
03426     * reachable IP address and port. This is done if:
03427     * 1. we have a localaddr list (containing 'internal' addresses marked
03428     *    as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them,
03429     *    and AST_SENSE_ALLOW on 'external' ones);
03430     * 2. externaddr is set, so we know what to use as the
03431     *    externally visible address;
03432     * 3. the remote address, 'them', is external;
03433     * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY
03434     *    when passed to ast_apply_ha() so it does need to be remapped.
03435     *    This fourth condition is checked later.
03436     */
03437    int want_remap = 0;
03438 
03439    ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */
03440    /* now ask the system what would it use to talk to 'them' */
03441    ast_ouraddrfor(them, us);
03442    ast_sockaddr_copy(&theirs, them);
03443 
03444    if (ast_sockaddr_is_ipv6(&theirs)) {
03445       if (localaddr && !ast_sockaddr_isnull(&externaddr)) {
03446          ast_log(LOG_WARNING, "Address remapping activated in sip.conf "
03447             "but we're using IPv6, which doesn't need it. Please "
03448             "remove \"localnet\" and/or \"externaddr\" settings.\n");
03449       }
03450    } else {
03451       want_remap = localaddr &&
03452          !ast_sockaddr_isnull(&externaddr) &&
03453          ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
03454    }
03455 
03456    if (want_remap &&
03457        (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) {
03458       /* if we used externhost, see if it is time to refresh the info */
03459       if (externexpire && time(NULL) >= externexpire) {
03460          if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
03461             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
03462          }
03463          externexpire = time(NULL) + externrefresh;
03464       }
03465       if (!ast_sockaddr_isnull(&externaddr)) {
03466          ast_sockaddr_copy(us, &externaddr);
03467          switch (p->socket.type) {
03468          case SIP_TRANSPORT_TCP:
03469             if (!externtcpport && ast_sockaddr_port(&externaddr)) {
03470                /* for consistency, default to the externaddr port */
03471                externtcpport = ast_sockaddr_port(&externaddr);
03472             }
03473             ast_sockaddr_set_port(us, externtcpport);
03474             break;
03475          case SIP_TRANSPORT_TLS:
03476             ast_sockaddr_set_port(us, externtlsport);
03477             break;
03478          case SIP_TRANSPORT_UDP:
03479             if (!ast_sockaddr_port(&externaddr)) {
03480                ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
03481             }
03482             break;
03483          default:
03484             break;
03485          }
03486       }
03487       ast_debug(1, "Target address %s is not local, substituting externaddr\n",
03488            ast_sockaddr_stringify(them));
03489    } else if (p) {
03490       /* no remapping, but we bind to a specific address, so use it. */
03491       switch (p->socket.type) {
03492       case SIP_TRANSPORT_TCP:
03493          if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) {
03494             ast_sockaddr_copy(us,
03495                     &sip_tcp_desc.local_address);
03496          } else {
03497             ast_sockaddr_set_port(us,
03498                         ast_sockaddr_port(&sip_tcp_desc.local_address));
03499          }
03500          break;
03501       case SIP_TRANSPORT_TLS:
03502          if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) {
03503             ast_sockaddr_copy(us,
03504                     &sip_tls_desc.local_address);
03505          } else {
03506             ast_sockaddr_set_port(us,
03507                         ast_sockaddr_port(&sip_tls_desc.local_address));
03508          }
03509          break;
03510       case SIP_TRANSPORT_UDP:
03511          /* fall through on purpose */
03512       default:
03513          if (!ast_sockaddr_is_any(&bindaddr)) {
03514             ast_sockaddr_copy(us, &bindaddr);
03515          }
03516          if (!ast_sockaddr_port(us)) {
03517             ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
03518          }
03519       }
03520    } else if (!ast_sockaddr_is_any(&bindaddr)) {
03521       ast_sockaddr_copy(us, &bindaddr);
03522    }
03523    ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", sip_get_transport(p->socket.type), ast_sockaddr_stringify(us));
03524 }

static int ast_sockaddr_resolve_first ( struct ast_sockaddr addr,
const char *  name,
int  flag 
) [static]

Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.

Using this function probably means you have a faulty design.

Definition at line 30813 of file chan_sip.c.

References ast_sockaddr_resolve_first_af(), bindaddr, and get_address_family_filter().

Referenced by __set_address_from_contact(), ast_sip_ouraddrfor(), check_via(), create_addr(), parse_register_contact(), process_via(), reload_config(), set_destination(), sip_do_debug_ip(), and sip_request_call().

30815 {
30816    return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(&bindaddr));
30817 }

static int ast_sockaddr_resolve_first_af ( struct ast_sockaddr addr,
const char *  name,
int  flag,
int  family 
) [static]

Return the first entry from ast_sockaddr_resolve filtered by address family.

Using this function probably means you have a faulty design.

Definition at line 30789 of file chan_sip.c.

References ast_debug, ast_free, ast_sockaddr_copy(), and ast_sockaddr_resolve().

Referenced by ast_sockaddr_resolve_first(), get_ip_and_port_from_sdp(), and process_sdp_c().

30791 {
30792    struct ast_sockaddr *addrs;
30793    int addrs_cnt;
30794 
30795    addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
30796    if (addrs_cnt <= 0) {
30797       return 1;
30798    }
30799    if (addrs_cnt > 1) {
30800       ast_debug(1, "Multiple addresses, using the first one only\n");
30801    }
30802 
30803    ast_sockaddr_copy(addr, &addrs[0]);
30804 
30805    ast_free(addrs);
30806    return 0;
30807 }

static int attempt_transfer ( struct sip_dual *  transferer,
struct sip_dual *  target 
) [static]

Attempt transfer of SIP call This fix for attended transfers on a local PBX.

Definition at line 22394 of file chan_sip.c.

References ast_channel_masquerade(), ast_channel_name(), ast_debug, ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), LOG_NOTICE, and LOG_WARNING.

22395 {
22396    int res = 0;
22397    struct ast_channel *peera = NULL,
22398       *peerb = NULL,
22399       *peerc = NULL,
22400       *peerd = NULL;
22401 
22402 
22403    /* We will try to connect the transferee with the target and hangup
22404       all channels to the transferer */
22405    ast_debug(4, "Sip transfer:--------------------\n");
22406    if (transferer->chan1)
22407       ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", ast_channel_name(transferer->chan1), ast_state2str(transferer->chan1->_state));
22408    else
22409       ast_debug(4, "-- No transferer first channel - odd??? \n");
22410    if (target->chan1)
22411       ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", ast_channel_name(target->chan1), ast_state2str(target->chan1->_state));
22412    else
22413       ast_debug(4, "-- No target first channel ---\n");
22414    if (transferer->chan2)
22415       ast_debug(4, "-- Bridged call to transferee: %s State %s\n", ast_channel_name(transferer->chan2), ast_state2str(transferer->chan2->_state));
22416    else
22417       ast_debug(4, "-- No bridged call to transferee\n");
22418    if (target->chan2)
22419       ast_debug(4, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? ast_channel_name(target->chan2) : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)");
22420    else
22421       ast_debug(4, "-- No target second channel ---\n");
22422    ast_debug(4, "-- END Sip transfer:--------------------\n");
22423    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
22424       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
22425       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
22426       peerc = transferer->chan2; /* Asterisk to Transferee */
22427       peerd = target->chan2;     /* Asterisk to Target */
22428       ast_debug(3, "SIP transfer: Four channels to handle\n");
22429    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
22430       peera = target->chan1;     /* Transferer to PBX -> target channel */
22431       peerb = transferer->chan1; /* Transferer to IVR*/
22432       peerc = target->chan2;     /* Asterisk to Target */
22433       peerd = transferer->chan2; /* Nothing */
22434       ast_debug(3, "SIP transfer: Three channels to handle\n");
22435    }
22436 
22437    if (peera && peerb && peerc && (peerb != peerc)) {
22438       ast_quiet_chan(peera);     /* Stop generators */
22439       ast_quiet_chan(peerb);
22440       ast_quiet_chan(peerc);
22441       if (peerd)
22442          ast_quiet_chan(peerd);
22443 
22444       ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", ast_channel_name(peerc), ast_channel_name(peerb));
22445       if (ast_channel_masquerade(peerb, peerc)) {
22446          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", ast_channel_name(peerb), ast_channel_name(peerc));
22447          res = -1;
22448       } else
22449          ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n");
22450       return res;
22451    } else {
22452       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
22453       if (transferer->chan1)
22454          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
22455       if (target->chan1)
22456          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
22457       return -1;
22458    }
22459    return 0;
22460 }

static int auto_congest ( const void *  arg  )  [static]

Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.

Definition at line 5593 of file chan_sip.c.

References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_queue_control(), sip_pvt_lock, sip_pvt_unlock, and sip_scheddestroy().

05594 {
05595    struct sip_pvt *p = (struct sip_pvt *)arg;
05596 
05597    sip_pvt_lock(p);
05598    p->initid = -1;   /* event gone, will not be rescheduled */
05599    if (p->owner) {
05600       /* XXX fails on possible deadlock */
05601       if (!ast_channel_trylock(p->owner)) {
05602          append_history(p, "Cong", "Auto-congesting (timer)");
05603          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
05604          ast_channel_unlock(p->owner);
05605       }
05606 
05607       /* Give the channel a chance to act before we proceed with destruction */
05608       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05609    }
05610    sip_pvt_unlock(p);
05611    dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)");
05612    return 0;
05613 }

static const char* autocreatepeer2str ( enum autocreatepeer_mode  r  )  [static]

Definition at line 17113 of file chan_sip.c.

References map_x_s().

Referenced by sip_show_settings().

17114 {
17115    return map_x_s(autopeermodes, r, "Unknown");
17116 }

static int block_msg_header ( const char *  header_name  )  [static]

Definition at line 24789 of file chan_sip.c.

References ARRAY_LEN.

Referenced by sip_msg_send().

24790 {
24791    int idx;
24792 
24793    /*
24794     * Don't block Content-Type or Max-Forwards headers because the
24795     * user can override them.
24796     */
24797    static const char *hdr[] = {
24798       "To",
24799       "From",
24800       "Via",
24801       "Route",
24802       "Contact",
24803       "Call-ID",
24804       "CSeq",
24805       "Allow",
24806       "Content-Length",
24807    };
24808 
24809    for (idx = 0; idx < ARRAY_LEN(hdr); ++idx) {
24810       if (!strcasecmp(header_name, hdr[idx])) {
24811          /* Block addition of this header. */
24812          return 1;
24813       }
24814    }
24815    return 0;
24816 }

static void build_callid_pvt ( struct sip_pvt *  pvt  )  [static]

Build SIP Call-ID value for a non-REGISTER transaction.

Note:
The passed in pvt must not be in a dialogs container since this function changes the hash key used by the container.

Definition at line 7690 of file chan_sip.c.

References ast_sockaddr_stringify_remote(), ast_string_field_build, generate_random_string(), and S_OR.

Referenced by change_callid_pvt(), and sip_alloc().

07691 {
07692    char buf[33];
07693    const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify_remote(&pvt->ourip));
07694 
07695    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
07696 }

static void build_callid_registry ( struct sip_registry *  reg,
const struct ast_sockaddr ourip,
const char *  fromdomain 
) [static]

Build SIP Call-ID value for a REGISTER transaction.

Definition at line 7748 of file chan_sip.c.

References ast_sockaddr_stringify_host_remote(), ast_string_field_build, generate_random_string(), and S_OR.

Referenced by transmit_register().

07749 {
07750    char buf[33];
07751 
07752    const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host_remote(ourip));
07753 
07754    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
07755 }

static void build_contact ( struct sip_pvt *  p  )  [static]

Build contact header - the contact header we send out.

Definition at line 12319 of file chan_sip.c.

References ast_sockaddr_stringify_remote(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), ast_uri_sip_user, and sip_get_transport().

Referenced by __sip_subscribe_mwi_do(), check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().

12320 {
12321    char tmp[SIPBUFSIZE];
12322    char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), ast_uri_sip_user);
12323 
12324    if (p->socket.type == SIP_TRANSPORT_UDP) {
12325       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user,
12326          ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip));
12327    } else {
12328       ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user,
12329          ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip),
12330          sip_get_transport(p->socket.type));
12331    }
12332 }

static struct sip_peer * build_peer ( const char *  name,
struct ast_variable v,
struct ast_variable alt,
int  realtime,
int  devstate_only 
) [static, read]

Build peer from configuration (file or realtime static/dynamic).

< The first transport listed should be default outbound

Definition at line 28235 of file chan_sip.c.

References __set_address_from_contact(), accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), ao2_alloc, ao2_lock, ao2_t_alloc, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, asprintf, ast_append_ha(), ast_atomic_fetchadd_int(), ast_callerid_split(), AST_CC_AGENT_NATIVE, AST_CC_AGENT_NEVER, ast_cc_config_params_init, ast_cc_is_config_param(), ast_cc_set_param(), ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_debug, ast_dnsmgr_lookup_cb(), ast_dnsmgr_refresh(), ast_format_cap_alloc_nolock(), ast_free, ast_free_ha(), ast_get_cc_agent_policy(), ast_get_group(), ast_get_indication_zone(), ast_get_ip(), ast_get_time_t(), AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL_UNREF, ast_set2_flag, ast_set_cc_agent_policy(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_tone_zone_unref(), ast_true(), ast_variables_destroy(), bindaddr, cid_name, cid_num, context, DEFAULT_MAXMS, destroy_association(), destroy_mailbox(), ast_tls_config::enabled, errno, FALSE, ast_flags::flags, format, get_address_family_filter(), get_srv_protocol(), get_srv_service(), handle_common_options(), handle_t38_options(), language, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, mark_parsed_methods(), MAXHOSTNAMELEN, mohinterpret, mohsuggest, ast_variable::name, ast_variable::next, OBJ_POINTER, OBJ_UNLINK, on_dns_update_peer(), parkinglot, PARSE_PORT_FORBID, port_str2int(), proxy_update(), reg_source_db(), secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), sip_parse_host(), sip_poke_peer(), sip_ref_peer(), sip_register(), sip_send_mwi_to_peer(), sip_unref_peer(), srvlookup, str2stmode(), str2strefresher(), strsep(), TRUE, and ast_variable::value.

28236 {
28237    struct sip_peer *peer = NULL;
28238    struct ast_ha *oldha = NULL;
28239    struct ast_ha *olddirectmediaha = NULL;
28240    int found = 0;
28241    int firstpass = 1;
28242    uint16_t port = 0;
28243    int format = 0;      /* Ama flags */
28244    int timerb_set = 0, timert1_set = 0;
28245    time_t regseconds = 0;
28246    struct ast_flags peerflags[3] = {{(0)}};
28247    struct ast_flags mask[3] = {{(0)}};
28248    struct sip_peer tmp_peer;
28249    const char *srvlookup = NULL;
28250    static int deprecation_warning = 1;
28251    int alt_fullcontact = alt ? 1 : 0, headercount = 0;
28252    struct ast_str *fullcontact = ast_str_alloca(512);
28253 
28254    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
28255       /* Note we do NOT use sip_find_peer here, to avoid realtime recursion */
28256       /* We also use a case-sensitive comparison (unlike sip_find_peer) so
28257          that case changes made to the peer name will be properly handled
28258          during reload
28259       */
28260       ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name));
28261       peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table");
28262    }
28263 
28264    if (peer) {
28265       /* Already in the list, remove it and it will be added back (or FREE'd)  */
28266       found++;
28267       /* we've unlinked the peer from the peers container but not unlinked from the peers_by_ip container yet
28268         this leads to a wrong refcounter and the peer object is never destroyed */
28269       if (!ast_sockaddr_isnull(&peer->addr)) {
28270          ao2_t_unlink(peers_by_ip, peer, "ao2_unlink peer from peers_by_ip table");
28271       }
28272       if (!(peer->the_mark))
28273          firstpass = 0;
28274    } else {
28275       if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) {
28276          return NULL;
28277       }
28278       if (!(peer->caps = ast_format_cap_alloc_nolock())) {
28279          ao2_t_ref(peer, -1, "failed to allocate format capabilities, drop peer");
28280          return NULL;
28281       }
28282       if (ast_string_field_init(peer, 512)) {
28283          ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
28284          return NULL;
28285       }
28286 
28287       if (!(peer->cc_params = ast_cc_config_params_init())) {
28288          ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
28289          return NULL;
28290       }
28291 
28292       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
28293          ast_atomic_fetchadd_int(&rpeerobjs, 1);
28294          ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs);
28295       } else
28296          ast_atomic_fetchadd_int(&speerobjs, 1);
28297    }
28298 
28299    /* Note that our peer HAS had its reference count increased */
28300    if (firstpass) {
28301       oldha = peer->ha;
28302       peer->ha = NULL;
28303       olddirectmediaha = peer->directmediaha;
28304       peer->directmediaha = NULL;
28305       set_peer_defaults(peer);   /* Set peer defaults */
28306       peer->type = 0;
28307    }
28308 
28309    /* in case the case of the peer name has changed, update the name */
28310    ast_copy_string(peer->name, name, sizeof(peer->name));
28311 
28312    /* If we have channel variables, remove them (reload) */
28313    if (peer->chanvars) {
28314       ast_variables_destroy(peer->chanvars);
28315       peer->chanvars = NULL;
28316       /* XXX should unregister ? */
28317    }
28318 
28319    if (found)
28320       peer->portinuri = 0;
28321 
28322    /* If we have realm authentication information, remove them (reload) */
28323    ao2_lock(peer);
28324    if (peer->auth) {
28325       ao2_t_ref(peer->auth, -1, "Removing old peer authentication");
28326       peer->auth = NULL;
28327    }
28328    ao2_unlock(peer);
28329 
28330    /* clear the transport information.  We will detect if a default value is required after parsing the config */
28331    peer->default_outbound_transport = 0;
28332    peer->transports = 0;
28333 
28334    if (!devstate_only) {
28335       struct sip_mailbox *mailbox;
28336       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
28337          mailbox->delme = 1;
28338       }
28339    }
28340 
28341    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
28342       if (!devstate_only) {
28343          if (handle_common_options(&peerflags[0], &mask[0], v)) {
28344             continue;
28345          }
28346          if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) {
28347             continue;
28348          }
28349          if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) {
28350             char *val = ast_strdupa(v->value);
28351             char *trans;
28352 
28353             while ((trans = strsep(&val, ","))) {
28354                trans = ast_skip_blanks(trans);
28355 
28356                if (!strncasecmp(trans, "udp", 3)) {
28357                   peer->transports |= SIP_TRANSPORT_UDP;
28358                } else if (sip_cfg.tcp_enabled && !strncasecmp(trans, "tcp", 3)) {
28359                   peer->transports |= SIP_TRANSPORT_TCP;
28360                } else if (default_tls_cfg.enabled && !strncasecmp(trans, "tls", 3)) {
28361                   peer->transports |= SIP_TRANSPORT_TLS;
28362                } else if (!strncasecmp(trans, "tcp", 3) || !strncasecmp(trans, "tls", 3)) {
28363                   ast_log(LOG_WARNING, "'%.3s' is not a valid transport type when %.3senabled=no. If no other is specified, the defaults from general will be used.\n", trans, trans);
28364                } else {
28365                   ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, the defaults from general will be used.\n", trans);
28366                }
28367 
28368                if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */
28369                   peer->default_outbound_transport = peer->transports;
28370                }
28371             }
28372          } else if (realtime && !strcasecmp(v->name, "regseconds")) {
28373             ast_get_time_t(v->value, &regseconds, 0, NULL);
28374          } else if (realtime && !strcasecmp(v->name, "name")) {
28375             ast_copy_string(peer->name, v->value, sizeof(peer->name));
28376          } else if (realtime && !strcasecmp(v->name, "useragent")) {
28377             ast_string_field_set(peer, useragent, v->value);
28378          } else if (!strcasecmp(v->name, "type")) {
28379             if (!strcasecmp(v->value, "peer")) {
28380                peer->type |= SIP_TYPE_PEER;
28381             } else if (!strcasecmp(v->value, "user")) {
28382                peer->type |= SIP_TYPE_USER;
28383             } else if (!strcasecmp(v->value, "friend")) {
28384                peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
28385             }
28386          } else if (!strcasecmp(v->name, "remotesecret")) {
28387             ast_string_field_set(peer, remotesecret, v->value);
28388          } else if (!strcasecmp(v->name, "secret")) {
28389             ast_string_field_set(peer, secret, v->value);
28390          } else if (!strcasecmp(v->name, "description")) {
28391             ast_string_field_set(peer, description, v->value);
28392          } else if (!strcasecmp(v->name, "md5secret")) {
28393             ast_string_field_set(peer, md5secret, v->value);
28394          } else if (!strcasecmp(v->name, "auth")) {
28395             add_realm_authentication(&peer->auth, v->value, v->lineno);
28396          } else if (!strcasecmp(v->name, "callerid")) {
28397             char cid_name[80] = { '\0' }, cid_num[80] = { '\0' };
28398 
28399             ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
28400             ast_string_field_set(peer, cid_name, cid_name);
28401             ast_string_field_set(peer, cid_num, cid_num);
28402          } else if (!strcasecmp(v->name, "mwi_from")) {
28403             ast_string_field_set(peer, mwi_from, v->value);
28404          } else if (!strcasecmp(v->name, "fullname")) {
28405             ast_string_field_set(peer, cid_name, v->value);
28406          } else if (!strcasecmp(v->name, "trunkname")) {
28407             /* This is actually for a trunk, so we don't want to override callerid */
28408             ast_string_field_set(peer, cid_name, "");
28409          } else if (!strcasecmp(v->name, "cid_number")) {
28410             ast_string_field_set(peer, cid_num, v->value);
28411          } else if (!strcasecmp(v->name, "cid_tag")) {
28412             ast_string_field_set(peer, cid_tag, v->value);
28413          } else if (!strcasecmp(v->name, "context")) {
28414             ast_string_field_set(peer, context, v->value);
28415             ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT);
28416          } else if (!strcasecmp(v->name, "recordonfeature")) {
28417             ast_string_field_set(peer, record_on_feature, v->value);
28418          } else if (!strcasecmp(v->name, "recordofffeature")) {
28419             ast_string_field_set(peer, record_off_feature, v->value);
28420          } else if (!strcasecmp(v->name, "outofcall_message_context")) {
28421             ast_string_field_set(peer, messagecontext, v->value);
28422          } else if (!strcasecmp(v->name, "subscribecontext")) {
28423             ast_string_field_set(peer, subscribecontext, v->value);
28424          } else if (!strcasecmp(v->name, "fromdomain")) {
28425             char *fromdomainport;
28426             ast_string_field_set(peer, fromdomain, v->value);
28427             if ((fromdomainport = strchr(peer->fromdomain, ':'))) {
28428                *fromdomainport++ = '\0';
28429                if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) {
28430                   ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
28431                }
28432             } else {
28433                peer->fromdomainport = STANDARD_SIP_PORT;
28434             }
28435          } else if (!strcasecmp(v->name, "usereqphone")) {
28436             ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
28437          } else if (!strcasecmp(v->name, "fromuser")) {
28438             ast_string_field_set(peer, fromuser, v->value);
28439          } else if (!strcasecmp(v->name, "outboundproxy")) {
28440             char *tok, *proxyname;
28441 
28442             if (ast_strlen_zero(v->value)) {
28443                ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno);
28444                continue;
28445             }
28446 
28447             peer->outboundproxy =
28448                 ao2_alloc(sizeof(*peer->outboundproxy), NULL);
28449 
28450             tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
28451 
28452             sip_parse_host(tok, v->lineno, &proxyname,
28453                       &peer->outboundproxy->port,
28454                       &peer->outboundproxy->transport);
28455 
28456             tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
28457 
28458             if ((tok = strtok(NULL, ","))) {
28459                peer->outboundproxy->force = !strncasecmp(ast_skip_blanks(tok), "force", 5);
28460             } else {
28461                peer->outboundproxy->force = FALSE;
28462             }
28463 
28464             if (ast_strlen_zero(proxyname)) {
28465                ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno);
28466                sip_cfg.outboundproxy.name[0] = '\0';
28467                continue;
28468             }
28469 
28470             ast_copy_string(peer->outboundproxy->name, proxyname, sizeof(peer->outboundproxy->name));
28471 
28472             proxy_update(peer->outboundproxy);
28473          } else if (!strcasecmp(v->name, "host")) {
28474             if (!strcasecmp(v->value, "dynamic")) {
28475                /* They'll register with us */
28476                if (!found || !peer->host_dynamic) {
28477                   /* Initialize stuff if this is a new peer, or if it used to
28478                    * not be dynamic before the reload. */
28479                   ast_sockaddr_setnull(&peer->addr);
28480                }
28481                peer->host_dynamic = TRUE;
28482             } else {
28483                /* Non-dynamic.  Make sure we become that way if we're not */
28484                AST_SCHED_DEL_UNREF(sched, peer->expire,
28485                      sip_unref_peer(peer, "removing register expire ref"));
28486                peer->host_dynamic = FALSE;
28487                srvlookup = v->value;
28488             }
28489          } else if (!strcasecmp(v->name, "defaultip")) {
28490             if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) {
28491                sip_unref_peer(peer, "sip_unref_peer: from build_peer defaultip");
28492                return NULL;
28493             }
28494          } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
28495             int ha_error = 0;
28496             if (!ast_strlen_zero(v->value)) {
28497                peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
28498             }
28499             if (ha_error) {
28500                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
28501             }
28502          } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
28503             int ha_error = 0;
28504             if (!ast_strlen_zero(v->value)) {
28505                peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error);
28506             }
28507             if (ha_error) {
28508                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
28509             }
28510          } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) {
28511             int ha_error = 0;
28512             peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error);
28513             if (ha_error) {
28514                ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value);
28515             }
28516          } else if (!strcasecmp(v->name, "port")) {
28517             peer->portinuri = 1;
28518             if (!(port = port_str2int(v->value, 0))) {
28519                if (realtime) {
28520                   /* If stored as integer, could be 0 for some DBs (notably MySQL) */
28521                   peer->portinuri = 0;
28522                } else {
28523                   ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value);
28524                }
28525             }
28526          } else if (!strcasecmp(v->name, "callingpres")) {
28527             peer->callingpres = ast_parse_caller_presentation(v->value);
28528             if (peer->callingpres == -1) {
28529                peer->callingpres = atoi(v->value);
28530             }
28531          } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) {   /* "username" is deprecated */
28532             ast_string_field_set(peer, username, v->value);
28533             if (!strcasecmp(v->name, "username")) {
28534                if (deprecation_warning) {
28535                   ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n");
28536                   deprecation_warning = 0;
28537                }
28538                peer->deprecated_username = 1;
28539             }
28540          } else if (!strcasecmp(v->name, "tonezone")) {
28541             struct ast_tone_zone *new_zone;
28542             if (!(new_zone = ast_get_indication_zone(v->value))) {
28543                ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone in device [%s] at line %d. Check indications.conf for available country codes.\n", v->value, peer->name, v->lineno);
28544             } else {
28545                ast_tone_zone_unref(new_zone);
28546                ast_string_field_set(peer, zone, v->value);
28547             }
28548          } else if (!strcasecmp(v->name, "language")) {
28549             ast_string_field_set(peer, language, v->value);
28550          } else if (!strcasecmp(v->name, "regexten")) {
28551             ast_string_field_set(peer, regexten, v->value);
28552          } else if (!strcasecmp(v->name, "callbackextension")) {
28553             ast_string_field_set(peer, callback, v->value);
28554          } else if (!strcasecmp(v->name, "amaflags")) {
28555             format = ast_cdr_amaflags2int(v->value);
28556             if (format < 0) {
28557                ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
28558             } else {
28559                peer->amaflags = format;
28560             }
28561          } else if (!strcasecmp(v->name, "maxforwards")) {
28562             if (sscanf(v->value, "%30d", &peer->maxforwards) != 1
28563                || peer->maxforwards < 1 || 255 < peer->maxforwards) {
28564                ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d.  Using default.\n", v->value, v->lineno);
28565                peer->maxforwards = sip_cfg.default_max_forwards;
28566             }
28567          } else if (!strcasecmp(v->name, "accountcode")) {
28568             ast_string_field_set(peer, accountcode, v->value);
28569          } else if (!strcasecmp(v->name, "mohinterpret")) {
28570             ast_string_field_set(peer, mohinterpret, v->value);
28571          } else if (!strcasecmp(v->name, "mohsuggest")) {
28572             ast_string_field_set(peer, mohsuggest, v->value);
28573          } else if (!strcasecmp(v->name, "parkinglot")) {
28574             ast_string_field_set(peer, parkinglot, v->value);
28575          } else if (!strcasecmp(v->name, "rtp_engine")) {
28576             ast_string_field_set(peer, engine, v->value);
28577          } else if (!strcasecmp(v->name, "mailbox")) {
28578             add_peer_mailboxes(peer, v->value);
28579          } else if (!strcasecmp(v->name, "hasvoicemail")) {
28580             /* People expect that if 'hasvoicemail' is set, that the mailbox will
28581              * be also set, even if not explicitly specified. */
28582             if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) {
28583                add_peer_mailboxes(peer, name);
28584             }
28585          } else if (!strcasecmp(v->name, "subscribemwi")) {
28586             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
28587          } else if (!strcasecmp(v->name, "vmexten")) {
28588             ast_string_field_set(peer, vmexten, v->value);
28589          } else if (!strcasecmp(v->name, "callgroup")) {
28590             peer->callgroup = ast_get_group(v->value);
28591          } else if (!strcasecmp(v->name, "allowtransfer")) {
28592             peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
28593          } else if (!strcasecmp(v->name, "pickupgroup")) {
28594             peer->pickupgroup = ast_get_group(v->value);
28595          } else if (!strcasecmp(v->name, "allow")) {
28596             int error = ast_parse_allow_disallow(&peer->prefs, peer->caps, v->value, TRUE);
28597             if (error) {
28598                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
28599             }
28600          } else if (!strcasecmp(v->name, "disallow")) {
28601             int error =  ast_parse_allow_disallow(&peer->prefs, peer->caps, v->value, FALSE);
28602             if (error) {
28603                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
28604             }
28605          } else if (!strcasecmp(v->name, "preferred_codec_only")) {
28606             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
28607          } else if (!strcasecmp(v->name, "autoframing")) {
28608             peer->autoframing = ast_true(v->value);
28609          } else if (!strcasecmp(v->name, "rtptimeout")) {
28610             if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
28611                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
28612                peer->rtptimeout = global_rtptimeout;
28613             }
28614          } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
28615             if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
28616                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
28617                peer->rtpholdtimeout = global_rtpholdtimeout;
28618             }
28619          } else if (!strcasecmp(v->name, "rtpkeepalive")) {
28620             if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
28621                ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
28622                peer->rtpkeepalive = global_rtpkeepalive;
28623             }
28624          } else if (!strcasecmp(v->name, "timert1")) {
28625             if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) {
28626                ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d.  Using default.\n", v->value, v->lineno);
28627                peer->timer_t1 = global_t1min;
28628             }
28629             timert1_set = 1;
28630          } else if (!strcasecmp(v->name, "timerb")) {
28631             if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) {
28632                ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d.  Using default.\n", v->value, v->lineno);
28633                peer->timer_b = global_timer_b;
28634             }
28635             timerb_set = 1;
28636          } else if (!strcasecmp(v->name, "setvar")) {
28637             peer->chanvars = add_var(v->value, peer->chanvars);
28638          } else if (!strcasecmp(v->name, "header")) {
28639             char tmp[4096];
28640             snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value);
28641             peer->chanvars = add_var(tmp, peer->chanvars);
28642          } else if (!strcasecmp(v->name, "qualifyfreq")) {
28643             int i;
28644             if (sscanf(v->value, "%30d", &i) == 1) {
28645                peer->qualifyfreq = i * 1000;
28646             } else {
28647                ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
28648                peer->qualifyfreq = global_qualifyfreq;
28649             }
28650          } else if (!strcasecmp(v->name, "maxcallbitrate")) {
28651             peer->maxcallbitrate = atoi(v->value);
28652             if (peer->maxcallbitrate < 0) {
28653                peer->maxcallbitrate = default_maxcallbitrate;
28654             }
28655          } else if (!strcasecmp(v->name, "session-timers")) {
28656             int i = (int) str2stmode(v->value);
28657             if (i < 0) {
28658                ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
28659                peer->stimer.st_mode_oper = global_st_mode;
28660             } else {
28661                peer->stimer.st_mode_oper = i;
28662             }
28663          } else if (!strcasecmp(v->name, "session-expires")) {
28664             if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) {
28665                ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
28666                peer->stimer.st_max_se = global_max_se;
28667             }
28668          } else if (!strcasecmp(v->name, "session-minse")) {
28669             if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) {
28670                ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
28671                peer->stimer.st_min_se = global_min_se;
28672             }
28673             if (peer->stimer.st_min_se < 90) {
28674                ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config);
28675                peer->stimer.st_min_se = global_min_se;
28676             }
28677          } else if (!strcasecmp(v->name, "session-refresher")) {
28678             int i = (int) str2strefresher(v->value);
28679             if (i < 0) {
28680                ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
28681                peer->stimer.st_ref = global_st_refresher;
28682             } else {
28683                peer->stimer.st_ref = i;
28684             }
28685          } else if (!strcasecmp(v->name, "disallowed_methods")) {
28686             char *disallow = ast_strdupa(v->value);
28687             mark_parsed_methods(&peer->disallowed_methods, disallow);
28688          } else if (!strcasecmp(v->name, "unsolicited_mailbox")) {
28689             ast_string_field_set(peer, unsolicited_mailbox, v->value);
28690          } else if (!strcasecmp(v->name, "use_q850_reason")) {
28691             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
28692          } else if (!strcasecmp(v->name, "encryption")) {
28693             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP);
28694          } else if (!strcasecmp(v->name, "encryption_taglen")) {
28695             ast_set2_flag(&peer->flags[2], !strcasecmp(v->value, "32"), SIP_PAGE3_SRTP_TAG_32);
28696          } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
28697             ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
28698          }
28699       }
28700 
28701       /* These apply to devstate lookups */
28702       if (realtime && !strcasecmp(v->name, "lastms")) {
28703          sscanf(v->value, "%30d", &peer->lastms);
28704       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
28705          ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID);
28706       } else if (realtime && !strcasecmp(v->name, "fullcontact")) {
28707          if (alt_fullcontact && !alt) {
28708             /* Reset, because the alternate also has a fullcontact and we
28709              * do NOT want the field value to be doubled. It might be
28710              * tempting to skip this, but the first table might not have
28711              * fullcontact and since we're here, we know that the alternate
28712              * absolutely does. */
28713             alt_fullcontact = 0;
28714             ast_str_reset(fullcontact);
28715          }
28716          /* Reconstruct field, because realtime separates our value at the ';' */
28717          if (fullcontact->used > 0) {
28718             ast_str_append(&fullcontact, 0, ";%s", v->value);
28719          } else {
28720             ast_str_set(&fullcontact, 0, "%s", v->value);
28721          }
28722       } else if (!strcasecmp(v->name, "qualify")) {
28723          if (!strcasecmp(v->value, "no")) {
28724             peer->maxms = 0;
28725          } else if (!strcasecmp(v->value, "yes")) {
28726             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
28727          } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
28728             ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
28729             peer->maxms = 0;
28730          }
28731          if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
28732             /* This would otherwise cause a network storm, where the
28733              * qualify response refreshes the peer from the database,
28734              * which in turn causes another qualify to be sent, ad
28735              * infinitum. */
28736             ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime.  Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name);
28737             peer->maxms = 0;
28738          }
28739       } else if (!strcasecmp(v->name, "callcounter")) {
28740          peer->call_limit = ast_true(v->value) ? INT_MAX : 0;
28741       } else if (!strcasecmp(v->name, "call-limit")) {
28742          peer->call_limit = atoi(v->value);
28743          if (peer->call_limit < 0) {
28744             peer->call_limit = 0;
28745          }
28746       } else if (!strcasecmp(v->name, "busylevel")) {
28747          peer->busy_level = atoi(v->value);
28748          if (peer->busy_level < 0) {
28749             peer->busy_level = 0;
28750          }
28751       } else if (ast_cc_is_config_param(v->name)) {
28752          ast_cc_set_param(peer->cc_params, v->name, v->value);
28753       }
28754    }
28755 
28756    if (!devstate_only) {
28757       struct sip_mailbox *mailbox;
28758       AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) {
28759          if (mailbox->delme) {
28760             AST_LIST_REMOVE_CURRENT(entry);
28761             destroy_mailbox(mailbox);
28762          }
28763       }
28764       AST_LIST_TRAVERSE_SAFE_END;
28765    }
28766 
28767    if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) {
28768       ast_log(LOG_WARNING, "Peer %s has a cc_agent_policy of 'native' but required libxml2 dependency is not installed. Changing policy to 'never'\n", peer->name);
28769       ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER);
28770    }
28771 
28772    /* Note that Timer B is dependent upon T1 and MUST NOT be lower
28773     * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */
28774    if (peer->timer_b < peer->timer_t1 * 64) {
28775       if (timerb_set && timert1_set) {
28776          ast_log(LOG_WARNING, "Timer B has been set lower than recommended for peer %s (%d < 64 * Timer-T1=%d)\n", peer->name, peer->timer_b, peer->timer_t1);
28777       } else if (timerb_set) {
28778          if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) {
28779             ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", peer->timer_b, peer->timer_t1);
28780             peer->timer_t1 = global_t1min;
28781             peer->timer_b = peer->timer_t1 * 64;
28782          }
28783          peer->timer_t1 = peer->timer_b / 64;
28784       } else {
28785          peer->timer_b = peer->timer_t1 * 64;
28786       }
28787    }
28788 
28789    if (!peer->default_outbound_transport) {
28790       /* Set default set of transports */
28791       peer->transports = default_transports;
28792       /* Set default primary transport */
28793       peer->default_outbound_transport = default_primary_transport;
28794    }
28795 
28796    /* The default transport type set during build_peer should only replace the socket.type when...
28797     * 1. Registration is not present and the socket.type and default transport types are different.
28798     * 2. The socket.type is not an acceptable transport type after rebuilding peer.
28799     * 3. The socket.type is not set yet. */
28800    if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) ||
28801       !(peer->socket.type & peer->transports) || !(peer->socket.type)) {
28802 
28803       set_socket_transport(&peer->socket, peer->default_outbound_transport);
28804    }
28805 
28806    if (ast_str_strlen(fullcontact)) {
28807       ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact));
28808       peer->rt_fromcontact = TRUE;
28809       /* We have a hostname in the fullcontact, but if we don't have an
28810        * address listed on the entry (or if it's 'dynamic'), then we need to
28811        * parse the entry to obtain the IP address, so a dynamic host can be
28812        * contacted immediately after reload (as opposed to waiting for it to
28813        * register once again). But if we have an address for this peer and NAT was
28814        * specified, use that address instead. */
28815       /* XXX May need to revisit the final argument; does the realtime DB store whether
28816        * the original contact was over TLS or not? XXX */
28817       if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) || ast_sockaddr_isnull(&peer->addr)) {
28818          __set_address_from_contact(fullcontact->str, &peer->addr, 0);
28819       }
28820    }
28821 
28822    if (srvlookup && peer->dnsmgr == NULL) {
28823       char transport[MAXHOSTNAMELEN];
28824       char _srvlookup[MAXHOSTNAMELEN];
28825       char *params;
28826 
28827       ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup));
28828       if ((params = strchr(_srvlookup, ';'))) {
28829          *params++ = '\0';
28830       }
28831 
28832       snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type));
28833 
28834       peer->addr.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
28835       if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL,
28836                on_dns_update_peer, sip_ref_peer(peer, "Store peer on dnsmgr"))) {
28837          ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
28838          sip_unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref");
28839          sip_unref_peer(peer, "getting rid of a peer pointer");
28840          return NULL;
28841       }
28842       if (!peer->dnsmgr) {
28843          /* dnsmgr refresh disabeld, release reference */
28844          sip_unref_peer(peer, "dnsmgr disabled, unref peer");
28845       }
28846 
28847       ast_string_field_set(peer, tohost, srvlookup);
28848 
28849       if (global_dynamic_exclude_static) {
28850          int ha_error = 0;
28851          sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 
28852                      sip_cfg.contact_ha, &ha_error);
28853          if (ha_error) {
28854             ast_log(LOG_ERROR, "Bad or unresolved host/IP entry in configuration for peer %s, cannot add to contact ACL\n", peer->name);
28855          }
28856       }
28857    } else if (peer->dnsmgr && !peer->host_dynamic) {
28858       /* force a refresh here on reload if dnsmgr already exists and host is set. */
28859       ast_dnsmgr_refresh(peer->dnsmgr);
28860    }
28861 
28862    if (port && !realtime && peer->host_dynamic) {
28863       ast_sockaddr_set_port(&peer->defaddr, port);
28864    } else if (port) {
28865       ast_sockaddr_set_port(&peer->addr, port);
28866    }
28867 
28868    if (ast_sockaddr_port(&peer->addr) == 0) {
28869       ast_sockaddr_set_port(&peer->addr,
28870                   (peer->socket.type & SIP_TRANSPORT_TLS) ?
28871                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
28872    }
28873    if (ast_sockaddr_port(&peer->defaddr) == 0) {
28874       ast_sockaddr_set_port(&peer->defaddr,
28875                   (peer->socket.type & SIP_TRANSPORT_TLS) ?
28876                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
28877    }
28878    if (!peer->socket.port) {
28879       peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
28880    }
28881 
28882    if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) {
28883       time_t nowtime = time(NULL);
28884 
28885       if ((nowtime - regseconds) > 0) {
28886          destroy_association(peer);
28887          memset(&peer->addr, 0, sizeof(peer->addr));
28888          peer->lastms = -1;
28889          ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
28890       }
28891    }
28892 
28893    /* Startup regular pokes */
28894    if (!devstate_only && realtime && peer->lastms > 0) {
28895       sip_ref_peer(peer, "schedule qualify");
28896       sip_poke_peer(peer, 0);
28897    }
28898 
28899    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
28900    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
28901    ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags);
28902    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
28903       sip_cfg.allowsubscribe = TRUE;   /* No global ban any more */
28904    }
28905    /* If read-only RT backend, then refresh from local DB cache */
28906    if (peer->host_dynamic && (!peer->is_realtime || !sip_cfg.peer_rtupdate)) {
28907       reg_source_db(peer);
28908    }
28909 
28910    /* If they didn't request that MWI is sent *only* on subscribe, go ahead and
28911     * subscribe to it now. */
28912    if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
28913       !AST_LIST_EMPTY(&peer->mailboxes)) {
28914       add_peer_mwi_subs(peer);
28915       /* Send MWI from the event cache only.  This is so we can send initial
28916        * MWI if app_voicemail got loaded before chan_sip.  If it is the other
28917        * way, then we will get events when app_voicemail gets loaded. */
28918       sip_send_mwi_to_peer(peer, 1);
28919    }
28920 
28921    peer->the_mark = 0;
28922 
28923    ast_free_ha(oldha);
28924    ast_free_ha(olddirectmediaha);
28925    if (!ast_strlen_zero(peer->callback)) { /* build string from peer info */
28926       char *reg_string;
28927       if (asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, peer->callback) < 0) {
28928          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
28929       } else if (reg_string) {
28930          sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
28931          ast_free(reg_string);
28932       }
28933    }
28934    return peer;
28935 }

static int build_reply_digest ( struct sip_pvt *  p,
int  method,
char *  digest,
int  digest_len 
) [static]

Build reply digest.

Returns:
Returns -1 if we have no auth
Note:
Build digest challenge for authentication of registrations and calls Also used for authentication of BYE

Definition at line 19983 of file chan_sip.c.

References ao2_lock, ao2_t_ref, ao2_unlock, append_history, ast_copy_string(), ast_debug, ast_md5_hash(), ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), authl_lock, find_realm_authentication(), secret, sip_methods, and text.

Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().

19984 {
19985    char a1[256];
19986    char a2[256];
19987    char a1_hash[256];
19988    char a2_hash[256];
19989    char resp[256];
19990    char resp_hash[256];
19991    char uri[256];
19992    char opaque[256] = "";
19993    char cnonce[80];
19994    const char *username;
19995    const char *secret;
19996    const char *md5secret;
19997    struct sip_auth *auth;  /* Realm authentication credential */
19998    struct sip_auth_container *credentials;
19999 
20000    if (!ast_strlen_zero(p->domain))
20001       snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->domain);
20002    else if (!ast_strlen_zero(p->uri))
20003       ast_copy_string(uri, p->uri, sizeof(uri));
20004    else
20005       snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa));
20006 
20007    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
20008 
20009    /* Check if we have peer credentials */
20010    ao2_lock(p);
20011    credentials = p->peerauth;
20012    if (credentials) {
20013       ao2_t_ref(credentials, +1, "Ref peer auth for digest");
20014    }
20015    ao2_unlock(p);
20016    auth = find_realm_authentication(credentials, p->realm);
20017    if (!auth) {
20018       /* If not, check global credentials */
20019       if (credentials) {
20020          ao2_t_ref(credentials, -1, "Unref peer auth for digest");
20021       }
20022       ast_mutex_lock(&authl_lock);
20023       credentials = authl;
20024       if (credentials) {
20025          ao2_t_ref(credentials, +1, "Ref global auth for digest");
20026       }
20027       ast_mutex_unlock(&authl_lock);
20028       auth = find_realm_authentication(credentials, p->realm);
20029    }
20030 
20031    if (auth) {
20032       ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
20033       username = auth->username;
20034       secret = auth->secret;
20035       md5secret = auth->md5secret;
20036       if (sipdebug)
20037          ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid);
20038    } else {
20039       /* No authentication, use peer or register= config */
20040       username = p->authname;
20041       secret = p->relatedpeer 
20042          && !ast_strlen_zero(p->relatedpeer->remotesecret)
20043             ? p->relatedpeer->remotesecret : p->peersecret;
20044       md5secret = p->peermd5secret;
20045    }
20046    if (ast_strlen_zero(username)) {
20047       /* We have no authentication */
20048       if (credentials) {
20049          ao2_t_ref(credentials, -1, "Unref auth for digest");
20050       }
20051       return -1;
20052    }
20053 
20054    /* Calculate SIP digest response */
20055    snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
20056    snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri);
20057    if (!ast_strlen_zero(md5secret))
20058       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
20059    else
20060       ast_md5_hash(a1_hash, a1);
20061    ast_md5_hash(a2_hash, a2);
20062 
20063    p->noncecount++;
20064    if (!ast_strlen_zero(p->qop))
20065       snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
20066    else
20067       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash);
20068    ast_md5_hash(resp_hash, resp);
20069 
20070    /* only include the opaque string if it's set */
20071    if (!ast_strlen_zero(p->opaque)) {
20072       snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
20073    }
20074 
20075    /* XXX We hard code our qop to "auth" for now.  XXX */
20076    if (!ast_strlen_zero(p->qop))
20077       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount);
20078    else
20079       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque);
20080 
20081    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
20082 
20083    if (credentials) {
20084       ao2_t_ref(credentials, -1, "Unref auth for digest");
20085    }
20086    return 0;
20087 }

static void build_route ( struct sip_pvt *  p,
struct sip_request *  req,
int  backwards 
) [static]

Build route list from Record-Route header.

Definition at line 14636 of file chan_sip.c.

References __get_header(), ast_copy_string(), ast_debug, ast_malloc, ast_strdupa, ast_strlen_zero(), free_old_route(), get_in_brackets(), len(), list_route(), sip_debug_test_pvt(), sip_get_header(), and strsep().

Referenced by build_profile(), build_user_routes(), forked_invite_init(), handle_request_invite(), handle_request_subscribe(), and handle_response_invite().

14637 {
14638    struct sip_route *thishop, *head, *tail;
14639    int start = 0;
14640    int len;
14641    const char *rr, *c;
14642 
14643    /* Once a persistent route is set, don't fool with it */
14644    if (p->route && p->route_persistent) {
14645       ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop);
14646       return;
14647    }
14648 
14649    if (p->route) {
14650       free_old_route(p->route);
14651       p->route = NULL;
14652    }
14653 
14654    /* We only want to create the route set the first time this is called */
14655    p->route_persistent = 1;
14656 
14657    /* Build a tailq, then assign it to p->route when done.
14658     * If backwards, we add entries from the head so they end up
14659     * in reverse order. However, we do need to maintain a correct
14660     * tail pointer because the contact is always at the end.
14661     */
14662    head = NULL;
14663    tail = head;
14664    /* 1st we pass through all the hops in any Record-Route headers */
14665    for (;;) {
14666       /* Each Record-Route header */
14667       char rr_copy[256];
14668       char *rr_copy_ptr;
14669       char *rr_iter;
14670       rr = __get_header(req, "Record-Route", &start);
14671       if (*rr == '\0') {
14672          break;
14673       }
14674       ast_copy_string(rr_copy, rr, sizeof(rr_copy));
14675       rr_copy_ptr = rr_copy;
14676       while ((rr_iter = strsep(&rr_copy_ptr, ","))) { /* Each route entry */
14677          char *uri = get_in_brackets(rr_iter);
14678          len = strlen(uri) + 1;
14679          /* Make a struct route */
14680          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
14681             /* ast_calloc is not needed because all fields are initialized in this block */
14682             ast_copy_string(thishop->hop, uri, len);
14683             ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop);
14684             /* Link in */
14685             if (backwards) {
14686                /* Link in at head so they end up in reverse order */
14687                thishop->next = head;
14688                head = thishop;
14689                /* If this was the first then it'll be the tail */
14690                if (!tail) {
14691                   tail = thishop;
14692                }
14693             } else {
14694                thishop->next = NULL;
14695                /* Link in at the end */
14696                if (tail) {
14697                   tail->next = thishop;
14698                } else {
14699                   head = thishop;
14700                }
14701                tail = thishop;
14702             }
14703          }
14704       }
14705    }
14706 
14707    /* Only append the contact if we are dealing with a strict router */
14708    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) {
14709       /* 2nd append the Contact: if there is one */
14710       /* Can be multiple Contact headers, comma separated values - we just take the first */
14711       char *contact = ast_strdupa(sip_get_header(req, "Contact"));
14712       if (!ast_strlen_zero(contact)) {
14713          ast_debug(2, "build_route: Contact hop: %s\n", contact);
14714          /* Look for <: delimited address */
14715          c = get_in_brackets(contact);
14716          len = strlen(c) + 1;
14717          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
14718             /* ast_calloc is not needed because all fields are initialized in this block */
14719             ast_copy_string(thishop->hop, c, len);
14720             thishop->next = NULL;
14721             /* Goes at the end */
14722             if (tail) {
14723                tail->next = thishop;
14724             } else {
14725                head = thishop;
14726             }
14727          }
14728       }
14729    }
14730 
14731    /* Store as new route */
14732    p->route = head;
14733 
14734    /* For debugging dump what we ended up with */
14735    if (sip_debug_test_pvt(p)) {
14736       list_route(p->route);
14737    }
14738 }

static void build_via ( struct sip_pvt *  p  )  [static]

Build a Via header for a request.

Definition at line 3402 of file chan_sip.c.

References ast_sockaddr_stringify_remote(), ast_test_flag, and get_transport_pvt().

Referenced by __sip_subscribe_mwi_do(), reqprep(), sip_alloc(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().

03403 {
03404    /* Work around buggy UNIDEN UIP200 firmware */
03405    const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : "";
03406 
03407    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
03408    snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s",
03409        get_transport_pvt(p),
03410        ast_sockaddr_stringify_remote(&p->ourip),
03411        (int) p->branch, rport);
03412 }

static int cb_extensionstate ( const char *  context,
const char *  exten,
enum ast_extension_states  state,
void *  data 
) [static]

Callback for the devicestate notification (SUBSCRIBE) support subsystem.

Note:
If you add an "hint" priority to the extension in the dial plan, you will get notifications on device state changes

Definition at line 15013 of file chan_sip.c.

References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_set_flag, ast_test_flag, ast_verb, FALSE, NONE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), and transmit_state_notify().

Referenced by dialog_unlink_all(), handle_request_subscribe(), and handle_response_notify().

15014 {
15015    struct sip_pvt *p = data;
15016 
15017    sip_pvt_lock(p);
15018 
15019    switch(state) {
15020    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
15021    case AST_EXTENSION_REMOVED:   /* Extension is gone */
15022       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
15023       ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
15024       p->subscribed = NONE;
15025       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
15026       break;
15027    default: /* Tell user */
15028       p->laststate = state;
15029       break;
15030    }
15031    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
15032       if (!p->pendinginvite) {
15033          transmit_state_notify(p, state, 1, FALSE);
15034       } else {
15035          /* We already have a NOTIFY sent that is not answered. Queue the state up.
15036             if many state changes happen meanwhile, we will only send a notification of the last one */
15037          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
15038       }
15039    }
15040    ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
15041          ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
15042 
15043    sip_pvt_unlock(p);
15044 
15045    return 0;
15046 }

static void cb_extensionstate_destroy ( int  id,
void *  data 
) [static]

Definition at line 15003 of file chan_sip.c.

Referenced by handle_request_subscribe().

15004 {
15005    struct sip_pvt *p = data;
15006 
15007    dialog_unref(p, "the extensionstate containing this dialog ptr was destroyed");
15008 }

static void cc_epa_destructor ( void *  data  )  [static]

Definition at line 896 of file chan_sip.c.

References ast_free.

00897 {
00898    struct sip_epa_entry *epa_entry = data;
00899    struct cc_epa_entry *cc_entry = epa_entry->instance_data;
00900    ast_free(cc_entry);
00901 }

static void cc_handle_publish_error ( struct sip_pvt *  pvt,
const int  resp,
struct sip_request *  req,
struct sip_epa_entry *  epa_entry 
) [static]

Definition at line 20598 of file chan_sip.c.

References ao2_callback, ao2_ref, ast_cc_monitor_failed(), ast_log(), ast_strlen_zero(), FALSE, find_sip_monitor_instance_by_suspension_entry(), LOG_WARNING, sip_get_header(), and transmit_invite().

20599 {
20600    struct cc_epa_entry *cc_entry = epa_entry->instance_data;
20601    struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
20602          find_sip_monitor_instance_by_suspension_entry, epa_entry);
20603    const char *min_expires;
20604 
20605    if (!monitor_instance) {
20606       ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry);
20607       return;
20608    }
20609 
20610    if (resp != 423) {
20611       ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
20612             "Received error response to our PUBLISH");
20613       ao2_ref(monitor_instance, -1);
20614       return;
20615    }
20616 
20617    /* Allrighty, the other end doesn't like our Expires value. They think it's
20618     * too small, so let's see if they've provided a more sensible value. If they
20619     * haven't, then we'll just double our Expires value and see if they like that
20620     * instead.
20621     *
20622     * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE,
20623     * PUBLISH, and REGISTER could all benefit from the same shared code.
20624     */
20625    min_expires = sip_get_header(req, "Min-Expires");
20626    if (ast_strlen_zero(min_expires)) {
20627       pvt->expiry *= 2;
20628       if (pvt->expiry < 0) {
20629          /* You dork! You overflowed! */
20630          ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
20631                "PUBLISH expiry overflowed");
20632          ao2_ref(monitor_instance, -1);
20633          return;
20634       }
20635    } else if (sscanf(min_expires, "%30d", &pvt->expiry) != 1) {
20636       ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
20637             "Min-Expires has non-numeric value");
20638       ao2_ref(monitor_instance, -1);
20639       return;
20640    }
20641    /* At this point, we have most certainly changed pvt->expiry, so try transmitting
20642     * again
20643     */
20644    transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL);
20645    ao2_ref(monitor_instance, -1);
20646 }

static void change_callid_pvt ( struct sip_pvt *  pvt,
const char *  callid 
) [static]

Definition at line 7721 of file chan_sip.c.

References ao2_lock, ao2_t_link, ao2_unlock, ast_string_field_set, build_callid_pvt(), and CONTAINER_UNLINK.

Referenced by __sip_subscribe_mwi_do(), create_addr_from_peer(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().

07722 {
07723    int in_dialog_container;
07724    int in_rtp_container;
07725 
07726    ao2_lock(dialogs);
07727    ao2_lock(dialogs_rtpcheck);
07728    in_dialog_container = CONTAINER_UNLINK(dialogs, pvt,
07729       "About to change the callid -- remove the old name");
07730    in_rtp_container = CONTAINER_UNLINK(dialogs_rtpcheck, pvt,
07731       "About to change the callid -- remove the old name");
07732    if (callid) {
07733       ast_string_field_set(pvt, callid, callid);
07734    } else {
07735       build_callid_pvt(pvt);
07736    }
07737    if (in_dialog_container) {
07738       ao2_t_link(dialogs, pvt, "New dialog callid -- inserted back into table");
07739    }
07740    if (in_rtp_container) {
07741       ao2_t_link(dialogs_rtpcheck, pvt, "New dialog callid -- inserted back into table");
07742    }
07743    ao2_unlock(dialogs_rtpcheck);
07744    ao2_unlock(dialogs);
07745 }

static void change_hold_state ( struct sip_pvt *  dialog,
struct sip_request *  req,
int  holdstate,
int  sendonly 
) [static]

Change hold state for a call.

Definition at line 8906 of file chan_sip.c.

References append_history, ast_channel_name(), ast_channel_uniqueid(), ast_clear_flag, ast_set_flag, ast_test_flag, EVENT_FLAG_CALL, manager_event, sip_cfg, and sip_peer_hold().

Referenced by handle_request_invite(), and process_sdp().

08907 {
08908    if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
08909       sip_peer_hold(dialog, holdstate);
08910    if (sip_cfg.callevents)
08911       manager_event(EVENT_FLAG_CALL, "Hold",
08912                "Status: %s\r\n"
08913                "Channel: %s\r\n"
08914                "Uniqueid: %s\r\n",
08915                holdstate ? "On" : "Off",
08916                ast_channel_name(dialog->owner),
08917                ast_channel_uniqueid(dialog->owner));
08918    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data->str);
08919    if (!holdstate) { /* Put off remote hold */
08920       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
08921       return;
08922    }
08923    /* No address for RTP, we're on hold */
08924 
08925    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
08926       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
08927    else if (sendonly == 2) /* Inactive stream */
08928       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
08929    else
08930       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
08931    return;
08932 }

static void change_redirecting_information ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_party_redirecting redirecting,
struct ast_set_party_redirecting update_redirecting,
int  set_call_forward 
) [static]

update redirecting information for a channel based on headers

Definition at line 20335 of file chan_sip.c.

References ast_debug, ast_free, AST_REDIRECTING_REASON_UNCONDITIONAL, ast_strdup, ast_strlen_zero(), ast_party_redirecting::from, ast_set_party_redirecting::from, get_name_and_number(), get_rdnis(), ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_moved_contact(), ast_party_redirecting::reason, sip_get_header(), ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_set_party_redirecting::to, ast_party_redirecting::to, ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_request_invite(), handle_response(), and handle_response_invite().

20338 {
20339    char *redirecting_from_name = NULL;
20340    char *redirecting_from_number = NULL;
20341    char *redirecting_to_name = NULL;
20342    char *redirecting_to_number = NULL;
20343    int reason = AST_REDIRECTING_REASON_UNCONDITIONAL;
20344    int is_response = req->method == SIP_RESPONSE;
20345    int res = 0;
20346 
20347    res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason);
20348    if (res == -1) {
20349       if (is_response) {
20350          get_name_and_number(sip_get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number);
20351       } else {
20352          return;
20353       }
20354    }
20355 
20356    /* At this point, all redirecting "from" info should be filled in appropriately
20357     * on to the "to" info
20358     */
20359 
20360    if (is_response) {
20361       parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward);
20362    } else {
20363       get_name_and_number(sip_get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number);
20364    }
20365 
20366    if (!ast_strlen_zero(redirecting_from_number)) {
20367       ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number);
20368       update_redirecting->from.number = 1;
20369       redirecting->from.number.valid = 1;
20370       ast_free(redirecting->from.number.str);
20371       redirecting->from.number.str = redirecting_from_number;
20372    }
20373    if (!ast_strlen_zero(redirecting_from_name)) {
20374       ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name);
20375       update_redirecting->from.name = 1;
20376       redirecting->from.name.valid = 1;
20377       ast_free(redirecting->from.name.str);
20378       redirecting->from.name.str = redirecting_from_name;
20379    }
20380    if (!ast_strlen_zero(p->cid_tag)) {
20381       ast_free(redirecting->from.tag);
20382       redirecting->from.tag = ast_strdup(p->cid_tag);
20383       ast_free(redirecting->to.tag);
20384       redirecting->to.tag = ast_strdup(p->cid_tag);
20385    }
20386    if (!ast_strlen_zero(redirecting_to_number)) {
20387       ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number);
20388       update_redirecting->to.number = 1;
20389       redirecting->to.number.valid = 1;
20390       ast_free(redirecting->to.number.str);
20391       redirecting->to.number.str = redirecting_to_number;
20392    }
20393    if (!ast_strlen_zero(redirecting_to_name)) {
20394       ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number);
20395       update_redirecting->to.name = 1;
20396       redirecting->to.name.valid = 1;
20397       ast_free(redirecting->to.name.str);
20398       redirecting->to.name.str = redirecting_to_name;
20399    }
20400    redirecting->reason = reason;
20401 }

static void change_t38_state ( struct sip_pvt *  p,
int  state 
) [static]

Change the T38 state on a SIP dialog.

Definition at line 5193 of file chan_sip.c.

References ast_channel_name(), AST_CONTROL_T38_PARAMETERS, ast_debug, ast_queue_control_data(), AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_TERMINATED, ast_udptl_get_far_max_ifp(), ast_udptl_set_tag(), ast_control_t38_parameters::max_ifp, and ast_control_t38_parameters::request_response.

Referenced by handle_response_invite(), interpret_t38_parameters(), process_sdp(), and sip_t38_abort().

05194 {
05195    int old = p->t38.state;
05196    struct ast_channel *chan = p->owner;
05197    struct ast_control_t38_parameters parameters = { .request_response = 0 };
05198 
05199    /* Don't bother changing if we are already in the state wanted */
05200    if (old == state)
05201       return;
05202 
05203    p->t38.state = state;
05204    ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, chan ? ast_channel_name(chan) : "<none>");
05205 
05206    /* If no channel was provided we can't send off a control frame */
05207    if (!chan)
05208       return;
05209 
05210    /* Given the state requested and old state determine what control frame we want to queue up */
05211    switch (state) {
05212    case T38_PEER_REINVITE:
05213       parameters = p->t38.their_parms;
05214       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
05215       parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
05216       ast_udptl_set_tag(p->udptl, "%s", ast_channel_name(chan));
05217       break;
05218    case T38_ENABLED:
05219       parameters = p->t38.their_parms;
05220       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
05221       parameters.request_response = AST_T38_NEGOTIATED;
05222       ast_udptl_set_tag(p->udptl, "%s", ast_channel_name(chan));
05223       break;
05224    case T38_REJECTED:
05225    case T38_DISABLED:
05226       if (old == T38_ENABLED) {
05227          parameters.request_response = AST_T38_TERMINATED;
05228       } else if (old == T38_LOCAL_REINVITE) {
05229          parameters.request_response = AST_T38_REFUSED;
05230       }
05231       break;
05232    case T38_LOCAL_REINVITE:
05233       /* wait until we get a peer response before responding to local reinvite */
05234       break;
05235    }
05236 
05237    /* Woot we got a message, create a control frame and send it on! */
05238    if (parameters.request_response)
05239       ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
05240 }

static enum check_auth_result check_auth ( struct sip_pvt *  p,
struct sip_request *  req,
const char *  username,
const char *  secret,
const char *  md5secret,
int  sipmethod,
const char *  uri,
enum xmittype  reliable,
int  ignore 
) [static]

Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).

Returns:
0 on success, non-zero on error

XXX

Todo:
need a better return code here

XXX

Todo:
need a better return code here

Definition at line 14787 of file chan_sip.c.

References append_history, ast_copy_string(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), FALSE, LOG_NOTICE, LOG_WARNING, S_OR, set_nonce_randdata(), sip_auth_headers(), sip_digest_parser(), sip_get_header(), sip_methods, sip_scheddestroy(), text, transmit_response_with_auth(), and TRUE.

Referenced by check_peer_ok(), and register_verify().

14790 {
14791    const char *response;
14792    char *reqheader, *respheader;
14793    const char *authtoken;
14794    char a1_hash[256];
14795    char resp_hash[256]="";
14796    char *c;
14797    int  wrongnonce = FALSE;
14798    int  good_response;
14799    const char *usednonce = p->randdata;
14800    struct ast_str *buf;
14801    int res;
14802 
14803    /* table of recognised keywords, and their value in the digest */
14804    struct digestkeys keys[] = {
14805       [K_RESP] = { "response=", "" },
14806       [K_URI] = { "uri=", "" },
14807       [K_USER] = { "username=", "" },
14808       [K_NONCE] = { "nonce=", "" },
14809       [K_LAST] = { NULL, NULL}
14810    };
14811 
14812    /* Always OK if no secret */
14813    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) {
14814       return AUTH_SUCCESSFUL;
14815    }
14816 
14817    /* Always auth with WWW-auth since we're NOT a proxy */
14818    /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */
14819    response = "401 Unauthorized";
14820 
14821    /*
14822     * Note the apparent swap of arguments below, compared to other
14823     * usages of sip_auth_headers().
14824     */
14825    sip_auth_headers(WWW_AUTH, &respheader, &reqheader);
14826 
14827    authtoken =  sip_get_header(req, reqheader); 
14828    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
14829       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
14830          information */
14831       if (!reliable) {
14832          /* Resend message if this was NOT a reliable delivery.   Otherwise the
14833             retransmission should get it */
14834          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
14835          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
14836          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14837       }
14838       return AUTH_CHALLENGE_SENT;
14839    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
14840       /* We have no auth, so issue challenge and request authentication */
14841       set_nonce_randdata(p, 1); /* Create nonce for challenge */
14842       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
14843       /* Schedule auto destroy in 32 seconds */
14844       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14845       return AUTH_CHALLENGE_SENT;
14846    }
14847 
14848    /* --- We have auth, so check it */
14849 
14850    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
14851       an example in the spec of just what it is you're doing a hash on. */
14852 
14853    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
14854       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
14855    }
14856 
14857    /* Make a copy of the response and parse it */
14858    res = ast_str_set(&buf, 0, "%s", authtoken);
14859 
14860    if (res == AST_DYNSTR_BUILD_FAILED) {
14861       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
14862    }
14863 
14864    c = buf->str;
14865 
14866    sip_digest_parser(c, keys);
14867 
14868    /* Verify that digest username matches  the username we auth as */
14869    if (strcmp(username, keys[K_USER].s)) {
14870       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
14871          username, keys[K_USER].s);
14872       /* Oops, we're trying something here */
14873       return AUTH_USERNAME_MISMATCH;
14874    }
14875 
14876    /* Verify nonce from request matches our nonce, and the nonce has not already been responded to.
14877     * If this check fails, send 401 with new nonce */
14878    if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */
14879       wrongnonce = TRUE;
14880       usednonce = keys[K_NONCE].s;
14881    } else {
14882       p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */
14883    }
14884 
14885    if (!ast_strlen_zero(md5secret)) {
14886       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
14887    } else {
14888       char a1[256];
14889 
14890       snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
14891       ast_md5_hash(a1_hash, a1);
14892    }
14893 
14894    /* compute the expected response to compare with what we received */
14895    {
14896       char a2[256];
14897       char a2_hash[256];
14898       char resp[256];
14899 
14900       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
14901             S_OR(keys[K_URI].s, uri));
14902       ast_md5_hash(a2_hash, a2);
14903       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
14904       ast_md5_hash(resp_hash, resp);
14905    }
14906 
14907    good_response = keys[K_RESP].s &&
14908          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
14909    if (wrongnonce) {
14910       if (good_response) {
14911          if (sipdebug)
14912             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", sip_get_header(req, "From"));
14913          /* We got working auth token, based on stale nonce . */
14914          set_nonce_randdata(p, 0);
14915          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
14916       } else {
14917          /* Everything was wrong, so give the device one more try with a new challenge */
14918          if (!req->ignore) {
14919             if (sipdebug) {
14920                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", sip_get_header(req, "To"));
14921             }
14922             set_nonce_randdata(p, 1);
14923          } else {
14924             if (sipdebug) {
14925                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", sip_get_header(req, "To"));
14926             }
14927          }
14928          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
14929       }
14930 
14931       /* Schedule auto destroy in 32 seconds */
14932       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14933       return AUTH_CHALLENGE_SENT;
14934    }
14935    if (good_response) {
14936       append_history(p, "AuthOK", "Auth challenge successful for %s", username);
14937       return AUTH_SUCCESSFUL;
14938    }
14939 
14940    /* Ok, we have a bad username/secret pair */
14941    /* Tell the UAS not to re-send this authentication data, because
14942       it will continue to fail
14943    */
14944 
14945    return AUTH_SECRET_FAILED;
14946 }

static enum check_auth_result check_peer_ok ( struct sip_pvt *  p,
char *  of,
struct sip_request *  req,
int  sipmethod,
struct ast_sockaddr addr,
struct sip_peer **  authpeer,
enum xmittype  reliable,
char *  calleridname,
char *  uri2 
) [static]

Validate device authentication.

Definition at line 16404 of file chan_sip.c.

References accountcode, ao2_t_ref, ast_apply_ha(), ast_cc_copy_config_params(), ast_copy_flags, ast_copy_string(), ast_debug, ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_is_empty(), ast_format_cap_joint(), ast_is_shrinkable_phonenumber(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_set_flag, ast_shrink_phone_number(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variables_destroy(), ast_verbose, check_auth(), cid_name, cid_num, context, copy_vars(), debug, dialog_initialize_rtp(), do_setnat(), dummy(), FALSE, get_rpid(), language, mohinterpret, mohsuggest, parkinglot, parse_uri(), set_pvt_allowed_methods(), set_t38_capabilities(), sip_debug_test_addr(), sip_find_peer(), sip_find_peer_by_ip_and_exten(), sip_unref_peer(), and TRUE.

Referenced by check_user_full().

16408 {
16409    enum check_auth_result res;
16410    int debug = sip_debug_test_addr(addr);
16411    struct sip_peer *peer;
16412 
16413    if (sipmethod == SIP_SUBSCRIBE) {
16414       /* For subscribes, match on device name only; for other methods,
16415       * match on IP address-port of the incoming request.
16416       */
16417       peer = sip_find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0);
16418    } else {
16419       /* First find devices based on username (avoid all type=peer's) */
16420       peer = sip_find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0);
16421 
16422       /* Then find devices based on IP */
16423       if (!peer) {
16424          char *uri_tmp, *callback = NULL, *dummy;
16425          uri_tmp = ast_strdupa(uri2);
16426          parse_uri(uri_tmp, "sip:,sips:", &callback, &dummy, &dummy, &dummy);
16427          if (!ast_strlen_zero(callback) && (peer = sip_find_peer_by_ip_and_exten(&p->recv, callback, p->socket.type))) {
16428             ; /* found, fall through */
16429          } else {
16430             peer = sip_find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
16431          }
16432       }
16433    }
16434 
16435    if (!peer) {
16436       if (debug) {
16437          ast_verbose("No matching peer for '%s' from '%s'\n",
16438             of, ast_sockaddr_stringify(&p->recv));
16439       }
16440       return AUTH_DONT_KNOW;
16441    }
16442 
16443    if (!ast_apply_ha(peer->ha, addr)) {
16444       ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
16445       sip_unref_peer(peer, "sip_unref_peer: check_peer_ok: from sip_find_peer call, early return of AUTH_ACL_FAILED");
16446       return AUTH_ACL_FAILED;
16447    }
16448    if (debug)
16449       ast_verbose("Found peer '%s' for '%s' from %s\n",
16450          peer->name, of, ast_sockaddr_stringify(&p->recv));
16451 
16452    /* XXX what about p->prefs = peer->prefs; ? */
16453    /* Set Frame packetization */
16454    if (p->rtp) {
16455       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
16456       p->autoframing = peer->autoframing;
16457    }
16458 
16459    /* Take the peer */
16460    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
16461    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16462    ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
16463 
16464    if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) {
16465       p->t38_maxdatagram = peer->t38_maxdatagram;
16466       set_t38_capabilities(p);
16467    }
16468 
16469    /* Copy SIP extensions profile to peer */
16470    /* XXX is this correct before a successful auth ? */
16471    if (p->sipoptions)
16472       peer->sipoptions = p->sipoptions;
16473 
16474    do_setnat(p);
16475 
16476    ast_string_field_set(p, peersecret, peer->secret);
16477    ast_string_field_set(p, peermd5secret, peer->md5secret);
16478    ast_string_field_set(p, subscribecontext, peer->subscribecontext);
16479    ast_string_field_set(p, mohinterpret, peer->mohinterpret);
16480    ast_string_field_set(p, mohsuggest, peer->mohsuggest);
16481    if (!ast_strlen_zero(peer->parkinglot)) {
16482       ast_string_field_set(p, parkinglot, peer->parkinglot);
16483    }
16484    ast_string_field_set(p, engine, peer->engine);
16485    p->disallowed_methods = peer->disallowed_methods;
16486    set_pvt_allowed_methods(p, req);
16487    ast_cc_copy_config_params(p->cc_params, peer->cc_params);
16488    if (peer->callingpres)  /* Peer calling pres setting will override RPID */
16489       p->callingpres = peer->callingpres;
16490    if (peer->maxms && peer->lastms)
16491       p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
16492    else
16493       p->timer_t1 = peer->timer_t1;
16494 
16495    /* Set timer B to control transaction timeouts */
16496    if (peer->timer_b)
16497       p->timer_b = peer->timer_b;
16498    else
16499       p->timer_b = 64 * p->timer_t1;
16500 
16501    if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
16502       /* Pretend there is no required authentication */
16503       ast_string_field_set(p, peersecret, NULL);
16504       ast_string_field_set(p, peermd5secret, NULL);
16505    }
16506    if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) {
16507       ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
16508       ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16509       ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
16510       /* If we have a call limit, set flag */
16511       if (peer->call_limit)
16512          ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
16513       ast_string_field_set(p, peername, peer->name);
16514       ast_string_field_set(p, authname, peer->name);
16515 
16516       if (sipmethod == SIP_INVITE) {
16517          /* destroy old channel vars and copy in new ones. */
16518          ast_variables_destroy(p->chanvars);
16519          p->chanvars = copy_vars(peer->chanvars);
16520       }
16521 
16522       if (authpeer) {
16523          ao2_t_ref(peer, 1, "copy pointer into (*authpeer)");
16524          (*authpeer) = peer;  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
16525       }
16526 
16527       if (!ast_strlen_zero(peer->username)) {
16528          ast_string_field_set(p, username, peer->username);
16529          /* Use the default username for authentication on outbound calls */
16530          /* XXX this takes the name from the caller... can we override ? */
16531          ast_string_field_set(p, authname, peer->username);
16532       }
16533       if (!get_rpid(p, req)) {
16534          if (!ast_strlen_zero(peer->cid_num)) {
16535             char *tmp = ast_strdupa(peer->cid_num);
16536             if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
16537                ast_shrink_phone_number(tmp);
16538             ast_string_field_set(p, cid_num, tmp);
16539          }
16540          if (!ast_strlen_zero(peer->cid_name))
16541             ast_string_field_set(p, cid_name, peer->cid_name);
16542          if (!ast_strlen_zero(peer->cid_tag))
16543             ast_string_field_set(p, cid_tag, peer->cid_tag);
16544          if (peer->callingpres)
16545             p->callingpres = peer->callingpres;
16546       }
16547       ast_string_field_set(p, fullcontact, peer->fullcontact);
16548       if (!ast_strlen_zero(peer->context)) {
16549          ast_string_field_set(p, context, peer->context);
16550       }
16551       if (!ast_strlen_zero(peer->messagecontext)) {
16552          ast_string_field_set(p, messagecontext, peer->messagecontext);
16553       }
16554       if (!ast_strlen_zero(peer->mwi_from)) {
16555          ast_string_field_set(p, mwi_from, peer->mwi_from);
16556       }
16557       ast_string_field_set(p, peersecret, peer->secret);
16558       ast_string_field_set(p, peermd5secret, peer->md5secret);
16559       ast_string_field_set(p, language, peer->language);
16560       ast_string_field_set(p, accountcode, peer->accountcode);
16561       p->amaflags = peer->amaflags;
16562       p->callgroup = peer->callgroup;
16563       p->pickupgroup = peer->pickupgroup;
16564       ast_format_cap_copy(p->caps, peer->caps);
16565       ast_format_cap_copy(p->jointcaps, peer->caps);
16566       p->prefs = peer->prefs;
16567       ast_copy_string(p->zone, peer->zone, sizeof(p->zone));
16568       if (peer->maxforwards > 0) {
16569          p->maxforwards = peer->maxforwards;
16570       }
16571       if (!(ast_format_cap_is_empty(p->peercaps))) {
16572          struct ast_format_cap *tmp = ast_format_cap_joint(p->jointcaps, p->peercaps);
16573          struct ast_format_cap *tmp2;
16574          if (tmp) {
16575             tmp2 = p->jointcaps;
16576             p->jointcaps = tmp;
16577             ast_format_cap_destroy(tmp2);
16578          }
16579       }
16580       p->maxcallbitrate = peer->maxcallbitrate;
16581       if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
16582           (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
16583          p->noncodeccapability |= AST_RTP_DTMF;
16584       else
16585          p->noncodeccapability &= ~AST_RTP_DTMF;
16586       p->jointnoncodeccapability = p->noncodeccapability;
16587       p->rtptimeout = peer->rtptimeout;
16588       p->rtpholdtimeout = peer->rtpholdtimeout;
16589       p->rtpkeepalive = peer->rtpkeepalive;
16590       if (!dialog_initialize_rtp(p)) {
16591          if (p->rtp) {
16592             ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
16593             p->autoframing = peer->autoframing;
16594          }
16595       } else {
16596          res = AUTH_RTP_FAILED;
16597       }
16598    }
16599    sip_unref_peer(peer, "check_peer_ok: sip_unref_peer: tossing temp ptr to peer from sip_find_peer");
16600    return res;
16601 }

static void check_pendings ( struct sip_pvt *  p  )  [static]

Check pending actions on SIP call.

Note:
both sip_pvt and sip_pvt's owner channel (if present) must be locked for this function.

Definition at line 20521 of file chan_sip.c.

References ast_clear_flag, ast_debug, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, FALSE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), and TRUE.

Referenced by handle_incoming(), handle_response_invite(), and sip_reinvite_retry().

20522 {
20523    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
20524       /* if we can't BYE, then this is really a pending CANCEL */
20525       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
20526          p->invitestate = INV_CANCELLED;
20527          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
20528          /* Actually don't destroy us yet, wait for the 487 on our original
20529             INVITE, but do set an autodestruct just in case we never get it. */
20530       } else {
20531          /* We have a pending outbound invite, don't send something
20532             new in-transaction */
20533          if (p->pendinginvite)
20534             return;
20535 
20536          if (p->owner) {
20537             ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
20538          }
20539          /* Perhaps there is an SD change INVITE outstanding */
20540          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
20541       }
20542       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
20543       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20544    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
20545       /* if we can't REINVITE, hold it for later */
20546       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
20547          ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
20548       } else {
20549          ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid);
20550          /* Didn't get to reinvite yet, so do it now */
20551          transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE);
20552          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);
20553       }
20554    }
20555 }

static int check_rtp_timeout ( struct sip_pvt *  dialog,
time_t  t 
) [static]

helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked

Returns:
CMP_MATCH for items to be unlinked from dialogs_rtpcheck.

Todo:
Check video RTP keepalives
Do we need to move the lastrtptx to the RTP structure to have one for audio and one for video? It really does belong to the RTP structure.

Definition at line 26710 of file chan_sip.c.

References ast_channel_name(), ast_channel_trylock, ast_channel_uniqueid(), ast_channel_unlock, ast_log(), ast_rtp_instance_get_hold_timeout(), ast_rtp_instance_get_keepalive(), ast_rtp_instance_get_timeout(), ast_rtp_instance_sendcng(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_timeout(), ast_sockaddr_isnull(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, CMP_MATCH, EVENT_FLAG_CALL, keepalive, LOG_NOTICE, and manager_event.

Referenced by dialog_checkrtp_cb().

26711 {
26712    int timeout;
26713    int hold_timeout;
26714    int keepalive;
26715 
26716    if (!dialog->rtp) {
26717       /*
26718        * We have no RTP.  Since we don't do much with video RTP for
26719        * now, stop checking this dialog.
26720        */
26721       return CMP_MATCH;
26722    }
26723 
26724    /* If we have no active owner, no need to check timers */
26725    if (!dialog->owner) {
26726       return CMP_MATCH;
26727    }
26728 
26729    /* If the call is redirected outside Asterisk, no need to check timers */
26730    if (!ast_sockaddr_isnull(&dialog->redirip)) {
26731       return CMP_MATCH;
26732    }
26733 
26734    /* If the call is involved in a T38 fax session do not check RTP timeout */
26735    if (dialog->t38.state == T38_ENABLED) {
26736       return CMP_MATCH;
26737    }
26738    /* If the call is not in UP state return for later check. */
26739    if (dialog->owner->_state != AST_STATE_UP) {
26740       return 0;
26741    }
26742 
26743    /* Store these values locally to avoid multiple function calls */
26744    timeout = ast_rtp_instance_get_timeout(dialog->rtp);
26745    hold_timeout = ast_rtp_instance_get_hold_timeout(dialog->rtp);
26746    keepalive = ast_rtp_instance_get_keepalive(dialog->rtp);
26747 
26748    /* If we have no timers set, return now */
26749    if (!keepalive && !timeout && !hold_timeout) {
26750       return CMP_MATCH;
26751    }
26752 
26753    /* Check AUDIO RTP keepalives */
26754    if (dialog->lastrtptx && keepalive && (t > dialog->lastrtptx + keepalive)) {
26755       /* Need to send an empty RTP packet */
26756       dialog->lastrtptx = time(NULL);
26757       ast_rtp_instance_sendcng(dialog->rtp, 0);
26758    }
26759 
26760    /*! \todo Check video RTP keepalives
26761 
26762       Do we need to move the lastrtptx to the RTP structure to have one for audio and one
26763       for video? It really does belong to the RTP structure.
26764    */
26765 
26766    /* Check AUDIO RTP timers */
26767    if (dialog->lastrtprx && (timeout || hold_timeout) && (t > dialog->lastrtprx + timeout)) {
26768       if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (hold_timeout && (t > dialog->lastrtprx + hold_timeout))) {
26769          /* Needs a hangup */
26770          if (timeout) {
26771             if (!dialog->owner || ast_channel_trylock(dialog->owner)) {
26772                /*
26773                 * Don't block, just try again later.
26774                 * If there was no owner, the call is dead already.
26775                 */
26776                return 0;
26777             }
26778             ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
26779                ast_channel_name(dialog->owner), (long) (t - dialog->lastrtprx));
26780             manager_event(EVENT_FLAG_CALL, "SessionTimeout", "Source: RTPTimeout\r\n"
26781                   "Channel: %s\r\nUniqueid: %s\r\n", ast_channel_name(dialog->owner), ast_channel_uniqueid(dialog->owner));
26782             /* Issue a softhangup */
26783             ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV);
26784             ast_channel_unlock(dialog->owner);
26785             /* forget the timeouts for this call, since a hangup
26786                has already been requested and we don't want to
26787                repeatedly request hangups
26788             */
26789             ast_rtp_instance_set_timeout(dialog->rtp, 0);
26790             ast_rtp_instance_set_hold_timeout(dialog->rtp, 0);
26791             if (dialog->vrtp) {
26792                ast_rtp_instance_set_timeout(dialog->vrtp, 0);
26793                ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0);
26794             }
26795             /* finally unlink the dialog from dialogs_rtpcheck. */
26796             return CMP_MATCH;
26797          }
26798       }
26799    }
26800    return 0;
26801 }

static int check_sip_domain ( const char *  domain,
char *  context,
size_t  len 
) [static]

check_sip_domain: Check if domain part of uri is local to our server

Definition at line 27925 of file chan_sip.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().

Referenced by func_check_sipdomain(), get_destination(), get_realm(), handle_request_refer(), and register_verify().

27926 {
27927    struct domain *d;
27928    int result = 0;
27929 
27930    AST_LIST_LOCK(&domain_list);
27931    AST_LIST_TRAVERSE(&domain_list, d, list) {
27932       if (strcasecmp(d->domain, domain)) {
27933          continue;
27934       }
27935 
27936       if (len && !ast_strlen_zero(d->context))
27937          ast_copy_string(context, d->context, len);
27938 
27939       result = 1;
27940       break;
27941    }
27942    AST_LIST_UNLOCK(&domain_list);
27943 
27944    return result;
27945 }

static int check_user ( struct sip_pvt *  p,
struct sip_request *  req,
int  sipmethod,
const char *  uri,
enum xmittype  reliable,
struct ast_sockaddr addr 
) [static]

Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.

Definition at line 16740 of file chan_sip.c.

References check_user_full().

Referenced by handle_request_options(), handle_request_publish(), and receive_message().

16741 {
16742    return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL);
16743 }

static enum check_auth_result check_user_full ( struct sip_pvt *  p,
struct sip_request *  req,
int  sipmethod,
const char *  uri,
enum xmittype  reliable,
struct ast_sockaddr addr,
struct sip_peer **  authpeer 
) [static]

Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.

Returns:
0 on success, non-zero on failure

Definition at line 16609 of file chan_sip.c.

References ast_copy_string(), ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), exten, extract_host_from_hostport(), get_calleridname(), get_in_brackets(), get_rpid(), LOG_ERROR, LOG_NOTICE, name, parse_uri_legacy_check(), sip_cfg, sip_get_header(), SIP_PEDANTIC_DECODE, strsep(), and terminate_uri().

Referenced by check_user(), handle_request_invite(), and handle_request_subscribe().

16612 {
16613    char from[256] = "", *of, *name, *unused_password, *domain;
16614    enum check_auth_result res = AUTH_DONT_KNOW;
16615    char calleridname[50];
16616    char *uri2 = ast_strdupa(uri);
16617 
16618    terminate_uri(uri2); /* trim extra stuff */
16619 
16620    ast_copy_string(from, sip_get_header(req, "From"), sizeof(from));
16621    /* XXX here tries to map the username for invite things */
16622 
16623    /* strip the display-name portion off the beginning of the FROM header. */
16624    if (!(of = (char *) get_calleridname(from, calleridname, sizeof(calleridname)))) {
16625       ast_log(LOG_ERROR, "FROM header can not be parsed \n");
16626       return res;
16627    }
16628 
16629    if (calleridname[0]) {
16630       ast_string_field_set(p, cid_name, calleridname);
16631    }
16632 
16633    if (ast_strlen_zero(p->exten)) {
16634       char *t = uri2;
16635       if (!strncasecmp(t, "sip:", 4))
16636          t+= 4;
16637       else if (!strncasecmp(t, "sips:", 5))
16638          t += 5;
16639       ast_string_field_set(p, exten, t);
16640       t = strchr(p->exten, '@');
16641       if (t)
16642          *t = '\0';
16643 
16644       if (ast_strlen_zero(p->our_contact))
16645          build_contact(p);
16646    }
16647 
16648    of = get_in_brackets(of);
16649 
16650    /* save the URI part of the From header */
16651    ast_string_field_set(p, from, of);
16652 
16653    if (parse_uri_legacy_check(of, "sip:,sips:", &name, &unused_password, &domain, NULL)) {
16654       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
16655    }
16656 
16657    SIP_PEDANTIC_DECODE(name);
16658    SIP_PEDANTIC_DECODE(domain);
16659 
16660    extract_host_from_hostport(&domain);
16661 
16662    if (ast_strlen_zero(domain)) {
16663       /* <sip:name@[EMPTY]>, never good */
16664       ast_log(LOG_ERROR, "Empty domain name in FROM header\n");
16665       return res;
16666    }
16667 
16668    if (ast_strlen_zero(name)) {
16669       /* <sip:[EMPTY][@]hostport>. Asterisk 1.4 and 1.6 have always
16670        * treated that as a username, so we continue the tradition:
16671        * uri is now <sip:host@hostport>. */
16672       name = domain;
16673    } else {
16674       /* Non-empty name, try to get caller id from it */
16675       char *tmp = ast_strdupa(name);
16676       /* We need to be able to handle from-headers looking like
16677          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
16678       */
16679       tmp = strsep(&tmp, ";");
16680       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) {
16681          ast_shrink_phone_number(tmp);
16682       }
16683       ast_string_field_set(p, cid_num, tmp);
16684    }
16685 
16686    if (global_match_auth_username) {
16687       /*
16688        * XXX This is experimental code to grab the search key from the
16689        * Auth header's username instead of the 'From' name, if available.
16690        * Do not enable this block unless you understand the side effects (if any!)
16691        * Note, the search for "username" should be done in a more robust way.
16692        * Note2, at the moment we check both fields, though maybe we should
16693        * pick one or another depending on the request ? XXX
16694        */
16695       const char *hdr = sip_get_header(req, "Authorization");
16696       if (ast_strlen_zero(hdr)) {
16697          hdr = sip_get_header(req, "Proxy-Authorization");
16698       }
16699 
16700       if (!ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\""))) {
16701          ast_copy_string(from, hdr + strlen("username=\""), sizeof(from));
16702          name = from;
16703          name = strsep(&name, "\"");
16704       }
16705    }
16706 
16707    res = check_peer_ok(p, name, req, sipmethod, addr,
16708          authpeer, reliable, calleridname, uri2);
16709    if (res != AUTH_DONT_KNOW) {
16710       return res;
16711    }
16712 
16713    /* Finally, apply the guest policy */
16714    if (sip_cfg.allowguest) {
16715       get_rpid(p, req);
16716       p->rtptimeout = global_rtptimeout;
16717       p->rtpholdtimeout = global_rtpholdtimeout;
16718       p->rtpkeepalive = global_rtpkeepalive;
16719       if (!dialog_initialize_rtp(p)) {
16720          res = AUTH_SUCCESSFUL;
16721       } else {
16722          res = AUTH_RTP_FAILED;
16723       }
16724    } else if (sip_cfg.alwaysauthreject) {
16725       res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
16726    } else {
16727       res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
16728    }
16729 
16730    if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) {
16731       ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
16732    }
16733 
16734    return res;
16735 }

static void check_via ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

check Via: header for hostname, port and rport request/answer

Definition at line 16319 of file chan_sip.c.

References ast_clear_flag, ast_copy_string(), ast_debug, ast_log(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_cmp(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, ast_test_flag, ast_verbose, LOG_WARNING, sip_debug_test_pvt(), sip_get_header(), sip_nat_mode(), and sip_real_dst().

Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().

16320 {
16321    char via[512];
16322    char *c, *maddr;
16323    struct ast_sockaddr tmp = { { 0, } };
16324    uint16_t port;
16325 
16326    ast_copy_string(via, sip_get_header(req, "Via"), sizeof(via));
16327 
16328    /* Work on the leftmost value of the topmost Via header */
16329    c = strchr(via, ',');
16330    if (c)
16331       *c = '\0';
16332 
16333    /* Check for rport */
16334    c = strstr(via, ";rport");
16335    if (c && (c[6] != '=')) { /* rport query, not answer */
16336       ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT);
16337       ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
16338    }
16339 
16340    /* Check for maddr */
16341    maddr = strstr(via, "maddr=");
16342    if (maddr) {
16343       maddr += 6;
16344       c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz"
16345                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]");
16346       *c = '\0';
16347    }
16348 
16349    c = strchr(via, ';');
16350    if (c)
16351       *c = '\0';
16352 
16353    c = strchr(via, ' ');
16354    if (c) {
16355       *c = '\0';
16356       c = ast_skip_blanks(c+1);
16357       if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) {
16358          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
16359          return;
16360       }
16361 
16362       if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) {
16363          p->sa = p->recv;
16364       }
16365 
16366       ast_sockaddr_resolve_first(&tmp, c, 0);
16367       port = ast_sockaddr_port(&tmp);
16368       ast_sockaddr_set_port(&p->sa,
16369                   port != 0 ? port : STANDARD_SIP_PORT);
16370 
16371       /* Check and see if the requesting UA is likely to be behind a NAT. If they are, set the
16372        * natdetected flag so that later, peers with nat=auto_* can use the value. Also
16373        * set the flags so that Asterisk responds identically whether or not a peer exists
16374        * so as not to leak peer name information. */
16375       if (ast_sockaddr_cmp(&tmp, &p->recv)) {
16376          char *tmp_str = ast_strdupa(ast_sockaddr_stringify(&tmp));
16377          ast_debug(3, "NAT detected for %s / %s\n", tmp_str, ast_sockaddr_stringify(&p->recv));
16378          p->natdetected = 1;
16379          if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
16380             ast_set_flag(&p->flags[0], SIP_NAT_FORCE_RPORT);
16381          }
16382          if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
16383             ast_set_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
16384          }
16385       } else {
16386          p->natdetected = 0;
16387          if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
16388             ast_clear_flag(&p->flags[0], SIP_NAT_FORCE_RPORT);
16389          }
16390          if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
16391             ast_clear_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
16392          }
16393       }
16394 
16395       if (sip_debug_test_pvt(p)) {
16396          ast_verbose("Sending to %s (%s)\n",
16397                 ast_sockaddr_stringify(sip_real_dst(p)),
16398                 sip_nat_mode(p));
16399       }
16400    }
16401 }

static attribute_unused void check_via_response ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/.

Definition at line 16289 of file chan_sip.c.

References ast_copy_string(), ast_parse_arg(), ast_sockaddr_set_port, PARSE_ADDR, sip_get_header(), and strsep().

16290 {
16291    char via[256];
16292    char *cur, *opts;
16293 
16294    ast_copy_string(via, sip_get_header(req, "Via"), sizeof(via));
16295 
16296    /* Work on the leftmost value of the topmost Via header */
16297    opts = strchr(via, ',');
16298    if (opts)
16299       *opts = '\0';
16300 
16301    /* parse all relevant options */
16302    opts = strchr(via, ';');
16303    if (!opts)
16304       return;  /* no options to parse */
16305    *opts++ = '\0';
16306    while ( (cur = strsep(&opts, ";")) ) {
16307       if (!strncmp(cur, "rport=", 6)) {
16308          int port = strtol(cur+6, NULL, 10);
16309          /* XXX add error checking */
16310          ast_sockaddr_set_port(&p->ourip, port);
16311       } else if (!strncmp(cur, "received=", 9)) {
16312          if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip))
16313             ;  /* XXX add error checking */
16314       }
16315    }
16316 }

static void cleanup_all_regs ( void   )  [static]

Definition at line 28974 of file chan_sip.c.

References ast_debug, ast_dnsmgr_release(), AST_SCHED_DEL_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, dialog_unlink_all(), registry_unref(), and regl.

Referenced by reload_config(), and unload_module().

28975 {
28976       /* First, destroy all outstanding registry calls */
28977       /* This is needed, since otherwise active registry entries will not be destroyed */
28978       ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {  /* regl is locked */
28979             ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */
28980             if (iterator->call) {
28981                ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
28982                /* This will also remove references to the registry */
28983                dialog_unlink_all(iterator->call);
28984                iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal");
28985             }
28986             if (iterator->expire > -1) {
28987                AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config"));
28988             }
28989             if (iterator->timeout > -1) {
28990                AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config"));
28991             }
28992             if (iterator->dnsmgr) {
28993                ast_dnsmgr_release(iterator->dnsmgr);
28994                iterator->dnsmgr = NULL;
28995                registry_unref(iterator, "reg ptr unref from dnsmgr");
28996             }
28997             ASTOBJ_UNLOCK(iterator);
28998       } while(0));
28999 }

static void cleanup_stale_contexts ( char *  new,
char *  old 
) [static]

Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.

Definition at line 17663 of file chan_sip.c.

References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().

Referenced by config_parse_variables(), and reload_config().

17664 {
17665    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
17666 
17667    while ((oldcontext = strsep(&old, "&"))) {
17668       stalecontext = '\0';
17669       ast_copy_string(newlist, new, sizeof(newlist));
17670       stringp = newlist;
17671       while ((newcontext = strsep(&stringp, "&"))) {
17672          if (!strcmp(newcontext, oldcontext)) {
17673             /* This is not the context you're looking for */
17674             stalecontext = '\0';
17675             break;
17676          } else if (strcmp(newcontext, oldcontext)) {
17677             stalecontext = oldcontext;
17678          }
17679          
17680       }
17681       if (stalecontext)
17682          ast_context_destroy(ast_context_find(stalecontext), "SIP");
17683    }
17684 }

static void clear_peer_mailboxes ( struct sip_peer *  peer  )  [static]

Destroy all peer-related mailbox subscriptions

Definition at line 4629 of file chan_sip.c.

References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.

Referenced by set_peer_defaults(), and sip_destroy_peer().

04630 {
04631    struct sip_mailbox *mailbox;
04632 
04633    while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry)))
04634       destroy_mailbox(mailbox);
04635 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

Definition at line 27948 of file chan_sip.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.

Referenced by reload_config(), and unload_module().

27949 {
27950    struct domain *d;
27951 
27952    AST_LIST_LOCK(&domain_list);
27953    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
27954       ast_free(d);
27955    AST_LIST_UNLOCK(&domain_list);
27956 }

static char * complete_sip_peer ( const char *  word,
int  state,
int  flags2 
) [static]

Do completion on peer name.

Definition at line 19139 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and sip_unref_peer().

Referenced by complete_sip_show_peer(), complete_sipnotify(), sip_do_debug(), and sip_prune_realtime().

19140 {
19141    char *result = NULL;
19142    int wordlen = strlen(word);
19143    int which = 0;
19144    struct ao2_iterator i = ao2_iterator_init(peers, 0);
19145    struct sip_peer *peer;
19146 
19147    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
19148       /* locking of the object is not required because only the name and flags are being compared */
19149       if (!strncasecmp(word, peer->name, wordlen) &&
19150             (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
19151             ++which > state)
19152          result = ast_strdup(peer->name);
19153       sip_unref_peer(peer, "toss iterator peer ptr before break");
19154       if (result) {
19155          break;
19156       }
19157    }
19158    ao2_iterator_destroy(&i);
19159    return result;
19160 }

static char * complete_sip_registered_peer ( const char *  word,
int  state,
int  flags2 
) [static]

Do completion on registered peer name.

Definition at line 19163 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and sip_unref_peer().

Referenced by complete_sip_unregister().

19164 {
19165        char *result = NULL;
19166        int wordlen = strlen(word);
19167        int which = 0;
19168        struct ao2_iterator i;
19169        struct sip_peer *peer;
19170        
19171        i = ao2_iterator_init(peers, 0);
19172        while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
19173           if (!strncasecmp(word, peer->name, wordlen) &&
19174          (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
19175          ++which > state && peer->expire > 0)
19176              result = ast_strdup(peer->name);
19177           if (result) {
19178              sip_unref_peer(peer, "toss iterator peer ptr before break");
19179              break;
19180           }
19181           sip_unref_peer(peer, "toss iterator peer ptr");
19182        }
19183        ao2_iterator_destroy(&i);
19184        return result;
19185 }

static char * complete_sip_show_history ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show history' CLI.

Definition at line 19188 of file chan_sip.c.

References complete_sipch().

Referenced by sip_show_history().

19189 {
19190    if (pos == 3)
19191       return complete_sipch(line, word, pos, state);
19192 
19193    return NULL;
19194 }

static char * complete_sip_show_peer ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show peer' CLI.

Definition at line 19197 of file chan_sip.c.

References complete_sip_peer().

Referenced by sip_qualify_peer(), and sip_show_peer().

19198 {
19199    if (pos == 3) {
19200       return complete_sip_peer(word, state, 0);
19201    }
19202 
19203    return NULL;
19204 }

static char* complete_sip_show_user ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show user' CLI.

Definition at line 18408 of file chan_sip.c.

References complete_sip_user().

Referenced by sip_show_user().

18409 {
18410    if (pos == 3)
18411       return complete_sip_user(word, state);
18412 
18413    return NULL;
18414 }

static char * complete_sip_unregister ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip unregister' CLI.

Definition at line 19207 of file chan_sip.c.

References complete_sip_registered_peer().

Referenced by sip_unregister().

19208 {
19209        if (pos == 2)
19210                return complete_sip_registered_peer(word, state, 0);
19211 
19212        return NULL;
19213 }

static char* complete_sip_user ( const char *  word,
int  state 
) [static]

Do completion on user name.

Definition at line 18378 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_strdup, and sip_unref_peer().

Referenced by complete_sip_show_user().

18379 {
18380    char *result = NULL;
18381    int wordlen = strlen(word);
18382    int which = 0;
18383    struct ao2_iterator user_iter;
18384    struct sip_peer *user;
18385 
18386    user_iter = ao2_iterator_init(peers, 0);
18387    while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) {
18388       ao2_lock(user);
18389       if (!(user->type & SIP_TYPE_USER)) {
18390          ao2_unlock(user);
18391          sip_unref_peer(user, "complete sip user");
18392          continue;
18393       }
18394       /* locking of the object is not required because only the name and flags are being compared */
18395       if (!strncasecmp(word, user->name, wordlen) && ++which > state) {
18396          result = ast_strdup(user->name);
18397       }
18398       ao2_unlock(user);
18399       sip_unref_peer(user, "complete sip user");
18400       if (result) {
18401          break;
18402       }
18403    }
18404    ao2_iterator_destroy(&user_iter);
18405    return result;
18406 }

static char* complete_sipch ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.

Definition at line 19109 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, sip_pvt_lock, and sip_pvt_unlock.

Referenced by complete_sip_show_history(), and sip_show_channel().

19110 {
19111    int which=0;
19112    struct sip_pvt *cur;
19113    char *c = NULL;
19114    int wordlen = strlen(word);
19115    struct ao2_iterator i;
19116 
19117    if (pos != 3) {
19118       return NULL;
19119    }
19120 
19121    i = ao2_iterator_init(dialogs, 0);
19122    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
19123       sip_pvt_lock(cur);
19124       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
19125          c = ast_strdup(cur->callid);
19126          sip_pvt_unlock(cur);
19127          dialog_unref(cur, "drop ref in iterator loop break");
19128          break;
19129       }
19130       sip_pvt_unlock(cur);
19131       dialog_unref(cur, "drop ref in iterator loop");
19132    }
19133    ao2_iterator_destroy(&i);
19134    return c;
19135 }

static char * complete_sipnotify ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip notify' CLI.

Definition at line 19216 of file chan_sip.c.

References ast_category_browse(), ast_strdup, and complete_sip_peer().

Referenced by sip_cli_notify().

19217 {
19218    char *c = NULL;
19219 
19220    if (pos == 2) {
19221       int which = 0;
19222       char *cat = NULL;
19223       int wordlen = strlen(word);
19224 
19225       /* do completion for notify type */
19226 
19227       if (!notify_types)
19228          return NULL;
19229       
19230       while ( (cat = ast_category_browse(notify_types, cat)) ) {
19231          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
19232             c = ast_strdup(cat);
19233             break;
19234          }
19235       }
19236       return c;
19237    }
19238 
19239    if (pos > 2)
19240       return complete_sip_peer(word, state, 0);
19241 
19242    return NULL;
19243 }

static int construct_pidf_body ( enum sip_cc_publish_state  state,
char *  pidf_body,
size_t  size,
const char *  presentity 
) [static]

Definition at line 1965 of file chan_sip.c.

References ast_copy_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), and generate_random_string().

Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), and sip_cc_monitor_unsuspend().

01966 {
01967    struct ast_str *body = ast_str_alloca(size);
01968    char tuple_id[32];
01969 
01970    generate_random_string(tuple_id, sizeof(tuple_id));
01971 
01972    /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF
01973     * body gets a lot more extra junk that isn't necessary, so we'll leave it out here.
01974     */
01975    ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
01976    /* XXX The entity attribute is currently set to the peer name associated with the
01977     * dialog. This is because we currently only call this function for call-completion
01978     * PUBLISH bodies. In such cases, the entity is completely disregarded. For other
01979     * event packages, it may be crucial to have a proper URI as the presentity so this
01980     * should be revisited as support is expanded.
01981     */
01982    ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity);
01983    ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id);
01984    ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed");
01985    ast_str_append(&body, 0, "</tuple>\n");
01986    ast_str_append(&body, 0, "</presence>\n");
01987    ast_copy_string(pidf_body, ast_str_buffer(body), size);
01988    return 0;
01989 }

static int copy_all_header ( struct sip_request *  req,
const struct sip_request *  orig,
const char *  field 
) [static]

Copy all headers from one request to another.

Definition at line 10208 of file chan_sip.c.

References __get_header(), add_header(), and ast_strlen_zero().

Referenced by respprep().

10209 {
10210    int start = 0;
10211    int copied = 0;
10212    for (;;) {
10213       const char *tmp = __get_header(orig, field, &start);
10214 
10215       if (ast_strlen_zero(tmp))
10216          break;
10217       /* Add what we're responding to */
10218       add_header(req, field, tmp);
10219       copied++;
10220    }
10221    return copied ? 0 : -1;
10222 }

static int copy_header ( struct sip_request *  req,
const struct sip_request *  orig,
const char *  field 
) [static]

Copy one header field from one request to another.

Definition at line 10197 of file chan_sip.c.

References add_header(), ast_log(), ast_strlen_zero(), LOG_NOTICE, and sip_get_header().

Referenced by reqprep(), and respprep().

10198 {
10199    const char *tmp = sip_get_header(orig, field);
10200 
10201    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
10202       return add_header(req, field, tmp);
10203    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
10204    return -1;
10205 }

static void copy_request ( struct sip_request *  dst,
const struct sip_request *  src 
) [static]

copy SIP request (mostly used to save request for responses)

Definition at line 12098 of file chan_sip.c.

References ast_str_copy_string(), ast_str_create(), and ast_str_strlen().

Referenced by _sip_tcp_helper_thread(), forked_invite_init(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), receive_message(), and sip_park().

12099 {
12100    /* XXX this function can encounter memory allocation errors, perhaps it
12101     * should return a value */
12102 
12103    struct ast_str *duplicate = dst->data;
12104    struct ast_str *duplicate_content = dst->content;
12105 
12106    /* copy the entire request then restore the original data and content
12107     * members from the dst request */
12108    memcpy(dst, src, sizeof(*dst));
12109    dst->data = duplicate;
12110    dst->content = duplicate_content;
12111 
12112    /* copy the data into the dst request */
12113    if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1)))
12114       return;
12115    ast_str_copy_string(&dst->data, src->data);
12116 
12117    /* copy the content into the dst request (if it exists) */
12118    if (src->content) {
12119       if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1)))
12120          return;
12121       ast_str_copy_string(&dst->content, src->content);
12122    }
12123 }

static void copy_socket_data ( struct sip_socket *  to_sock,
const struct sip_socket *  from_sock 
) [static]

Definition at line 5256 of file chan_sip.c.

References ao2_ref.

Referenced by create_addr_from_peer(), handle_request_do(), parse_register_contact(), sip_poke_peer(), and transmit_response_using_temp().

05257 {
05258    if (to_sock->tcptls_session) {
05259       ao2_ref(to_sock->tcptls_session, -1);
05260       to_sock->tcptls_session = NULL;
05261    }
05262 
05263    if (from_sock->tcptls_session) {
05264       ao2_ref(from_sock->tcptls_session, +1);
05265    }
05266 
05267    *to_sock = *from_sock;
05268 }

static struct ast_variable * copy_vars ( struct ast_variable src  )  [static, read]

duplicate a list of channel variables,

Returns:
the copy.

Definition at line 2348 of file chan_sip.c.

References ast_variable_new(), and ast_variable::next.

02349 {
02350    struct ast_variable *res = NULL, *tmp, *v = NULL;
02351 
02352    for (v = src ; v ; v = v->next) {
02353       if ((tmp = ast_variable_new(v->name, v->value, v->file))) {
02354          tmp->next = res;
02355          res = tmp;
02356       }
02357    }
02358    return res;
02359 }

static int copy_via_headers ( struct sip_pvt *  p,
struct sip_request *  req,
const struct sip_request *  orig,
const char *  field 
) [static]

Copy SIP VIA Headers from the request to the response.

Note:
If the client indicates that it wishes to know the port we received from, it adds ;rport without an argument to the topmost via header. We need to add the port number (from our point of view) to that parameter.
	We always add ;received=<ip address> to the topmost via header.
Received: RFC 3261, rport RFC 3581

Definition at line 10232 of file chan_sip.c.

References __get_header(), add_header(), ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_stringify_addr_remote(), ast_strlen_zero(), ast_test_flag, and LOG_NOTICE.

Referenced by respprep().

10233 {
10234    int copied = 0;
10235    int start = 0;
10236 
10237    for (;;) {
10238       char new[512];
10239       const char *oh = __get_header(orig, field, &start);
10240 
10241       if (ast_strlen_zero(oh))
10242          break;
10243 
10244       if (!copied) { /* Only check for empty rport in topmost via header */
10245          char leftmost[512], *others, *rport;
10246 
10247          /* Only work on leftmost value */
10248          ast_copy_string(leftmost, oh, sizeof(leftmost));
10249          others = strchr(leftmost, ',');
10250          if (others)
10251              *others++ = '\0';
10252 
10253          /* Find ;rport;  (empty request) */
10254          rport = strstr(leftmost, ";rport");
10255          if (rport && *(rport+6) == '=')
10256             rport = NULL;     /* We already have a parameter to rport */
10257 
10258          if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) {
10259             /* We need to add received port - rport */
10260             char *end;
10261 
10262             rport = strstr(leftmost, ";rport");
10263 
10264             if (rport) {
10265                end = strchr(rport + 1, ';');
10266                if (end)
10267                   memmove(rport, end, strlen(end) + 1);
10268                else
10269                   *rport = '\0';
10270             }
10271 
10272             /* Add rport to first VIA header if requested */
10273             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
10274                leftmost, ast_sockaddr_stringify_addr_remote(&p->recv),
10275                ast_sockaddr_port(&p->recv),
10276                others ? "," : "", others ? others : "");
10277          } else {
10278             /* We should *always* add a received to the topmost via */
10279             snprintf(new, sizeof(new), "%s;received=%s%s%s",
10280                leftmost, ast_sockaddr_stringify_addr_remote(&p->recv),
10281                others ? "," : "", others ? others : "");
10282          }
10283          oh = new;   /* the header to copy */
10284       }  /* else add the following via headers untouched */
10285       add_header(req, field, oh);
10286       copied++;
10287    }
10288    if (!copied) {
10289       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
10290       return -1;
10291    }
10292    return 0;
10293 }

static int create_addr ( struct sip_pvt *  dialog,
const char *  opeer,
struct ast_sockaddr addr,
int  newdialog,
struct ast_sockaddr remote_address 
) [static]

create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success

Todo:
Fix this function. When we ask for SRV, we should check all transports In the future, we should first check NAPTR to find out transport preference

Definition at line 5485 of file chan_sip.c.

References AST_APP_ARG, ast_check_digits(), AST_DECLARE_APP_ARGS, ast_get_srv(), ast_log(), AST_NONSTANDARD_RAW_ARGS, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_strdupa, ast_string_field_set, bindaddr, create_addr_from_peer(), default_sip_port(), dialog_initialize_rtp(), FALSE, get_srv_protocol(), get_srv_service(), LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), ref_proxy(), service, set_socket_transport(), sip_cfg, sip_find_peer(), sip_ref_peer(), sip_unref_peer(), and TRUE.

05486 {
05487    struct sip_peer *peer;
05488    char *peername, *peername2, *hostn;
05489    char host[MAXHOSTNAMELEN];
05490    char service[MAXHOSTNAMELEN];
05491    int srv_ret = 0;
05492    int tportno;
05493 
05494    AST_DECLARE_APP_ARGS(hostport,
05495       AST_APP_ARG(host);
05496       AST_APP_ARG(port);
05497    );
05498 
05499    peername = ast_strdupa(opeer);
05500    peername2 = ast_strdupa(opeer);
05501    AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':');
05502 
05503    if (hostport.port)
05504       dialog->portinuri = 1;
05505 
05506    dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
05507    dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
05508    peer = sip_find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
05509 
05510    if (peer) {
05511       int res;
05512       if (newdialog) {
05513          set_socket_transport(&dialog->socket, 0);
05514       }
05515       res = create_addr_from_peer(dialog, peer);
05516       if (!ast_sockaddr_isnull(remote_address)) {
05517          ast_sockaddr_copy(&dialog->sa, remote_address);
05518       }
05519       dialog->relatedpeer = sip_ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer");
05520       sip_unref_peer(peer, "create_addr: unref peer from sip_find_peer hashtab lookup");
05521       return res;
05522    } else if (ast_check_digits(peername)) {
05523       /* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and
05524        * it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is
05525        * almost certainly not intended. It is much better to just reject purely numeric hostnames */
05526       ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername);
05527       return -1;
05528    } else {
05529       dialog->rtptimeout = global_rtptimeout;
05530       dialog->rtpholdtimeout = global_rtpholdtimeout;
05531       dialog->rtpkeepalive = global_rtpkeepalive;
05532       if (dialog_initialize_rtp(dialog)) {
05533          return -1;
05534       }
05535    }
05536 
05537    ast_string_field_set(dialog, tohost, hostport.host);
05538    dialog->allowed_methods &= ~sip_cfg.disallowed_methods;
05539 
05540    /* Get the outbound proxy information */
05541    ref_proxy(dialog, obproxy_get(dialog, NULL));
05542 
05543    if (addr) {
05544       /* This address should be updated using dnsmgr */
05545       ast_sockaddr_copy(&dialog->sa, addr);
05546    } else {
05547 
05548       /* Let's see if we can find the host in DNS. First try DNS SRV records,
05549          then hostname lookup */
05550       /*! \todo Fix this function. When we ask for SRV, we should check all transports
05551            In the future, we should first check NAPTR to find out transport preference
05552        */
05553       hostn = peername;
05554       /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then
05555        * an A record lookup should be used instead of SRV.
05556        */
05557       if (!hostport.port && sip_cfg.srvlookup) {
05558          snprintf(service, sizeof(service), "_%s._%s.%s", 
05559              get_srv_service(dialog->socket.type),
05560              get_srv_protocol(dialog->socket.type), peername);
05561          if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno,
05562                      service)) > 0) {
05563             hostn = host;
05564          }
05565       }
05566 
05567       if (ast_sockaddr_resolve_first(&dialog->sa, hostn, 0)) {
05568          ast_log(LOG_WARNING, "No such host: %s\n", peername);
05569          return -1;
05570       }
05571 
05572       if (srv_ret > 0) {
05573          ast_sockaddr_set_port(&dialog->sa, tportno);
05574       }
05575    }
05576 
05577    if (!dialog->socket.type)
05578       set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP);
05579    if (!dialog->socket.port) {
05580       dialog->socket.port = htons(ast_sockaddr_port(&bindaddr));
05581    }
05582 
05583    if (!ast_sockaddr_port(&dialog->sa)) {
05584       ast_sockaddr_set_port(&dialog->sa, default_sip_port(dialog->socket.type));
05585    }
05586    ast_sockaddr_copy(&dialog->recv, &dialog->sa);
05587    return 0;
05588 }

static int create_addr_from_peer ( struct sip_pvt *  dialog,
struct sip_peer *  peer 
) [static]

Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.

Returns:
-1 on error, 0 on success.

Definition at line 5330 of file chan_sip.c.

References accountcode, ao2_lock, ao2_t_ref, ao2_unlock, ast_cc_copy_config_params(), ast_copy_flags, ast_copy_string(), ast_duplicate_ha_list(), ast_format_cap_copy(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify_host_remote(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, change_callid_pvt(), check_request_transport, cid_name, cid_num, context, copy_socket_data(), copy_vars(), dialog_initialize_rtp(), language, mohinterpret, mohsuggest, obproxy_get(), parkinglot, and ref_proxy().

Referenced by create_addr(), and sip_send_mwi_to_peer().

05331 {
05332    struct sip_auth_container *credentials;
05333 
05334    /* this checks that the dialog is contacting the peer on a valid
05335     * transport type based on the peers transport configuration,
05336     * otherwise, this function bails out */
05337    if (dialog->socket.type && check_request_transport(peer, dialog))
05338       return -1;
05339    copy_socket_data(&dialog->socket, &peer->socket);
05340 
05341    if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) &&
05342        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
05343       dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr;
05344       dialog->recv = dialog->sa;
05345    } else
05346       return -1;
05347 
05348    /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */
05349    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
05350    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
05351    ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
05352    ast_format_cap_copy(dialog->caps, peer->caps);
05353    dialog->prefs = peer->prefs;
05354    dialog->amaflags = peer->amaflags;
05355 
05356    ast_string_field_set(dialog, engine, peer->engine);
05357 
05358    dialog->rtptimeout = peer->rtptimeout;
05359    dialog->rtpholdtimeout = peer->rtpholdtimeout;
05360    dialog->rtpkeepalive = peer->rtpkeepalive;
05361    if (dialog_initialize_rtp(dialog)) {
05362       return -1;
05363    }
05364 
05365    if (dialog->rtp) { /* Audio */
05366       ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
05367       ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
05368       /* Set Frame packetization */
05369       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs);
05370       dialog->autoframing = peer->autoframing;
05371    }
05372 
05373    /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */
05374    ast_string_field_set(dialog, peername, peer->name);
05375    ast_string_field_set(dialog, authname, peer->username);
05376    ast_string_field_set(dialog, username, peer->username);
05377    ast_string_field_set(dialog, peersecret, peer->secret);
05378    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
05379    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
05380    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
05381    ast_string_field_set(dialog, tohost, peer->tohost);
05382    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
05383    ast_string_field_set(dialog, accountcode, peer->accountcode);
05384    ast_string_field_set(dialog, context, peer->context);
05385    ast_string_field_set(dialog, cid_num, peer->cid_num);
05386    ast_string_field_set(dialog, cid_name, peer->cid_name);
05387    ast_string_field_set(dialog, cid_tag, peer->cid_tag);
05388    ast_string_field_set(dialog, mwi_from, peer->mwi_from);
05389    if (!ast_strlen_zero(peer->parkinglot)) {
05390       ast_string_field_set(dialog, parkinglot, peer->parkinglot);
05391    }
05392    ast_string_field_set(dialog, engine, peer->engine);
05393    ref_proxy(dialog, obproxy_get(dialog, peer));
05394    dialog->callgroup = peer->callgroup;
05395    dialog->pickupgroup = peer->pickupgroup;
05396    ast_copy_string(dialog->zone, peer->zone, sizeof(dialog->zone));
05397    dialog->allowtransfer = peer->allowtransfer;
05398    dialog->jointnoncodeccapability = dialog->noncodeccapability;
05399 
05400    /* Update dialog authorization credentials */
05401    ao2_lock(peer);
05402    credentials = peer->auth;
05403    if (credentials) {
05404       ao2_t_ref(credentials, +1, "Ref peer auth for dialog");
05405    }
05406    ao2_unlock(peer);
05407    ao2_lock(dialog);
05408    if (dialog->peerauth) {
05409       ao2_t_ref(dialog->peerauth, -1, "Unref old dialog peer auth");
05410    }
05411    dialog->peerauth = credentials;
05412    ao2_unlock(dialog);
05413 
05414    dialog->maxcallbitrate = peer->maxcallbitrate;
05415    dialog->disallowed_methods = peer->disallowed_methods;
05416    ast_cc_copy_config_params(dialog->cc_params, peer->cc_params);
05417    if (ast_strlen_zero(dialog->tohost))
05418       ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host_remote(&dialog->sa));
05419    if (!ast_strlen_zero(peer->fromdomain)) {
05420       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
05421       if (!dialog->initreq.headers) {
05422          char *new_callid;
05423          char *tmpcall = ast_strdupa(dialog->callid);
05424          /* this sure looks to me like we are going to change the callid on this dialog!! */
05425          new_callid = strchr(tmpcall, '@');
05426          if (new_callid) {
05427             int callid_size;
05428 
05429             *new_callid = '\0';
05430 
05431             /* Change the dialog callid. */
05432             callid_size = strlen(tmpcall) + strlen(peer->fromdomain) + 2;
05433             new_callid = alloca(callid_size);
05434             snprintf(new_callid, callid_size, "%s@%s", tmpcall, peer->fromdomain);
05435             change_callid_pvt(dialog, new_callid);
05436          }
05437       }
05438    }
05439    if (!ast_strlen_zero(peer->fromuser))
05440       ast_string_field_set(dialog, fromuser, peer->fromuser);
05441    if (!ast_strlen_zero(peer->language))
05442       ast_string_field_set(dialog, language, peer->language);
05443    /* Set timer T1 to RTT for this peer (if known by qualify=) */
05444    /* Minimum is settable or default to 100 ms */
05445    /* If there is a maxms and lastms from a qualify use that over a manual T1
05446       value. Otherwise, use the peer's T1 value. */
05447    if (peer->maxms && peer->lastms)
05448       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
05449    else
05450       dialog->timer_t1 = peer->timer_t1;
05451 
05452    /* Set timer B to control transaction timeouts, the peer setting is the default and overrides
05453       the known timer */
05454    if (peer->timer_b)
05455       dialog->timer_b = peer->timer_b;
05456    else
05457       dialog->timer_b = 64 * dialog->timer_t1;
05458 
05459    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
05460        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
05461       dialog->noncodeccapability |= AST_RTP_DTMF;
05462    else
05463       dialog->noncodeccapability &= ~AST_RTP_DTMF;
05464    dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha);
05465    if (peer->call_limit)
05466       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
05467    if (!dialog->portinuri)
05468       dialog->portinuri = peer->portinuri;
05469    dialog->chanvars = copy_vars(peer->chanvars);
05470    if (peer->fromdomainport)
05471       dialog->fromdomainport = peer->fromdomainport;
05472 
05473    return 0;
05474 }

static struct sip_epa_entry* create_epa_entry ( const char *const   event_package,
const char *const   destination 
) [static, read]

Definition at line 924 of file chan_sip.c.

References ao2_t_alloc, ast_copy_string(), and find_static_data().

Referenced by sip_cc_monitor_suspend().

00925 {
00926    struct sip_epa_entry *epa_entry;
00927    const struct epa_static_data *static_data;
00928 
00929    if (!(static_data = find_static_data(event_package))) {
00930       return NULL;
00931    }
00932 
00933    if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) {
00934       return NULL;
00935    }
00936 
00937    epa_entry->static_data = static_data;
00938    ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination));
00939    return epa_entry;
00940 }

static struct sip_esc_entry* create_esc_entry ( struct event_state_compositor esc,
struct sip_request *  req,
const int  expires 
) [static, read]

Definition at line 1050 of file chan_sip.c.

References ao2_alloc, ao2_ref, ast_sched_add(), create_new_sip_etag(), esc_entry_destructor(), event_state_compositor::name, and publish_expire().

Referenced by handle_sip_publish_initial().

01051 {
01052    struct sip_esc_entry *esc_entry;
01053    int expires_ms;
01054 
01055    if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) {
01056       return NULL;
01057    }
01058 
01059    esc_entry->event = esc->name;
01060 
01061    expires_ms = expires * 1000;
01062    /* Bump refcount for scheduler */
01063    ao2_ref(esc_entry, +1);
01064    esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry);
01065 
01066    /* Note: This links the esc_entry into the ESC properly */
01067    create_new_sip_etag(esc_entry, 0);
01068 
01069    return esc_entry;
01070 }

static void create_new_sip_etag ( struct sip_esc_entry *  esc_entry,
int  is_linked 
) [static]

Definition at line 1037 of file chan_sip.c.

References ao2_link, ao2_unlink, ast_assert, ast_atomic_fetchadd_int(), event_state_compositor::compositor, and get_esc().

Referenced by create_esc_entry(), and transmit_response_with_sip_etag().

01038 {
01039    int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1);
01040    struct event_state_compositor *esc = get_esc(esc_entry->event);
01041 
01042    ast_assert(esc != NULL);
01043    if (is_linked) {
01044       ao2_unlink(esc->compositor, esc_entry);
01045    }
01046    snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag);
01047    ao2_link(esc->compositor, esc_entry);
01048 }

static int default_sip_port ( enum sip_transport  type  )  [inline, static]

The default sip port for the given transport.

Definition at line 5477 of file chan_sip.c.

Referenced by create_addr(), on_dns_update_peer(), and parse_register_contact().

05478 {
05479    return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
05480 }

static void deinit_req ( struct sip_request *  req  )  [static]

Deinitialize SIP response/request.

Definition at line 10449 of file chan_sip.c.

References ast_free.

Referenced by __sip_destroy(), _sip_tcp_helper_thread(), send_request(), send_response(), sip_park(), sip_park_thread(), and sipsock_read().

10450 {
10451    if (req->data) {
10452       ast_free(req->data);
10453       req->data = NULL;
10454    }
10455    if (req->content) {
10456       ast_free(req->content);
10457       req->content = NULL;
10458    }
10459 }

static void destroy_association ( struct sip_peer *  peer  )  [static]

Remove registration data from realtime database or AST/DB when registration expires.

Definition at line 14129 of file chan_sip.c.

References ast_check_realtime(), ast_db_del(), ast_update_realtime(), SENTINEL, and sip_cfg.

Referenced by build_peer(), and expire_register().

14130 {
14131    int realtimeregs = ast_check_realtime("sipregs");
14132    char *tablename = (realtimeregs) ? "sipregs" : "sippeers";
14133 
14134    if (!sip_cfg.ignore_regexpire) {
14135       if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
14136          ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "0", SENTINEL);
14137       } else {
14138          ast_db_del("SIP/Registry", peer->name);
14139          ast_db_del("SIP/PeerMethods", peer->name);
14140       }
14141    }
14142 }

static void destroy_escs ( void   )  [static]

Definition at line 1084 of file chan_sip.c.

References ao2_ref, ARRAY_LEN, and event_state_compositors.

Referenced by unload_module().

01085 {
01086    int i;
01087    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01088       ao2_ref(event_state_compositors[i].compositor, -1);
01089    }
01090 }

static void destroy_mailbox ( struct sip_mailbox *  mailbox  )  [static]

Destroy mailbox subscriptions

Definition at line 4621 of file chan_sip.c.

References ast_event_unsubscribe(), and ast_free.

Referenced by build_peer(), and clear_peer_mailboxes().

04622 {
04623    if (mailbox->event_sub)
04624       ast_event_unsubscribe(mailbox->event_sub);
04625    ast_free(mailbox);
04626 }

static void destroy_msg_headers ( struct sip_pvt *  pvt  )  [static]

Definition at line 11098 of file chan_sip.c.

References ast_free, and AST_LIST_REMOVE_HEAD.

Referenced by __sip_destroy(), sip_park_thread(), and sip_sendtext().

11099 {
11100    struct sip_msg_hdr *doomed;
11101 
11102    while ((doomed = AST_LIST_REMOVE_HEAD(&pvt->msg_headers, next))) {
11103       ast_free(doomed);
11104    }
11105 }

static void destroy_realm_authentication ( void *  obj  )  [static]

Definition at line 27966 of file chan_sip.c.

References ast_free, and AST_LIST_REMOVE_HEAD.

Referenced by add_realm_authentication().

27967 {
27968    struct sip_auth_container *credentials = obj;
27969    struct sip_auth *auth;
27970 
27971    while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) {
27972       ast_free(auth);
27973    }
27974 }

static int determine_firstline_parts ( struct sip_request *  req  )  [static]

Parse first line of incoming SIP request.

Definition at line 12195 of file chan_sip.c.

References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), and ast_trim_blanks().

Referenced by parse_request().

12196 {
12197    char *e = ast_skip_blanks(req->data->str);   /* there shouldn't be any */
12198    char *local_rlPart1;
12199 
12200    if (!*e)
12201       return -1;
12202    req->rlPart1 = e - req->data->str;  /* method or protocol */
12203    local_rlPart1 = e;
12204    e = ast_skip_nonblanks(e);
12205    if (*e)
12206       *e++ = '\0';
12207    /* Get URI or status code */
12208    e = ast_skip_blanks(e);
12209    if ( !*e )
12210       return -1;
12211    ast_trim_blanks(e);
12212 
12213    if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */
12214       if (strlen(e) < 3)   /* status code is 3 digits */
12215          return -1;
12216       req->rlPart2 = e - req->data->str;
12217    } else { /* We have a request */
12218       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
12219          ast_debug(3, "Oops. Bogus uri in <> %s\n", e);
12220          e++;
12221          if (!*e)
12222             return -1;
12223       }
12224       req->rlPart2 = e - req->data->str;  /* URI */
12225       e = ast_skip_nonblanks(e);
12226       if (*e)
12227          *e++ = '\0';
12228       e = ast_skip_blanks(e);
12229       if (strcasecmp(e, "SIP/2.0") ) {
12230          ast_debug(3, "Skipping packet - Bad request protocol %s\n", e);
12231          return -1;
12232       }
12233    }
12234    return 1;
12235 }

static enum sip_publish_type determine_sip_publish_type ( struct sip_request *  req,
const char *const   event,
const char *const   etag,
const char *const   expires,
int *  expires_int 
) [static]

Definition at line 24925 of file chan_sip.c.

References ast_assert, and ast_strlen_zero().

Referenced by handle_request_publish().

24926 {
24927    int etag_present = !ast_strlen_zero(etag);
24928    int body_present = req->lines > 0;
24929 
24930    ast_assert(expires_int != NULL);
24931 
24932    if (ast_strlen_zero(expires)) {
24933       /* Section 6, item 4, second bullet point of RFC 3903 says to
24934        * use a locally-configured default expiration if none is provided
24935        * in the request
24936        */
24937       *expires_int = DEFAULT_PUBLISH_EXPIRES;
24938    } else if (sscanf(expires, "%30d", expires_int) != 1) {
24939       return SIP_PUBLISH_UNKNOWN;
24940    }
24941 
24942    if (*expires_int == 0) {
24943       return SIP_PUBLISH_REMOVE;
24944    } else if (!etag_present && body_present) {
24945       return SIP_PUBLISH_INITIAL;
24946    } else if (etag_present && !body_present) {
24947       return SIP_PUBLISH_REFRESH;
24948    } else if (etag_present && body_present) {
24949       return SIP_PUBLISH_MODIFY;
24950    }
24951 
24952    return SIP_PUBLISH_UNKNOWN;
24953 }

static int dialog_checkrtp_cb ( void *  dialogobj,
void *  arg,
int  flags 
) [static]

Check RTP Timeout on dialogs.

This is used with ao2_callback to check rtptimeout rtponholdtimeout and send rtpkeepalive packets.

Returns:
CMP_MATCH for items to be unlinked from dialogs_rtpcheck.

Definition at line 17694 of file chan_sip.c.

References check_rtp_timeout(), CMP_MATCH, sip_pvt_trylock, and sip_pvt_unlock.

Referenced by do_monitor().

17695 {
17696    struct sip_pvt *dialog = dialogobj;
17697    time_t *t = arg;
17698    int match_status;
17699 
17700    if (sip_pvt_trylock(dialog)) {
17701       return 0;
17702    }
17703 
17704    if (dialog->rtp || dialog->vrtp) {
17705       match_status = check_rtp_timeout(dialog, *t);
17706    } else {
17707       /* Dialog has no active RTP or VRTP. unlink it from dialogs_rtpcheck. */
17708       match_status = CMP_MATCH;
17709    }
17710    sip_pvt_unlock(dialog);
17711 
17712    return match_status;
17713 }

static int dialog_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Note:
The only member of the dialog used here callid string

Definition at line 30955 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

30956 {
30957    struct sip_pvt *pvt = obj, *pvt2 = arg;
30958 
30959    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0;
30960 }

static int dialog_dump_func ( void *  userobj,
void *  arg,
int  flags 
) [static]

Definition at line 17564 of file chan_sip.c.

References ao2_t_ref, ast_cli(), and ast_cli_args::fd.

Referenced by sip_show_objects().

17565 {
17566    struct sip_pvt *pvt = userobj;
17567    int refc = ao2_t_ref(userobj, 0, "");
17568    struct ast_cli_args *a = (struct ast_cli_args *) arg;
17569    
17570    ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n",
17571       pvt->callid, 0, refc);
17572    return 0;
17573 }

static int dialog_find_multiple ( void *  obj,
void *  arg,
int  flags 
) [static]

Note:
Same as dialog_cmp_cb, except without the CMP_STOP on match

Definition at line 30945 of file chan_sip.c.

References CMP_MATCH.

Referenced by find_call().

30946 {
30947    struct sip_pvt *pvt = obj, *pvt2 = arg;
30948 
30949    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0;
30950 }

static int dialog_hash_cb ( const void *  obj,
const int  flags 
) [static]

Note:
The only member of the dialog used here callid string

Definition at line 30935 of file chan_sip.c.

References ast_str_case_hash().

Referenced by load_module().

30936 {
30937    const struct sip_pvt *pvt = obj;
30938 
30939    return ast_str_case_hash(pvt->callid);
30940 }

static int dialog_initialize_rtp ( struct sip_pvt *  dialog  )  [static]

Initialize RTP portion of a dialog.

Returns:
-1 on failure, 0 on success

Definition at line 5273 of file chan_sip.c.

References ast_format_cap_has_type(), AST_FORMAT_TYPE_VIDEO, ast_rtp_instance_new(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_keepalive(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_sockaddr_copy(), ast_test_flag, bindaddr, do_setnat(), cfsip_methods::need_rtp, and sip_methods.

Referenced by check_peer_ok(), check_user_full(), create_addr(), and create_addr_from_peer().

05274 {
05275    struct ast_sockaddr bindaddr_tmp;
05276 
05277    if (!sip_methods[dialog->method].need_rtp) {
05278       return 0;
05279    }
05280 
05281    ast_sockaddr_copy(&bindaddr_tmp, &bindaddr);
05282    if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
05283       return -1;
05284    }
05285 
05286    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
05287          (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (ast_format_cap_has_type(dialog->caps, AST_FORMAT_TYPE_VIDEO)))) {
05288       if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
05289          return -1;
05290       }
05291       ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout);
05292       ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout);
05293       ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive);
05294 
05295       ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1);
05296    }
05297 
05298    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) {
05299       if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
05300          return -1;
05301       }
05302       /* Do not timeout text as its not constant*/
05303       ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive);
05304 
05305       ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1);
05306    }
05307 
05308    ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout);
05309    ast_rtp_instance_set_hold_timeout(dialog->rtp, dialog->rtpholdtimeout);
05310    ast_rtp_instance_set_keepalive(dialog->rtp, dialog->rtpkeepalive);
05311 
05312    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1);
05313    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
05314    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
05315 
05316    ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP");
05317 
05318    do_setnat(dialog);
05319 
05320    return 0;
05321 }

static int dialog_needdestroy ( void *  dialogobj,
void *  arg,
int  flags 
) [static]

Match dialogs that need to be destroyed.

This is used with ao2_callback to unlink/delete all dialogs that are marked needdestroy.

Todo:
Re-work this to improve efficiency. Currently, this function is called on _every_ dialog after processing _every_ incoming SIP/UDP packet, or potentially even more often when the scheduler has entries to run.

Definition at line 17725 of file chan_sip.c.

References ast_debug, ast_rtp_instance_get_bridged(), dialog_unlink_all(), sip_methods, sip_pvt_trylock, sip_pvt_unlock, and cfsip_methods::text.

Referenced by do_monitor().

17726 {
17727    struct sip_pvt *dialog = dialogobj;
17728 
17729    if (sip_pvt_trylock(dialog)) {
17730       /* Don't block the monitor thread.  This function is called often enough
17731        * that we can wait for the next time around. */
17732       return 0;
17733    }
17734 
17735    /* If we have sessions that needs to be destroyed, do it now */
17736    /* Check if we have outstanding requests not responsed to or an active call
17737       - if that's the case, wait with destruction */
17738    if (dialog->needdestroy && !dialog->packets && !dialog->owner) {
17739       /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
17740       if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
17741          ast_debug(2, "Bridge still active.  Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
17742          sip_pvt_unlock(dialog);
17743          return 0;
17744       }
17745 
17746       if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) {
17747          ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
17748          sip_pvt_unlock(dialog);
17749          return 0;
17750       }
17751 
17752       sip_pvt_unlock(dialog);
17753       /* no, the unlink should handle this: dialog_unref(dialog, "needdestroy: one more refcount decrement to allow dialog to be destroyed"); */
17754       /* the CMP_MATCH will unlink this dialog from the dialog hash table */
17755       dialog_unlink_all(dialog);
17756       return 0; /* the unlink_all should unlink this from the table, so.... no need to return a match */
17757    }
17758 
17759    sip_pvt_unlock(dialog);
17760 
17761    return 0;
17762 }

struct sip_pvt* dialog_ref_debug ( struct sip_pvt *  p,
const char *  tag,
char *  file,
int  line,
const char *  func 
) [read]

Definition at line 2236 of file chan_sip.c.

References __ao2_ref_debug(), ao2_ref, ast_log(), and LOG_ERROR.

02237 {
02238    if (p)
02239 #ifdef REF_DEBUG
02240       __ao2_ref_debug(p, 1, tag, file, line, func);
02241 #else
02242       ao2_ref(p, 1);
02243 #endif
02244    else
02245       ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
02246    return p;
02247 }

void dialog_unlink_all ( struct sip_pvt *  dialog  ) 

Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.

Note:
A reference to the dialog must be held before calling this function, and this function does not release that reference.

Definition at line 2971 of file chan_sip.c.

References ao2_t_unlink, ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_debug, ast_extension_state_del(), ast_free, AST_SCHED_DEL, AST_SCHED_DEL_UNREF, cb_extensionstate(), registry_unref(), sip_pvt_lock_full(), sip_pvt_unlock, stop_session_timer(), and ast_channel::tech_pvt.

Referenced by __sip_autodestruct(), __sip_subscribe_mwi_do(), cleanup_all_regs(), dialog_needdestroy(), handle_request_subscribe(), manager_sipnotify(), sip_cli_notify(), sip_destroy_peer(), sip_msg_send(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and unload_module().

02972 {
02973    struct sip_pkt *cp;
02974    struct ast_channel *owner;
02975 
02976    dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done");
02977 
02978    ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
02979    ao2_t_unlink(dialogs_needdestroy, dialog, "unlinking dialog_needdestroy via ao2_unlink");
02980    ao2_t_unlink(dialogs_rtpcheck, dialog, "unlinking dialog_rtpcheck via ao2_unlink");
02981 
02982    /* Unlink us from the owner (channel) if we have one */
02983    owner = sip_pvt_lock_full(dialog);
02984    if (owner) {
02985       ast_debug(1, "Detaching from channel %s\n", ast_channel_name(owner));
02986       owner->tech_pvt = dialog_unref(owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
02987       ast_channel_unlock(owner);
02988       ast_channel_unref(owner);
02989       dialog->owner = NULL;
02990    }
02991    sip_pvt_unlock(dialog);
02992 
02993    if (dialog->registry) {
02994       if (dialog->registry->call == dialog) {
02995          dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
02996       }
02997       dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
02998    }
02999    if (dialog->stateid != -1) {
03000       ast_extension_state_del(dialog->stateid, cb_extensionstate);
03001       dialog->stateid = -1;
03002    }
03003    /* Remove link from peer to subscription of MWI */
03004    if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) {
03005       dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
03006    }
03007    if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) {
03008       dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
03009    }
03010 
03011    /* remove all current packets in this dialog */
03012    while((cp = dialog->packets)) {
03013       dialog->packets = dialog->packets->next;
03014       AST_SCHED_DEL(sched, cp->retransid);
03015       dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy");
03016       if (cp->data) {
03017          ast_free(cp->data);
03018       }
03019       ast_free(cp);
03020    }
03021 
03022    AST_SCHED_DEL_UNREF(sched, dialog->waitid, dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
03023 
03024    AST_SCHED_DEL_UNREF(sched, dialog->initid, dialog_unref(dialog, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr"));
03025    
03026    if (dialog->autokillid > -1) {
03027       AST_SCHED_DEL_UNREF(sched, dialog->autokillid, dialog_unref(dialog, "when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr"));
03028    }
03029 
03030    if (dialog->request_queue_sched_id > -1) {
03031       AST_SCHED_DEL_UNREF(sched, dialog->request_queue_sched_id, dialog_unref(dialog, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr"));
03032    }
03033 
03034    AST_SCHED_DEL_UNREF(sched, dialog->provisional_keepalive_sched_id, dialog_unref(dialog, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
03035 
03036    if (dialog->t38id > -1) {
03037       AST_SCHED_DEL_UNREF(sched, dialog->t38id, dialog_unref(dialog, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
03038    }
03039 
03040    if (dialog->stimer) {
03041       stop_session_timer(dialog);
03042    }
03043 
03044    dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
03045 }

struct sip_pvt* dialog_unref_debug ( struct sip_pvt *  p,
const char *  tag,
char *  file,
int  line,
const char *  func 
) [read]

Definition at line 2249 of file chan_sip.c.

References __ao2_ref_debug(), and ao2_ref.

02250 {
02251    if (p)
02252 #ifdef REF_DEBUG
02253       __ao2_ref_debug(p, -1, tag, file, line, func);
02254 #else
02255       ao2_ref(p, -1);
02256 #endif
02257    return NULL;
02258 }

static void disable_dsp_detect ( struct sip_pvt *  p  )  [static]

Definition at line 4297 of file chan_sip.c.

References ast_dsp_free().

Referenced by sip_dtmfmode(), sip_hangup(), and sip_setoption().

04298 {
04299    if (p->dsp) {
04300       ast_dsp_free(p->dsp);
04301       p->dsp = NULL;
04302    }
04303 }

static void display_nat_warning ( const char *  cat,
int  reason,
struct ast_flags flags 
) [static]

Definition at line 28962 of file chan_sip.c.

References AST_CLI_YESNO, ast_log(), ast_test_flag, CHANNEL_MODULE_LOAD, and LOG_WARNING.

Referenced by reload_config().

28962                                                                                       {
28963    int global_nat, specific_nat;
28964 
28965    if (reason == CHANNEL_MODULE_LOAD && (specific_nat = ast_test_flag(&flags[0], SIP_NAT_FORCE_RPORT)) != (global_nat = ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))) {
28966       ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the  global setting can make\n");
28967       ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n");
28968       ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n");
28969       ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n");
28970       ast_log(LOG_WARNING, "!!! (config category='%s' global force_rport='%s' peer/user force_rport='%s')\n", cat, AST_CLI_YESNO(global_nat), AST_CLI_YESNO(specific_nat));
28971    }
28972 }

static int do_magic_pickup ( struct ast_channel channel,
const char *  extension,
const char *  context 
) [static]

Note:
No channel or pvt locks should be held while calling this function.

Definition at line 22926 of file chan_sip.c.

References ast_debug, ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_str_alloca, ast_str_set(), LOG_ERROR, pbx_exec(), pbx_findapp(), sip_cfg, and str.

Referenced by handle_request_invite().

22927 {
22928    struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2);
22929    struct ast_app *pickup = pbx_findapp("Pickup");
22930 
22931    if (!pickup) {
22932       ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n");
22933       return -1;
22934    }
22935 
22936    ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context);
22937 
22938    ast_debug(2, "About to call Pickup(%s)\n", str->str);
22939 
22940    /* There is no point in capturing the return value since pickup_exec
22941       doesn't return anything meaningful unless the passed data is an empty
22942       string (which in our case it will not be) */
22943    pbx_exec(channel, pickup, str->str);
22944 
22945    return 0;
22946 }

static int do_message_auth ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Definition at line 21647 of file chan_sip.c.

References append_history, ast_debug, ast_log(), ast_sockaddr_stringify(), LOG_NOTICE, reply_digest(), sip_auth_headers(), and transmit_message().

Referenced by handle_response_message().

21648 {
21649    char *header;
21650    char *respheader;
21651    char digest[1024];
21652 
21653    if (p->options) {
21654       p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
21655    }
21656 
21657    if (p->authtries == MAX_AUTHTRIES) {
21658       ast_log(LOG_NOTICE, "Failed to authenticate MESSAGE with host '%s'\n",
21659          ast_sockaddr_stringify(&p->sa));
21660       return -1;
21661    }
21662 
21663    ++p->authtries;
21664    sip_auth_headers((resp == 401 ? WWW_AUTH : PROXY_AUTH), &header, &respheader);
21665    memset(digest, 0, sizeof(digest));
21666    if (reply_digest(p, req, header, SIP_MESSAGE, digest, sizeof(digest))) {
21667       /* There's nothing to use for authentication */
21668       ast_debug(1, "Nothing to use for MESSAGE authentication\n");
21669       return -1;
21670    }
21671 
21672    if (p->do_history) {
21673       append_history(p, "MessageAuth", "Try: %d", p->authtries);
21674    }
21675 
21676    transmit_message(p, 0, 1);
21677    return 0;
21678 }

static void * do_monitor ( void *  data  )  [static]

The SIP monitoring thread.

Note:
This thread monitors all the SIP sessions and peers that needs notification of mwi (and thus do not have a separate thread) indefinitely

Definition at line 26807 of file chan_sip.c.

References ao2_t_callback, ast_debug, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_verb, dialog_checkrtp_cb(), dialog_needdestroy(), FALSE, monlock, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sip_do_reload(), sip_reload_lock, and sipsock_read().

26808 {
26809    int res;
26810    time_t t;
26811    int reloading;
26812 
26813    /* Add an I/O event to our SIP UDP socket */
26814    if (sipsock > -1) {
26815       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
26816    }
26817 
26818    /* From here on out, we die whenever asked */
26819    for(;;) {
26820       /* Check for a reload request */
26821       ast_mutex_lock(&sip_reload_lock);
26822       reloading = sip_reloading;
26823       sip_reloading = FALSE;
26824       ast_mutex_unlock(&sip_reload_lock);
26825       if (reloading) {
26826          ast_verb(1, "Reloading SIP\n");
26827          sip_do_reload(sip_reloadreason);
26828 
26829          /* Change the I/O fd of our UDP socket */
26830          if (sipsock > -1) {
26831             if (sipsock_read_id) {
26832                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
26833             } else {
26834                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
26835             }
26836          } else if (sipsock_read_id) {
26837             ast_io_remove(io, sipsock_read_id);
26838             sipsock_read_id = NULL;
26839          }
26840       }
26841 
26842       /* Check for dialogs needing to be killed */
26843       t = time(NULL);
26844 
26845       /*
26846        * Check dialogs with rtp and rtptimeout.
26847        * All dialogs which have rtp are in dialogs_rtpcheck.
26848        */
26849       ao2_t_callback(dialogs_rtpcheck, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE,
26850          dialog_checkrtp_cb, &t,
26851          "callback to check rtptimeout and hangup calls if necessary");
26852       /*
26853        * Check dialogs marked to be destroyed.
26854        * All dialogs with needdestroy set are in dialogs_needdestroy.
26855        */
26856       ao2_t_callback(dialogs_needdestroy, OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy,
26857          NULL, "callback to check dialogs which need to be destroyed");
26858 
26859       /* XXX TODO The scheduler usage in this module does not have sufficient
26860        * synchronization being done between running the scheduler and places
26861        * scheduling tasks.  As it is written, any scheduled item may not run
26862        * any sooner than about  1 second, regardless of whether a sooner time
26863        * was asked for. */
26864 
26865       pthread_testcancel();
26866       /* Wait for sched or io */
26867       res = ast_sched_wait(sched);
26868       if ((res < 0) || (res > 1000)) {
26869          res = 1000;
26870       }
26871       res = ast_io_wait(io, res);
26872       if (res > 20) {
26873          ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res);
26874       }
26875       ast_mutex_lock(&monlock);
26876       res = ast_sched_runq(sched);
26877       if (res >= 20) {
26878          ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res);
26879       }
26880       ast_mutex_unlock(&monlock);
26881    }
26882 
26883    /* Never reached */
26884    return NULL;
26885 }

static int do_proxy_auth ( struct sip_pvt *  p,
struct sip_request *  req,
enum sip_auth_type  code,
int  sipmethod,
int  init 
) [static]

Add authentication on outbound SIP packet.

Definition at line 19883 of file chan_sip.c.

References ast_calloc, ast_debug, reply_digest(), sip_auth_headers(), sip_methods, cfsip_methods::text, and transmit_invite().

Referenced by handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_refer(), handle_response_subscribe(), and handle_response_update().

19884 {
19885    char *header, *respheader;
19886    char digest[1024];
19887 
19888    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
19889       return -2;
19890 
19891    p->authtries++;
19892    sip_auth_headers(code, &header, &respheader);
19893    ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
19894    memset(digest, 0, sizeof(digest));
19895    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
19896       /* No way to authenticate */
19897       return -1;
19898    }
19899    /* Now we have a reply digest */
19900    p->options->auth = digest;
19901    p->options->authheader = respheader;
19902    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL);
19903 }

static int do_register_auth ( struct sip_pvt *  p,
struct sip_request *  req,
enum sip_auth_type  code 
) [static]

Authenticate for outbound registration.

Definition at line 19859 of file chan_sip.c.

References append_history, ast_verbose, reply_digest(), sip_auth_headers(), sip_debug_test_pvt(), and transmit_register().

Referenced by handle_response_register().

19860 {
19861    char *header, *respheader;
19862    char digest[1024];
19863 
19864    p->authtries++;
19865    sip_auth_headers(code, &header, &respheader);
19866    memset(digest, 0, sizeof(digest));
19867    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
19868       /* There's nothing to use for authentication */
19869       /* No digest challenge in request */
19870       if (sip_debug_test_pvt(p) && p->registry)
19871          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
19872          /* No old challenge */
19873       return -1;
19874    }
19875    if (p->do_history)
19876       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
19877    if (sip_debug_test_pvt(p) && p->registry)
19878       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
19879    return transmit_register(p->registry, SIP_REGISTER, digest, respheader);
19880 }

static void do_setnat ( struct sip_pvt *  p  )  [static]

Set nat mode on the various data sockets.

Definition at line 5166 of file chan_sip.c.

References ast_debug, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_NAT, ast_test_flag, and ast_udptl_setnat().

Referenced by check_peer_ok(), dialog_initialize_rtp(), sip_alloc(), and transmit_response_using_temp().

05167 {
05168    const char *mode;
05169    int natflags;
05170 
05171    natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
05172    mode = natflags ? "On" : "Off";
05173 
05174    if (p->rtp) {
05175       ast_debug(1, "Setting NAT on RTP to %s\n", mode);
05176       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags);
05177    }
05178    if (p->vrtp) {
05179       ast_debug(1, "Setting NAT on VRTP to %s\n", mode);
05180       ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags);
05181    }
05182    if (p->udptl) {
05183       ast_debug(1, "Setting NAT on UDPTL to %s\n", mode);
05184       ast_udptl_setnat(p->udptl, natflags);
05185    }
05186    if (p->trtp) {
05187       ast_debug(1, "Setting NAT on TRTP to %s\n", mode);
05188       ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags);
05189    }
05190 }

static const char * domain_mode_to_text ( const enum domain_mode  mode  )  [static]

Print domain mode to cli.

Definition at line 17924 of file chan_sip.c.

Referenced by sip_show_domains().

17925 {
17926    switch (mode) {
17927    case SIP_DOMAIN_AUTO:
17928       return "[Automatic]";
17929    case SIP_DOMAIN_CONFIG:
17930       return "[Configured]";
17931    }
17932 
17933    return "";
17934 }

static const char * dtmfmode2str ( int  mode  )  [static]

Convert DTMF mode to printable string.

Definition at line 17622 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer(), sip_show_channel(), and sip_show_settings().

17623 {
17624    return map_x_s(dtmfstr, mode, "<error>");
17625 }

static void enable_dsp_detect ( struct sip_pvt *  p  )  [static]

Definition at line 4263 of file chan_sip.c.

References ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_features(), AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_mode_set(), ast_test_flag, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DIGIT_DETECT, and DSP_FEATURE_FAX_DETECT.

Referenced by sip_dtmfmode(), sip_new(), and sip_setoption().

04264 {
04265    int features = 0;
04266 
04267    if (p->dsp) {
04268       return;
04269    }
04270 
04271    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
04272        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
04273       if (p->rtp) {
04274          ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND);
04275       }
04276       features |= DSP_FEATURE_DIGIT_DETECT;
04277    }
04278 
04279    if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) {
04280       features |= DSP_FEATURE_FAX_DETECT;
04281    }
04282 
04283    if (!features) {
04284       return;
04285    }
04286 
04287    if (!(p->dsp = ast_dsp_new())) {
04288       return;
04289    }
04290 
04291    ast_dsp_set_features(p->dsp, features);
04292    if (global_relaxdtmf) {
04293       ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
04294    }
04295 }

static int esc_cmp_fn ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 996 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by initialize_escs().

00997 {
00998    struct sip_esc_entry *entry1 = obj;
00999    struct sip_esc_entry *entry2 = arg;
01000 
01001    return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0;
01002 }

static void esc_entry_destructor ( void *  obj  )  [static]

Definition at line 982 of file chan_sip.c.

References AST_SCHED_DEL.

Referenced by create_esc_entry().

00983 {
00984    struct sip_esc_entry *esc_entry = obj;
00985    if (esc_entry->sched_id > -1) {
00986       AST_SCHED_DEL(sched, esc_entry->sched_id);
00987    }
00988 }

static int esc_hash_fn ( const void *  obj,
const int  flags 
) [static]

Definition at line 990 of file chan_sip.c.

References ast_str_hash().

Referenced by initialize_escs().

00991 {
00992    const struct sip_esc_entry *entry = obj;
00993    return ast_str_hash(entry->entity_tag);
00994 }

static int expire_register ( const void *  data  )  [static]

Expire registration of SIP peer.

Definition at line 14158 of file chan_sip.c.

References ao2_ref, ao2_t_unlink, ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_sockaddr_isnull(), ast_test_flag, destroy_association(), EVENT_FLAG_SYSTEM, FALSE, manager_event, register_peer_exten(), set_socket_transport(), sip_unref_peer(), and unlink_peer_from_tables().

Referenced by parse_register_contact(), realtime_peer(), reg_source_db(), sip_show_sched(), and sip_unregister().

14159 {
14160    struct sip_peer *peer = (struct sip_peer *)data;
14161 
14162    if (!peer) {      /* Hmmm. We have no peer. Weird. */
14163       return 0;
14164    }
14165 
14166    peer->expire = -1;
14167    peer->portinuri = 0;
14168 
14169    destroy_association(peer); /* remove registration data from storage */
14170    set_socket_transport(&peer->socket, peer->default_outbound_transport);
14171 
14172    if (peer->socket.tcptls_session) {
14173       ao2_ref(peer->socket.tcptls_session, -1);
14174       peer->socket.tcptls_session = NULL;
14175    }
14176 
14177    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
14178    register_peer_exten(peer, FALSE);   /* Remove regexten */
14179    ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
14180 
14181    /* Do we need to release this peer from memory?
14182       Only for realtime peers and autocreated peers
14183    */
14184    if (peer->is_realtime) {
14185       ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
14186    }
14187 
14188    if (peer->selfdestruct ||
14189        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
14190       unlink_peer_from_tables(peer);
14191    } else if (!ast_sockaddr_isnull(&peer->addr)) {
14192       /* If we aren't self-destructing a temp_peer, we still need to unlink the peer
14193        * from the peers_by_ip table, otherwise we end up with multiple copies hanging
14194        * around each time a registration expires and the peer re-registers. */
14195       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
14196    }
14197 
14198    /* Only clear the addr after we check for destruction.  The addr must remain
14199     * in order to unlink from the peers_by_ip container correctly */
14200    memset(&peer->addr, 0, sizeof(peer->addr));
14201 
14202    sip_unref_peer(peer, "removing peer ref for expire_register");
14203 
14204    return 0;
14205 }

static void extract_host_from_hostport ( char **  hostport  )  [static]

Terminate a host:port at the ':'.

Parameters:
hostport The address of the hostport string
Note:
In the case of a bracket-enclosed IPv6 address, the hostport variable will contain the non-bracketed host as a result of calling this function.

Definition at line 15173 of file chan_sip.c.

References ast_sockaddr_split_hostport(), and PARSE_PORT_IGNORE.

Referenced by check_user_full(), get_destination(), register_verify(), and sip_msg_send().

15174 {
15175    char *dont_care;
15176    ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE);
15177 }

static void extract_uri ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Check Contact: URI of SIP message.

Definition at line 12303 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_in_brackets(), remove_uri_parameters(), and sip_get_header().

Referenced by handle_incoming(), and handle_request_invite().

12304 {
12305    char stripped[SIPBUFSIZE];
12306    char *c;
12307 
12308    ast_copy_string(stripped, sip_get_header(req, "Contact"), sizeof(stripped));
12309    c = get_in_brackets(stripped);
12310    /* Cut the URI at the at sign after the @, not in the username part */
12311    c = remove_uri_parameters(c);
12312    if (!ast_strlen_zero(c)) {
12313       ast_string_field_set(p, uri, c);
12314    }
12315 
12316 }

static const char* faxec2str ( int  faxec  )  [static]

Definition at line 18088 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

18089 {
18090    return map_x_s(faxecmodes, faxec, "Unknown");
18091 }

static int finalize_content ( struct sip_request *  req  )  [static]

Add 'Content-Length' header and content to SIP message.

Definition at line 10165 of file chan_sip.c.

References add_header(), ast_log(), ast_str_append(), ast_str_buffer(), ast_str_strlen(), and LOG_WARNING.

Referenced by send_request(), and send_response().

10166 {
10167    char clen[10];
10168 
10169    if (req->lines) {
10170       ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n");
10171       return -1;
10172    }
10173 
10174    snprintf(clen, sizeof(clen), "%zd", ast_str_strlen(req->content));
10175    add_header(req, "Content-Length", clen);
10176 
10177    if (ast_str_strlen(req->content)) {
10178       ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content));
10179    }
10180    req->lines = ast_str_strlen(req->content) ? 1 : 0;
10181    return 0;
10182 }

static const char * find_alias ( const char *  name,
const char *  _default 
) [static]

Find compressed SIP alias.

Definition at line 7432 of file chan_sip.c.

References ARRAY_LEN.

07433 {
07434    int x;
07435 
07436    for (x = 0; x < ARRAY_LEN(aliases); x++) {
07437       if (!strcasecmp(aliases[x].fullname, name))
07438          return aliases[x].shortname;
07439    }
07440 
07441    return _default;
07442 }

static int find_by_callid_helper ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1699 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.

Referenced by find_sip_cc_agent_by_original_callid().

01700 {
01701    struct ast_cc_agent *agent = obj;
01702    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01703    struct sip_pvt *call_pvt = arg;
01704 
01705    return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0;
01706 }

static int find_by_name ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 5065 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by sip_find_peer_full().

05066 {
05067    struct sip_peer *search = obj, *match = arg;
05068    int *which_objects = data;
05069 
05070    /* Usernames in SIP uri's are case sensitive. Domains are not */
05071    if (strcmp(search->name, match->name)) {
05072       return 0;
05073    }
05074 
05075    switch (*which_objects) {
05076    case FINDUSERS:
05077       if (!(search->type & SIP_TYPE_USER)) {
05078          return 0;
05079       }
05080       break;
05081    case FINDPEERS:
05082       if (!(search->type & SIP_TYPE_PEER)) {
05083          return 0;
05084       }
05085       break;
05086    case FINDALLDEVICES:
05087       break;
05088    }
05089 
05090    return CMP_MATCH | CMP_STOP;
05091 }

static int find_by_notify_uri_helper ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1669 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, and sip_uri_cmp().

Referenced by find_sip_cc_agent_by_notify_uri().

01670 {
01671    struct ast_cc_agent *agent = obj;
01672    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01673    const char *uri = arg;
01674 
01675    return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
01676 }

static int find_by_subscribe_uri_helper ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1684 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, and sip_uri_cmp().

Referenced by find_sip_cc_agent_by_subscribe_uri().

01685 {
01686    struct ast_cc_agent *agent = obj;
01687    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01688    const char *uri = arg;
01689 
01690    return !sip_uri_cmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
01691 }

static struct sip_pvt * find_call ( struct sip_request *  req,
struct ast_sockaddr addr,
const int  intended_method 
) [static, read]

find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_request_do

Definition at line 8267 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_next, ao2_t_callback, ao2_t_find, args, ast_debug, ast_skip_blanks(), ast_strlen_zero(), match_req_args::authentication_present, match_req_args::callid, dialog_find_multiple(), forked_invite_init(), free_via(), match_req_args::fromtag, gettag(), match_req_to_dialog(), match_req_args::method, OBJ_MULTIPLE, OBJ_POINTER, parse_via(), match_req_args::respid, match_req_args::ruri, match_req_args::seqno, sip_alloc(), sip_cfg, sip_get_header(), sip_methods, SIP_REQ_FORKED, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, cfsip_methods::text, match_req_args::totag, transmit_response_using_temp(), match_req_args::viabranch, and match_req_args::viasentby.

Referenced by handle_request_do().

08268 {
08269    char totag[128];
08270    char fromtag[128];
08271    const char *callid = sip_get_header(req, "Call-ID");
08272    const char *from = sip_get_header(req, "From");
08273    const char *to = sip_get_header(req, "To");
08274    const char *cseq = sip_get_header(req, "Cseq");
08275    struct sip_pvt *sip_pvt_ptr;
08276    uint32_t seqno;
08277    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
08278    /* sip_get_header always returns non-NULL so we must use ast_strlen_zero() */
08279    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
08280          ast_strlen_zero(from) || ast_strlen_zero(cseq) ||
08281          (sscanf(cseq, "%30u", &seqno) != 1)) {
08282 
08283       /* RFC 3261 section 24.4.1.   Send a 400 Bad Request if the request is malformed. */
08284       if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
08285          transmit_response_using_temp(callid, addr, 1, intended_method,
08286                        req, "400 Bad Request");
08287       }
08288       return NULL;   /* Invalid packet */
08289    }
08290 
08291    if (sip_cfg.pedanticsipchecking) {
08292       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
08293          we need more to identify a branch - so we have to check branch, from
08294          and to tags to identify a call leg.
08295          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
08296          in sip.conf
08297          */
08298       if (gettag(req, "To", totag, sizeof(totag)))
08299          req->has_to_tag = 1; /* Used in handle_request/response */
08300       gettag(req, "From", fromtag, sizeof(fromtag));
08301 
08302       ast_debug(5, "= Looking for  Call ID: %s (Checking %s) --From tag %s --To-tag %s  \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
08303 
08304       /* All messages must always have From: tag */
08305       if (ast_strlen_zero(fromtag)) {
08306          ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
08307          return NULL;
08308       }
08309       /* reject requests that must always have a To: tag */
08310       if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) {
08311          if (req->method != SIP_ACK) {
08312             transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
08313          }
08314          ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
08315          return NULL;
08316       }
08317    }
08318 
08319    if (!sip_cfg.pedanticsipchecking) {
08320       struct sip_pvt tmp_dialog = {
08321          .callid = callid,
08322       };
08323       sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs");
08324       if (sip_pvt_ptr) {  /* well, if we don't find it-- what IS in there? */
08325          /* Found the call */
08326          return sip_pvt_ptr;
08327       }
08328    } else { /* in pedantic mode! -- do the fancy search */
08329       struct sip_pvt tmp_dialog = {
08330          .callid = callid,
08331       };
08332       /* if a Outbound forked Request is detected, this pvt will point
08333        * to the dialog the Request is forking off of. */
08334       struct sip_pvt *fork_pvt = NULL;
08335       struct match_req_args args = { 0, };
08336       int found;
08337       struct ao2_iterator *iterator = ao2_t_callback(dialogs,
08338          OBJ_POINTER | OBJ_MULTIPLE,
08339          dialog_find_multiple,
08340          &tmp_dialog,
08341          "pedantic ao2_find in dialogs");
08342       struct sip_via *via = NULL;
08343 
08344       args.method = req->method;
08345       args.callid = NULL; /* we already matched this. */
08346       args.totag = totag;
08347       args.fromtag = fromtag;
08348       args.seqno = seqno;
08349       /* get via header information. */
08350       args.ruri = REQ_OFFSET_TO_STR(req, rlPart2);
08351       via = parse_via(sip_get_header(req, "Via"));
08352       if (via) {
08353          args.viasentby = via->sent_by;
08354          args.viabranch = via->branch;
08355       }
08356       /* determine if this is a Request with authentication credentials. */
08357       if (!ast_strlen_zero(sip_get_header(req, "Authorization")) ||
08358          !ast_strlen_zero(sip_get_header(req, "Proxy-Authorization"))) {
08359          args.authentication_present = 1;
08360       }
08361       /* if it is a response, get the response code */
08362       if (req->method == SIP_RESPONSE) {
08363          const char* e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2));
08364          int respid;
08365          if (!ast_strlen_zero(e) && (sscanf(e, "%30d", &respid) == 1)) {
08366             args.respid = respid;
08367          }
08368       }
08369 
08370       /* Iterate a list of dialogs already matched by Call-id */
08371       while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) {
08372          found = match_req_to_dialog(sip_pvt_ptr, &args);
08373 
08374          switch (found) {
08375          case SIP_REQ_MATCH:
08376             ao2_iterator_destroy(iterator);
08377             dialog_unref(fork_pvt, "unref fork_pvt");
08378             free_via(via);
08379             return sip_pvt_ptr; /* return pvt with ref */
08380          case SIP_REQ_LOOP_DETECTED:
08381             /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
08382             * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
08383             transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
08384             dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search.");
08385             ao2_iterator_destroy(iterator);
08386             dialog_unref(fork_pvt, "unref fork_pvt");
08387             free_via(via);
08388             return NULL;
08389          case SIP_REQ_FORKED:
08390             dialog_unref(fork_pvt, "throwing way pvt to fork off of.");
08391             fork_pvt = dialog_ref(sip_pvt_ptr, "this pvt has a forked request, save this off to copy information into new dialog\n");
08392             /* fall through */
08393          case SIP_REQ_NOT_MATCH:
08394          default:
08395             dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search");
08396          }
08397       }
08398       if (iterator) {
08399          ao2_iterator_destroy(iterator);
08400       }
08401 
08402       /* Handle any possible forked requests. This must be done only after transaction matching is complete. */
08403       if (fork_pvt) {
08404          /* XXX right now we only support handling forked INVITE Requests. Any other
08405           * forked request type must be added here. */
08406          if (fork_pvt->method == SIP_INVITE) {
08407             forked_invite_init(req, args.totag, fork_pvt, addr);
08408             dialog_unref(fork_pvt, "throwing way old forked pvt");
08409             free_via(via);
08410             return NULL;
08411          }
08412          fork_pvt = dialog_unref(fork_pvt, "throwing way pvt to fork off of");
08413       }
08414 
08415       free_via(via);
08416    } /* end of pedantic mode Request/Reponse to Dialog matching */
08417 
08418    /* See if the method is capable of creating a dialog */
08419    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
08420       struct sip_pvt *p = NULL;
08421 
08422       if (intended_method == SIP_REFER) {
08423          /* We do support REFER, but not outside of a dialog yet */
08424          transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)");
08425    
08426       /* Ok, time to create a new SIP dialog object, a pvt */
08427       } else if (!(p = sip_alloc(callid, addr, 1, intended_method, req)))  {
08428          /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
08429             getting a dialog from sip_alloc.
08430 
08431             Without a dialog we can't retransmit and handle ACKs and all that, but at least
08432             send an error message.
08433 
08434             Sorry, we apologize for the inconvienience
08435          */
08436          transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error");
08437          ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
08438       }
08439       return p; /* can be NULL */
08440    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
08441       /* A method we do not support, let's take it on the volley */
08442       transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented");
08443       ast_debug(2, "Got a request with unsupported SIP method.\n");
08444    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
08445       /* This is a request outside of a dialog that we don't know about */
08446       transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
08447       ast_debug(2, "That's odd...  Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
08448    }
08449    /* We do not respond to responses for dialogs that we don't know about, we just drop
08450       the session quickly */
08451    if (intended_method == SIP_RESPONSE)
08452       ast_debug(2, "That's odd...  Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>");
08453 
08454    return NULL;
08455 }

static int find_calling_channel ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Find the channel that is causing the RINGING update.

Definition at line 12940 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, CMP_MATCH, CMP_STOP, ast_channel::context, ast_channel::exten, ast_channel::macroexten, ast_channel::pbx, and sip_cfg.

Referenced by state_notify_build_xml().

12941 {
12942    struct ast_channel *c = obj;
12943    struct sip_pvt *p = data;
12944    int res;
12945 
12946    ast_channel_lock(c);
12947 
12948    res = (c->pbx &&
12949          (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) &&
12950          (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context)));
12951 
12952    ast_channel_unlock(c);
12953 
12954    return res ? CMP_MATCH | CMP_STOP : 0;
12955 }

const char* find_closing_quote ( const char *  start,
const char *  lim 
)

Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.

Definition at line 4441 of file chan_sip.c.

Referenced by get_comma(), get_in_brackets_full(), and parse_moved_contact().

04442 {
04443    char last_char = '\0';
04444    const char *s;
04445    for (s = start; *s && s != lim; last_char = *s++) {
04446       if (*s == '"' && last_char != '\\')
04447          break;
04448    }
04449    return s;
04450 }

static const char* find_full_alias ( const char *  name,
const char *  _default 
) [static]

Find full SIP alias.

Definition at line 7445 of file chan_sip.c.

References ARRAY_LEN.

Referenced by set_message_vars_from_req().

07446 {
07447    int x;
07448 
07449    if (strlen(name) == 1) {
07450       /* We have a short header name to convert. */
07451       for (x = 0; x < ARRAY_LEN(aliases); ++x) {
07452          if (!strcasecmp(aliases[x].shortname, name))
07453             return aliases[x].fullname;
07454       }
07455    }
07456 
07457    return _default;
07458 }

static struct sip_auth * find_realm_authentication ( struct sip_auth_container *  credentials,
const char *  realm 
) [static, read]

Definition at line 28055 of file chan_sip.c.

References AST_LIST_TRAVERSE.

Referenced by build_reply_digest().

28056 {
28057    struct sip_auth *auth;
28058 
28059    if (credentials) {
28060       AST_LIST_TRAVERSE(&credentials->list, auth, node) {
28061          if (!strcasecmp(auth->realm, realm)) {
28062             break;
28063          }
28064       }
28065    } else {
28066       auth = NULL;
28067    }
28068 
28069    return auth;
28070 }

static int find_sdp ( struct sip_request *  req  )  [static]

Determine whether a SIP message contains an SDP in its body.

Parameters:
req the SIP request to process
Returns:
1 if SDP found, 0 if not found
Also updates req->sdp_start and req->sdp_count to indicate where the SDP lives in the message body.

Definition at line 8813 of file chan_sip.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_WARNING, sip_get_header(), strcasestr(), and TRUE.

Referenced by handle_incoming(), handle_request_invite(), handle_response(), and handle_response_invite().

08814 {
08815    const char *content_type;
08816    const char *content_length;
08817    const char *search;
08818    char *boundary;
08819    unsigned int x;
08820    int boundaryisquoted = FALSE;
08821    int found_application_sdp = FALSE;
08822    int found_end_of_headers = FALSE;
08823 
08824    content_length = sip_get_header(req, "Content-Length");
08825 
08826    if (!ast_strlen_zero(content_length)) {
08827       if (sscanf(content_length, "%30u", &x) != 1) {
08828          ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
08829          return 0;
08830       }
08831 
08832       /* Content-Length of zero means there can't possibly be an
08833          SDP here, even if the Content-Type says there is */
08834       if (x == 0)
08835          return 0;
08836    }
08837 
08838    content_type = sip_get_header(req, "Content-Type");
08839 
08840    /* if the body contains only SDP, this is easy */
08841    if (!strncasecmp(content_type, "application/sdp", 15)) {
08842       req->sdp_start = 0;
08843       req->sdp_count = req->lines;
08844       return req->lines ? 1 : 0;
08845    }
08846 
08847    /* if it's not multipart/mixed, there cannot be an SDP */
08848    if (strncasecmp(content_type, "multipart/mixed", 15))
08849       return 0;
08850 
08851    /* if there is no boundary marker, it's invalid */
08852    if ((search = strcasestr(content_type, ";boundary=")))
08853       search += 10;
08854    else if ((search = strcasestr(content_type, "; boundary=")))
08855       search += 11;
08856    else
08857       return 0;
08858 
08859    if (ast_strlen_zero(search))
08860       return 0;
08861 
08862    /* If the boundary is quoted with ", remove quote */
08863    if (*search == '\"')  {
08864       search++;
08865       boundaryisquoted = TRUE;
08866    }
08867 
08868    /* make a duplicate of the string, with two extra characters
08869       at the beginning */
08870    boundary = ast_strdupa(search - 2);
08871    boundary[0] = boundary[1] = '-';
08872    /* Remove final quote */
08873    if (boundaryisquoted)
08874       boundary[strlen(boundary) - 1] = '\0';
08875 
08876    /* search for the boundary marker, the empty line delimiting headers from
08877       sdp part and the end boundry if it exists */
08878 
08879    for (x = 0; x < (req->lines); x++) {
08880       const char *line = REQ_OFFSET_TO_STR(req, line[x]);
08881       if (!strncasecmp(line, boundary, strlen(boundary))){
08882          if (found_application_sdp && found_end_of_headers) {
08883             req->sdp_count = (x - 1) - req->sdp_start;
08884             return 1;
08885          }
08886          found_application_sdp = FALSE;
08887       }
08888       if (!strcasecmp(line, "Content-Type: application/sdp"))
08889          found_application_sdp = TRUE;
08890       
08891       if (ast_strlen_zero(line)) {
08892          if (found_application_sdp && !found_end_of_headers){
08893             req->sdp_start = x;
08894             found_end_of_headers = TRUE;
08895          }
08896       }
08897    }
08898    if (found_application_sdp && found_end_of_headers) {
08899       req->sdp_count = x - req->sdp_start;
08900       return TRUE;
08901    }
08902    return FALSE;
08903 }

static struct ast_cc_agent* find_sip_cc_agent_by_notify_uri ( const char *const   uri  )  [static, read]

Definition at line 1678 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_notify_uri_helper().

Referenced by get_destination().

01679 {
01680    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP");
01681    return agent;
01682 }

static struct ast_cc_agent* find_sip_cc_agent_by_original_callid ( struct sip_pvt *  pvt  )  [static, read]

Definition at line 1708 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_callid_helper().

Referenced by add_cc_call_info_to_response().

01709 {
01710    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP");
01711    return agent;
01712 }

static struct ast_cc_agent* find_sip_cc_agent_by_subscribe_uri ( const char *const   uri  )  [static, read]

Definition at line 1693 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().

Referenced by handle_cc_subscribe().

01694 {
01695    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP");
01696    return agent;
01697 }

static int find_sip_method ( const char *  msg  )  [static]

find_sip_method: Find SIP method from header

Definition at line 3190 of file chan_sip.c.

References ARRAY_LEN, ast_strlen_zero(), cfsip_methods::id, method_match(), and sip_methods.

Referenced by __sip_pretend_ack(), handle_request_do(), handle_response(), mark_parsed_methods(), and sip_hangup().

03191 {
03192    int i, res = 0;
03193    
03194    if (ast_strlen_zero(msg)) {
03195       return 0;
03196    }
03197    for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) {
03198       if (method_match(i, msg)) {
03199          res = sip_methods[i].id;
03200       }
03201    }
03202    return res;
03203 }

static int find_sip_monitor_instance_by_subscription_pvt ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1906 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by handle_cc_notify(), and handle_response_subscribe().

01907 {
01908    struct sip_monitor_instance *monitor_instance = obj;
01909    return monitor_instance->subscription_pvt == arg ? CMP_MATCH | CMP_STOP : 0;
01910 }

static int find_sip_monitor_instance_by_suspension_entry ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1912 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by cc_handle_publish_error().

01913 {
01914    struct sip_monitor_instance *monitor_instance = obj;
01915    return monitor_instance->suspension_entry == arg ? CMP_MATCH | CMP_STOP : 0;
01916 }

static struct epa_static_data* find_static_data ( const char *const   event_package  )  [static, read]

Definition at line 910 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by create_epa_entry().

00911 {
00912    const struct epa_backend *backend = NULL;
00913 
00914    AST_LIST_LOCK(&epa_static_data_list);
00915    AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) {
00916       if (!strcmp(backend->static_data->name, event_package)) {
00917          break;
00918       }
00919    }
00920    AST_LIST_UNLOCK(&epa_static_data_list);
00921    return backend ? backend->static_data : NULL;
00922 }

static struct cfsubscription_types * find_subscription_type ( enum subscriptiontype  subtype  )  [static, read]

Find subscription type in array.

Definition at line 18994 of file chan_sip.c.

References ARRAY_LEN, subscription_types, and type.

Referenced by transmit_state_notify().

18995 {
18996    int i;
18997 
18998    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
18999       if (subscription_types[i].type == subtype) {
19000          return &subscription_types[i];
19001       }
19002    }
19003    return &subscription_types[0];
19004 }

static void forked_invite_init ( struct sip_request *  req,
const char *  new_theirtag,
struct sip_pvt *  original,
struct ast_sockaddr addr 
) [static]

This function creates a dialog to handle a forked request. This dialog exists only to properly terminiate the the forked request immediately.

Definition at line 8168 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, build_route(), copy_request(), parse_ok_contact(), pvt_set_needdestroy(), sip_alloc(), transmit_request(), and TRUE.

Referenced by find_call().

08169 {
08170    struct sip_pvt *p;
08171 
08172    if (!(p = sip_alloc(original->callid, addr, 1, SIP_INVITE, req)))  {
08173       return; /* alloc error */
08174    }
08175    p->invitestate = INV_TERMINATED;
08176    p->ocseq = original->ocseq;
08177    p->branch = original->branch;
08178 
08179    memcpy(&p->flags, &original->flags, sizeof(p->flags));
08180    copy_request(&p->initreq, &original->initreq);
08181    ast_string_field_set(p, theirtag, new_theirtag);
08182    ast_copy_string(p->tag, original->tag, sizeof(p->tag));
08183    ast_string_field_set(p, uri, original->uri);
08184    ast_string_field_set(p, our_contact, original->our_contact);
08185    ast_string_field_set(p, fullcontact, original->fullcontact);
08186    parse_ok_contact(p, req);
08187    build_route(p, req, 1);
08188 
08189    transmit_request(p, SIP_ACK, p->ocseq, XMIT_UNRELIABLE, TRUE);
08190    transmit_request(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
08191 
08192    pvt_set_needdestroy(p, "forked request"); /* this dialog will terminate once the BYE is responed to or times out. */
08193    dialog_unref(p, "setup forked invite termination");
08194 }

static void free_old_route ( struct sip_route *  route  )  [static]

Remove route from route list.

Definition at line 14613 of file chan_sip.c.

References ast_free.

Referenced by __sip_destroy(), and build_route().

14614 {
14615    struct sip_route *next;
14616 
14617    while (route) {
14618       next = route->next;
14619       ast_free(route);
14620       route = next;
14621    }
14622 }

static int func_check_sipdomain ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Dial plan function to check if domain is local.

Definition at line 20149 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.

20150 {
20151    if (ast_strlen_zero(data)) {
20152       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
20153       return -1;
20154    }
20155    if (check_sip_domain(data, NULL, 0))
20156       ast_copy_string(buf, data, len);
20157    else
20158       buf[0] = '\0';
20159    return 0;
20160 }

static int func_header_read ( struct ast_channel chan,
const char *  function,
char *  data,
char *  buf,
size_t  len 
) [static]

Read SIP header (dialplan function).

Definition at line 20090 of file chan_sip.c.

References __get_header(), args, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.

20091 {
20092    struct sip_pvt *p;
20093    const char *content = NULL;
20094    AST_DECLARE_APP_ARGS(args,
20095       AST_APP_ARG(header);
20096       AST_APP_ARG(number);
20097    );
20098    int i, number, start = 0;
20099 
20100    if (ast_strlen_zero(data)) {
20101       ast_log(LOG_WARNING, "This function requires a header name.\n");
20102       return -1;
20103    }
20104 
20105    ast_channel_lock(chan);
20106    if (!IS_SIP_TECH(chan->tech)) {
20107       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
20108       ast_channel_unlock(chan);
20109       return -1;
20110    }
20111 
20112    AST_STANDARD_APP_ARGS(args, data);
20113    if (!args.number) {
20114       number = 1;
20115    } else {
20116       sscanf(args.number, "%30d", &number);
20117       if (number < 1)
20118          number = 1;
20119    }
20120 
20121    p = chan->tech_pvt;
20122 
20123    /* If there is no private structure, this channel is no longer alive */
20124    if (!p) {
20125       ast_channel_unlock(chan);
20126       return -1;
20127    }
20128 
20129    for (i = 0; i < number; i++)
20130       content = __get_header(&p->initreq, args.header, &start);
20131 
20132    if (ast_strlen_zero(content)) {
20133       ast_channel_unlock(chan);
20134       return -1;
20135    }
20136 
20137    ast_copy_string(buf, content, len);
20138    ast_channel_unlock(chan);
20139 
20140    return 0;
20141 }

static int function_sipchaninfo_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

${SIPCHANINFO()} Dialplan function - reads sip channel data

Definition at line 20267 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_sockaddr_stringify_addr(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.

20268 {
20269    struct sip_pvt *p;
20270    static int deprecated = 0;
20271 
20272    *buf = 0;
20273    
20274    if (!data) {
20275       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
20276       return -1;
20277    }
20278 
20279    ast_channel_lock(chan);
20280    if (!IS_SIP_TECH(chan->tech)) {
20281       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
20282       ast_channel_unlock(chan);
20283       return -1;
20284    }
20285 
20286    if (deprecated++ % 20 == 0) {
20287       /* Deprecated in 1.6.1 */
20288       ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated.  Please transition to using CHANNEL().\n");
20289    }
20290 
20291    p = chan->tech_pvt;
20292 
20293    /* If there is no private structure, this channel is no longer alive */
20294    if (!p) {
20295       ast_channel_unlock(chan);
20296       return -1;
20297    }
20298 
20299    if (!strcasecmp(data, "peerip")) {
20300       ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len);
20301    } else  if (!strcasecmp(data, "recvip")) {
20302       ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len);
20303    } else  if (!strcasecmp(data, "from")) {
20304       ast_copy_string(buf, p->from, len);
20305    } else  if (!strcasecmp(data, "uri")) {
20306       ast_copy_string(buf, p->uri, len);
20307    } else  if (!strcasecmp(data, "useragent")) {
20308       ast_copy_string(buf, p->useragent, len);
20309    } else  if (!strcasecmp(data, "peername")) {
20310       ast_copy_string(buf, p->peername, len);
20311    } else if (!strcasecmp(data, "t38passthrough")) {
20312       if ((p->t38.state == T38_DISABLED) || (p->t38.state == T38_REJECTED)) {
20313          ast_copy_string(buf, "0", len);
20314       } else { /* T38 is offered or enabled in this call */
20315          ast_copy_string(buf, "1", len);
20316       }
20317    } else {
20318       ast_channel_unlock(chan);
20319       return -1;
20320    }
20321    ast_channel_unlock(chan);
20322 
20323    return 0;
20324 }

static int function_sippeer ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

${SIPPEER()} Dialplan function - reads peer data

Todo:
Will be deprecated after 1.4

Definition at line 20168 of file chan_sip.c.

References ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_print_group(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_test_flag, chanvar, FALSE, LOG_WARNING, ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), sip_find_peer(), sip_unref_peer(), strsep(), TRUE, and ast_variable::value.

20169 {
20170    struct sip_peer *peer;
20171    char *colname;
20172 
20173    if ((colname = strchr(data, ':'))) {   /*! \todo Will be deprecated after 1.4 */
20174       static int deprecation_warning = 0;
20175       *colname++ = '\0';
20176       if (deprecation_warning++ % 10 == 0)
20177          ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated.  Please use ',' instead.\n");
20178    } else if ((colname = strchr(data, ',')))
20179       *colname++ = '\0';
20180    else
20181       colname = "ip";
20182 
20183    if (!(peer = sip_find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0)))
20184       return -1;
20185 
20186    if (!strcasecmp(colname, "ip")) {
20187       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
20188    } else  if (!strcasecmp(colname, "port")) {
20189       snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr));
20190    } else  if (!strcasecmp(colname, "status")) {
20191       peer_status(peer, buf, len);
20192    } else  if (!strcasecmp(colname, "language")) {
20193       ast_copy_string(buf, peer->language, len);
20194    } else  if (!strcasecmp(colname, "regexten")) {
20195       ast_copy_string(buf, peer->regexten, len);
20196    } else  if (!strcasecmp(colname, "limit")) {
20197       snprintf(buf, len, "%d", peer->call_limit);
20198    } else  if (!strcasecmp(colname, "busylevel")) {
20199       snprintf(buf, len, "%d", peer->busy_level);
20200    } else  if (!strcasecmp(colname, "curcalls")) {
20201       snprintf(buf, len, "%d", peer->inUse);
20202    } else if (!strcasecmp(colname, "maxforwards")) {
20203       snprintf(buf, len, "%d", peer->maxforwards);
20204    } else  if (!strcasecmp(colname, "accountcode")) {
20205       ast_copy_string(buf, peer->accountcode, len);
20206    } else  if (!strcasecmp(colname, "callgroup")) {
20207       ast_print_group(buf, len, peer->callgroup);
20208    } else  if (!strcasecmp(colname, "pickupgroup")) {
20209       ast_print_group(buf, len, peer->pickupgroup);
20210    } else  if (!strcasecmp(colname, "useragent")) {
20211       ast_copy_string(buf, peer->useragent, len);
20212    } else  if (!strcasecmp(colname, "mailbox")) {
20213       struct ast_str *mailbox_str = ast_str_alloca(512);
20214       peer_mailboxes_to_str(&mailbox_str, peer);
20215       ast_copy_string(buf, mailbox_str->str, len);
20216    } else  if (!strcasecmp(colname, "context")) {
20217       ast_copy_string(buf, peer->context, len);
20218    } else  if (!strcasecmp(colname, "expire")) {
20219       snprintf(buf, len, "%d", peer->expire);
20220    } else  if (!strcasecmp(colname, "dynamic")) {
20221       ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len);
20222    } else  if (!strcasecmp(colname, "callerid_name")) {
20223       ast_copy_string(buf, peer->cid_name, len);
20224    } else  if (!strcasecmp(colname, "callerid_num")) {
20225       ast_copy_string(buf, peer->cid_num, len);
20226    } else  if (!strcasecmp(colname, "codecs")) {
20227       ast_getformatname_multiple(buf, len -1, peer->caps);
20228    } else if (!strcasecmp(colname, "encryption")) {
20229       snprintf(buf, len, "%d", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP));
20230    } else  if (!strncasecmp(colname, "chanvar[", 8)) {
20231       char *chanvar=colname + 8;
20232       struct ast_variable *v;
20233 
20234       chanvar = strsep(&chanvar, "]");
20235       for (v = peer->chanvars ; v ; v = v->next) {
20236          if (!strcasecmp(v->name, chanvar)) {
20237             ast_copy_string(buf, v->value, len);
20238          }
20239       }
20240    } else  if (!strncasecmp(colname, "codec[", 6)) {
20241       char *codecnum;
20242       struct ast_format codec;
20243 
20244       codecnum = colname + 6; /* move past the '[' */
20245       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
20246       if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &codec))) {
20247          ast_copy_string(buf, ast_getformatname(&codec), len);
20248       } else {
20249          buf[0] = '\0';
20250       }
20251    } else {
20252       buf[0] = '\0';
20253    }
20254 
20255    sip_unref_peer(peer, "sip_unref_peer from function_sippeer, just before return");
20256 
20257    return 0;
20258 }

static char * generate_random_string ( char *  buf,
size_t  size 
) [static]

Generate 32 byte random string for callid's etc.

Definition at line 7658 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), build_callid_registry(), calendar_query_exec(), construct_pidf_body(), do_notify(), and generate_uri().

07659 {
07660    long val[4];
07661    int x;
07662 
07663    for (x=0; x<4; x++)
07664       val[x] = ast_random();
07665    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
07666 
07667    return buf;
07668 }

static char* generate_uri ( struct sip_pvt *  pvt,
char *  buf,
size_t  size 
) [static]

Definition at line 7670 of file chan_sip.c.

References ast_copy_string(), ast_sockaddr_stringify_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), and generate_random_string().

Referenced by add_cc_call_info_to_response(), and transmit_cc_notify().

07671 {
07672    struct ast_str *uri = ast_str_alloca(size);
07673    ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:");
07674    /* Here would be a great place to generate a UUID, but for now we'll
07675     * use the handy random string generation function we already have
07676     */
07677    ast_str_append(&uri, 0, "%s", generate_random_string(buf, size));
07678    ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify_remote(&pvt->ourip));
07679    ast_copy_string(buf, ast_str_buffer(uri), size);
07680    return buf;
07681 }

int get_address_family_filter ( const struct ast_sockaddr addr  )  [static]

Helper for dns resolution to filter by address family.

Note:
return 0 if addr is [::] else it returns addr's family.

Definition at line 26441 of file chan_sip.c.

References ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), and ast_sockaddr::ss.

Referenced by __sip_subscribe_mwi_do(), ast_sockaddr_resolve_first(), build_peer(), proxy_update(), realtime_peer_by_name(), and transmit_register().

26442 {
26443    if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) {
26444       return 0;
26445    }
26446 
26447    return addr->ss.ss_family;
26448 }

static int get_also_info ( struct sip_pvt *  p,
struct sip_request *  oreq 
) [static]

Call transfer support (old way, deprecated by the IETF).

Note:
does not account for SIPS: uri requirements, nor check transport

Definition at line 16224 of file chan_sip.c.

References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose, context, get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), pbx_builtin_getvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), sip_get_header(), SIP_PEDANTIC_DECODE, and sip_refer_allocate().

Referenced by handle_request_bye().

16225 {
16226    char tmp[256] = "", *c, *a;
16227    struct sip_request *req = oreq ? oreq : &p->initreq;
16228    struct sip_refer *referdata = NULL;
16229    const char *transfer_context = NULL;
16230    
16231    if (!p->refer && !sip_refer_allocate(p))
16232       return -1;
16233 
16234    referdata = p->refer;
16235 
16236    ast_copy_string(tmp, sip_get_header(req, "Also"), sizeof(tmp));
16237    c = get_in_brackets(tmp);
16238 
16239    if (parse_uri_legacy_check(c, "sip:,sips:", &c, NULL, &a, NULL)) {
16240       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
16241       return -1;
16242    }
16243    
16244    SIP_PEDANTIC_DECODE(c);
16245    SIP_PEDANTIC_DECODE(a);
16246 
16247    if (!ast_strlen_zero(a)) {
16248       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
16249    }
16250 
16251    if (sip_debug_test_pvt(p))
16252       ast_verbose("Looking for %s in %s\n", c, p->context);
16253 
16254    if (p->owner)  /* Mimic behaviour in res_features.c */
16255       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
16256 
16257    /* By default, use the context in the channel sending the REFER */
16258    if (ast_strlen_zero(transfer_context)) {
16259       transfer_context = S_OR(p->owner->macrocontext,
16260                S_OR(p->context, sip_cfg.default_context));
16261    }
16262    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
16263       /* This is a blind transfer */
16264       ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
16265       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
16266       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
16267       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
16268       referdata->refer_call = dialog_unref(referdata->refer_call, "unreffing referdata->refer_call");
16269       /* Set new context */
16270       ast_string_field_set(p, context, transfer_context);
16271       return 0;
16272    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
16273       return 1;
16274    }
16275 
16276    return -1;
16277 }

static char* get_body ( struct sip_request *  req,
char *  name,
char  delimiter 
) [static]

Get a specific line from the message body.

Definition at line 7387 of file chan_sip.c.

References get_body_by_line(), and len().

Referenced by handle_cc_notify(), handle_request_info(), and handle_request_notify().

07388 {
07389    int x;
07390    int len = strlen(name);
07391    char *r;
07392 
07393    for (x = 0; x < req->lines; x++) {
07394       r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter);
07395       if (r[0] != '\0') {
07396          return r;
07397       }
07398    }
07399 
07400    return "";
07401 }

static char* get_body_by_line ( const char *  line,
const char *  name,
int  nameLen,
char  delimiter 
) [static]

Reads one line of SIP message body.

Definition at line 7331 of file chan_sip.c.

References ast_skip_blanks().

Referenced by get_body(), and get_sdp_iterate().

07332 {
07333    if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter) {
07334       return ast_skip_blanks(line + nameLen + 1);
07335    }
07336 
07337    return "";
07338 }

static int get_cached_mwi ( struct sip_peer *  peer,
int *  new,
int *  old 
) [static]

Get cached MWI info.

Returns:
TRUE if found MWI in cache

Definition at line 26583 of file chan_sip.c.

References ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_LIST_TRAVERSE, mailbox, and S_OR.

Referenced by sip_send_mwi_to_peer().

26584 {
26585    struct sip_mailbox *mailbox;
26586    int in_cache;
26587 
26588    in_cache = 0;
26589    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
26590       struct ast_event *event;
26591       event = ast_event_get_cached(AST_EVENT_MWI,
26592          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
26593          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
26594          AST_EVENT_IE_END);
26595       if (!event)
26596          continue;
26597       *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
26598       *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
26599       ast_event_destroy(event);
26600       in_cache = 1;
26601    }
26602 
26603    return in_cache;
26604 }

static void get_crypto_attrib ( struct sip_pvt *  p,
struct sip_srtp *  srtp,
const char **  a_crypto 
) [static]

Definition at line 11586 of file chan_sip.c.

References ast_log(), ast_test_flag, LOG_WARNING, sdp_crypto_attrib(), sdp_crypto_offer(), and sdp_crypto_setup().

Referenced by add_sdp().

11587 {
11588    int taglen = 80;
11589 
11590    /* Set encryption properties */
11591    if (srtp) {
11592       if (!srtp->crypto) {
11593          srtp->crypto = sdp_crypto_setup();
11594       }
11595 
11596       /* set the key length based on INVITE or settings */
11597       if (ast_test_flag(srtp, SRTP_CRYPTO_TAG_80)) {
11598          taglen = 80;
11599       } else if (ast_test_flag(&p->flags[2], SIP_PAGE3_SRTP_TAG_32) ||
11600           ast_test_flag(srtp, SRTP_CRYPTO_TAG_32)) {
11601          taglen = 32;
11602       }
11603 
11604       if (srtp->crypto && (sdp_crypto_offer(srtp->crypto, taglen) >= 0)) {
11605          *a_crypto = sdp_crypto_attrib(srtp->crypto);
11606       }
11607 
11608       if (!*a_crypto) {
11609          ast_log(LOG_WARNING, "No SRTP key management enabled\n");
11610       }
11611    }
11612 }

static enum sip_get_dest_result get_destination ( struct sip_pvt *  p,
struct sip_request *  oreq,
int *  cc_recall_core_id 
) [static]

Find out who the call is for.

We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.

Returns:
0 on success (found a matching extension), non-zero on failure
Note:
If the incoming uri is a SIPS: uri, we are required to carry this across the dialplan, so that the outbound call also is a sips: call or encrypted IAX2 call. If that's not available, the call should FAIL.

Definition at line 15774 of file chan_sip.c.

References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_uri_sip_user, ast_verbose, check_sip_domain(), context, ast_cc_agent::core_id, ast_cc_agent::device_name, exten, extract_host_from_hostport(), find_sip_cc_agent_by_notify_uri(), get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), ast_cc_agent::private_data, S_OR, sip_cfg, sip_debug_test_pvt(), sip_get_header(), sip_methods, SIP_PEDANTIC_DECODE, and cfsip_methods::text.

Referenced by handle_request_invite(), handle_request_options(), handle_request_subscribe(), and receive_message().

15775 {
15776    char tmp[256] = "", *uri, *unused_password, *domain;
15777    char tmpf[256] = "", *from = NULL;
15778    struct sip_request *req;
15779    char *decoded_uri;
15780 
15781    req = oreq;
15782    if (!req) {
15783       req = &p->initreq;
15784    }
15785 
15786    /* Find the request URI */
15787    if (req->rlPart2)
15788       ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp));
15789    
15790    uri = ast_strdupa(get_in_brackets(tmp));
15791 
15792    if (parse_uri_legacy_check(uri, "sip:,sips:", &uri, &unused_password, &domain, NULL)) {
15793       ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
15794       return SIP_GET_DEST_INVALID_URI;
15795    }
15796 
15797    SIP_PEDANTIC_DECODE(domain);
15798    SIP_PEDANTIC_DECODE(uri);
15799 
15800    extract_host_from_hostport(&domain);
15801 
15802    if (ast_strlen_zero(uri)) {
15803       /*
15804        * Either there really was no extension found or the request
15805        * URI had encoded nulls that made the string "empty".  Use "s"
15806        * as the extension.
15807        */
15808       uri = "s";
15809    }
15810 
15811    ast_string_field_set(p, domain, domain);
15812 
15813    /* Now find the From: caller ID and name */
15814    /* XXX Why is this done in get_destination? Isn't it already done?
15815       Needs to be checked
15816         */
15817    ast_copy_string(tmpf, sip_get_header(req, "From"), sizeof(tmpf));
15818    if (!ast_strlen_zero(tmpf)) {
15819       from = get_in_brackets(tmpf);
15820       if (parse_uri_legacy_check(from, "sip:,sips:", &from, NULL, &domain, NULL)) {
15821          ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from);
15822          return SIP_GET_DEST_INVALID_URI;
15823       }
15824 
15825       SIP_PEDANTIC_DECODE(from);
15826       SIP_PEDANTIC_DECODE(domain);
15827 
15828       extract_host_from_hostport(&domain);
15829 
15830       ast_string_field_set(p, fromdomain, domain);
15831    }
15832 
15833    if (!AST_LIST_EMPTY(&domain_list)) {
15834       char domain_context[AST_MAX_EXTENSION];
15835 
15836       domain_context[0] = '\0';
15837       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
15838          if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
15839             ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
15840             return SIP_GET_DEST_REFUSED;
15841          }
15842       }
15843       /* If we don't have a peer (i.e. we're a guest call),
15844        * overwrite the original context */
15845       if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) {
15846          ast_string_field_set(p, context, domain_context);
15847       }
15848    }
15849 
15850    /* If the request coming in is a subscription and subscribecontext has been specified use it */
15851    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) {
15852       ast_string_field_set(p, context, p->subscribecontext);
15853    }
15854 
15855    if (sip_debug_test_pvt(p)) {
15856       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
15857    }
15858 
15859    /* Since extensions.conf can have unescaped characters, try matching a
15860     * decoded uri in addition to the non-decoded uri. */
15861    decoded_uri = ast_strdupa(uri);
15862    ast_uri_decode(decoded_uri, ast_uri_sip_user);
15863 
15864    /* If this is a subscription we actually just need to see if a hint exists for the extension */
15865    if (req->method == SIP_SUBSCRIBE) {
15866       char hint[AST_MAX_EXTENSION];
15867       int which = 0;
15868       if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) ||
15869           (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) {
15870          if (!oreq) {
15871             ast_string_field_set(p, exten, which ? decoded_uri : uri);
15872          }
15873          return SIP_GET_DEST_EXTEN_FOUND;
15874       } else {
15875          return SIP_GET_DEST_EXTEN_NOT_FOUND;
15876       }
15877    } else {
15878       struct ast_cc_agent *agent;
15879       /* Check the dialplan for the username part of the request URI,
15880          the domain will be stored in the SIPDOMAIN variable
15881          Return 0 if we have a matching extension */
15882       if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) {
15883          if (!oreq) {
15884             ast_string_field_set(p, exten, uri);
15885          }
15886          return SIP_GET_DEST_EXTEN_FOUND;
15887       }
15888       if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
15889          || !strcmp(decoded_uri, ast_pickup_ext())) {
15890          if (!oreq) {
15891             ast_string_field_set(p, exten, decoded_uri);
15892          }
15893          return SIP_GET_DEST_EXTEN_FOUND;
15894       }
15895       if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) {
15896          struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
15897          /* This is a CC recall. We can set p's extension to the exten from
15898           * the original INVITE
15899           */
15900          ast_string_field_set(p, exten, agent_pvt->original_exten);
15901          /* And we need to let the CC core know that the caller is attempting
15902           * his recall
15903           */
15904          ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall",
15905                agent->device_name);
15906          if (cc_recall_core_id) {
15907             *cc_recall_core_id = agent->core_id;
15908          }
15909          ao2_ref(agent, -1);
15910          return SIP_GET_DEST_EXTEN_FOUND;
15911       }
15912    }
15913 
15914    if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)
15915       && (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))
15916          || ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
15917          || !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri)))) {
15918       /* Overlap dialing is enabled and we need more digits to match an extension. */
15919       return SIP_GET_DEST_EXTEN_MATCHMORE;
15920    }
15921 
15922    return SIP_GET_DEST_EXTEN_NOT_FOUND;
15923 }

static int get_domain ( const char *  str,
char *  domain,
int  len 
) [static]

Extract domain from SIP To/From header.

Returns:
-1 on error, 1 if domain string is empty, 0 if domain was properly extracted
Note:
TODO: Such code is all over SIP channel, there is a sense to organize this patern in one function

Definition at line 10993 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), get_in_brackets(), and LOG_WARNING.

Referenced by get_realm().

10994 {
10995    char tmpf[256];
10996    char *a, *from;
10997 
10998    *domain = '\0';
10999    ast_copy_string(tmpf, str, sizeof(tmpf));
11000    from = get_in_brackets(tmpf);
11001    if (!ast_strlen_zero(from)) {
11002       if (strncasecmp(from, "sip:", 4)) {
11003          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
11004          return -1;
11005       }
11006       from += 4;
11007    } else
11008       from = NULL;
11009 
11010    if (from) {
11011       int bracket = 0;
11012 
11013       /* Strip any params or options from user */
11014       if ((a = strchr(from, ';')))
11015          *a = '\0';
11016       /* Strip port from domain if present */
11017       for (a = from; *a != '\0'; ++a) {
11018          if (*a == ':' && bracket == 0) {
11019             *a = '\0';
11020             break;
11021          } else if (*a == '[') {
11022             ++bracket;
11023          } else if (*a == ']') {
11024             --bracket;
11025          }
11026       }
11027       if ((a = strchr(from, '@'))) {
11028          *a = '\0';
11029          ast_copy_string(domain, a + 1, len);
11030       } else
11031          ast_copy_string(domain, from, len);
11032    }
11033 
11034    return ast_strlen_zero(domain);
11035 }

static struct event_state_compositor* get_esc ( const char *const   event_package  )  [static, read]

Definition at line 1004 of file chan_sip.c.

References ARRAY_LEN, event_state_compositors, and name.

Referenced by create_new_sip_etag(), handle_request_publish(), and publish_expire().

01004                                                                                 {
01005    int i;
01006    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01007       if (!strcasecmp(event_package, event_state_compositors[i].name)) {
01008          return &event_state_compositors[i];
01009       }
01010    }
01011    return NULL;
01012 }

static struct sip_esc_entry* get_esc_entry ( const char *  entity_tag,
struct event_state_compositor esc 
) [static, read]

Definition at line 1014 of file chan_sip.c.

References ao2_find, ast_copy_string(), event_state_compositor::compositor, and OBJ_POINTER.

Referenced by handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().

01014                                                                                                         {
01015    struct sip_esc_entry *entry;
01016    struct sip_esc_entry finder;
01017 
01018    ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag));
01019 
01020    entry = ao2_find(esc->compositor, &finder, OBJ_POINTER);
01021 
01022    return entry;
01023 }

static struct ast_variable * get_insecure_variable_from_config ( struct ast_config config  )  [static, read]

Definition at line 4712 of file chan_sip.c.

References ast_category_browse(), ast_category_root(), ast_test_flag, ast_variable_retrieve(), set_insecure_flags(), and var.

Referenced by get_insecure_variable_from_sippeers().

04713 {
04714    struct ast_variable *var = NULL;
04715    struct ast_flags flags = {0};
04716    char *cat = NULL;
04717    const char *insecure;
04718    while ((cat = ast_category_browse(cfg, cat))) {
04719       insecure = ast_variable_retrieve(cfg, cat, "insecure");
04720       set_insecure_flags(&flags, insecure, -1);
04721       if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
04722          var = ast_category_root(cfg, cat);
04723          break;
04724       }
04725    }
04726    return var;
04727 }

static struct ast_variable* get_insecure_variable_from_sippeers ( const char *  column,
const char *  value 
) [static, read]

Definition at line 4729 of file chan_sip.c.

References ast_config_destroy(), ast_load_realtime_multientry(), ast_variables_dup(), get_insecure_variable_from_config(), SENTINEL, and var.

Referenced by realtime_peer_by_addr().

04730 {
04731    struct ast_config *peerlist;
04732    struct ast_variable *var = NULL;
04733    if ((peerlist = ast_load_realtime_multientry("sippeers", column, value, "insecure LIKE", "%port%", SENTINEL))) {
04734       if ((var = get_insecure_variable_from_config(peerlist))) {
04735          /* Must clone, because var will get freed along with
04736           * peerlist. */
04737          var = ast_variables_dup(var);
04738       }
04739       ast_config_destroy(peerlist);
04740    }
04741    return var;
04742 }

static struct ast_variable* get_insecure_variable_from_sipregs ( const char *  column,
const char *  value,
struct ast_variable **  var 
) [static, read]

Definition at line 4749 of file chan_sip.c.

References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_load_realtime_multientry(), ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ast_variables_dup(), SENTINEL, and set_insecure_flags().

Referenced by realtime_peer_by_addr().

04750 {
04751    struct ast_variable *varregs = NULL;
04752    struct ast_config *regs, *peers;
04753    char *regscat;
04754    const char *regname;
04755 
04756    if (!(regs = ast_load_realtime_multientry("sipregs", column, value, SENTINEL))) {
04757       return NULL;
04758    }
04759 
04760    /* Load *all* peers that are probably insecure=port */
04761    if (!(peers = ast_load_realtime_multientry("sippeers", "insecure LIKE", "%port%", SENTINEL))) {
04762       ast_config_destroy(regs);
04763       return NULL;
04764    }
04765 
04766    /* Loop over the sipregs that match IP address and attempt to find an
04767     * insecure=port match to it in sippeers. */
04768    regscat = NULL;
04769    while ((regscat = ast_category_browse(regs, regscat)) && (regname = ast_variable_retrieve(regs, regscat, "name"))) {
04770       char *peerscat;
04771       const char *peername;
04772 
04773       peerscat = NULL;
04774       while ((peerscat = ast_category_browse(peers, peerscat)) && (peername = ast_variable_retrieve(peers, peerscat, "name"))) {
04775          if (!strcasecmp(regname, peername)) {
04776             /* Ensure that it really is insecure=port and
04777              * not something else. */
04778             const char *insecure = ast_variable_retrieve(peers, peerscat, "insecure");
04779             struct ast_flags flags = {0};
04780             set_insecure_flags(&flags, insecure, -1);
04781             if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
04782                /* ENOMEM checks till the bitter end. */
04783                if ((varregs = ast_variables_dup(ast_category_root(regs, regscat)))) {
04784                   if (!(*var = ast_variables_dup(ast_category_root(peers, peerscat)))) {
04785                      ast_variables_destroy(varregs);
04786                      varregs = NULL;
04787                   }
04788                }
04789                goto done;
04790             }
04791          }
04792       }
04793    }
04794 
04795 done:
04796    ast_config_destroy(regs);
04797    ast_config_destroy(peers);
04798    return varregs;
04799 }

static int get_ip_and_port_from_sdp ( struct sip_request *  req,
const enum media_type  media,
struct ast_sockaddr addr 
) [static]

Definition at line 8935 of file chan_sip.c.

References ast_log(), ast_sockaddr_resolve_first_af(), ast_strlen_zero(), get_sdp_iterate(), len(), and LOG_WARNING.

Referenced by handle_request_invite().

08936 {
08937    const char *m;
08938    const char *c;
08939    int miterator = req->sdp_start;
08940    int citerator = req->sdp_start;
08941    int x = 0;
08942    int numberofports;
08943    int len;
08944    int af;
08945    char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */
08946 
08947    c = get_sdp_iterate(&citerator, req, "c");
08948    if (sscanf(c, "IN %3s %256s", proto, host) != 2) {
08949          ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
08950          /* Continue since there may be a valid host in a c= line specific to the audio stream */
08951    }
08952    /* We only want the m and c lines for audio */
08953    for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) {
08954       if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
08955           (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) ||
08956          (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
08957           (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) {
08958          /* See if there's a c= line for this media stream.
08959           * XXX There is no guarantee that we'll be grabbing the c= line for this
08960           * particular media stream here. However, this is the same logic used in process_sdp.
08961           */
08962          c = get_sdp_iterate(&citerator, req, "c");
08963          if (!ast_strlen_zero(c)) {
08964             sscanf(c, "IN %3s %256s", proto, host);
08965          }
08966          break;
08967       }
08968    }
08969 
08970    if (!strcmp("IP4", proto)) {
08971       af = AF_INET;
08972    } else if (!strcmp("IP6", proto)) {
08973       af = AF_INET6;
08974    } else {
08975       ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
08976       return -1;
08977    }
08978 
08979    if (ast_strlen_zero(host) || x == 0) {
08980       ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video");
08981       return -1;
08982    }
08983 
08984    if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
08985       ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video");
08986       return -1;
08987    }
08988 
08989    return 0;
08990 }

static int get_msg_text ( char *  buf,
int  len,
struct sip_request *  req 
) [static]

Get message body from a SIP request.

Parameters:
buf Destination buffer
len Destination buffer size
req The SIP request
When parsing the request originally, the lines are split by LF or CRLF. This function adds a single LF after every line.

Definition at line 16753 of file chan_sip.c.

Referenced by handle_request_info(), and handle_request_notify().

16754 {
16755    int x;
16756    int linelen;
16757 
16758    buf[0] = '\0';
16759    --len; /* reserve strncat null */
16760    for (x = 0; len && x < req->lines; ++x) {
16761       const char *line = REQ_OFFSET_TO_STR(req, line[x]);
16762       strncat(buf, line, len); /* safe */
16763       linelen = strlen(buf);
16764       buf += linelen;
16765       len -= linelen;
16766       if (len) {
16767          strcat(buf, "\n"); /* safe */
16768          ++buf;
16769          --len;
16770       }
16771    }
16772    return 0;
16773 }

static int get_msg_text2 ( struct ast_str **  buf,
struct sip_request *  req 
) [static]

Definition at line 16775 of file chan_sip.c.

References ast_str_append(), and ast_str_reset().

Referenced by receive_message().

16776 {
16777    int i, res = 0;
16778 
16779    ast_str_reset(*buf);
16780 
16781    for (i = 0; res >= 0 && i < req->lines; i++) {
16782       const char *line = REQ_OFFSET_TO_STR(req, line[i]);
16783 
16784       res = ast_str_append(buf, 0, "%s\n", line);
16785    }
16786 
16787    return res < 0 ? -1 : 0;
16788 }

static const char * get_name_from_variable ( const struct ast_variable var  )  [static]

Definition at line 4801 of file chan_sip.c.

References ast_strlen_zero(), ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by realtime_peer_by_addr(), and realtime_peer_get_sippeer_helper().

04802 {
04803    /* Don't expect this to return non-NULL. Both NULL and empty
04804     * values can cause the option to get removed from the variable
04805     * list. This is called on ast_variables gotten from both
04806     * ast_load_realtime and ast_load_realtime_multientry.
04807     * - ast_load_realtime removes options with empty values
04808     * - ast_load_realtime_multientry does not!
04809     * For consistent behaviour, we check for the empty name and
04810     * return NULL instead. */
04811    const struct ast_variable *tmp;
04812    for (tmp = var; tmp; tmp = tmp->next) {
04813       if (!strcasecmp(tmp->name, "name")) {
04814          if (!ast_strlen_zero(tmp->value)) {
04815             return tmp->value;
04816          }
04817          break;
04818       }
04819    }
04820    return NULL;
04821 }

static void get_our_media_address ( struct sip_pvt *  p,
int  needvideo,
int  needtext,
struct ast_sockaddr addr,
struct ast_sockaddr vaddr,
struct ast_sockaddr taddr,
struct ast_sockaddr dest,
struct ast_sockaddr vdest,
struct ast_sockaddr tdest 
) [static]

Set all IP media addresses for this call.

Note:
called from add_sdp()

Definition at line 11493 of file chan_sip.c.

References ast_rtp_instance_get_local_address(), ast_sockaddr_cmp_addr(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, and media_address.

Referenced by add_sdp().

11497 {
11498    int use_externip = 0;
11499 
11500    /* First, get our address */
11501    ast_rtp_instance_get_local_address(p->rtp, addr);
11502    if (p->vrtp) {
11503       ast_rtp_instance_get_local_address(p->vrtp, vaddr);
11504    }
11505    if (p->trtp) {
11506       ast_rtp_instance_get_local_address(p->trtp, taddr);
11507    }
11508 
11509    /* If our real IP differs from the local address returned by the RTP engine, use it. */
11510    /* The premise is that if we are already using that IP to communicate with the client, */
11511    /* we should be using it for RTP too. */
11512         use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr);
11513 
11514    /* Now, try to figure out where we want them to send data */
11515    /* Is this a re-invite to move the media out, then use the original offer from caller  */
11516    if (!ast_sockaddr_isnull(&p->redirip)) {  /* If we have a redirection IP, use it */
11517       ast_sockaddr_copy(dest, &p->redirip);
11518    } else {
11519       /*
11520        * Audio Destination IP:
11521        *
11522        * 1. Specifically configured media address.
11523        * 2. Local address as specified by the RTP engine.
11524        * 3. The local IP as defined by chan_sip.
11525        *
11526        * Audio Destination Port:
11527        *
11528        * 1. Provided by the RTP engine.
11529        */
11530       ast_sockaddr_copy(dest,
11531               !ast_sockaddr_isnull(&media_address) ? &media_address :
11532               !ast_sockaddr_is_any(addr) && !use_externip ? addr    :
11533               &p->ourip);
11534       ast_sockaddr_set_port(dest, ast_sockaddr_port(addr));
11535    }
11536 
11537    if (needvideo) {
11538       /* Determine video destination */
11539       if (!ast_sockaddr_isnull(&p->vredirip)) {
11540          ast_sockaddr_copy(vdest, &p->vredirip);
11541       } else {
11542          /*
11543           * Video Destination IP:
11544           *
11545           * 1. Specifically configured media address.
11546           * 2. Local address as specified by the RTP engine.
11547           * 3. The local IP as defined by chan_sip.
11548           *
11549           * Video Destination Port:
11550           *
11551           * 1. Provided by the RTP engine.
11552           */
11553          ast_sockaddr_copy(vdest,
11554                  !ast_sockaddr_isnull(&media_address) ? &media_address :
11555                  !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr  :
11556                  &p->ourip);
11557          ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr));
11558       }
11559    }
11560 
11561    if (needtext) {
11562       /* Determine text destination */
11563       if (!ast_sockaddr_isnull(&p->tredirip)) {
11564          ast_sockaddr_copy(tdest, &p->tredirip);
11565       } else {
11566          /*
11567           * Text Destination IP:
11568           *
11569           * 1. Specifically configured media address.
11570           * 2. Local address as specified by the RTP engine.
11571           * 3. The local IP as defined by chan_sip.
11572           *
11573           * Text Destination Port:
11574           *
11575           * 1. Provided by the RTP engine.
11576           */
11577          ast_sockaddr_copy(tdest,
11578                  !ast_sockaddr_isnull(&media_address) ? &media_address  :
11579                  !ast_sockaddr_is_any(taddr) && !use_externip ? taddr   :
11580                  &p->ourip);
11581          ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr));
11582       }
11583    }
11584 }

static int get_pai ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id.

Definition at line 15503 of file chan_sip.c.

References ast_copy_string(), ast_free, ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, ast_set_callerid(), ast_shrink_phone_number(), ast_string_field_set, ast_strlen_zero(), cid_name, cid_num, get_in_brackets(), get_name_and_number(), and sip_get_header().

Referenced by get_rpid().

15504 {
15505    char pai[256];
15506    char privacy[64];
15507    char *cid_num = NULL;
15508    char *cid_name = NULL;
15509    char emptyname[1] = "";
15510    int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
15511    char *uri = NULL;
15512    int is_anonymous = 0, do_update = 1, no_name = 0;
15513 
15514    ast_copy_string(pai, sip_get_header(req, "P-Asserted-Identity"), sizeof(pai));
15515 
15516    if (ast_strlen_zero(pai)) {
15517       return 0;
15518    }
15519 
15520    /* use the reqresp_parser function get_name_and_number*/
15521    if (get_name_and_number(pai, &cid_name, &cid_num)) {
15522       return 0;
15523    }
15524 
15525    if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) {
15526       ast_shrink_phone_number(cid_num);
15527    }
15528 
15529    uri = get_in_brackets(pai);
15530    if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) {
15531       callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
15532       /*XXX Assume no change in cid_num. Perhaps it should be
15533        * blanked?
15534        */
15535       ast_free(cid_num);
15536       is_anonymous = 1;
15537       cid_num = (char *)p->cid_num;
15538    }
15539 
15540    ast_copy_string(privacy, sip_get_header(req, "Privacy"), sizeof(privacy));
15541    if (!ast_strlen_zero(privacy) && strncmp(privacy, "id", 2)) {
15542       callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
15543    }
15544    if (!cid_name) {
15545       no_name = 1;
15546       cid_name = (char *)emptyname;
15547    }  
15548    /* Only return true if the supplied caller id is different */
15549    if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) {
15550       do_update = 0;
15551    } else {
15552 
15553       ast_string_field_set(p, cid_num, cid_num);
15554       ast_string_field_set(p, cid_name, cid_name);
15555       p->callingpres = callingpres;
15556 
15557       if (p->owner) {
15558          ast_set_callerid(p->owner, cid_num, cid_name, NULL);
15559          p->owner->caller.id.name.presentation = callingpres;
15560          p->owner->caller.id.number.presentation = callingpres;
15561       }
15562    }
15563 
15564    /* get_name_and_number allocates memory for cid_num and cid_name so we have to free it */
15565    if (!is_anonymous) {
15566       ast_free(cid_num);
15567    }
15568    if (!no_name) {
15569       ast_free(cid_name);
15570    }
15571 
15572    return do_update;
15573 }

static int get_rdnis ( struct sip_pvt *  p,
struct sip_request *  oreq,
char **  name,
char **  number,
int *  reason 
) [static]

Get referring dnis.

Definition at line 15676 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_strdup, ast_strip_quoted(), ast_strlen_zero(), ast_verbose, exten, get_in_brackets(), LOG_WARNING, pbx_builtin_setvar_helper(), sip_debug_test_pvt(), sip_get_header(), sip_reason_str_to_code(), sip_set_redirstr(), strcasestr(), and strsep().

Referenced by change_redirecting_information().

15677 {
15678    char tmp[256], *exten, *rexten, *rdomain, *rname = NULL;
15679    char *params, *reason_param = NULL;
15680    struct sip_request *req;
15681 
15682    req = oreq ? oreq : &p->initreq;
15683 
15684    ast_copy_string(tmp, sip_get_header(req, "Diversion"), sizeof(tmp));
15685    if (ast_strlen_zero(tmp))
15686       return -1;
15687 
15688    if ((params = strchr(tmp, '>'))) {
15689       params = strchr(params, ';');
15690    }
15691 
15692    exten = get_in_brackets(tmp);
15693    if (!strncasecmp(exten, "sip:", 4)) {
15694       exten += 4;
15695    } else if (!strncasecmp(exten, "sips:", 5)) {
15696       exten += 5;
15697    } else {
15698       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", exten);
15699       return -1;
15700    }
15701 
15702    /* Get diversion-reason param if present */
15703    if (params) {
15704       *params = '\0';   /* Cut off parameters  */
15705       params++;
15706       while (*params == ';' || *params == ' ')
15707          params++;
15708       /* Check if we have a reason parameter */
15709       if ((reason_param = strcasestr(params, "reason="))) {
15710          char *end;
15711          reason_param+=7;
15712          if ((end = strchr(reason_param, ';'))) {
15713             *end = '\0';
15714          }
15715          /* Remove enclosing double-quotes */
15716          if (*reason_param == '"')
15717             ast_strip_quoted(reason_param, "\"", "\"");
15718          if (!ast_strlen_zero(reason_param)) {
15719             sip_set_redirstr(p, reason_param);
15720             if (p->owner) {
15721                pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause);
15722                pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param);
15723             }
15724          }
15725       }
15726    }
15727 
15728    rdomain = exten;
15729    rexten = strsep(&rdomain, "@");  /* trim anything after @ */
15730    if (p->owner)
15731       pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain);
15732 
15733    if (sip_debug_test_pvt(p))
15734       ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, reason ? reason_param : "");
15735 
15736    /*ast_string_field_set(p, rdnis, rexten);*/
15737 
15738    if (*tmp == '\"') {
15739       char *end_quote;
15740       rname = tmp + 1;
15741       end_quote = strchr(rname, '\"');
15742       *end_quote = '\0';
15743    }
15744 
15745    if (number) {
15746       *number = ast_strdup(rexten);
15747    }
15748 
15749    if (name && rname) {
15750       *name = ast_strdup(rname);
15751    }
15752 
15753    if (reason && !ast_strlen_zero(reason_param)) {
15754       *reason = sip_reason_str_to_code(reason_param);
15755    }
15756 
15757    return 0;
15758 }

static void get_realm ( struct sip_pvt *  p,
const struct sip_request *  req 
) [static]

Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=...

Definition at line 11041 of file chan_sip.c.

References AST_LIST_EMPTY, ast_string_field_set, ast_strlen_zero(), check_sip_domain(), get_domain(), MAXHOSTNAMELEN, sip_cfg, and sip_get_header().

Referenced by transmit_response_with_auth().

11042 {
11043    char domain[MAXHOSTNAMELEN];
11044 
11045    if (!ast_strlen_zero(p->realm))
11046       return;
11047 
11048    if (sip_cfg.domainsasrealm &&
11049        !AST_LIST_EMPTY(&domain_list))
11050    {
11051       /* Check From header first */
11052       if (!get_domain(sip_get_header(req, "From"), domain, sizeof(domain))) {
11053          if (check_sip_domain(domain, NULL, 0)) {
11054             ast_string_field_set(p, realm, domain);
11055             return;
11056          }
11057       }
11058       /* Check To header */
11059       if (!get_domain(sip_get_header(req, "To"), domain, sizeof(domain))) {
11060          if (check_sip_domain(domain, NULL, 0)) {
11061             ast_string_field_set(p, realm, domain);
11062             return;
11063          }
11064       }
11065    }
11066    
11067    /* Use default realm from config file */
11068    ast_string_field_set(p, realm, sip_cfg.realm);
11069 }

static int get_refer_info ( struct sip_pvt *  transferer,
struct sip_request *  outgoing_req 
) [static]

Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.

Note:
If we get a SIPS uri in the refer-to header, we're required to set up a secure signalling path to that extension. As a minimum, this needs to be added to a channel variable, if not a channel flag.

Definition at line 16017 of file chan_sip.c.

References ast_bridged_channel(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_uri_sip_user, ast_verbose, ast_channel::context, get_in_brackets(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), sip_get_header(), SIP_PEDANTIC_DECODE, and strcasestr().

Referenced by handle_request_refer().

16018 {
16019 
16020    const char *p_referred_by = NULL;
16021    char *h_refer_to = NULL;
16022    char *h_referred_by = NULL;
16023    char *refer_to;
16024    const char *p_refer_to;
16025    char *referred_by_uri = NULL;
16026    char *ptr;
16027    struct sip_request *req = NULL;
16028    const char *transfer_context = NULL;
16029    struct sip_refer *referdata;
16030 
16031 
16032    req = outgoing_req;
16033    referdata = transferer->refer;
16034 
16035    if (!req) {
16036       req = &transferer->initreq;
16037    }
16038 
16039    p_refer_to = sip_get_header(req, "Refer-To");
16040    if (ast_strlen_zero(p_refer_to)) {
16041       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
16042       return -2;  /* Syntax error */
16043    }
16044    h_refer_to = ast_strdupa(p_refer_to);
16045    refer_to = get_in_brackets(h_refer_to);
16046    if (!strncasecmp(refer_to, "sip:", 4)) {
16047       refer_to += 4;       /* Skip sip: */
16048    } else if (!strncasecmp(refer_to, "sips:", 5)) {
16049       refer_to += 5;
16050    } else {
16051       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
16052       return -3;
16053    }
16054 
16055    /* Get referred by header if it exists */
16056    p_referred_by = sip_get_header(req, "Referred-By");
16057 
16058    /* Give useful transfer information to the dialplan */
16059    if (transferer->owner) {
16060       struct ast_channel *peer = ast_bridged_channel(transferer->owner);
16061       if (peer) {
16062          pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context);
16063          pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by);
16064       }
16065    }
16066 
16067    if (!ast_strlen_zero(p_referred_by)) {
16068       char *lessthan;
16069       h_referred_by = ast_strdupa(p_referred_by);
16070 
16071       /* Store referrer's caller ID name */
16072       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
16073       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
16074          *(lessthan - 1) = '\0'; /* Space */
16075       }
16076 
16077       referred_by_uri = get_in_brackets(h_referred_by);
16078 
16079       if (!strncasecmp(referred_by_uri, "sip:", 4)) {
16080          referred_by_uri += 4;      /* Skip sip: */
16081       } else if (!strncasecmp(referred_by_uri, "sips:", 5)) {
16082          referred_by_uri += 5;      /* Skip sips: */
16083       } else {
16084          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
16085          referred_by_uri = NULL;
16086       }
16087    }
16088 
16089    /* Check for arguments in the refer_to header */
16090    if ((ptr = strcasestr(refer_to, "replaces="))) {
16091       char *to = NULL, *from = NULL;
16092       
16093       /* This is an attended transfer */
16094       referdata->attendedtransfer = 1;
16095       ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
16096       ast_uri_decode(referdata->replaces_callid, ast_uri_sip_user);
16097       if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
16098          *ptr++ = '\0';
16099       }
16100       
16101       if (ptr) {
16102          /* Find the different tags before we destroy the string */
16103          to = strcasestr(ptr, "to-tag=");
16104          from = strcasestr(ptr, "from-tag=");
16105       }
16106       
16107       /* Grab the to header */
16108       if (to) {
16109          ptr = to + 7;
16110          if ((to = strchr(ptr, '&'))) {
16111             *to = '\0';
16112          }
16113          if ((to = strchr(ptr, ';'))) {
16114             *to = '\0';
16115          }
16116          ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
16117       }
16118 
16119       if (from) {
16120          ptr = from + 9;
16121          if ((to = strchr(ptr, '&'))) {
16122             *to = '\0';
16123          }
16124          if ((to = strchr(ptr, ';'))) {
16125             *to = '\0';
16126          }
16127          ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
16128       }
16129 
16130       if (!strcmp(referdata->replaces_callid, transferer->callid) &&
16131          (!sip_cfg.pedanticsipchecking ||
16132          (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) &&
16133          !strcmp(referdata->replaces_callid_totag, transferer->tag)))) {
16134             ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid);
16135             return -4;
16136       }
16137 
16138       if (!sip_cfg.pedanticsipchecking) {
16139          ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
16140       } else {
16141          ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" );
16142       }
16143    }
16144 
16145    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
16146       char *urioption = NULL, *domain;
16147       int bracket = 0;
16148       *ptr++ = '\0';
16149 
16150       if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */
16151          *urioption++ = '\0';
16152       }
16153 
16154       domain = ptr;
16155 
16156       /* Remove :port */
16157       for (; *ptr != '\0'; ++ptr) {
16158          if (*ptr == ':' && bracket == 0) {
16159             *ptr = '\0';
16160             break;
16161          } else if (*ptr == '[') {
16162             ++bracket;
16163          } else if (*ptr == ']') {
16164             --bracket;
16165          }
16166       }
16167 
16168       SIP_PEDANTIC_DECODE(domain);
16169       SIP_PEDANTIC_DECODE(urioption);
16170 
16171       /* Save the domain for the dial plan */
16172       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
16173       if (urioption) {
16174          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
16175       }
16176    }
16177 
16178    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
16179       *ptr = '\0';
16180 
16181    SIP_PEDANTIC_DECODE(refer_to);
16182    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
16183    
16184    if (referred_by_uri) {
16185       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
16186          *ptr = '\0';
16187       SIP_PEDANTIC_DECODE(referred_by_uri);
16188       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
16189    } else {
16190       referdata->referred_by[0] = '\0';
16191    }
16192 
16193    /* Determine transfer context */
16194    if (transferer->owner)  /* Mimic behaviour in res_features.c */
16195       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
16196 
16197    /* By default, use the context in the channel sending the REFER */
16198    if (ast_strlen_zero(transfer_context)) {
16199       transfer_context = S_OR(transferer->owner->macrocontext,
16200                S_OR(transferer->context, sip_cfg.default_context));
16201    }
16202 
16203    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
16204    
16205    /* Either an existing extension or the parking extension */
16206    if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
16207       if (sip_debug_test_pvt(transferer)) {
16208          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
16209       }
16210       /* We are ready to transfer to the extension */
16211       return 0;
16212    }
16213    if (sip_debug_test_pvt(transferer))
16214       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
16215 
16216    /* Failure, we can't find this extension */
16217    return -1;
16218 }

static int get_rpid ( struct sip_pvt *  p,
struct sip_request *  oreq 
) [static]

Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id.

Definition at line 15579 of file chan_sip.c.

References ast_copy_string(), ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, ast_set_callerid(), ast_shrink_phone_number(), ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cid_name, cid_num, get_pai(), and sip_get_header().

Referenced by check_peer_ok(), check_user_full(), handle_request_invite(), handle_request_update(), and handle_response_invite().

15580 {
15581    char tmp[256];
15582    struct sip_request *req;
15583    char *cid_num = "";
15584    char *cid_name = "";
15585    int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
15586    char *privacy = "";
15587    char *screen = "";
15588    char *start, *end;
15589 
15590    if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID))
15591       return 0;
15592    req = oreq;
15593    if (!req)
15594       req = &p->initreq;
15595    ast_copy_string(tmp, sip_get_header(req, "Remote-Party-ID"), sizeof(tmp));
15596    if (ast_strlen_zero(tmp)) {
15597       return get_pai(p, req);
15598    }
15599 
15600    start = tmp;
15601    if (*start == '"') {
15602       *start++ = '\0';
15603       end = strchr(start, '"');
15604       if (!end)
15605          return 0;
15606       *end++ = '\0';
15607       cid_name = start;
15608       start = ast_skip_blanks(end);
15609    }
15610 
15611    if (*start != '<')
15612       return 0;
15613    *start++ = '\0';
15614    end = strchr(start, '@');
15615    if (!end)
15616       return 0;
15617    *end++ = '\0';
15618    if (strncasecmp(start, "sip:", 4))
15619       return 0;
15620    cid_num = start + 4;
15621    if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num))
15622       ast_shrink_phone_number(cid_num);
15623    start = end;
15624 
15625    end = strchr(start, '>');
15626    if (!end)
15627       return 0;
15628    *end++ = '\0';
15629    if (*end) {
15630       start = end;
15631       if (*start != ';')
15632          return 0;
15633       *start++ = '\0';
15634       while (!ast_strlen_zero(start)) {
15635          end = strchr(start, ';');
15636          if (end)
15637             *end++ = '\0';
15638          if (!strncasecmp(start, "privacy=", 8))
15639             privacy = start + 8;
15640          else if (!strncasecmp(start, "screen=", 7))
15641             screen = start + 7;
15642          start = end;
15643       }
15644 
15645       if (!strcasecmp(privacy, "full")) {
15646          if (!strcasecmp(screen, "yes"))
15647             callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
15648          else if (!strcasecmp(screen, "no"))
15649             callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
15650       } else {
15651          if (!strcasecmp(screen, "yes"))
15652             callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
15653          else if (!strcasecmp(screen, "no"))
15654             callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
15655       }
15656    }
15657 
15658    /* Only return true if the supplied caller id is different */
15659    if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres)
15660       return 0;
15661 
15662    ast_string_field_set(p, cid_num, cid_num);
15663    ast_string_field_set(p, cid_name, cid_name);
15664    p->callingpres = callingpres;
15665 
15666    if (p->owner) {
15667       ast_set_callerid(p->owner, cid_num, cid_name, NULL);
15668       p->owner->caller.id.name.presentation = callingpres;
15669       p->owner->caller.id.number.presentation = callingpres;
15670    }
15671 
15672    return 1;
15673 }

static const char * get_sdp_iterate ( int *  start,
struct sip_request *  req,
const char *  name 
) [static]

Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.

Definition at line 7344 of file chan_sip.c.

References get_body_by_line(), and len().

07345 {
07346    int len = strlen(name);
07347 
07348    while (*start < (req->sdp_start + req->sdp_count)) {
07349       const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '=');
07350       if (r[0] != '\0')
07351          return r;
07352    }
07353 
07354    /* if the line was not found, ensure that *start points past the SDP */
07355    (*start)++;
07356 
07357    return "";
07358 }

static char get_sdp_line ( int *  start,
int  stop,
struct sip_request *  req,
const char **  value 
) [static]

Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.

Definition at line 7365 of file chan_sip.c.

References ast_skip_blanks(), and type.

Referenced by process_sdp().

07366 {
07367    char type = '\0';
07368    const char *line = NULL;
07369 
07370    if (stop > (req->sdp_start + req->sdp_count)) {
07371       stop = req->sdp_start + req->sdp_count;
07372    }
07373 
07374    while (*start < stop) {
07375       line = REQ_OFFSET_TO_STR(req, line[(*start)++]);
07376       if (line[1] == '=') {
07377          type = line[0];
07378          *value = ast_skip_blanks(line + 2);
07379          break;
07380       }
07381    }
07382 
07383    return type;
07384 }

static struct sip_pvt * get_sip_pvt_byid_locked ( const char *  callid,
const char *  totag,
const char *  fromtag 
) [static, read]

Lock dialog lock and find matching pvt lock.

Returns:
a reference, remember to release it when done

Definition at line 15928 of file chan_sip.c.

References ao2_t_find, ast_channel_trylock, ast_debug, ast_strlen_zero(), OBJ_POINTER, sip_cfg, sip_pvt_lock, sip_pvt_unlock, and TRUE.

Referenced by handle_request_invite(), and local_attended_transfer().

15929 {
15930    struct sip_pvt *sip_pvt_ptr;
15931    struct sip_pvt tmp_dialog = {
15932       .callid = callid,
15933    };
15934 
15935    if (totag) {
15936       ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
15937    }
15938 
15939    /* Search dialogs and find the match */
15940 
15941    sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table");
15942    if (sip_pvt_ptr) {
15943       /* Go ahead and lock it (and its owner) before returning */
15944       sip_pvt_lock(sip_pvt_ptr);
15945       if (sip_cfg.pedanticsipchecking) {
15946          unsigned char frommismatch = 0, tomismatch = 0;
15947 
15948          if (ast_strlen_zero(fromtag)) {
15949             sip_pvt_unlock(sip_pvt_ptr);
15950             ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n",
15951                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
15952             return NULL;
15953          }
15954 
15955          if (ast_strlen_zero(totag)) {
15956             sip_pvt_unlock(sip_pvt_ptr);
15957             ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n",
15958                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
15959             return NULL;
15960          }
15961          /* RFC 3891
15962           * > 3.  User Agent Server Behavior: Receiving a Replaces Header
15963           * > The Replaces header contains information used to match an existing
15964           * > SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
15965           * > with a Replaces header, the User Agent (UA) attempts to match this
15966           * > information with a confirmed or early dialog.  The User Agent Server
15967           * > (UAS) matches the to-tag and from-tag parameters as if they were tags
15968           * > present in an incoming request.  In other words, the to-tag parameter
15969           * > is compared to the local tag, and the from-tag parameter is compared
15970           * > to the remote tag.
15971           *
15972           * Thus, the totag is always compared to the local tag, regardless if
15973           * this our call is an incoming or outgoing call.
15974           */
15975          frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag);
15976          tomismatch = !!strcmp(totag, sip_pvt_ptr->tag);
15977 
15978          if (frommismatch || tomismatch) {
15979             sip_pvt_unlock(sip_pvt_ptr);
15980             if (frommismatch) {
15981                ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n",
15982                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
15983                     fromtag, sip_pvt_ptr->theirtag);
15984             }
15985             if (tomismatch) {
15986                ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n",
15987                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
15988                     totag, sip_pvt_ptr->tag);
15989             }
15990             return NULL;
15991          }
15992       }
15993 
15994       if (totag)
15995          ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n",
15996                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING",
15997                  sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
15998 
15999       /* deadlock avoidance... */
16000       while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
16001          sip_pvt_unlock(sip_pvt_ptr);
16002          usleep(1);
16003          sip_pvt_lock(sip_pvt_ptr);
16004       }
16005    }
16006    
16007    return sip_pvt_ptr;
16008 }

static const char* get_srv_protocol ( enum sip_transport  t  )  [inline, static]

Return protocol string for srv dns query.

Definition at line 3312 of file chan_sip.c.

Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().

03313 {
03314    switch (t) {
03315    case SIP_TRANSPORT_UDP:
03316       return "udp";
03317    case SIP_TRANSPORT_TLS:
03318    case SIP_TRANSPORT_TCP:
03319       return "tcp";
03320    }
03321 
03322    return "udp";
03323 }

static const char* get_srv_service ( enum sip_transport  t  )  [inline, static]

Return service string for srv dns query.

Definition at line 3326 of file chan_sip.c.

Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().

03327 {
03328    switch (t) {
03329    case SIP_TRANSPORT_TCP:
03330    case SIP_TRANSPORT_UDP:
03331       return "sip";
03332    case SIP_TRANSPORT_TLS:
03333       return "sips";
03334    }
03335    return "sip";
03336 }

static const char* get_transport_list ( unsigned int  transports  )  [inline, static]

Return configuration of transports for a device.

Definition at line 3276 of file chan_sip.c.

Referenced by _sip_show_peer(), peers_data_provider_get(), and sip_show_settings().

03276                                                                       {
03277    switch (transports) {
03278       case SIP_TRANSPORT_UDP:
03279          return "UDP";
03280       case SIP_TRANSPORT_TCP:
03281          return "TCP";
03282       case SIP_TRANSPORT_TLS:
03283          return "TLS";
03284       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP:
03285          return "TCP,UDP";
03286       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS:
03287          return "TLS,UDP";
03288       case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS:
03289          return "TLS,TCP";
03290       default:
03291          return transports ?
03292             "TLS,TCP,UDP" : "UNKNOWN"; 
03293    }
03294 }

static const char* get_transport_pvt ( struct sip_pvt *  p  )  [inline, static]

Return transport of dialog.

Note:
this is based on a false assumption. We don't always use the outbound proxy for all requests in a dialog. It depends on the "force" parameter. The FIRST request is always sent to the ob proxy.
Todo:
Fix this function to work correctly

Definition at line 3344 of file chan_sip.c.

References set_socket_transport(), and sip_get_transport().

Referenced by __sip_xmit(), and build_via().

03345 {
03346    if (p->outboundproxy && p->outboundproxy->transport) {
03347       set_socket_transport(&p->socket, p->outboundproxy->transport);
03348    }
03349 
03350    return sip_get_transport(p->socket.type);
03351 }

static int get_transport_str2enum ( const char *  transport  )  [static]

Return int representing a bit field of transport types found in const char *transport.

Definition at line 3254 of file chan_sip.c.

References ast_strlen_zero().

Referenced by __set_address_from_contact(), and parse_register_contact().

03255 {
03256    int res = 0;
03257 
03258    if (ast_strlen_zero(transport)) {
03259       return res;
03260    }
03261 
03262    if (!strcasecmp(transport, "udp")) {
03263       res |= SIP_TRANSPORT_UDP;
03264    }
03265    if (!strcasecmp(transport, "tcp")) {
03266       res |= SIP_TRANSPORT_TCP;
03267    }
03268    if (!strcasecmp(transport, "tls")) {
03269       res |= SIP_TRANSPORT_TLS;
03270    }
03271 
03272    return res;
03273 }

static const char * gettag ( const struct sip_request *  req,
const char *  header,
char *  tagbuf,
int  tagbufsize 
) [static]

Get tag from packet.

Returns:
Returns the pointer to the provided tag buffer, or NULL if the tag was not found.

Definition at line 22467 of file chan_sip.c.

References ast_copy_string(), sip_get_header(), strcasestr(), and strsep().

Referenced by find_call(), handle_incoming(), handle_request_subscribe(), and handle_response().

22468 {
22469    const char *thetag;
22470 
22471    if (!tagbuf)
22472       return NULL;
22473    tagbuf[0] = '\0';    /* reset the buffer */
22474    thetag = sip_get_header(req, header);
22475    thetag = strcasestr(thetag, ";tag=");
22476    if (thetag) {
22477       thetag += 5;
22478       ast_copy_string(tagbuf, thetag, tagbufsize);
22479       return strsep(&tagbuf, ";");
22480    }
22481    return NULL;
22482 }

static int handle_cc_notify ( struct sip_pvt *  pvt,
struct sip_request *  req 
) [static]

Definition at line 22484 of file chan_sip.c.

References ao2_callback, ao2_ref, ast_cc_monitor_callee_available(), ast_cc_monitor_request_acked(), ast_string_field_set, ast_strlen_zero(), construct_pidf_body(), find_sip_monitor_instance_by_subscription_pvt(), get_body(), get_in_brackets(), sip_get_header(), status, transmit_publish(), and transmit_response().

Referenced by handle_request_notify().

22485 {
22486    struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
22487          find_sip_monitor_instance_by_subscription_pvt, pvt);
22488    const char *status = get_body(req, "cc-state", ':');
22489    struct cc_epa_entry *cc_entry;
22490    char *uri;
22491 
22492    if (!monitor_instance) {
22493       transmit_response(pvt, "400 Bad Request", req);
22494       return -1;
22495    }
22496 
22497    if (ast_strlen_zero(status)) {
22498       ao2_ref(monitor_instance, -1);
22499       transmit_response(pvt, "400 Bad Request", req);
22500       return -1;
22501    }
22502 
22503    if (!strcmp(status, "queued")) {
22504       /* We've been told that we're queued. This is the endpoint's way of telling
22505        * us that it has accepted our CC request. We need to alert the core of this
22506        * development
22507        */
22508       ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name);
22509       transmit_response(pvt, "200 OK", req);
22510       ao2_ref(monitor_instance, -1);
22511       return 0;
22512    }
22513 
22514    /* It's open! Yay! */
22515    uri = get_body(req, "cc-URI", ':');
22516    if (ast_strlen_zero(uri)) {
22517       uri = get_in_brackets((char *)sip_get_header(req, "From"));
22518    }
22519 
22520    ast_string_field_set(monitor_instance, notify_uri, uri);
22521    if (monitor_instance->suspension_entry) {
22522       cc_entry = monitor_instance->suspension_entry->instance_data;
22523       if (cc_entry->current_state == CC_CLOSED) {
22524          /* If we've created a suspension entry and the current state is closed, then that means
22525           * we got a notice from the CC core earlier to suspend monitoring, but because this particular
22526           * call leg had not yet notified us that it was ready for recall, it meant that we
22527           * could not yet send a PUBLISH. Now, however, we can.
22528           */
22529          construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body,
22530                sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
22531          transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri);
22532       } else {
22533          ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
22534       }
22535    } else {
22536       ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
22537    }
22538    ao2_ref(monitor_instance, -1);
22539    transmit_response(pvt, "200 OK", req);
22540 
22541    return 0;
22542 }

static int handle_cc_subscribe ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Definition at line 25453 of file chan_sip.c.

References ao2_ref, ast_cc_agent_accept_request(), ast_cc_failed(), ast_log(), ast_strlen_zero(), ast_cc_agent::core_id, ast_cc_agent::device_name, find_sip_cc_agent_by_subscribe_uri(), LOG_WARNING, ast_cc_agent::private_data, sip_get_header(), and transmit_response().

Referenced by handle_request_subscribe().

25454 {
25455    const char *uri = REQ_OFFSET_TO_STR(req, rlPart2);
25456    char *param_separator;
25457    struct ast_cc_agent *agent;
25458    struct sip_cc_agent_pvt *agent_pvt;
25459    const char *expires_str = sip_get_header(req, "Expires");
25460    int expires = -1; /* Just need it to be non-zero */
25461 
25462    if (!ast_strlen_zero(expires_str)) {
25463       sscanf(expires_str, "%30d", &expires);
25464    }
25465 
25466    if ((param_separator = strchr(uri, ';'))) {
25467       *param_separator = '\0';
25468    }
25469 
25470    p->subscribed = CALL_COMPLETION;
25471 
25472    if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) {
25473       if (!expires) {
25474          /* Typically, if a 0 Expires reaches us and we can't find
25475           * the corresponding agent, it means that the CC transaction
25476           * has completed and so the calling side is just trying to
25477           * clean up its subscription. We'll just respond with a
25478           * 200 OK and be done with it
25479           */
25480          transmit_response(p, "200 OK", req);
25481          return 0;
25482       }
25483       ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri);
25484       transmit_response(p, "404 Not Found", req);
25485       return -1;
25486    }
25487 
25488    agent_pvt = agent->private_data;
25489 
25490    if (!expires) {
25491       /* We got sent a SUBSCRIBE and found an agent. This means that CC
25492        * is being canceled.
25493        */
25494       ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name);
25495       transmit_response(p, "200 OK", req);
25496       ao2_ref(agent, -1);
25497       return 0;
25498    }
25499 
25500    agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog");
25501    ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE",
25502          agent->device_name);
25503 
25504    /* We don't send a response here. That is done in the agent's ack callback or in the
25505     * agent destructor, should a failure occur before we have responded
25506     */
25507    ao2_ref(agent, -1);
25508    return 0;
25509 }

static int handle_common_options ( struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v 
) [static]

Handle flag-type options common to configuration of devices - peers.

Parameters:
flags array of three struct ast_flags
mask array of three struct ast_flags
v linked list of config variables to process
Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 27754 of file chan_sip.c.

References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), sip_parse_nat_option(), strsep(), ast_variable::value, and word.

Referenced by build_peer(), and reload_config().

27755 {
27756    int res = 1;
27757 
27758    if (!strcasecmp(v->name, "trustrpid")) {
27759       ast_set_flag(&mask[0], SIP_TRUSTRPID);
27760       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
27761    } else if (!strcasecmp(v->name, "sendrpid")) {
27762       ast_set_flag(&mask[0], SIP_SENDRPID);
27763       if (!strcasecmp(v->value, "pai")) {
27764          ast_set_flag(&flags[0], SIP_SENDRPID_PAI);
27765       } else if (!strcasecmp(v->value, "rpid")) {
27766          ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
27767       } else if (ast_true(v->value)) {
27768          ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
27769       }
27770    } else if (!strcasecmp(v->name, "rpid_update")) {
27771       ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE);
27772       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE);
27773    } else if (!strcasecmp(v->name, "rpid_immediate")) {
27774       ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE);
27775       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE);
27776    } else if (!strcasecmp(v->name, "g726nonstandard")) {
27777       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
27778       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
27779    } else if (!strcasecmp(v->name, "useclientcode")) {
27780       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
27781       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
27782    } else if (!strcasecmp(v->name, "dtmfmode")) {
27783       ast_set_flag(&mask[0], SIP_DTMF);
27784       ast_clear_flag(&flags[0], SIP_DTMF);
27785       if (!strcasecmp(v->value, "inband"))
27786          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
27787       else if (!strcasecmp(v->value, "rfc2833"))
27788          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
27789       else if (!strcasecmp(v->value, "info"))
27790          ast_set_flag(&flags[0], SIP_DTMF_INFO);
27791       else if (!strcasecmp(v->value, "shortinfo"))
27792          ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO);
27793       else if (!strcasecmp(v->value, "auto"))
27794          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
27795       else {
27796          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
27797          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
27798       }
27799    } else if (!strcasecmp(v->name, "nat")) {
27800       sip_parse_nat_option(v->value, mask, flags);
27801    } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
27802       ast_set_flag(&mask[0], SIP_REINVITE);
27803       ast_clear_flag(&flags[0], SIP_REINVITE);
27804       if (ast_true(v->value)) {
27805          ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT);
27806       } else if (!ast_false(v->value)) {
27807          char buf[64];
27808          char *word, *next = buf;
27809 
27810          ast_copy_string(buf, v->value, sizeof(buf));
27811          while ((word = strsep(&next, ","))) {
27812             if (!strcasecmp(word, "update")) {
27813                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA);
27814             } else if (!strcasecmp(word, "nonat")) {
27815                ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
27816                ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT);
27817             } else {
27818                ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno);
27819             }
27820          }
27821       }
27822    } else if (!strcasecmp(v->name, "insecure")) {
27823       ast_set_flag(&mask[0], SIP_INSECURE);
27824       ast_clear_flag(&flags[0], SIP_INSECURE);
27825       set_insecure_flags(&flags[0], v->value, v->lineno);   
27826    } else if (!strcasecmp(v->name, "progressinband")) {
27827       ast_set_flag(&mask[0], SIP_PROG_INBAND);
27828       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
27829       if (ast_true(v->value))
27830          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
27831       else if (strcasecmp(v->value, "never"))
27832          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
27833    } else if (!strcasecmp(v->name, "promiscredir")) {
27834       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
27835       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
27836    } else if (!strcasecmp(v->name, "videosupport")) {
27837       if (!strcasecmp(v->value, "always")) {
27838          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
27839          ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
27840       } else {
27841          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
27842          ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
27843       }
27844    } else if (!strcasecmp(v->name, "textsupport")) {
27845       ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT);
27846       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT);
27847       res = 1;
27848    } else if (!strcasecmp(v->name, "allowoverlap")) {
27849       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
27850       ast_clear_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP);
27851       if (ast_true(v->value)) {
27852          ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_YES);
27853       } else if (!strcasecmp(v->value, "dtmf")){
27854          ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_DTMF);
27855       }
27856    } else if (!strcasecmp(v->name, "allowsubscribe")) {
27857       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
27858       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
27859    } else if (!strcasecmp(v->name, "ignoresdpversion")) {
27860       ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION);
27861       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION);
27862    } else if (!strcasecmp(v->name, "faxdetect")) {
27863       ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT);
27864       if (ast_true(v->value)) {
27865          ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH);
27866       } else if (ast_false(v->value)) {
27867          ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH);
27868       } else {
27869          char *buf = ast_strdupa(v->value);
27870          char *word, *next = buf;
27871 
27872          while ((word = strsep(&next, ","))) {
27873             if (!strcasecmp(word, "cng")) {
27874                ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG);
27875             } else if (!strcasecmp(word, "t38")) {
27876                ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38);
27877             } else {
27878                ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
27879             }
27880          }
27881       }
27882    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
27883       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
27884       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
27885    } else if (!strcasecmp(v->name, "buggymwi")) {
27886       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
27887       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
27888    } else
27889       res = 0;
27890 
27891    return res;
27892 }

static int handle_incoming ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr addr,
int *  recount,
int *  nounlock 
) [static]

Handle incoming SIP requests (methods).

Note:
This is where all incoming requests go first.

called with p and p->owner locked

Definition at line 25973 of file chan_sip.c.

References __get_header(), __sip_ack(), ast_channel_name(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_log(), ast_random(), ast_skip_blanks(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_verbose, check_pendings(), debug, extract_uri(), find_sdp(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), cfsip_methods::id, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_sdp(), pvt_set_needdestroy(), sip_cfg, sip_debug_test_pvt(), sip_get_header(), sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_report_security_event(), sip_scheddestroy(), cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and transmit_response_with_retry_after().

Referenced by handle_request_do().

25974 {
25975    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
25976       relatively static */
25977    const char *cmd;
25978    const char *cseq;
25979    const char *useragent;
25980    const char *via;
25981    const char *callid;
25982    int via_pos = 0;
25983    uint32_t seqno;
25984    int len;
25985    int respid;
25986    int res = 0;
25987    int debug = sip_debug_test_pvt(p);
25988    const char *e;
25989    int error = 0;
25990    int oldmethod = p->method;
25991    int acked = 0;
25992 
25993    /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via.
25994     * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request,
25995     * so we can check to make sure these fields exist for all requests and responses */
25996    cseq = sip_get_header(req, "Cseq");
25997    cmd = REQ_OFFSET_TO_STR(req, header[0]);
25998    /* Save the via_pos so we can check later that responses only have 1 Via header */
25999    via = __get_header(req, "Via", &via_pos);
26000    /* This must exist already because we've called find_call by now */
26001    callid = sip_get_header(req, "Call-ID");
26002 
26003    /* Must have Cseq */
26004    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) {
26005       ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid);
26006       error = 1;
26007    }
26008    if (!error && sscanf(cseq, "%30u%n", &seqno, &len) != 1) {
26009       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
26010       error = 1;
26011    }
26012    if (error) {
26013       if (!p->initreq.headers) { /* New call */
26014          pvt_set_needdestroy(p, "no headers");
26015       }
26016       return -1;
26017    }
26018    /* Get the command XXX */
26019 
26020    cmd = REQ_OFFSET_TO_STR(req, rlPart1);
26021    e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2));
26022 
26023    /* Save useragent of the client */
26024    useragent = sip_get_header(req, "User-Agent");
26025    if (!ast_strlen_zero(useragent))
26026       ast_string_field_set(p, useragent, useragent);
26027 
26028    /* Find out SIP method for incoming request */
26029    if (req->method == SIP_RESPONSE) {  /* Response to our request */
26030       /* ignore means "don't do anything with it" but still have to
26031        * respond appropriately.
26032        * But in this case this is a response already, so we really
26033        * have nothing to do with this message, and even setting the
26034        * ignore flag is pointless.
26035        */
26036       if (ast_strlen_zero(e)) {
26037          return 0;
26038       }
26039       if (sscanf(e, "%30d %n", &respid, &len) != 1) {
26040          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
26041          return 0;
26042       }
26043       if (respid <= 0) {
26044          ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
26045          return 0;
26046       }
26047       /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse
26048        * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple
26049        * headers joined with a comma. Fixing that would pretty much involve writing a new parser */
26050       if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) {
26051          ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid);
26052          return 0;
26053       }
26054       if (p->ocseq && (p->ocseq < seqno)) {
26055          ast_debug(1, "Ignoring out of order response %u (expecting %u)\n", seqno, p->ocseq);
26056          return -1;
26057       } else {
26058          char causevar[256], causeval[256];
26059 
26060          if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
26061             extract_uri(p, req);
26062          }
26063 
26064          handle_response(p, respid, e + len, req, seqno);
26065 
26066          if (global_store_sip_cause && p->owner) {
26067             struct ast_channel *owner = p->owner;
26068 
26069             snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", ast_channel_name(owner));
26070             snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
26071 
26072             ast_channel_ref(owner);
26073             sip_pvt_unlock(p);
26074             ast_channel_unlock(owner);
26075             *nounlock = 1;
26076             pbx_builtin_setvar_helper(owner, causevar, causeval);
26077             ast_channel_unref(owner);
26078             sip_pvt_lock(p);
26079          }
26080       }
26081       return 0;
26082    }
26083 
26084    /* New SIP request coming in
26085       (could be new request in existing SIP dialog as well...)
26086     */
26087    p->method = req->method;   /* Find out which SIP method they are using */
26088    ast_debug(4, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd);
26089 
26090    if (p->icseq && (p->icseq > seqno) ) {
26091       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
26092          ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n");
26093       } else {
26094          ast_debug(1, "Ignoring too old SIP packet packet %u (expecting >= %u)\n", seqno, p->icseq);
26095          if (req->method == SIP_INVITE) {
26096             unsigned int ran = (ast_random() % 10) + 1;
26097             char seconds[4];
26098             snprintf(seconds, sizeof(seconds), "%u", ran);
26099             transmit_response_with_retry_after(p, "500 Server error", req, seconds);   /* respond according to RFC 3261 14.2 with Retry-After betwewn 0 and 10 */
26100          } else if (req->method != SIP_ACK) {
26101             transmit_response(p, "500 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
26102          }
26103          return -1;
26104       }
26105    } else if (p->icseq &&
26106          p->icseq == seqno &&
26107          req->method != SIP_ACK &&
26108          (p->method != SIP_CANCEL || p->alreadygone)) {
26109       /* ignore means "don't do anything with it" but still have to
26110          respond appropriately.  We do this if we receive a repeat of
26111          the last sequence number  */
26112       req->ignore = 1;
26113       ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %u, ours %u)\n", sip_methods[p->method].text, p->icseq, seqno);
26114    }
26115 
26116    /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has
26117     * already given a final response." */
26118    if (!p->pendinginvite && (req->method == SIP_CANCEL)) {
26119       transmit_response(p, "481 Call/Transaction Does Not Exist", req);
26120       return res;
26121    }
26122 
26123    if (seqno >= p->icseq)
26124       /* Next should follow monotonically (but not necessarily
26125          incrementally -- thanks again to the genius authors of SIP --
26126          increasing */
26127       p->icseq = seqno;
26128 
26129    /* Find their tag if we haven't got it */
26130    if (ast_strlen_zero(p->theirtag)) {
26131       char tag[128];
26132 
26133       gettag(req, "From", tag, sizeof(tag));
26134       ast_string_field_set(p, theirtag, tag);
26135    }
26136    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
26137 
26138    if (sip_cfg.pedanticsipchecking) {
26139       /* If this is a request packet without a from tag, it's not
26140          correct according to RFC 3261  */
26141       /* Check if this a new request in a new dialog with a totag already attached to it,
26142          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
26143       if (!p->initreq.headers && req->has_to_tag) {
26144          /* If this is a first request and it got a to-tag, it is not for us */
26145          if (!req->ignore && req->method == SIP_INVITE) {
26146             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
26147             /* Will cease to exist after ACK */
26148          } else if (req->method != SIP_ACK) {
26149             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
26150             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
26151          } else {
26152             ast_debug(1, "Got ACK for unknown dialog... strange.\n");
26153          }
26154          return res;
26155       }
26156    }
26157 
26158    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) {
26159       transmit_response(p, "400 Bad request", req);
26160       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
26161       return -1;
26162    }
26163 
26164    /* Handle various incoming SIP methods in requests */
26165    switch (p->method) {
26166    case SIP_OPTIONS:
26167       res = handle_request_options(p, req, addr, e);
26168       break;
26169    case SIP_INVITE:
26170       res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock);
26171 
26172       if (res < 9) {
26173          sip_report_security_event(p, req, res);
26174       }
26175 
26176       switch (res) {
26177       case INV_REQ_SUCCESS:
26178          res = 1;
26179          break;
26180       case INV_REQ_FAILED:
26181          res = 0;
26182          break;
26183       case INV_REQ_ERROR:
26184          res = -1;
26185          break;
26186       default:
26187          res = 0;
26188          break;
26189       }
26190 
26191       break;
26192    case SIP_REFER:
26193       res = handle_request_refer(p, req, debug, seqno, nounlock);
26194       break;
26195    case SIP_CANCEL:
26196       res = handle_request_cancel(p, req);
26197       break;
26198    case SIP_BYE:
26199       res = handle_request_bye(p, req);
26200       break;
26201    case SIP_MESSAGE:
26202       res = handle_request_message(p, req, addr, e);
26203       break;
26204    case SIP_PUBLISH:
26205       res = handle_request_publish(p, req, addr, seqno, e);
26206       break;
26207    case SIP_SUBSCRIBE:
26208       res = handle_request_subscribe(p, req, addr, seqno, e);
26209       break;
26210    case SIP_REGISTER:
26211       res = handle_request_register(p, req, addr, e);
26212       sip_report_security_event(p, req, res);
26213       break;
26214    case SIP_INFO:
26215       if (req->debug)
26216          ast_verbose("Receiving INFO!\n");
26217       if (!req->ignore)
26218          handle_request_info(p, req);
26219       else  /* if ignoring, transmit response */
26220          transmit_response(p, "200 OK", req);
26221       break;
26222    case SIP_NOTIFY:
26223       res = handle_request_notify(p, req, addr, seqno, e);
26224       break;
26225    case SIP_UPDATE:
26226       res = handle_request_update(p, req);
26227       break;
26228    case SIP_ACK:
26229       /* Make sure we don't ignore this */
26230       if (seqno == p->pendinginvite) {
26231          p->invitestate = INV_TERMINATED;
26232          p->pendinginvite = 0;
26233          acked = __sip_ack(p, seqno, 1 /* response */, 0);
26234          if (find_sdp(req)) {
26235             if (process_sdp(p, req, SDP_T38_NONE))
26236                return -1;
26237          }
26238          check_pendings(p);
26239       } else if (p->glareinvite == seqno) {
26240          /* handle ack for the 491 pending sent for glareinvite */
26241          p->glareinvite = 0;
26242          acked = __sip_ack(p, seqno, 1, 0);
26243       }
26244       if (!acked) {
26245          /* Got an ACK that did not match anything. Ignore
26246           * silently and restore previous method */
26247          p->method = oldmethod;
26248       }
26249       if (!p->lastinvite && ast_strlen_zero(p->randdata)) {
26250          pvt_set_needdestroy(p, "unmatched ACK");
26251       }
26252       break;
26253    default:
26254       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
26255       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n",
26256          cmd, ast_sockaddr_stringify(&p->sa));
26257       /* If this is some new method, and we don't have a call, destroy it now */
26258       if (!p->initreq.headers) {
26259          pvt_set_needdestroy(p, "unimplemented method");
26260       }
26261       break;
26262    }
26263    return res;
26264 }

static int handle_invite_replaces ( struct sip_pvt *  p,
struct sip_request *  req,
int  debug,
uint32_t  seqno,
struct ast_sockaddr addr,
int *  nounlock 
) [static]

Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.

Note:
this function is called by handle_request_invite(). Four locks held at the beginning of this function, p, p->owner, p->refer->refer_call and p->refere->refer_call->owner. only p's lock should remain at the end of this function. p's lock as well as the channel p->owner's lock are held by handle_request_do(), we unlock p->owner before the masq. By setting nounlock we are indicating to handle_request_do() that we have already unlocked the owner.

Definition at line 22802 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_lock, ast_channel_masquerade(), ast_channel_name(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_quiet_chan(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, FALSE, ast_channel::hangupcause, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), and transmit_response_with_sdp().

Referenced by handle_request_invite().

22803 {
22804    int earlyreplace = 0;
22805    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
22806    struct ast_channel *c = p->owner;   /* Our incoming call */
22807    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
22808    struct ast_channel *targetcall;     /* The bridge to the take-over target */
22809 
22810    /* Check if we're in ring state */
22811    if (replacecall->_state == AST_STATE_RING)
22812       earlyreplace = 1;
22813 
22814    /* Check if we have a bridge */
22815    if (!(targetcall = ast_bridged_channel(replacecall))) {
22816       /* We have no bridge */
22817       if (!earlyreplace) {
22818          ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", ast_channel_name(replacecall));
22819          oneleggedreplace = 1;
22820       }
22821    }
22822    if (targetcall && targetcall->_state == AST_STATE_RINGING)
22823       ast_debug(4, "SIP transfer: Target channel is in ringing state\n");
22824 
22825    if (targetcall)
22826       ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", ast_channel_name(targetcall), ast_channel_name(replacecall));
22827    else
22828       ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", ast_channel_name(replacecall));
22829 
22830    if (req->ignore) {
22831       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
22832       /* We should answer something here. If we are here, the
22833          call we are replacing exists, so an accepted
22834          can't harm */
22835       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
22836       /* Do something more clever here */
22837       if (c) {
22838          *nounlock = 1;
22839          ast_channel_unlock(c);
22840       }
22841       ast_channel_unlock(replacecall);
22842       sip_pvt_unlock(p->refer->refer_call);
22843       return 1;
22844    }
22845    if (!c) {
22846       /* What to do if no channel ??? */
22847       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
22848       transmit_response_reliable(p, "503 Service Unavailable", req);
22849       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
22850       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22851       ast_channel_unlock(replacecall);
22852       sip_pvt_unlock(p->refer->refer_call);
22853       return 1;
22854    }
22855    append_history(p, "Xfer", "INVITE/Replace received");
22856    /* We have three channels to play with
22857       channel c: New incoming call
22858       targetcall: Call from PBX to target
22859       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
22860       replacecall: The owner of the previous
22861       We need to masq C into refer_call to connect to
22862       targetcall;
22863       If we are talking to internal audio stream, target call is null.
22864    */
22865 
22866    /* Fake call progress */
22867    transmit_response(p, "100 Trying", req);
22868    ast_setstate(c, AST_STATE_RING);
22869 
22870    /* Masquerade the new call into the referred call to connect to target call
22871       Targetcall is not touched by the masq */
22872 
22873    /* Answer the incoming call and set channel to UP state */
22874    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
22875 
22876    ast_setstate(c, AST_STATE_UP);
22877 
22878    /* Stop music on hold and other generators */
22879    ast_quiet_chan(replacecall);
22880    ast_quiet_chan(targetcall);
22881    ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", ast_channel_name(c), ast_channel_name(replacecall));
22882 
22883    /* Make sure that the masq does not free our PVT for the old call */
22884    if (! earlyreplace && ! oneleggedreplace )
22885       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
22886 
22887    /* Prepare the masquerade - if this does not happen, we will be gone */
22888    if(ast_channel_masquerade(replacecall, c))
22889       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
22890    else
22891       ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", ast_channel_name(c), ast_channel_name(replacecall));
22892 
22893    /* C should now be in place of replacecall. all channel locks and pvt locks should be removed
22894     * before issuing the masq.  Since we are unlocking both the pvt (p) and its owner channel (c)
22895     * it is possible for channel c to be destroyed on us.  To prevent this, we must give c a reference
22896     * before any unlocking takes place and remove it only once we are completely done with it */
22897    ast_channel_ref(c);
22898    ast_channel_unlock(replacecall);
22899    ast_channel_unlock(c);
22900    sip_pvt_unlock(p->refer->refer_call);
22901    sip_pvt_unlock(p);
22902    if (ast_do_masquerade(replacecall)) {
22903       ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n");
22904    }
22905    ast_channel_lock(c);
22906    if (earlyreplace || oneleggedreplace ) {
22907       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
22908    }
22909    ast_setstate(c, AST_STATE_DOWN);
22910    ast_channel_unlock(c);
22911 
22912    /* The call should be down with no ast_channel, so hang it up */
22913    c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt");
22914 
22915    /* c and c's tech pvt must be unlocked at this point for ast_hangup */
22916    ast_hangup(c);
22917    /* this indicates to handle_request_do that the owner channel has already been unlocked */
22918    *nounlock = 1;
22919    /* lock PVT structure again after hangup */
22920    sip_pvt_lock(p);
22921    ast_channel_unref(c);
22922    return 0;
22923 }

static int handle_request_bye ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Handle incoming BYE request.

Definition at line 24611 of file chan_sip.c.

References __sip_pretend_ack(), append_history, ARRAY_LEN, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_log(), AST_MAX_USER_FIELD, ast_queue_control(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, ast_set_hangupsource(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), ast_channel::context, context, copy_request(), get_also_info(), LOG_NOTICE, LOG_WARNING, parse_sip_options(), pbx_builtin_setvar_helper(), quality, sip_alreadygone(), sip_cfg, sip_get_header(), sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy_final(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, cfsip_methods::text, transmit_response(), transmit_response_reliable(), and transmit_response_with_unsupported().

Referenced by handle_incoming().

24612 {
24613    struct ast_channel *c=NULL;
24614    int res;
24615    struct ast_channel *bridged_to;
24616    const char *required;
24617 
24618    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
24619    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) {
24620       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
24621    }
24622 
24623    __sip_pretend_ack(p);
24624 
24625    p->invitestate = INV_TERMINATED;
24626 
24627    copy_request(&p->initreq, req);
24628    if (sipdebug)
24629       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
24630    check_via(p, req);
24631    sip_alreadygone(p);
24632 
24633    /* Get RTCP quality before end of call */
24634    if (p->do_history || p->owner) {
24635       char quality_buf[AST_MAX_USER_FIELD], *quality;
24636       struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
24637 
24638       /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt
24639        * to lock the bridge. This may get hairy...
24640        */
24641       while (bridge && ast_channel_trylock(bridge)) {
24642          ast_channel_unlock(p->owner);
24643          do {
24644             /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */
24645             sip_pvt_unlock(p);
24646             usleep(1);
24647             sip_pvt_lock(p);
24648          } while (p->owner && ast_channel_trylock(p->owner));
24649          bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
24650       }
24651 
24652 
24653       if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
24654          if (p->do_history) {
24655             append_history(p, "RTCPaudio", "Quality:%s", quality);
24656 
24657             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) {
24658                append_history(p, "RTCPaudioJitter", "Quality:%s", quality);
24659             }
24660             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) {
24661                append_history(p, "RTCPaudioLoss", "Quality:%s", quality);
24662             }
24663             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) {
24664                append_history(p, "RTCPaudioRTT", "Quality:%s", quality);
24665             }
24666          }
24667 
24668          if (p->owner) {
24669             ast_rtp_instance_set_stats_vars(p->owner, p->rtp);
24670          }
24671 
24672       }
24673 
24674       if (bridge) {
24675          struct sip_pvt *q = bridge->tech_pvt;
24676 
24677          if (IS_SIP_TECH(bridge->tech) && q && q->rtp) {
24678             ast_rtp_instance_set_stats_vars(bridge, q->rtp);
24679          }
24680          ast_channel_unlock(bridge);
24681       }
24682 
24683       if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
24684          if (p->do_history) {
24685             append_history(p, "RTCPvideo", "Quality:%s", quality);
24686          }
24687          if (p->owner) {
24688             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality);
24689          }
24690       }
24691       if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
24692          if (p->do_history) {
24693             append_history(p, "RTCPtext", "Quality:%s", quality);
24694          }
24695          if (p->owner) {
24696             pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality);
24697          }
24698       }
24699    }
24700 
24701    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
24702    stop_session_timer(p); /* Stop Session-Timer */
24703 
24704    if (!ast_strlen_zero(sip_get_header(req, "Also"))) {
24705       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
24706          ast_sockaddr_stringify(&p->recv));
24707       if (ast_strlen_zero(p->context))
24708          ast_string_field_set(p, context, sip_cfg.default_context);
24709       res = get_also_info(p, req);
24710       if (!res) {
24711          c = p->owner;
24712          if (c) {
24713             bridged_to = ast_bridged_channel(c);
24714             if (bridged_to) {
24715                /* Don't actually hangup here... */
24716                ast_queue_control(c, AST_CONTROL_UNHOLD);
24717                ast_channel_unlock(c);  /* async_goto can do a masquerade, no locks can be held during a masq */
24718                ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1);
24719                ast_channel_lock(c);
24720             } else
24721                ast_queue_hangup(p->owner);
24722          }
24723       } else {
24724          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv));
24725          if (p->owner)
24726             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
24727       }
24728    } else if (p->owner) {
24729       ast_set_hangupsource(p->owner, ast_channel_name(p->owner), 0);
24730       ast_queue_hangup(p->owner);
24731       sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT);
24732       ast_debug(3, "Received bye, issuing owner hangup\n");
24733    } else {
24734       sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT);
24735       ast_debug(3, "Received bye, no owner, selfdestruct soon.\n");
24736    }
24737    ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
24738 
24739    /* Find out what they require */
24740    required = sip_get_header(req, "Require");
24741    if (!ast_strlen_zero(required)) {
24742       char unsupported[256] = { 0, };
24743       parse_sip_options(required, unsupported, ARRAY_LEN(unsupported));
24744       /* If there are any options required that we do not support,
24745        * then send a 420 with only those unsupported options listed */
24746       if (!ast_strlen_zero(unsupported)) {
24747          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported);
24748          ast_log(LOG_WARNING, "Received SIP BYE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported);
24749       } else {
24750          transmit_response(p, "200 OK", req);
24751       }
24752    } else {
24753       transmit_response(p, "200 OK", req);
24754    }
24755 
24756    return 1;
24757 }

static int handle_request_cancel ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Handle incoming CANCEL request.

Definition at line 24542 of file chan_sip.c.

References __sip_pretend_ack(), ast_channel_name(), ast_debug, ast_free, ast_queue_hangup(), AST_SCHED_DEL, ast_set_hangupsource(), AST_STATE_UP, ast_str_strlen(), ast_test_flag, check_via(), sip_alreadygone(), sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().

Referenced by handle_incoming().

24543 {
24544 
24545    check_via(p, req);
24546    sip_alreadygone(p);
24547 
24548    if (p->owner && p->owner->_state == AST_STATE_UP) {
24549       /* This call is up, cancel is ignored, we need a bye */
24550       transmit_response(p, "200 OK", req);
24551       ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n");
24552       return 0;
24553    }
24554 
24555    /* At this point, we could have cancelled the invite at the same time
24556       as the other side sends a CANCEL. Our final reply with error code
24557       might not have been received by the other side before the CANCEL
24558       was sent, so let's just give up retransmissions and waiting for
24559       ACK on our error code. The call is hanging up any way. */
24560    if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) {
24561       __sip_pretend_ack(p);
24562    }
24563    if (p->invitestate != INV_TERMINATED)
24564       p->invitestate = INV_CANCELLED;
24565 
24566    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
24567       update_call_counter(p, DEC_CALL_LIMIT);
24568 
24569    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
24570    if (p->owner) {
24571       ast_set_hangupsource(p->owner, ast_channel_name(p->owner), 0);
24572       ast_queue_hangup(p->owner);
24573    }
24574    else
24575       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
24576    if (ast_str_strlen(p->initreq.data) > 0) {
24577       struct sip_pkt *pkt, *prev_pkt;
24578       /* If the CANCEL we are receiving is a retransmission, and we already have scheduled
24579        * a reliable 487, then we don't want to schedule another one on top of the previous
24580        * one.
24581        *
24582        * As odd as this may sound, we can't rely on the previously-transmitted "reliable"
24583        * response in this situation. What if we've sent all of our reliable responses
24584        * already and now all of a sudden, we get this second CANCEL?
24585        *
24586        * The only way to do this correctly is to cancel our previously-scheduled reliably-
24587        * transmitted response and send a new one in its place.
24588        */
24589       for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) {
24590          if (pkt->seqno == p->lastinvite && pkt->response_code == 487) {
24591             AST_SCHED_DEL(sched, pkt->retransid);
24592             UNLINK(pkt, p->packets, prev_pkt);
24593             dialog_unref(pkt->owner, "unref packet->owner from dialog");
24594             if (pkt->data) {
24595                ast_free(pkt->data);
24596             }
24597             ast_free(pkt);
24598             break;
24599          }
24600       }
24601       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
24602       transmit_response(p, "200 OK", req);
24603       return 1;
24604    } else {
24605       transmit_response(p, "481 Call Leg Does Not Exist", req);
24606       return 0;
24607    }
24608 }

static int handle_request_do ( struct sip_request *  req,
struct ast_sockaddr addr 
) [static]

Handle incoming SIP message - request or response.

This is used for all transports (udp, tcp and tcp/tls)

Definition at line 26316 of file chan_sip.c.

References ao2_t_ref, append_history, ast_channel_unlock, ast_channel_unref, ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_str_reset(), ast_str_strlen(), ast_update_use_count(), ast_verbose, copy_socket_data(), find_call(), find_sip_method(), handle_incoming(), lws2sws(), netlock, parse_request(), sip_cfg, sip_debug_test_addr(), sip_get_header(), sip_get_transport(), sip_pvt_lock_full(), and sip_pvt_unlock.

Referenced by _sip_tcp_helper_thread(), and sipsock_read().

26317 {
26318    struct sip_pvt *p;
26319    struct ast_channel *owner_chan_ref = NULL;
26320    int recount = 0;
26321    int nounlock = 0;
26322 
26323    if (sip_debug_test_addr(addr))   /* Set the debug flag early on packet level */
26324       req->debug = 1;
26325    if (sip_cfg.pedanticsipchecking)
26326       lws2sws(req->data);  /* Fix multiline headers */
26327    if (req->debug) {
26328       ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n",
26329          sip_get_transport(req->socket.type), ast_sockaddr_stringify(addr), req->data->str);
26330    }
26331 
26332    if (parse_request(req) == -1) { /* Bad packet, can't parse */
26333       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
26334       return 1;
26335    }
26336    req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1));
26337 
26338    if (req->debug)
26339       ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : "");
26340 
26341    if (req->headers < 2) { /* Must have at least two headers */
26342       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
26343       return 1;
26344    }
26345    ast_mutex_lock(&netlock);
26346 
26347    /* Find the active SIP dialog or create a new one */
26348    p = find_call(req, addr, req->method); /* returns p with a reference only. _NOT_ locked*/
26349    if (p == NULL) {
26350       ast_debug(1, "Invalid SIP message - rejected , no callid, len %zu\n", ast_str_strlen(req->data));
26351       ast_mutex_unlock(&netlock);
26352       return 1;
26353    }
26354 
26355    /* Lock both the pvt and the owner if owner is present.  This will
26356     * not fail. */
26357    owner_chan_ref = sip_pvt_lock_full(p);
26358 
26359    copy_socket_data(&p->socket, &req->socket);
26360    ast_sockaddr_copy(&p->recv, addr);
26361 
26362    /* if we have an owner, then this request has been authenticated */
26363    if (p->owner) {
26364       req->authenticated = 1;
26365    }
26366 
26367    if (p->do_history) /* This is a request or response, note what it was for */
26368       append_history(p, "Rx", "%s / %s / %s", req->data->str, sip_get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2));
26369 
26370    if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) {
26371       /* Request failed */
26372       ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
26373    }
26374 
26375    if (recount) {
26376       ast_update_use_count();
26377    }
26378 
26379    if (p->owner && !nounlock) {
26380       ast_channel_unlock(p->owner);
26381    }
26382    if (owner_chan_ref) {
26383       ast_channel_unref(owner_chan_ref);
26384    }
26385    sip_pvt_unlock(p);
26386    ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
26387    ast_mutex_unlock(&netlock);
26388 
26389    return 1;
26390 }

static void handle_request_info ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Receive SIP INFO Message.

Definition at line 19483 of file chan_sip.c.

References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, ast_find_call_feature(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), AST_LOG_WARNING, ast_queue_control(), ast_queue_frame(), ast_rdlock_call_features(), ast_strlen_zero(), ast_test_flag, ast_unlock_call_features(), ast_verbose, ast_channel::cdr, ast_call_feature::exten, f, get_body(), get_msg_text(), ast_frame_subclass::integer, ast_frame::len, LOG_ERROR, LOG_WARNING, sip_get_header(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().

Referenced by handle_incoming().

19484 {
19485    char buf[1024] = "";
19486    unsigned int event;
19487    const char *c = sip_get_header(req, "Content-Type");
19488 
19489    /* Need to check the media/type */
19490    if (!strcasecmp(c, "application/dtmf-relay") ||
19491        !strcasecmp(c, "application/vnd.nortelnetworks.digits") ||
19492        !strcasecmp(c, "application/dtmf")) {
19493       unsigned int duration = 0;
19494 
19495       if (!p->owner) {  /* not a PBX call */
19496          transmit_response(p, "481 Call leg/transaction does not exist", req);
19497          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19498          return;
19499       }
19500 
19501       /* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration;
19502        * otherwise use the body as the signal */
19503       if (strcasecmp(c, "application/dtmf")) {
19504          const char *msg_body;
19505 
19506          if (   ast_strlen_zero(msg_body = get_body(req, "Signal", '='))
19507             && ast_strlen_zero(msg_body = get_body(req, "d", '='))) {
19508             ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on "
19509                   "call %s\n", p->callid);
19510             transmit_response(p, "200 OK", req);
19511             return;
19512          }
19513          ast_copy_string(buf, msg_body, sizeof(buf));
19514 
19515          if (!ast_strlen_zero((msg_body = get_body(req, "Duration", '=')))) {
19516             sscanf(msg_body, "%30u", &duration);
19517          }
19518       } else {
19519          /* Type is application/dtmf, simply use what's in the message body */
19520          get_msg_text(buf, sizeof(buf), req);
19521       }
19522 
19523       /* An empty message body requires us to send a 200 OK */
19524       if (ast_strlen_zero(buf)) {
19525          transmit_response(p, "200 OK", req);
19526          return;
19527       }
19528 
19529       if (!duration) {
19530          duration = 100; /* 100 ms */
19531       }
19532 
19533       if (buf[0] == '*') {
19534          event = 10;
19535       } else if (buf[0] == '#') {
19536          event = 11;
19537       } else if (buf[0] == '!') {
19538          event = 16;
19539       } else if ('A' <= buf[0] && buf[0] <= 'D') {
19540          event = 12 + buf[0] - 'A';
19541       } else if ('a' <= buf[0] && buf[0] <= 'd') {
19542          event = 12 + buf[0] - 'a';
19543       } else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) {
19544          ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid "
19545                "value for INFO message on call %s\n", p->callid);
19546          transmit_response(p, "200 OK", req);
19547          return;
19548       }
19549 
19550       if (event == 16) {
19551          /* send a FLASH event */
19552          struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
19553          ast_queue_frame(p->owner, &f);
19554          if (sipdebug) {
19555             ast_verbose("* DTMF-relay event received: FLASH\n");
19556          }
19557       } else {
19558          /* send a DTMF event */
19559          struct ast_frame f = { AST_FRAME_DTMF, };
19560          if (event < 10) {
19561             f.subclass.integer = '0' + event;
19562          } else if (event == 10) {
19563             f.subclass.integer = '*';
19564          } else if (event == 11) {
19565             f.subclass.integer = '#';
19566          } else {
19567             f.subclass.integer = 'A' + (event - 12);
19568          }
19569          f.len = duration;
19570          ast_queue_frame(p->owner, &f);
19571          if (sipdebug) {
19572             ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
19573          }
19574       }
19575       transmit_response(p, "200 OK", req);
19576       return;
19577    } else if (!strcasecmp(c, "application/media_control+xml")) {
19578       /* Eh, we'll just assume it's a fast picture update for now */
19579       if (p->owner) {
19580          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
19581       }
19582       transmit_response(p, "200 OK", req);
19583       return;
19584    } else if (!ast_strlen_zero(c = sip_get_header(req, "X-ClientCode"))) {
19585       /* Client code (from SNOM phone) */
19586       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
19587          if (p->owner && p->owner->cdr) {
19588             ast_cdr_setuserfield(p->owner, c);
19589          }
19590          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) {
19591             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
19592          }
19593          transmit_response(p, "200 OK", req);
19594       } else {
19595          transmit_response(p, "403 Forbidden", req);
19596       }
19597       return;
19598    } else if (!ast_strlen_zero(c = sip_get_header(req, "Record"))) {
19599       /* INFO messages generated by some phones to start/stop recording
19600        * on phone calls.
19601        */
19602 
19603       struct ast_call_feature *feat = NULL;
19604       int j;
19605       struct ast_frame f = { AST_FRAME_DTMF, };
19606       int suppress_warning = 0; /* Supress warning if the feature is blank */
19607 
19608       if (!p->owner) {        /* not a PBX call */
19609          transmit_response(p, "481 Call leg/transaction does not exist", req);
19610          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19611          return;
19612       }
19613 
19614       /* first, get the feature string, if it exists */
19615       ast_rdlock_call_features();
19616       if (p->relatedpeer) {
19617          if (!strcasecmp(c, "on")) {
19618             if (ast_strlen_zero(p->relatedpeer->record_on_feature)) {
19619                suppress_warning = 1;
19620             } else {
19621                feat = ast_find_call_feature(p->relatedpeer->record_on_feature);
19622             }
19623          } else if (!strcasecmp(c, "off")) {
19624             if (ast_strlen_zero(p->relatedpeer->record_on_feature)) {
19625                suppress_warning = 1;
19626             } else {
19627                feat = ast_find_call_feature(p->relatedpeer->record_off_feature);
19628             }
19629          } else {
19630             ast_log(LOG_ERROR, "Received INFO requesting to record with invalid value: %s\n", c);
19631          }
19632       }
19633       if (!feat || ast_strlen_zero(feat->exten)) {
19634          if (!suppress_warning) {
19635             ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
19636          }
19637          /* 403 means that we don't support this feature, so don't request it again */
19638          transmit_response(p, "403 Forbidden", req);
19639          ast_unlock_call_features();
19640          return;
19641       }
19642       /* Send the feature code to the PBX as DTMF, just like the handset had sent it */
19643       f.len = 100;
19644       for (j=0; j < strlen(feat->exten); j++) {
19645          f.subclass.integer = feat->exten[j];
19646          ast_queue_frame(p->owner, &f);
19647          if (sipdebug) {
19648             ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer);
19649          }
19650       }
19651       ast_unlock_call_features();
19652 
19653       ast_debug(1, "Got a Request to Record the channel, state %s\n", c);
19654       transmit_response(p, "200 OK", req);
19655       return;
19656    } else if (ast_strlen_zero(c = sip_get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
19657       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
19658       transmit_response(p, "200 OK", req);
19659       return;
19660    }
19661 
19662    /* Other type of INFO message, not really understood by Asterisk */
19663    /* if (get_msg_text(buf, sizeof(buf), req)) { */
19664 
19665    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
19666    transmit_response(p, "415 Unsupported media type", req);
19667    return;
19668 }

static int handle_request_invite ( struct sip_pvt *  p,
struct sip_request *  req,
int  debug,
uint32_t  seqno,
struct ast_sockaddr addr,
int *  recount,
const char *  e,
int *  nounlock 
) [static]

Handle incoming INVITE request.

Note:
If the INVITE has a Replaces header, it is part of an attended transfer. If so, we do not go through the dial plan but try to find the active call and masquerade into it

This is a spiral. What we need to do is to just change the outgoing INVITE so that it now routes to the new Request URI. Since we created the INVITE ourselves that should be all we need to do.

Todo:
XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet correctly instead...

Definition at line 23018 of file chan_sip.c.

References __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_FAILURE, ast_cc_agent_set_interfaces_chanvar(), ast_channel_name(), ast_channel_queue_connected_line_update(), ast_channel_set_redirecting(), ast_channel_unlock, ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, ast_copy_string(), ast_debug, ast_format_cap_copy(), ast_format_cap_is_empty(), ast_hangup(), ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_instance_set_alt_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), ast_setup_cc_recall_datastore(), ast_skip_blanks(), ast_sockaddr_stringify(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_uri_sip_user, ast_verbose, build_contact(), build_route(), change_hold_state(), change_redirecting_information(), check_user_full(), check_via(), connected, context, copy_request(), do_magic_pickup(), ast_channel::exten, exten, extract_uri(), FALSE, find_sdp(), get_destination(), get_ip_and_port_from_sdp(), get_rpid(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_our_tag(), ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_minse(), parse_ok_contact(), parse_session_expires(), parse_sip_options(), ast_party_name::presentation, ast_party_number::presentation, process_sdp(), restart_session_timer(), S_OR, set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_get_header(), sip_methods, sip_new(), sip_pickup(), sip_pvt_lock, sip_pvt_unlock, sip_ref_peer(), sip_refer_allocate(), sip_scheddestroy(), sip_st_alloc(), sip_t38_abort(), sip_unref_peer(), sip_uri_cmp(), ast_party_connected_line::source, st_get_mode(), st_get_refresher(), st_get_se(), start_session_timer(), ast_party_name::str, ast_party_number::str, strcasestr(), strsep(), ast_party_id::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_incoming().

23019 {
23020    int res = INV_REQ_SUCCESS;
23021    int gotdest;
23022    const char *p_replaces;
23023    char *replace_id = NULL;
23024    int refer_locked = 0;
23025    const char *required;
23026    unsigned int required_profile = 0;
23027    struct ast_channel *c = NULL;    /* New channel */
23028    struct sip_peer *authpeer = NULL;   /* Matching Peer */
23029    int reinvite = 0;
23030    int rtn;
23031    struct ast_party_redirecting redirecting;
23032    struct ast_set_party_redirecting update_redirecting;
23033 
23034    const char *p_uac_se_hdr;       /* UAC's Session-Expires header string                      */
23035    const char *p_uac_min_se;       /* UAC's requested Min-SE interval (char string)            */
23036    int uac_max_se = -1;            /* UAC's Session-Expires in integer format                  */
23037    int uac_min_se = -1;            /* UAC's Min-SE in integer format                           */
23038    int st_active = FALSE;          /* Session-Timer on/off boolean                             */
23039    int st_interval = 0;            /* Session-Timer negotiated refresh interval                */
23040    enum st_refresher st_ref;       /* Session-Timer session refresher                          */
23041    int dlg_min_se = -1;
23042    struct {
23043       char exten[AST_MAX_EXTENSION];
23044       char context[AST_MAX_CONTEXT];
23045    } pickup = {
23046          .exten = "",
23047    };
23048    st_ref = SESSION_TIMER_REFRESHER_AUTO;
23049 
23050    /* Find out what they support */
23051    if (!p->sipoptions) {
23052       const char *supported = sip_get_header(req, "Supported");
23053       if (!ast_strlen_zero(supported)) {
23054          p->sipoptions = parse_sip_options(supported, NULL, 0);
23055       }
23056    }
23057 
23058    /* Find out what they require */
23059    required = sip_get_header(req, "Require");
23060    if (!ast_strlen_zero(required)) {
23061       char unsupported[256] = { 0, };
23062       required_profile = parse_sip_options(required, unsupported, ARRAY_LEN(unsupported));
23063 
23064       /* If there are any options required that we do not support,
23065        * then send a 420 with only those unsupported options listed */
23066       if (!ast_strlen_zero(unsupported)) {
23067          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported);
23068          ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported);
23069          p->invitestate = INV_COMPLETED;
23070          if (!p->lastinvite)
23071             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23072          res = INV_REQ_ERROR;
23073          goto request_invite_cleanup;
23074       }
23075    }
23076 
23077    /* The option tags may be present in Supported: or Require: headers.
23078    Include the Require: option tags for further processing as well */
23079    p->sipoptions |= required_profile;
23080    p->reqsipoptions = required_profile;
23081 
23082    /* Check if this is a loop */
23083    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED) && p->owner->_state != AST_STATE_UP) {
23084       /* This is a call to ourself.  Send ourselves an error code and stop
23085          processing immediately, as SIP really has no good mechanism for
23086          being able to call yourself */
23087       /* If pedantic is on, we need to check the tags. If they're different, this is
23088          in fact a forked call through a SIP proxy somewhere. */
23089       int different;
23090       const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2);
23091       const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2);
23092       if (sip_cfg.pedanticsipchecking)
23093          different = sip_uri_cmp(initial_rlPart2, this_rlPart2);
23094       else
23095          different = strcmp(initial_rlPart2, this_rlPart2);
23096       if (!different) {
23097          transmit_response(p, "482 Loop Detected", req);
23098          p->invitestate = INV_COMPLETED;
23099          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23100          res = INV_REQ_FAILED;
23101          goto request_invite_cleanup;
23102       } else {
23103          /*! This is a spiral. What we need to do is to just change the outgoing INVITE
23104           * so that it now routes to the new Request URI. Since we created the INVITE ourselves
23105           * that should be all we need to do.
23106           *
23107           * \todo XXX This needs to be reviewed.  YOu don't change the request URI really, you route the packet
23108           * correctly instead...
23109           */
23110          char *uri = ast_strdupa(this_rlPart2);
23111          char *at = strchr(uri, '@');
23112          char *peerorhost;
23113          ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2);
23114          transmit_response(p, "100 Trying", req);
23115          if (at) {
23116             *at = '\0';
23117          }
23118          /* Parse out "sip:" */
23119          if ((peerorhost = strchr(uri, ':'))) {
23120             *peerorhost++ = '\0';
23121          }
23122          ast_string_field_set(p, theirtag, NULL);
23123          /* Treat this as if there were a call forward instead...
23124           */
23125          ast_channel_call_forward_set(p->owner, peerorhost);
23126          ast_queue_control(p->owner, AST_CONTROL_BUSY);
23127          res = INV_REQ_FAILED;
23128          goto request_invite_cleanup;
23129       }
23130    }
23131 
23132    if (!req->ignore && p->pendinginvite) {
23133       if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) {
23134          /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we
23135           * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero).
23136           * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set.
23137           * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with
23138           * credentials based on one we challenged earlier.
23139           *
23140           * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous
23141           * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response
23142           * from the previous transaction from the list of outstanding packets.
23143           */
23144          __sip_ack(p, p->pendinginvite, 1, 0);
23145       } else {
23146          /* We already have a pending invite. Sorry. You are on hold. */
23147          p->glareinvite = seqno;
23148          if (p->rtp && find_sdp(req)) {
23149             struct ast_sockaddr addr;
23150             if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) {
23151                ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n");
23152             } else {
23153                ast_rtp_instance_set_alt_remote_address(p->rtp, &addr);
23154             }
23155             if (p->vrtp) {
23156                if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) {
23157                   ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n");
23158                } else {
23159                   ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr);
23160                }
23161             }
23162          }
23163          transmit_response_reliable(p, "491 Request Pending", req);
23164          ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
23165          /* Don't destroy dialog here */
23166          res = INV_REQ_FAILED;
23167          goto request_invite_cleanup;
23168       }
23169    }
23170 
23171    p_replaces = sip_get_header(req, "Replaces");
23172    if (!ast_strlen_zero(p_replaces)) {
23173       /* We have a replaces header */
23174       char *ptr;
23175       char *fromtag = NULL;
23176       char *totag = NULL;
23177       char *start, *to;
23178       int error = 0;
23179 
23180       if (p->owner) {
23181          ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
23182          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
23183          /* Do not destroy existing call */
23184          res = INV_REQ_ERROR;
23185          goto request_invite_cleanup;
23186       }
23187 
23188       if (sipdebug)
23189          ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
23190       /* Create a buffer we can manipulate */
23191       replace_id = ast_strdupa(p_replaces);
23192       ast_uri_decode(replace_id, ast_uri_sip_user);
23193 
23194       if (!p->refer && !sip_refer_allocate(p)) {
23195          transmit_response_reliable(p, "500 Server Internal Error", req);
23196          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
23197          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23198          p->invitestate = INV_COMPLETED;
23199          res = INV_REQ_ERROR;
23200          goto request_invite_cleanup;
23201       }
23202 
23203       /*  Todo: (When we find phones that support this)
23204          if the replaces header contains ";early-only"
23205          we can only replace the call in early
23206          stage, not after it's up.
23207 
23208          If it's not in early mode, 486 Busy.
23209       */
23210 
23211       /* Skip leading whitespace */
23212       replace_id = ast_skip_blanks(replace_id);
23213 
23214       start = replace_id;
23215       while ( (ptr = strsep(&start, ";")) ) {
23216          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
23217          if ( (to = strcasestr(ptr, "to-tag=") ) )
23218             totag = to + 7;   /* skip the keyword */
23219          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
23220             fromtag = to + 9; /* skip the keyword */
23221             fromtag = strsep(&fromtag, "&"); /* trim what ? */
23222          }
23223       }
23224 
23225       if (sipdebug)
23226          ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n",
23227                  replace_id,
23228                  fromtag ? fromtag : "<no from tag>",
23229                  totag ? totag : "<no to tag>");
23230 
23231       /* Try to find call that we are replacing.
23232          If we have a Replaces header, we need to cancel that call if we succeed with this call.
23233          First we cheat a little and look for a magic call-id from phones that support
23234          dialog-info+xml so we can do technology independent pickup... */
23235       if (strncmp(replace_id, "pickup-", 7) == 0) {
23236          struct sip_pvt *subscription = NULL;
23237          replace_id += 7; /* Worst case we are looking at \0 */
23238 
23239          if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
23240             ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id);
23241             transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
23242             error = 1;
23243          } else {
23244             ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context);
23245             ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten));
23246             ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context));
23247             sip_pvt_unlock(subscription);
23248             if (subscription->owner) {
23249                ast_channel_unlock(subscription->owner);
23250             }
23251          }
23252       }
23253 
23254       /* This locks both refer_call pvt and refer_call pvt's owner!!!*/
23255       if (!error && ast_strlen_zero(pickup.exten) && (p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
23256          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
23257          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
23258          error = 1;
23259       } else {
23260          refer_locked = 1;
23261       }
23262 
23263       /* The matched call is the call from the transferer to Asterisk .
23264          We want to bridge the bridged part of the call to the
23265          incoming invite, thus taking over the refered call */
23266 
23267       if (p->refer->refer_call == p) {
23268          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
23269          p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
23270          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
23271          error = 1;
23272       }
23273 
23274       if (!error && ast_strlen_zero(pickup.exten) && !p->refer->refer_call->owner) {
23275          /* Oops, someting wrong anyway, no owner, no call */
23276          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
23277          /* Check for better return code */
23278          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req);
23279          error = 1;
23280       }
23281 
23282       if (!error && ast_strlen_zero(pickup.exten) && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP) {
23283          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
23284          transmit_response_reliable(p, "603 Declined (Replaces)", req);
23285          error = 1;
23286       }
23287 
23288       if (error) {   /* Give up this dialog */
23289          append_history(p, "Xfer", "INVITE/Replace Failed.");
23290          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23291          sip_pvt_unlock(p);
23292          if (p->refer->refer_call) {
23293             sip_pvt_unlock(p->refer->refer_call);
23294             if (p->refer->refer_call->owner) {
23295                ast_channel_unlock(p->refer->refer_call->owner);
23296             }
23297          }
23298          refer_locked = 0;
23299          p->invitestate = INV_COMPLETED;
23300          res = INV_REQ_ERROR;
23301          goto request_invite_cleanup;
23302       }
23303    }
23304 
23305    /* Check if this is an INVITE that sets up a new dialog or
23306       a re-invite in an existing dialog */
23307 
23308    if (!req->ignore) {
23309       int newcall = (p->initreq.headers ? TRUE : FALSE);
23310 
23311       if (sip_cancel_destroy(p))
23312          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
23313       /* This also counts as a pending invite */
23314       p->pendinginvite = seqno;
23315       check_via(p, req);
23316 
23317       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
23318       if (sipdebug)
23319          ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
23320       if (!p->owner) {  /* Not a re-invite */
23321          if (debug)
23322             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
23323          if (newcall)
23324             append_history(p, "Invite", "New call: %s", p->callid);
23325          parse_ok_contact(p, req);
23326       } else { /* Re-invite on existing call */
23327          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
23328          if (get_rpid(p, req)) {
23329             struct ast_party_connected_line connected;
23330             struct ast_set_party_connected_line update_connected;
23331 
23332             ast_party_connected_line_init(&connected);
23333             memset(&update_connected, 0, sizeof(update_connected));
23334 
23335             update_connected.id.number = 1;
23336             connected.id.number.valid = 1;
23337             connected.id.number.str = (char *) p->cid_num;
23338             connected.id.number.presentation = p->callingpres;
23339 
23340             update_connected.id.name = 1;
23341             connected.id.name.valid = 1;
23342             connected.id.name.str = (char *) p->cid_name;
23343             connected.id.name.presentation = p->callingpres;
23344 
23345             connected.id.tag = (char *) p->cid_tag;
23346             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
23347             ast_channel_queue_connected_line_update(p->owner, &connected,
23348                &update_connected);
23349          }
23350          /* Handle SDP here if we already have an owner */
23351          if (find_sdp(req)) {
23352             if (process_sdp(p, req, SDP_T38_INITIATE)) {
23353                if (!ast_strlen_zero(sip_get_header(req, "Content-Encoding"))) {
23354                   /* Asterisk does not yet support any Content-Encoding methods.  Always
23355                    * attempt to process the sdp, but return a 415 if a Content-Encoding header
23356                    * was present after processing failed.  */
23357                   transmit_response_reliable(p, "415 Unsupported Media type", req);
23358                } else {
23359                   transmit_response_reliable(p, "488 Not acceptable here", req);
23360                }
23361                if (!p->lastinvite)
23362                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23363                res = INV_REQ_ERROR;
23364                goto request_invite_cleanup;
23365             }
23366             ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
23367          } else {
23368             ast_format_cap_copy(p->jointcaps, p->caps);
23369             ast_debug(1, "Hm....  No sdp for the moment\n");
23370             /* Some devices signal they want to be put off hold by sending a re-invite
23371                *without* an SDP, which is supposed to mean "Go back to your state"
23372                and since they put os on remote hold, we go back to off hold */
23373             if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
23374                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
23375                /* Activate a re-invite */
23376                ast_queue_frame(p->owner, &ast_null_frame);
23377                change_hold_state(p, req, FALSE, 0);
23378             }
23379          }
23380          if (p->do_history) /* This is a response, note what it was for */
23381             append_history(p, "ReInv", "Re-invite received");
23382       }
23383    } else if (debug)
23384       ast_verbose("Ignoring this INVITE request\n");
23385 
23386    if (!p->lastinvite && !req->ignore && !p->owner) {
23387       /* This is a new invite */
23388       /* Handle authentication if this is our first invite */
23389       int cc_recall_core_id = -1;
23390       set_pvt_allowed_methods(p, req);
23391       res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer);
23392       if (res == AUTH_CHALLENGE_SENT) {
23393          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
23394          goto request_invite_cleanup;
23395       }
23396       if (res < 0) { /* Something failed in authentication */
23397          if (res == AUTH_FAKE_AUTH) {
23398             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
23399             transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
23400          } else {
23401             ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
23402             transmit_response_reliable(p, "403 Forbidden", req);
23403          }
23404          p->invitestate = INV_COMPLETED;
23405          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23406          goto request_invite_cleanup;
23407       }
23408 
23409       /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */
23410       if (p->relatedpeer) {
23411          p->relatedpeer = sip_unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
23412       }
23413       if (authpeer) {
23414          p->relatedpeer = sip_ref_peer(authpeer, "setting dialog's relatedpeer pointer");
23415       }
23416 
23417       req->authenticated = 1;
23418 
23419       /* We have a successful authentication, process the SDP portion if there is one */
23420       if (find_sdp(req)) {
23421          if (process_sdp(p, req, SDP_T38_INITIATE)) {
23422             /* Asterisk does not yet support any Content-Encoding methods.  Always
23423              * attempt to process the sdp, but return a 415 if a Content-Encoding header
23424              * was present after processing fails. */
23425             if (!ast_strlen_zero(sip_get_header(req, "Content-Encoding"))) {
23426                transmit_response_reliable(p, "415 Unsupported Media type", req);
23427             } else {
23428                /* Unacceptable codecs */
23429                transmit_response_reliable(p, "488 Not acceptable here", req);
23430             }
23431             p->invitestate = INV_COMPLETED;
23432             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23433             ast_debug(1, "No compatible codecs for this SIP call.\n");
23434             res = INV_REQ_ERROR;
23435             goto request_invite_cleanup;
23436          }
23437       } else { /* No SDP in invite, call control session */
23438          ast_format_cap_copy(p->jointcaps, p->caps);
23439          ast_debug(2, "No SDP in Invite, third party call control\n");
23440       }
23441 
23442       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
23443       /* This seems redundant ... see !p-owner above */
23444       if (p->owner)
23445          ast_queue_frame(p->owner, &ast_null_frame);
23446 
23447 
23448       /* Initialize the context if it hasn't been already */
23449       if (ast_strlen_zero(p->context))
23450          ast_string_field_set(p, context, sip_cfg.default_context);
23451 
23452 
23453       /* Check number of concurrent calls -vs- incoming limit HERE */
23454       ast_debug(1, "Checking SIP call limits for device %s\n", p->username);
23455       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
23456          if (res < 0) {
23457             ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username);
23458             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
23459             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23460             p->invitestate = INV_COMPLETED;
23461 
23462             res = AUTH_SESSION_LIMIT;
23463          }
23464 
23465          goto request_invite_cleanup;
23466       }
23467       gotdest = get_destination(p, NULL, &cc_recall_core_id);  /* Get destination right away */
23468       extract_uri(p, req);       /* Get the Contact URI */
23469       build_contact(p);       /* Build our contact header */
23470 
23471       if (p->rtp) {
23472          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
23473          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
23474       }
23475 
23476       if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */
23477          switch(gotdest) {
23478          case SIP_GET_DEST_INVALID_URI:
23479             transmit_response_reliable(p, "416 Unsupported URI scheme", req);
23480             break;
23481          case SIP_GET_DEST_EXTEN_MATCHMORE:
23482             if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)
23483                == SIP_PAGE2_ALLOWOVERLAP_YES) {
23484                transmit_response_reliable(p, "484 Address Incomplete", req);
23485                break;
23486             }
23487             /*
23488              * XXX We would have to implement collecting more digits in
23489              * chan_sip for any other schemes of overlap dialing.
23490              *
23491              * For SIP_PAGE2_ALLOWOVERLAP_DTMF it is better to do this in
23492              * the dialplan using the Incomplete application rather than
23493              * having the channel driver do it.
23494              */
23495             /* Fall through */
23496          case SIP_GET_DEST_EXTEN_NOT_FOUND:
23497          case SIP_GET_DEST_REFUSED:
23498          default:
23499             {
23500                char *decoded_exten = ast_strdupa(p->exten);
23501                transmit_response_reliable(p, "404 Not Found", req);
23502                ast_uri_decode(decoded_exten, ast_uri_sip_user);
23503                ast_log(LOG_NOTICE, "Call from '%s' (%s) to extension"
23504                   " '%s' rejected because extension not found in context '%s'.\n",
23505                   S_OR(p->username, p->peername), ast_sockaddr_stringify(&p->recv), decoded_exten, p->context);
23506             }
23507          } /* end switch */
23508 
23509          p->invitestate = INV_COMPLETED;
23510          update_call_counter(p, DEC_CALL_LIMIT);
23511          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23512          res = INV_REQ_FAILED;
23513          goto request_invite_cleanup;
23514       } else {
23515 
23516          /* If no extension was specified, use the s one */
23517          /* Basically for calling to IP/Host name only */
23518          if (ast_strlen_zero(p->exten))
23519             ast_string_field_set(p, exten, "s");
23520          /* Initialize our tag */
23521 
23522          make_our_tag(p->tag, sizeof(p->tag));
23523          /* First invitation - create the channel.  Allocation
23524           * failures are handled below. */
23525          c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL);
23526          if (cc_recall_core_id != -1) {
23527             ast_setup_cc_recall_datastore(c, cc_recall_core_id);
23528             ast_cc_agent_set_interfaces_chanvar(c);
23529          }
23530          *recount = 1;
23531 
23532          /* Save Record-Route for any later requests we make on this dialogue */
23533          build_route(p, req, 0);
23534 
23535          if (c) {
23536             ast_party_redirecting_init(&redirecting);
23537             memset(&update_redirecting, 0, sizeof(update_redirecting));
23538             change_redirecting_information(p, req, &redirecting, &update_redirecting,
23539                FALSE); /*Will return immediately if no Diversion header is present */
23540             ast_channel_set_redirecting(c, &redirecting, &update_redirecting);
23541             ast_party_redirecting_free(&redirecting);
23542          }
23543       }
23544    } else {
23545       ast_party_redirecting_init(&redirecting);
23546       memset(&update_redirecting, 0, sizeof(update_redirecting));
23547       if (sipdebug) {
23548          if (!req->ignore)
23549             ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid);
23550          else
23551             ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
23552       }
23553       if (!req->ignore)
23554          reinvite = 1;
23555       c = p->owner;
23556       change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */
23557       if (c) {
23558          ast_channel_set_redirecting(c, &redirecting, &update_redirecting);
23559       }
23560       ast_party_redirecting_free(&redirecting);
23561    }
23562 
23563    /* Session-Timers */
23564    if ((p->sipoptions & SIP_OPT_TIMER) && !ast_strlen_zero(sip_get_header(req, "Session-Expires"))) {
23565       /* The UAC has requested session-timers for this session. Negotiate
23566       the session refresh interval and who will be the refresher */
23567       ast_debug(2, "Incoming INVITE with 'timer' option supported and \"Session-Expires\" header.\n");
23568 
23569       /* Allocate Session-Timers struct w/in the dialog */
23570       if (!p->stimer)
23571          sip_st_alloc(p);
23572 
23573       /* Parse the Session-Expires header */
23574       p_uac_se_hdr = sip_get_header(req, "Session-Expires");
23575       rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref);
23576       if (rtn != 0) {
23577          transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
23578          p->invitestate = INV_COMPLETED;
23579          if (!p->lastinvite) {
23580             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23581          }
23582          res = INV_REQ_ERROR;
23583          goto request_invite_cleanup;
23584       }
23585 
23586       /* Parse the Min-SE header */
23587       p_uac_min_se = sip_get_header(req, "Min-SE");
23588       if (!ast_strlen_zero(p_uac_min_se)) {
23589          rtn = parse_minse(p_uac_min_se, &uac_min_se);
23590          if (rtn != 0) {
23591             transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req);
23592             p->invitestate = INV_COMPLETED;
23593             if (!p->lastinvite) {
23594                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23595             }
23596             res = INV_REQ_ERROR;
23597             goto request_invite_cleanup;
23598          }
23599       }
23600 
23601       dlg_min_se = st_get_se(p, FALSE);
23602       switch (st_get_mode(p, 1)) {
23603       case SESSION_TIMER_MODE_ACCEPT:
23604       case SESSION_TIMER_MODE_ORIGINATE:
23605          if (uac_max_se > 0 && uac_max_se < dlg_min_se) {
23606             transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se);
23607             p->invitestate = INV_COMPLETED;
23608             if (!p->lastinvite) {
23609                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23610             }
23611             res = INV_REQ_ERROR;
23612             goto request_invite_cleanup;
23613          }
23614 
23615          p->stimer->st_active_peer_ua = TRUE;
23616          st_active = TRUE;
23617          if (st_ref == SESSION_TIMER_REFRESHER_AUTO) {
23618             st_ref = st_get_refresher(p);
23619          }
23620 
23621          if (uac_max_se > 0) {
23622             int dlg_max_se = st_get_se(p, TRUE);
23623             if (dlg_max_se >= uac_min_se) {
23624                st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se;
23625             } else {
23626                st_interval = uac_max_se;
23627             }
23628          } else {
23629             /* Set to default max value */
23630             st_interval = global_max_se;
23631          }
23632          break;
23633 
23634       case SESSION_TIMER_MODE_REFUSE:
23635          if (p->reqsipoptions & SIP_OPT_TIMER) {
23636             transmit_response_with_unsupported(p, "420 Option Disabled", req, required);
23637             ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required);
23638             p->invitestate = INV_COMPLETED;
23639             if (!p->lastinvite) {
23640                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23641             }
23642             res = INV_REQ_ERROR;
23643             goto request_invite_cleanup;
23644          }
23645          break;
23646 
23647       default:
23648          ast_log(LOG_ERROR, "Internal Error %d at %s:%d\n", st_get_mode(p, 1), __FILE__, __LINE__);
23649          break;
23650       }
23651    } else {
23652       /* The UAC did not request session-timers.  Asterisk (UAS), will now decide
23653       (based on session-timer-mode in sip.conf) whether to run session-timers for
23654       this session or not. */
23655       switch (st_get_mode(p, 1)) {
23656       case SESSION_TIMER_MODE_ORIGINATE:
23657          st_active = TRUE;
23658          st_interval = st_get_se(p, TRUE);
23659          st_ref = SESSION_TIMER_REFRESHER_UAS;
23660          p->stimer->st_active_peer_ua = FALSE;
23661          break;
23662 
23663       default:
23664          break;
23665       }
23666    }
23667 
23668    if (reinvite == 0) {
23669       /* Session-Timers: Start session refresh timer based on negotiation/config */
23670       if (st_active == TRUE) {
23671          p->stimer->st_active   = TRUE;
23672          p->stimer->st_interval = st_interval;
23673          p->stimer->st_ref      = st_ref;
23674          start_session_timer(p);
23675       }
23676    } else {
23677       if (p->stimer->st_active == TRUE) {
23678          /* Session-Timers:  A re-invite request sent within a dialog will serve as
23679          a refresh request, no matter whether the re-invite was sent for refreshing
23680          the session or modifying it.*/
23681          ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid);
23682 
23683          /* The UAC may be adjusting the session-timers mid-session */
23684          if (st_interval > 0) {
23685             p->stimer->st_interval = st_interval;
23686             p->stimer->st_ref      = st_ref;
23687          }
23688 
23689          restart_session_timer(p);
23690          if (p->stimer->st_expirys > 0) {
23691             p->stimer->st_expirys--;
23692          }
23693       }
23694    }
23695 
23696    if (!req->ignore && p)
23697       p->lastinvite = seqno;
23698 
23699    if (c && replace_id) {  /* Attended transfer or call pickup - we're the target */
23700       if (!ast_strlen_zero(pickup.exten)) {
23701          append_history(p, "Xfer", "INVITE/Replace received");
23702 
23703          /* Let the caller know we're giving it a shot */
23704          transmit_response(p, "100 Trying", req);
23705          p->invitestate = INV_PROCEEDING;
23706          ast_setstate(c, AST_STATE_RING);
23707 
23708          /* Do the pickup itself */
23709          ast_channel_unlock(c);
23710          *nounlock = 1;
23711 
23712          /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both
23713           * magic pickup and ast_hangup.  Both of these functions will attempt to lock
23714           * p->owner again, which can cause a deadlock if we already hold a lock on p.
23715           * Locking order is, channel then pvt.  Dead lock avoidance must be used if
23716           * called the other way around. */
23717          sip_pvt_unlock(p);
23718          do_magic_pickup(c, pickup.exten, pickup.context);
23719          /* Now we're either masqueraded or we failed to pickup, in either case we... */
23720          ast_hangup(c);
23721          sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */
23722 
23723          res = INV_REQ_FAILED;
23724          goto request_invite_cleanup;
23725       } else {
23726          /* Go and take over the target call */
23727          if (sipdebug)
23728             ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
23729          res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock);
23730          refer_locked = 0;
23731          goto request_invite_cleanup;
23732       }
23733    }
23734 
23735 
23736    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
23737       enum ast_channel_state c_state = c->_state;
23738 
23739       if (c_state != AST_STATE_UP && reinvite &&
23740          (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
23741          /* If these conditions are true, and the channel is still in the 'ringing'
23742           * state, then this likely means that we have a situation where the initial
23743           * INVITE transaction has completed *but* the channel's state has not yet been
23744           * changed to UP. The reason this could happen is if the reinvite is received
23745           * on the SIP socket prior to an application calling ast_read on this channel
23746           * to read the answer frame we earlier queued on it. In this case, the reinvite
23747           * is completely legitimate so we need to handle this the same as if the channel
23748           * were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
23749           */
23750          c_state = AST_STATE_UP;
23751       }
23752 
23753       switch(c_state) {
23754       case AST_STATE_DOWN:
23755          ast_debug(2, "%s: New call is still down.... Trying... \n", ast_channel_name(c));
23756          transmit_provisional_response(p, "100 Trying", req, 0);
23757          p->invitestate = INV_PROCEEDING;
23758          ast_setstate(c, AST_STATE_RING);
23759          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
23760             enum ast_pbx_result result;
23761 
23762             result = ast_pbx_start(c);
23763 
23764             switch(result) {
23765             case AST_PBX_FAILED:
23766                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
23767                p->invitestate = INV_COMPLETED;
23768                transmit_response_reliable(p, "503 Unavailable", req);
23769                break;
23770             case AST_PBX_CALL_LIMIT:
23771                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
23772                p->invitestate = INV_COMPLETED;
23773                transmit_response_reliable(p, "480 Temporarily Unavailable", req);
23774                res = AUTH_SESSION_LIMIT;
23775                break;
23776             case AST_PBX_SUCCESS:
23777                /* nothing to do */
23778                break;
23779             }
23780 
23781             if (result) {
23782 
23783                /* Unlock locks so ast_hangup can do its magic */
23784                ast_channel_unlock(c);
23785                *nounlock = 1;
23786                sip_pvt_unlock(p);
23787                ast_hangup(c);
23788                sip_pvt_lock(p);
23789                c = NULL;
23790             }
23791          } else { /* Pickup call in call group */
23792             if (sip_pickup(c)) {
23793                ast_log(LOG_WARNING, "Failed to start Group pickup by %s\n", ast_channel_name(c));
23794                transmit_response_reliable(p, "480 Temporarily Unavailable", req);
23795                sip_alreadygone(p);
23796                c->hangupcause = AST_CAUSE_FAILURE;
23797 
23798                /* Unlock locks so ast_hangup can do its magic */
23799                ast_channel_unlock(c);
23800                *nounlock = 1;
23801 
23802                p->invitestate = INV_COMPLETED;
23803                sip_pvt_unlock(p);
23804                ast_hangup(c);
23805                sip_pvt_lock(p);
23806                c = NULL;
23807             }
23808          }
23809          break;
23810       case AST_STATE_RING:
23811          transmit_provisional_response(p, "100 Trying", req, 0);
23812          p->invitestate = INV_PROCEEDING;
23813          break;
23814       case AST_STATE_RINGING:
23815          transmit_provisional_response(p, "180 Ringing", req, 0);
23816          p->invitestate = INV_PROCEEDING;
23817          break;
23818       case AST_STATE_UP:
23819          ast_debug(2, "%s: This call is UP.... \n", ast_channel_name(c));
23820 
23821          transmit_response(p, "100 Trying", req);
23822 
23823          if (p->t38.state == T38_PEER_REINVITE) {
23824             if (p->t38id > -1) {
23825                /* reset t38 abort timer */
23826                AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "remove ref for t38id"));
23827             }
23828             p->t38id = ast_sched_add(sched, 5000, sip_t38_abort, dialog_ref(p, "passing dialog ptr into sched structure based on t38id for sip_t38_abort."));
23829          } else if (p->t38.state == T38_ENABLED) {
23830             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
23831             transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)));
23832          } else if ((p->t38.state == T38_DISABLED) || (p->t38.state == T38_REJECTED)) {
23833             /* If this is not a re-invite or something to ignore - it's critical */
23834             if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) {
23835                ast_log(LOG_WARNING, "Target does not support required crypto\n");
23836                transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req);
23837             } else {
23838                ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
23839                transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE);
23840                ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER);
23841             }
23842          }
23843 
23844          p->invitestate = INV_TERMINATED;
23845          break;
23846       default:
23847          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
23848          transmit_response(p, "100 Trying", req);
23849          break;
23850       }
23851    } else {
23852       if (p && (p->autokillid == -1)) {
23853          const char *msg;
23854 
23855          if ((ast_format_cap_is_empty(p->jointcaps)))
23856             msg = "488 Not Acceptable Here (codec error)";
23857          else {
23858             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
23859             msg = "503 Unavailable";
23860          }
23861          transmit_response_reliable(p, msg, req);
23862          p->invitestate = INV_COMPLETED;
23863          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23864       }
23865    }
23866 
23867 request_invite_cleanup:
23868 
23869    if (refer_locked && p->refer && p->refer->refer_call) {
23870       sip_pvt_unlock(p->refer->refer_call);
23871       if (p->refer->refer_call->owner) {
23872          ast_channel_unlock(p->refer->refer_call->owner);
23873       }
23874    }
23875    if (authpeer) {
23876       authpeer = sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_invite authpeer");
23877    }
23878 
23879    return res;
23880 }

static int handle_request_message ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr addr,
const char *  e 
) [static]

Handle incoming MESSAGE request.

Definition at line 24760 of file chan_sip.c.

References ast_verbose, receive_message(), and transmit_response().

Referenced by handle_incoming().

24761 {
24762    if (!req->ignore) {
24763       if (req->debug)
24764          ast_verbose("Receiving message!\n");
24765       receive_message(p, req, addr, e);
24766    } else
24767       transmit_response(p, "202 Accepted", req);
24768    return 1;
24769 }

static int handle_request_notify ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr addr,
uint32_t  seqno,
const char *  e 
) [static]

Handle incoming notifications.

Definition at line 22545 of file chan_sip.c.

References AST_CONTROL_TRANSFER, ast_debug, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_log(), ast_queue_control_data(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, FALSE, get_body(), get_msg_text(), handle_cc_notify(), LOG_NOTICE, LOG_WARNING, mailbox, sip_find_peer(), sip_get_header(), sip_scheddestroy(), sip_unref_peer(), strsep(), transmit_response(), and TRUE.

Referenced by handle_incoming().

22546 {
22547    /* This is mostly a skeleton for future improvements */
22548    /* Mostly created to return proper answers on notifications on outbound REFER's */
22549    int res = 0;
22550    const char *event = sip_get_header(req, "Event");
22551    char *sep;
22552 
22553    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
22554       *sep++ = '\0';
22555    }
22556 
22557    if (sipdebug)
22558       ast_debug(2, "Got NOTIFY Event: %s\n", event);
22559 
22560    if (!strcmp(event, "refer")) {
22561       /* Save nesting depth for now, since there might be other events we will
22562          support in the future */
22563 
22564       /* Handle REFER notifications */
22565 
22566       char buf[1024];
22567       char *cmd, *code;
22568       int respcode;
22569       int success = TRUE;
22570 
22571       /* EventID for each transfer... EventID is basically the REFER cseq
22572 
22573        We are getting notifications on a call that we transfered
22574        We should hangup when we are getting a 200 OK in a sipfrag
22575        Check if we have an owner of this event */
22576 
22577       /* Check the content type */
22578       if (strncasecmp(sip_get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
22579          /* We need a sipfrag */
22580          transmit_response(p, "400 Bad request", req);
22581          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22582          return -1;
22583       }
22584 
22585       /* Get the text of the attachment */
22586       if (get_msg_text(buf, sizeof(buf), req)) {
22587          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
22588          transmit_response(p, "400 Bad request", req);
22589          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22590          return -1;
22591       }
22592 
22593       /*
22594       From the RFC...
22595       A minimal, but complete, implementation can respond with a single
22596       NOTIFY containing either the body:
22597          SIP/2.0 100 Trying
22598       
22599       if the subscription is pending, the body:
22600          SIP/2.0 200 OK
22601       if the reference was successful, the body:
22602          SIP/2.0 503 Service Unavailable
22603       if the reference failed, or the body:
22604          SIP/2.0 603 Declined
22605 
22606       if the REFER request was accepted before approval to follow the
22607       reference could be obtained and that approval was subsequently denied
22608       (see Section 2.4.7).
22609       
22610       If there are several REFERs in the same dialog, we need to
22611       match the ID of the event header...
22612       */
22613       ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
22614       cmd = ast_skip_blanks(buf);
22615       code = cmd;
22616       /* We are at SIP/2.0 */
22617       while(*code && (*code > 32)) {   /* Search white space */
22618          code++;
22619       }
22620       *code++ = '\0';
22621       code = ast_skip_blanks(code);
22622       sep = code;
22623       sep++;
22624       while(*sep && (*sep > 32)) {  /* Search white space */
22625          sep++;
22626       }
22627       *sep++ = '\0';       /* Response string */
22628       respcode = atoi(code);
22629       switch (respcode) {
22630       case 200:   /* OK: The new call is up, hangup this call */
22631          /* Hangup the call that we are replacing */
22632          break;
22633       case 301: /* Moved permenantly */
22634       case 302: /* Moved temporarily */
22635          /* Do we get the header in the packet in this case? */
22636          success = FALSE;
22637          break;
22638       case 503:   /* Service Unavailable: The new call failed */
22639       case 603:   /* Declined: Not accepted */
22640             /* Cancel transfer, continue the current call */
22641          success = FALSE;
22642          break;
22643       case 0:     /* Parse error */
22644             /* Cancel transfer, continue the current call */
22645          ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n");
22646          success = FALSE;
22647          break;
22648       default:
22649          if (respcode < 200) {
22650             /* ignore provisional responses */
22651             success = -1;
22652          } else {
22653             ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode);
22654             success = FALSE;
22655          }
22656          break;
22657       }
22658       if (success == FALSE) {
22659          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
22660       }
22661 
22662       if (p->owner && success != -1) {
22663          enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED;
22664          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
22665       }
22666       /* Confirm that we received this packet */
22667       transmit_response(p, "200 OK", req);
22668    } else if (!strcmp(event, "message-summary")) {
22669       const char *mailbox = NULL;
22670       char *c = ast_strdupa(get_body(req, "Voice-Message", ':'));
22671 
22672       if (!p->mwi) {
22673          struct sip_peer *peer = sip_find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
22674 
22675          if (peer) {
22676             mailbox = ast_strdupa(peer->unsolicited_mailbox);
22677             sip_unref_peer(peer, "removing unsolicited mwi ref");
22678          }
22679       } else {
22680          mailbox = p->mwi->mailbox;
22681       }
22682 
22683       if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) {
22684          char *old = strsep(&c, " ");
22685          char *new = strsep(&old, "/");
22686          struct ast_event *event;
22687 
22688          if ((event = ast_event_new(AST_EVENT_MWI,
22689                      AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
22690                      AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "SIP_Remote",
22691                      AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(new),
22692                      AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(old),
22693                      AST_EVENT_IE_END))) {
22694             ast_event_queue_and_cache(event);
22695          }
22696          transmit_response(p, "200 OK", req);
22697       } else {
22698          transmit_response(p, "489 Bad event", req);
22699          res = -1;
22700       }
22701    } else if (!strcmp(event, "keep-alive")) {
22702        /* Used by Sipura/Linksys for NAT pinhole,
22703         * just confirm that we received the packet. */
22704       transmit_response(p, "200 OK", req);
22705    } else if (!strcmp(event, "call-completion")) {
22706       res = handle_cc_notify(p, req);
22707    } else {
22708       /* We don't understand this event. */
22709       transmit_response(p, "489 Bad event", req);
22710       res = -1;
22711    }
22712 
22713    if (!p->lastinvite)
22714       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22715 
22716    return res;
22717 }

static int handle_request_options ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr addr,
const char *  e 
) [static]

Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.

Definition at line 22722 of file chan_sip.c.

References ast_log(), ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), check_user(), context, copy_request(), get_destination(), LOG_NOTICE, set_pvt_allowed_methods(), sip_cfg, sip_get_header(), sip_scheddestroy(), transmit_fake_auth_response(), transmit_response(), and transmit_response_with_allow().

Referenced by handle_incoming().

22723 {
22724    const char *msg;
22725    enum sip_get_dest_result gotdest;
22726    int res;
22727 
22728    if (p->lastinvite) {
22729       /* if this is a request in an active dialog, just confirm that the dialog exists. */
22730       transmit_response_with_allow(p, "200 OK", req, 0);
22731       return 0;
22732    }
22733 
22734    if (sip_cfg.auth_options_requests) {
22735       /* Do authentication if this OPTIONS request began the dialog */
22736       copy_request(&p->initreq, req);
22737       set_pvt_allowed_methods(p, req);
22738       res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr);
22739       if (res == AUTH_CHALLENGE_SENT) {
22740          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22741          return 0;
22742       }
22743       if (res < 0) { /* Something failed in authentication */
22744          if (res == AUTH_FAKE_AUTH) {
22745             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
22746             transmit_fake_auth_response(p, SIP_OPTIONS, req, XMIT_UNRELIABLE);
22747          } else {
22748             ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
22749             transmit_response(p, "403 Forbidden", req);
22750          }
22751          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22752          return 0;
22753       }
22754    }
22755 
22756    /* must go through authentication before getting here */
22757    gotdest = get_destination(p, req, NULL);
22758    build_contact(p);
22759 
22760    if (ast_strlen_zero(p->context))
22761       ast_string_field_set(p, context, sip_cfg.default_context);
22762 
22763    if (ast_shutting_down()) {
22764       msg = "503 Unavailable";
22765    } else {
22766       msg = "404 Not Found";
22767       switch (gotdest) {
22768       case SIP_GET_DEST_INVALID_URI:
22769          msg = "416 Unsupported URI scheme";
22770          break;
22771       case SIP_GET_DEST_EXTEN_MATCHMORE:
22772       case SIP_GET_DEST_REFUSED:
22773       case SIP_GET_DEST_EXTEN_NOT_FOUND:
22774          //msg = "404 Not Found";
22775          break;
22776       case SIP_GET_DEST_EXTEN_FOUND:
22777          msg = "200 OK";
22778          break;
22779       }
22780    }
22781    transmit_response_with_allow(p, msg, req, 0);
22782 
22783    /* Destroy if this OPTIONS was the opening request, but not if
22784       it's in the middle of a normal call flow. */
22785    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22786 
22787    return 0;
22788 }

static int handle_request_publish ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr addr,
const uint32_t  seqno,
const char *  uri 
) [static]

Definition at line 25345 of file chan_sip.c.

References __sip_ack(), ast_log(), ast_string_field_set, ast_strlen_zero(), check_user(), determine_sip_publish_type(), get_esc(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), LOG_NOTICE, pvt_set_needdestroy(), sip_get_header(), sip_scheddestroy(), transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), and transmit_response_with_minexpires().

Referenced by handle_incoming().

25346 {
25347    const char *etag = sip_get_header(req, "SIP-If-Match");
25348    const char *event = sip_get_header(req, "Event");
25349    struct event_state_compositor *esc;
25350    enum sip_publish_type publish_type;
25351    const char *expires_str = sip_get_header(req, "Expires");
25352    int expires_int;
25353    int auth_result;
25354    int handler_result = -1;
25355 
25356    if (ast_strlen_zero(event)) {
25357       transmit_response(p, "489 Bad Event", req);
25358       pvt_set_needdestroy(p, "missing Event: header");
25359       return -1;
25360    }
25361 
25362    if (!(esc = get_esc(event))) {
25363       transmit_response(p, "489 Bad Event", req);
25364       pvt_set_needdestroy(p, "unknown event package in publish");
25365       return -1;
25366    }
25367 
25368    auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, addr);
25369    if (auth_result == AUTH_CHALLENGE_SENT) {
25370       p->lastinvite = seqno;
25371       return 0;
25372    } else if (auth_result < 0) {
25373       if (auth_result == AUTH_FAKE_AUTH) {
25374          ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
25375          transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
25376       } else {
25377          ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
25378          transmit_response_reliable(p, "403 Forbidden", req);
25379       }
25380       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
25381       ast_string_field_set(p, theirtag, NULL);
25382       return 0;
25383    } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) {
25384       /* We need to stop retransmitting the 401 */
25385       __sip_ack(p, p->lastinvite, 1, 0);
25386    }
25387 
25388    publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int);
25389 
25390    if (expires_int > max_expiry) {
25391       expires_int = max_expiry;
25392    } else if (expires_int < min_expiry && expires_int > 0) {
25393       transmit_response_with_minexpires(p, "423 Interval too small", req);
25394       pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
25395       return 0;
25396    }
25397    p->expiry = expires_int;
25398 
25399    /* It is the responsibility of these handlers to formulate any response
25400     * sent for a PUBLISH
25401     */
25402    switch (publish_type) {
25403    case SIP_PUBLISH_UNKNOWN:
25404       transmit_response(p, "400 Bad Request", req);
25405       break;
25406    case SIP_PUBLISH_INITIAL:
25407       handler_result = handle_sip_publish_initial(p, req, esc, expires_int);
25408       break;
25409    case SIP_PUBLISH_REFRESH:
25410       handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int);
25411       break;
25412    case SIP_PUBLISH_MODIFY:
25413       handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int);
25414       break;
25415    case SIP_PUBLISH_REMOVE:
25416       handler_result = handle_sip_publish_remove(p, req, esc, etag);
25417       break;
25418    default:
25419       transmit_response(p, "400 Impossible Condition", req);
25420       break;
25421    }
25422    if (!handler_result && p->expiry > 0) {
25423       sip_scheddestroy(p, (p->expiry + 10) * 1000);
25424    } else {
25425       pvt_set_needdestroy(p, "forcing expiration");
25426    }
25427 
25428    return handler_result;
25429 }

static int handle_request_refer ( struct sip_pvt *  p,
struct sip_request *  req,
int  debug,
uint32_t  seqno,
int *  nounlock 
) [static]

Chan1: Call between asterisk and transferer Chan2: Call between asterisk and transferee

Definition at line 24148 of file chan_sip.c.

References append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_lock, ast_channel_name(), ast_channel_ref, ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), AST_LIST_EMPTY, ast_manager_event_multichan, ast_parking_ext_valid(), ast_queue_control(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_sip_domain(), context, EVENT_FLAG_CALL, FALSE, get_refer_info(), local_attended_transfer(), pbx_builtin_setvar_helper(), pvt_set_needdestroy(), sip_alreadygone(), sip_cfg, sip_park(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by handle_incoming().

24149 {
24150    /*!
24151     * Chan1: Call between asterisk and transferer
24152     * Chan2: Call between asterisk and transferee
24153     */
24154    struct sip_dual current = { 0, };
24155    struct ast_channel *chans[2] = { 0, };
24156    char *refer_to = NULL;
24157    char *refer_to_domain = NULL;
24158    char *refer_to_context = NULL;
24159    char *referred_by = NULL;
24160    char *callid = NULL;
24161    int localtransfer = 0;
24162    int attendedtransfer = 0;
24163    int res = 0;
24164 
24165    if (req->debug) {
24166       ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n",
24167          p->callid,
24168          ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller");
24169    }
24170 
24171    if (!p->owner) {
24172       /* This is a REFER outside of an existing SIP dialog */
24173       /* We can't handle that, so decline it */
24174       ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
24175       transmit_response(p, "603 Declined (No dialog)", req);
24176       if (!req->ignore) {
24177          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
24178          sip_alreadygone(p);
24179          pvt_set_needdestroy(p, "outside of dialog");
24180       }
24181       res = 0;
24182       goto handle_refer_cleanup;
24183    }
24184 
24185    /* Check if transfer is allowed from this device */
24186    if (p->allowtransfer == TRANSFER_CLOSED ) {
24187       /* Transfer not allowed, decline */
24188       transmit_response(p, "603 Declined (policy)", req);
24189       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
24190       /* Do not destroy SIP session */
24191       res = 0;
24192       goto handle_refer_cleanup;
24193    }
24194 
24195    if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
24196       /* Already have a pending REFER */
24197       transmit_response(p, "491 Request pending", req);
24198       append_history(p, "Xfer", "Refer failed. Request pending.");
24199       res = 0;
24200       goto handle_refer_cleanup;
24201    }
24202 
24203    /* Allocate memory for call transfer data */
24204    if (!p->refer && !sip_refer_allocate(p)) {
24205       transmit_response(p, "500 Internal Server Error", req);
24206       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
24207       res = -3;
24208       goto handle_refer_cleanup;
24209    }
24210 
24211    res = get_refer_info(p, req); /* Extract headers */
24212 
24213    p->refer->status = REFER_SENT;
24214 
24215    if (res != 0) {
24216       switch (res) {
24217       case -2: /* Syntax error */
24218          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
24219          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
24220          if (req->debug) {
24221             ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n");
24222          }
24223          break;
24224       case -3:
24225          transmit_response(p, "603 Declined (Non sip: uri)", req);
24226          append_history(p, "Xfer", "Refer failed. Non SIP uri");
24227          if (req->debug) {
24228             ast_debug(1, "SIP transfer to non-SIP uri denied\n");
24229          }
24230          break;
24231       default:
24232          /* Refer-to extension not found, fake a failed transfer */
24233          transmit_response(p, "202 Accepted", req);
24234          append_history(p, "Xfer", "Refer failed. Bad extension.");
24235          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
24236          ast_clear_flag(&p->flags[0], SIP_GOTREFER);
24237          if (req->debug) {
24238             ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
24239          }
24240          break;
24241       }
24242       res = 0;
24243       goto handle_refer_cleanup;
24244    }
24245    if (ast_strlen_zero(p->context)) {
24246       ast_string_field_set(p, context, sip_cfg.default_context);
24247    }
24248 
24249    /* If we do not support SIP domains, all transfers are local */
24250    if (sip_cfg.allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
24251       p->refer->localtransfer = 1;
24252       if (sipdebug) {
24253          ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
24254       }
24255    } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
24256       /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
24257       p->refer->localtransfer = 1;
24258    } else if (sipdebug) {
24259       ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
24260    }
24261 
24262    /* Is this a repeat of a current request? Ignore it */
24263    /* Don't know what else to do right now. */
24264    if (req->ignore) {
24265       goto handle_refer_cleanup;
24266    }
24267 
24268    /* If this is a blind transfer, we have the following
24269    channels to work with:
24270    - chan1, chan2: The current call between transferer and transferee (2 channels)
24271    - target_channel: A new call from the transferee to the target (1 channel)
24272    We need to stay tuned to what happens in order to be able
24273    to bring back the call to the transferer */
24274 
24275    /* If this is a attended transfer, we should have all call legs within reach:
24276    - chan1, chan2: The call between the transferer and transferee (2 channels)
24277    - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
24278    We want to bridge chan2 with targetcall_pvt!
24279    
24280    The replaces call id in the refer message points
24281    to the call leg between Asterisk and the transferer.
24282    So we need to connect the target and the transferee channel
24283    and hangup the two other channels silently
24284    
24285    If the target is non-local, the call ID could be on a remote
24286    machine and we need to send an INVITE with replaces to the
24287    target. We basically handle this as a blind transfer
24288    and let the sip_call function catch that we need replaces
24289    header in the INVITE.
24290    */
24291 
24292    /* Get the transferer's channel */
24293    chans[0] = current.chan1 = p->owner;
24294 
24295    /* Find the other part of the bridge (2) - transferee */
24296    chans[1] = current.chan2 = ast_bridged_channel(current.chan1);
24297 
24298    ast_channel_ref(current.chan1);
24299    if (current.chan2) {
24300       ast_channel_ref(current.chan2);
24301    }
24302 
24303    if (sipdebug) {
24304       ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n",
24305          p->refer->attendedtransfer ? "attended" : "blind",
24306          ast_channel_name(current.chan1),
24307          current.chan2 ? ast_channel_name(current.chan2) : "<none>");
24308    }
24309 
24310    if (!current.chan2 && !p->refer->attendedtransfer) {
24311       /* No bridged channel, propably IVR or echo or similar... */
24312       /* Guess we should masquerade or something here */
24313       /* Until we figure it out, refuse transfer of such calls */
24314       if (sipdebug) {
24315          ast_debug(3, "Refused SIP transfer on non-bridged channel.\n");
24316       }
24317       p->refer->status = REFER_FAILED;
24318       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
24319       transmit_response(p, "603 Declined", req);
24320       res = -1;
24321       goto handle_refer_cleanup;
24322    }
24323 
24324    if (current.chan2) {
24325       if (sipdebug) {
24326          ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", ast_channel_name(current.chan2));
24327       }
24328       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
24329    }
24330 
24331    ast_set_flag(&p->flags[0], SIP_GOTREFER);
24332 
24333    /* From here on failures will be indicated with NOTIFY requests */
24334    transmit_response(p, "202 Accepted", req);
24335 
24336    /* Attended transfer: Find all call legs and bridge transferee with target*/
24337    if (p->refer->attendedtransfer) {
24338       /* both p and p->owner _MUST_ be locked while calling local_attended_transfer */
24339       if ((res = local_attended_transfer(p, &current, req, seqno, nounlock))) {
24340          goto handle_refer_cleanup; /* We're done with the transfer */
24341       }
24342       /* Fall through for remote transfers that we did not find locally */
24343       if (sipdebug) {
24344          ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
24345       }
24346       /* Fallthrough if we can't find the call leg internally */
24347    }
24348 
24349    /* Copy data we can not safely access after letting the pvt lock go. */
24350    refer_to = ast_strdupa(p->refer->refer_to);
24351    refer_to_domain = ast_strdupa(p->refer->refer_to_domain);
24352    refer_to_context = ast_strdupa(p->refer->refer_to_context);
24353    referred_by = ast_strdupa(p->refer->referred_by);
24354    callid = ast_strdupa(p->callid);
24355    localtransfer = p->refer->localtransfer;
24356    attendedtransfer = p->refer->attendedtransfer;
24357 
24358    if (!*nounlock) {
24359       ast_channel_unlock(p->owner);
24360       *nounlock = 1;
24361    }
24362    sip_pvt_unlock(p);
24363 
24364    /* Parking a call.  DO NOT hold any locks while calling ast_parking_ext_valid() */
24365    if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, current.chan1->context)) {
24366       sip_pvt_lock(p);
24367       ast_clear_flag(&p->flags[0], SIP_GOTREFER);
24368       p->refer->status = REFER_200OK;
24369       append_history(p, "Xfer", "REFER to call parking.");
24370       sip_pvt_unlock(p);
24371 
24372       ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans,
24373          "TransferMethod: SIP\r\n"
24374          "TransferType: Blind\r\n"
24375          "Channel: %s\r\n"
24376          "Uniqueid: %s\r\n"
24377          "SIP-Callid: %s\r\n"
24378          "TargetChannel: %s\r\n"
24379          "TargetUniqueid: %s\r\n"
24380          "TransferExten: %s\r\n"
24381          "Transfer2Parking: Yes\r\n",
24382          ast_channel_name(current.chan1),
24383          ast_channel_uniqueid(current.chan1),
24384          callid,
24385          ast_channel_name(current.chan2),
24386          ast_channel_uniqueid(current.chan2),
24387          refer_to);
24388 
24389       if (sipdebug) {
24390          ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", ast_channel_name(current.chan2), ast_channel_name(current.chan1));
24391       }
24392 
24393       /* DO NOT hold any locks while calling sip_park */
24394       if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, current.chan1->context)) {
24395          sip_pvt_lock(p);
24396          transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE);
24397       } else {
24398          sip_pvt_lock(p);
24399       }
24400       goto handle_refer_cleanup;
24401    }
24402 
24403    /* Blind transfers and remote attended xfers.
24404     * Locks should not be held while calling pbx_builtin_setvar_helper. This function
24405     * locks the channel being passed into it.*/
24406    if (current.chan1 && current.chan2) {
24407       ast_debug(3, "chan1->name: %s\n", ast_channel_name(current.chan1));
24408       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", ast_channel_name(current.chan2));
24409    }
24410 
24411    if (current.chan2) {
24412       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", ast_channel_name(current.chan1));
24413       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", refer_to_domain);
24414       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
24415       /* One for the new channel */
24416       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
24417       /* Attended transfer to remote host, prepare headers for the INVITE */
24418       if (!ast_strlen_zero(referred_by)) {
24419          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", referred_by);
24420       }
24421    }
24422 
24423    sip_pvt_lock(p);
24424    /* Generate a Replaces string to be used in the INVITE during attended transfer */
24425    if (!ast_strlen_zero(p->refer->replaces_callid)) {
24426       char tempheader[SIPBUFSIZE];
24427       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid,
24428          p->refer->replaces_callid_totag ? ";to-tag=" : "",
24429          p->refer->replaces_callid_totag,
24430          p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
24431          p->refer->replaces_callid_fromtag);
24432 
24433       if (current.chan2) {
24434          sip_pvt_unlock(p);
24435          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
24436          sip_pvt_lock(p);
24437       }
24438    }
24439 
24440    /* Connect the call */
24441 
24442    /* FAKE ringing if not attended transfer */
24443    if (!p->refer->attendedtransfer) {
24444       transmit_notify_with_sipfrag(p, seqno, "180 Ringing", FALSE);
24445    }
24446 
24447    /* For blind transfer, this will lead to a new call */
24448    /* For attended transfer to remote host, this will lead to
24449       a new SIP call with a replaces header, if the dial plan allows it
24450    */
24451    if (!current.chan2) {
24452       /* We have no bridge, so we're talking with Asterisk somehow */
24453       /* We need to masquerade this call */
24454       /* What to do to fix this situation:
24455          * Set up the new call in a new channel
24456          * Let the new channel masq into this channel
24457          Please add that code here :-)
24458       */
24459       p->refer->status = REFER_FAILED;
24460       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
24461       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
24462       append_history(p, "Xfer", "Refer failed (only bridged calls).");
24463       res = -1;
24464       goto handle_refer_cleanup;
24465    }
24466    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
24467 
24468    /* Do not hold the pvt lock during the indicate and async_goto. Those functions
24469     * lock channels which will invalidate locking order if the pvt lock is held.*/
24470    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
24471     * servers - generate an INVITE with Replaces. Either way, let the dial plan decided
24472     * indicate before masquerade so the indication actually makes it to the real channel
24473     * when using local channels with MOH passthru */
24474    sip_pvt_unlock(p);
24475    ast_indicate(current.chan2, AST_CONTROL_UNHOLD);
24476    res = ast_async_goto(current.chan2, refer_to_context, refer_to, 1);
24477 
24478    if (!res) {
24479       ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans,
24480          "TransferMethod: SIP\r\n"
24481          "TransferType: Blind\r\n"
24482          "Channel: %s\r\n"
24483          "Uniqueid: %s\r\n"
24484          "SIP-Callid: %s\r\n"
24485          "TargetChannel: %s\r\n"
24486          "TargetUniqueid: %s\r\n"
24487          "TransferExten: %s\r\n"
24488          "TransferContext: %s\r\n",
24489          ast_channel_name(current.chan1),
24490          ast_channel_uniqueid(current.chan1),
24491          callid,
24492          ast_channel_name(current.chan2),
24493          ast_channel_uniqueid(current.chan2),
24494          refer_to,
24495          refer_to_context);
24496       /* Success  - we have a new channel */
24497       ast_debug(3, "%s transfer succeeded. Telling transferer.\n", attendedtransfer? "Attended" : "Blind");
24498 
24499       /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */
24500       ast_channel_lock(current.chan1);
24501       ast_cel_report_event(current.chan1, p->refer->attendedtransfer? AST_CEL_ATTENDEDTRANSFER : AST_CEL_BLINDTRANSFER, NULL, p->refer->attendedtransfer ? NULL : p->refer->refer_to, current.chan2);
24502       ast_channel_unlock(current.chan1);
24503 
24504       sip_pvt_lock(p);
24505       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
24506       if (p->refer->localtransfer) {
24507          p->refer->status = REFER_200OK;
24508       }
24509       if (p->owner) {
24510          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
24511       }
24512       append_history(p, "Xfer", "Refer succeeded.");
24513       ast_clear_flag(&p->flags[0], SIP_GOTREFER);
24514       /* Do not hangup call, the other side do that when we say 200 OK */
24515       /* We could possibly implement a timer here, auto congestion */
24516       res = 0;
24517    } else {
24518       sip_pvt_lock(p);
24519       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
24520       ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
24521       append_history(p, "Xfer", "Refer failed.");
24522       /* Failure of some kind */
24523       p->refer->status = REFER_FAILED;
24524       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
24525       ast_clear_flag(&p->flags[0], SIP_GOTREFER);
24526       res = -1;
24527    }
24528 
24529 handle_refer_cleanup:
24530    if (current.chan1) {
24531       ast_channel_unref(current.chan1);
24532    }
24533    if (current.chan2) {
24534       ast_channel_unref(current.chan2);
24535    }
24536 
24537    /* Make sure we exit with the pvt locked */
24538    return res;
24539 }

static int handle_request_register ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr sin,
const char *  e 
) [static]

Handle incoming REGISTER request.

Definition at line 25899 of file chan_sip.c.

References append_history, ast_debug, ast_log(), ast_sockaddr_stringify(), check_via(), copy_request(), LOG_NOTICE, LOG_WARNING, register_verify(), sip_get_header(), sip_methods, sip_scheddestroy(), and cfsip_methods::text.

Referenced by handle_incoming().

25900 {
25901    enum check_auth_result res;
25902 
25903    /* If this is not the intial request, and the initial request isn't
25904     * a register, something screwy happened, so bail */
25905    if (p->initreq.headers && p->initreq.method != SIP_REGISTER) {
25906       ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid);
25907       return -1;
25908    }
25909 
25910    /* Use this as the basis */
25911    copy_request(&p->initreq, req);
25912    if (sipdebug)
25913       ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
25914    check_via(p, req);
25915 
25916    if ((res = register_verify(p, addr, req, e)) < 0) {
25917       const char *reason;
25918 
25919       switch (res) {
25920       case AUTH_SECRET_FAILED:
25921          reason = "Wrong password";
25922          break;
25923       case AUTH_USERNAME_MISMATCH:
25924          reason = "Username/auth name mismatch";
25925          break;
25926       case AUTH_NOT_FOUND:
25927          reason = "No matching peer found";
25928          break;
25929       case AUTH_UNKNOWN_DOMAIN:
25930          reason = "Not a local domain";
25931          break;
25932       case AUTH_PEER_NOT_DYNAMIC:
25933          reason = "Peer is not supposed to register";
25934          break;
25935       case AUTH_ACL_FAILED:
25936          reason = "Device does not match ACL";
25937          break;
25938       case AUTH_BAD_TRANSPORT:
25939          reason = "Device not configured to use this transport type";
25940          break;
25941       case AUTH_RTP_FAILED:
25942          reason = "RTP initialization failed";
25943          break;
25944       default:
25945          reason = "Unknown failure";
25946          break;
25947       }
25948       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
25949          sip_get_header(req, "To"), ast_sockaddr_stringify(addr),
25950          reason);
25951       append_history(p, "RegRequest", "Failed : Account %s : %s", sip_get_header(req, "To"), reason);
25952    } else {
25953       req->authenticated = 1;
25954       append_history(p, "RegRequest", "Succeeded : Account %s", sip_get_header(req, "To"));
25955    }
25956 
25957    if (res != AUTH_CHALLENGE_SENT) {
25958       /* Destroy the session, but keep us around for just a bit in case they don't
25959          get our 200 OK */
25960       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
25961    }
25962 
25963    return res;
25964 }

static int handle_request_subscribe ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr addr,
uint32_t  seqno,
const char *  e 
) [static]

Handle incoming SUBSCRIBE request.

Definition at line 25512 of file chan_sip.c.

References __get_header(), add_peer_mwi_subs(), ao2_lock, ao2_unlock, append_history, ast_debug, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add_destroy(), ast_extension_state_del(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_stringify(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose, build_contact(), build_route(), cb_extensionstate(), cb_extensionstate_destroy(), check_user_full(), check_via(), copy_request(), dialog_unlink_all(), FALSE, get_destination(), gettag(), handle_cc_subscribe(), LOG_NOTICE, LOG_WARNING, make_our_tag(), NONE, option_debug, parse_ok_contact(), pvt_set_needdestroy(), S_OR, set_pvt_allowed_methods(), sip_cancel_destroy(), sip_cfg, sip_get_header(), sip_methods, sip_ref_peer(), sip_scheddestroy(), sip_send_mwi_to_peer(), sip_unref_peer(), cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minexpires(), and transmit_state_notify().

Referenced by handle_incoming().

25513 {
25514    int gotdest = 0;
25515    int res = 0;
25516    int firststate;
25517    struct sip_peer *authpeer = NULL;
25518    const char *eventheader = sip_get_header(req, "Event");  /* Get Event package name */
25519    int resubscribe = (p->subscribed != NONE) && !req->ignore;
25520    char *temp, *event;
25521 
25522    if (p->initreq.headers) {
25523       /* We already have a dialog */
25524       if (p->initreq.method != SIP_SUBSCRIBE) {
25525          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
25526          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
25527          transmit_response(p, "403 Forbidden (within dialog)", req);
25528          /* Do not destroy session, since we will break the call if we do */
25529          ast_debug(1, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text);
25530          return 0;
25531       } else if (req->debug) {
25532          if (resubscribe)
25533             ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid);
25534          else
25535             ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid);
25536       }
25537    }
25538 
25539    /* Check if we have a global disallow setting on subscriptions.
25540       if so, we don't have to check peer settings after auth, which saves a lot of processing
25541    */
25542    if (!sip_cfg.allowsubscribe) {
25543       transmit_response(p, "403 Forbidden (policy)", req);
25544       pvt_set_needdestroy(p, "forbidden");
25545       return 0;
25546    }
25547 
25548    if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */
25549       const char *to = sip_get_header(req, "To");
25550       char totag[128];
25551       set_pvt_allowed_methods(p, req);
25552 
25553       /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
25554       if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
25555          if (req->debug)
25556             ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
25557          transmit_response(p, "481 Subscription does not exist", req);
25558          pvt_set_needdestroy(p, "subscription does not exist");
25559          return 0;
25560       }
25561 
25562       /* Use this as the basis */
25563       if (req->debug)
25564          ast_verbose("Creating new subscription\n");
25565 
25566       copy_request(&p->initreq, req);
25567       if (sipdebug)
25568          ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
25569       check_via(p, req);
25570       build_route(p, req, 0);
25571    } else if (req->debug && req->ignore)
25572       ast_verbose("Ignoring this SUBSCRIBE request\n");
25573 
25574    /* Find parameters to Event: header value and remove them for now */
25575    if (ast_strlen_zero(eventheader)) {
25576       transmit_response(p, "489 Bad Event", req);
25577       ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n");
25578       pvt_set_needdestroy(p, "unknown event package in subscribe");
25579       return 0;
25580    }
25581 
25582    if ( (strchr(eventheader, ';'))) {
25583       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
25584       temp = strchr(event, ';');
25585       *temp = '\0';           /* Remove any options for now */
25586                      /* We might need to use them later :-) */
25587    } else
25588       event = (char *) eventheader;    /* XXX is this legal ? */
25589 
25590    /* Handle authentication if we're new and not a retransmission. We can't just
25591     * use if !req->ignore, because then we'll end up sending
25592     * a 200 OK if someone retransmits without sending auth */
25593    if (p->subscribed == NONE || resubscribe) {
25594       res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, addr, &authpeer);
25595 
25596       /* if an authentication response was sent, we are done here */
25597       if (res == AUTH_CHALLENGE_SENT)  /* authpeer = NULL here */
25598          return 0;
25599       if (res != AUTH_SUCCESSFUL) {
25600          if (res == AUTH_FAKE_AUTH) {
25601             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
25602             transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
25603          } else {
25604             ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", sip_get_header(req, "From"));
25605             transmit_response_reliable(p, "403 Forbidden", req);
25606          }
25607 
25608          pvt_set_needdestroy(p, "authentication failed");
25609          return 0;
25610       }
25611    }
25612 
25613    /* At this point, we hold a reference to authpeer (if not NULL).  It
25614     * must be released when done.
25615     */
25616 
25617    /* Check if this device  is allowed to subscribe at all */
25618    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
25619       transmit_response(p, "403 Forbidden (policy)", req);
25620       pvt_set_needdestroy(p, "subscription not allowed");
25621       if (authpeer) {
25622          sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 1)");
25623       }
25624       return 0;
25625    }
25626 
25627    if (strcmp(event, "message-summary") && strcmp(event, "call-completion")) {
25628       /* Get destination right away */
25629       gotdest = get_destination(p, NULL, NULL);
25630    }
25631 
25632    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
25633    parse_ok_contact(p, req);
25634 
25635    build_contact(p);
25636    if (gotdest != SIP_GET_DEST_EXTEN_FOUND) {
25637       if (gotdest == SIP_GET_DEST_INVALID_URI) {
25638          transmit_response(p, "416 Unsupported URI scheme", req);
25639       } else {
25640          transmit_response(p, "404 Not Found", req);
25641       }
25642       pvt_set_needdestroy(p, "subscription target not found");
25643       if (authpeer) {
25644          sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
25645       }
25646       return 0;
25647    }
25648 
25649    /* Initialize tag for new subscriptions */   
25650    if (ast_strlen_zero(p->tag))
25651       make_our_tag(p->tag, sizeof(p->tag));
25652 
25653    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
25654       unsigned int pidf_xml;
25655       const char *accept;
25656       int start = 0;
25657       enum subscriptiontype subscribed = NONE;
25658       const char *unknown_acceptheader = NULL;
25659 
25660       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
25661       accept = __get_header(req, "Accept", &start);
25662       while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
25663          pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0;
25664 
25665          /* Older versions of Polycom firmware will claim pidf+xml, but really
25666           * they only support xpidf+xml. */
25667          if (pidf_xml && strstr(p->useragent, "Polycom")) {
25668             subscribed = XPIDF_XML;
25669          } else if (pidf_xml) {
25670             subscribed = PIDF_XML;         /* RFC 3863 format */
25671          } else if (strstr(accept, "application/dialog-info+xml")) {
25672             subscribed = DIALOG_INFO_XML;
25673             /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
25674          } else if (strstr(accept, "application/cpim-pidf+xml")) {
25675             subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
25676          } else if (strstr(accept, "application/xpidf+xml")) {
25677             subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
25678          } else {
25679             unknown_acceptheader = accept;
25680          }
25681          /* check to see if there is another Accept header present */
25682          accept = __get_header(req, "Accept", &start);
25683       }
25684 
25685       if (!start) {
25686          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
25687             transmit_response(p, "489 Bad Event", req);
25688             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: "
25689                "stateid: %d, laststate: %d, dialogver: %u, subscribecont: "
25690                "'%s', subscribeuri: '%s'\n",
25691                p->stateid,
25692                p->laststate,
25693                p->dialogver,
25694                p->subscribecontext,
25695                p->subscribeuri);
25696             pvt_set_needdestroy(p, "no Accept header");
25697             if (authpeer) {
25698                sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
25699             }
25700             return 0;
25701          }
25702          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
25703             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
25704       } else if (subscribed == NONE) {
25705          /* Can't find a format for events that we know about */
25706          char mybuf[200];
25707          if (!ast_strlen_zero(unknown_acceptheader)) {
25708             snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader);
25709          } else {
25710             snprintf(mybuf, sizeof(mybuf), "489 Bad Event");
25711          }
25712          transmit_response(p, mybuf, req);
25713          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:"
25714             "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d,"
25715             "dialogver: %u, subscribecont: '%s', subscribeuri: '%s'\n",
25716             unknown_acceptheader,
25717             (int)p->subscribed,
25718             p->stateid,
25719             p->laststate,
25720             p->dialogver,
25721             p->subscribecontext,
25722             p->subscribeuri);
25723          pvt_set_needdestroy(p, "unrecognized format");
25724          if (authpeer) {
25725             sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
25726          }
25727          return 0;
25728       } else {
25729          p->subscribed = subscribed;
25730       }
25731    } else if (!strcmp(event, "message-summary")) {
25732       int start = 0;
25733       int found_supported = 0;
25734       const char *acceptheader;
25735 
25736       acceptheader = __get_header(req, "Accept", &start);
25737       while (!found_supported && !ast_strlen_zero(acceptheader)) {
25738          found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1;
25739          if (!found_supported && (option_debug > 2)) {
25740             ast_debug(1, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
25741          }
25742          acceptheader = __get_header(req, "Accept", &start);
25743       }
25744       if (start && !found_supported) {
25745          /* Format requested that we do not support */
25746          transmit_response(p, "406 Not Acceptable", req);
25747          ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
25748          pvt_set_needdestroy(p, "unknown format");
25749          if (authpeer) {
25750             sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 3)");
25751          }
25752          return 0;
25753       }
25754       /* Looks like they actually want a mailbox status
25755         This version of Asterisk supports mailbox subscriptions
25756         The subscribed URI needs to exist in the dial plan
25757         In most devices, this is configurable to the voicemailmain extension you use
25758       */
25759       if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) {
25760          if (!authpeer) {
25761             transmit_response(p, "404 Not found", req);
25762          } else {
25763             transmit_response(p, "404 Not found (no mailbox)", req);
25764             ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, ""));
25765          }
25766          pvt_set_needdestroy(p, "received 404 response");
25767 
25768          if (authpeer) {
25769             sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 3)");
25770          }
25771          return 0;
25772       }
25773 
25774       p->subscribed = MWI_NOTIFICATION;
25775       if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) {
25776          ao2_unlock(p);
25777          add_peer_mwi_subs(authpeer);
25778          ao2_lock(p);
25779       }
25780       if (authpeer->mwipvt != p) {  /* Destroy old PVT if this is a new one */
25781          /* We only allow one subscription per peer */
25782          if (authpeer->mwipvt) {
25783             dialog_unlink_all(authpeer->mwipvt);
25784             authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
25785          }
25786          authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");
25787       }
25788 
25789       if (p->relatedpeer != authpeer) {
25790          if (p->relatedpeer) {
25791             sip_unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
25792          }
25793          p->relatedpeer = sip_ref_peer(authpeer, "setting dialog's relatedpeer pointer");
25794       }
25795       /* Do not release authpeer here */
25796    } else if (!strcmp(event, "call-completion")) {
25797       handle_cc_subscribe(p, req);
25798    } else { /* At this point, Asterisk does not understand the specified event */
25799       transmit_response(p, "489 Bad Event", req);
25800       ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event);
25801       pvt_set_needdestroy(p, "unknown event package");
25802       if (authpeer) {
25803          sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 5)");
25804       }
25805       return 0;
25806    }
25807 
25808    /* Add subscription for extension state from the PBX core */
25809    if (p->subscribed != MWI_NOTIFICATION  && p->subscribed != CALL_COMPLETION && !resubscribe) {
25810       if (p->stateid != -1) {
25811          ast_extension_state_del(p->stateid, cb_extensionstate);
25812       }
25813       dialog_ref(p, "copying dialog ptr into extension state struct");
25814       p->stateid = ast_extension_state_add_destroy(p->context, p->exten,
25815          cb_extensionstate, cb_extensionstate_destroy, p);
25816       if (p->stateid == -1) {
25817          dialog_unref(p, "copying dialog ptr into extension state struct failed");
25818       }
25819    }
25820 
25821    if (!req->ignore && p)
25822       p->lastinvite = seqno;
25823    if (p && !p->needdestroy) {
25824       p->expiry = atoi(sip_get_header(req, "Expires"));
25825 
25826       /* check if the requested expiry-time is within the approved limits from sip.conf */
25827       if (p->expiry > max_expiry) {
25828          p->expiry = max_expiry;
25829       } else if (p->expiry < min_expiry && p->expiry > 0) {
25830          transmit_response_with_minexpires(p, "423 Interval too small", req);
25831          ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" "
25832             "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n",
25833             p->exten, p->context, p->expiry, min_expiry);
25834          pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
25835          if (authpeer) {
25836             sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 6)");
25837          }
25838          return 0;
25839       }
25840 
25841       if (sipdebug) {
25842          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) {
25843             ast_debug(2, "Adding subscription for mailbox notification - peer %s\n", p->relatedpeer->name);
25844          } else if (p->subscribed == CALL_COMPLETION) {
25845             ast_debug(2, "Adding CC subscription for peer %s\n", p->username);
25846          } else {
25847             ast_debug(2, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
25848          }
25849       }
25850       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
25851          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
25852       if (p->expiry > 0)
25853          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
25854 
25855       if (p->subscribed == MWI_NOTIFICATION) {
25856          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
25857          transmit_response(p, "200 OK", req);
25858          if (p->relatedpeer) {   /* Send first notification */
25859             struct sip_peer *peer = p->relatedpeer;
25860             sip_ref_peer(peer, "ensure a peer ref is held during MWI sending");
25861             ao2_unlock(p);
25862             sip_send_mwi_to_peer(peer, 0);
25863             ao2_lock(p);
25864             sip_unref_peer(peer, "release a peer ref now that MWI is sent");
25865          }
25866       } else if (p->subscribed != CALL_COMPLETION) {
25867 
25868          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
25869 
25870             ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_sockaddr_stringify(&p->sa));
25871             transmit_response(p, "404 Not found", req);
25872             pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
25873             if (authpeer) {
25874                sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 6)");
25875             }
25876             return 0;
25877          }
25878          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
25879          transmit_response(p, "200 OK", req);
25880          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
25881          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
25882          /* hide the 'complete' exten/context in the refer_to field for later display */
25883          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
25884          /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */
25885 
25886       }
25887       if (!p->expiry) {
25888          pvt_set_needdestroy(p, "forcing expiration");
25889       }
25890    }
25891 
25892    if (authpeer) {
25893       sip_unref_peer(authpeer, "unref pointer into (*authpeer)");
25894    }
25895    return 1;
25896 }

static int handle_request_update ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

bare-bones support for SIP UPDATE

XXX This is not even close to being RFC 3311-compliant. We don't advertise that we support the UPDATE method, so no one should ever try sending us an UPDATE anyway. However, Asterisk can send an UPDATE to change connected line information, so we need to be prepared to handle this. The way we distinguish such an UPDATE is through the X-Asterisk-rpid-update header.

Actually updating the media session may be some future work.

Definition at line 22980 of file chan_sip.c.

References ast_channel_queue_connected_line_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_init(), ast_strlen_zero(), connected, get_rpid(), ast_party_connected_line::id, ast_set_party_connected_line::id, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, ast_party_name::presentation, ast_party_number::presentation, sip_get_header(), ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, transmit_response(), ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_incoming().

22981 {
22982    if (ast_strlen_zero(sip_get_header(req, "X-Asterisk-rpid-update"))) {
22983       transmit_response(p, "501 Method Not Implemented", req);
22984       return 0;
22985    }
22986    if (get_rpid(p, req)) {
22987       struct ast_party_connected_line connected;
22988       struct ast_set_party_connected_line update_connected;
22989 
22990       ast_party_connected_line_init(&connected);
22991       memset(&update_connected, 0, sizeof(update_connected));
22992 
22993       update_connected.id.number = 1;
22994       connected.id.number.valid = 1;
22995       connected.id.number.str = (char *) p->cid_num;
22996       connected.id.number.presentation = p->callingpres;
22997 
22998       update_connected.id.name = 1;
22999       connected.id.name.valid = 1;
23000       connected.id.name.str = (char *) p->cid_name;
23001       connected.id.name.presentation = p->callingpres;
23002 
23003       connected.id.tag = (char *) p->cid_tag;
23004       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
23005       ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
23006    }
23007    transmit_response(p, "200 OK", req);
23008    return 0;
23009 }

static void handle_response ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Handle SIP response in dialogue.

Note:
only called by handle_incoming

Definition at line 21748 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, AST_CC_CCBS, ast_channel_name(), ast_channel_set_redirecting(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_debug, ast_log(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_hangup_with_cause(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, change_redirecting_information(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), gettag(), handle_response_info(), handle_response_invite(), handle_response_message(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), hangup_sip2cause(), ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), process_sdp(), pvt_set_needdestroy(), rh, sip_alreadygone(), sip_cancel_destroy(), sip_get_header(), sip_handle_cc(), sip_methods, stop_media_flows(), text, transmit_request(), TRUE, and update_redirecting().

21749 {
21750    struct ast_channel *owner;
21751    int sipmethod;
21752    const char *c = sip_get_header(req, "Cseq");
21753    /* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */
21754    char *c_copy = ast_strdupa(c);
21755    /* Skip the Cseq and its subsequent spaces */
21756    const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
21757 
21758    if (!msg)
21759       msg = "";
21760 
21761    sipmethod = find_sip_method(msg);
21762 
21763    owner = p->owner;
21764    if (owner) {
21765       const char *rp = NULL, *rh = NULL;
21766 
21767       owner->hangupcause = 0;
21768       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && (rh = sip_get_header(req, "Reason"))) {
21769          rh = ast_skip_blanks(rh);
21770          if (!strncasecmp(rh, "Q.850", 5)) {
21771             rp = strstr(rh, "cause=");
21772             if (rp && sscanf(rp + 6, "%30d", &owner->hangupcause) == 1) {
21773                owner->hangupcause &= 0x7f;
21774                if (req->debug)
21775                   ast_verbose("Using Reason header for cause code: %d\n", owner->hangupcause);
21776             }
21777          }
21778       }
21779 
21780       if (!owner->hangupcause)
21781          owner->hangupcause = hangup_sip2cause(resp);
21782    }
21783 
21784    if (p->socket.type == SIP_TRANSPORT_UDP) {
21785       int ack_res = FALSE;
21786 
21787       /* Acknowledge whatever it is destined for */
21788       if ((resp >= 100) && (resp <= 199)) {
21789          /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */
21790          if (sipmethod == SIP_INVITE) {
21791             ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
21792          }
21793       } else {
21794          ack_res = __sip_ack(p, seqno, 0, sipmethod);
21795       }
21796 
21797       if (ack_res == FALSE) {
21798          /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */
21799          if (sipmethod == SIP_INVITE && resp >= 200) {
21800             transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE);
21801          }
21802 
21803          append_history(p, "Ignore", "Ignoring this retransmit\n");
21804          return;
21805       }
21806    }
21807 
21808    /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
21809    if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite)
21810       p->pendinginvite = 0;
21811 
21812    /* Get their tag if we haven't already */
21813    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
21814       char tag[128];
21815 
21816       gettag(req, "To", tag, sizeof(tag));
21817       ast_string_field_set(p, theirtag, tag);
21818    }
21819    /* This needs to be configurable on a channel/peer level,
21820       not mandatory for all communication. Sadly enough, NAT implementations
21821       are not so stable so we can always rely on these headers.
21822       Temporarily disabled, while waiting for fix.
21823       Fix assigned to Rizzo :-)
21824    */
21825    /* check_via_response(p, req); */
21826 
21827    /* RFC 3261 Section 15 specifies that if we receive a 408 or 481
21828     * in response to a BYE, then we should end the current dialog
21829     * and session.  It is known that at least one phone manufacturer
21830     * potentially will send a 404 in response to a BYE, so we'll be
21831     * liberal in what we accept and end the dialog and session if we
21832     * receive any of those responses to a BYE.
21833     */
21834    if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) {
21835       pvt_set_needdestroy(p, "received 4XX response to a BYE");
21836       return;
21837    }
21838 
21839    if (p->relatedpeer && sipmethod == SIP_OPTIONS) {
21840       /* We don't really care what the response is, just that it replied back.
21841          Well, as long as it's not a 100 response...  since we might
21842          need to hang around for something more "definitive" */
21843       if (resp != 100)
21844          handle_response_peerpoke(p, resp, req);
21845    } else if (sipmethod == SIP_REFER && resp >= 200) {
21846       handle_response_refer(p, resp, rest, req, seqno);
21847    } else if (sipmethod == SIP_PUBLISH) {
21848       /* SIP PUBLISH transcends this morass of doodoo and instead
21849        * we just always call the response handler. Good gravy!
21850        */
21851       handle_response_publish(p, resp, rest, req, seqno);
21852    } else if (sipmethod == SIP_INFO) {
21853       /* More good gravy! */
21854       handle_response_info(p, resp, rest, req, seqno);
21855    } else if (sipmethod == SIP_MESSAGE) {
21856       /* More good gravy! */
21857       handle_response_message(p, resp, rest, req, seqno);
21858    } else if (sipmethod == SIP_NOTIFY) {
21859       /* The gravy train continues to roll */
21860       handle_response_notify(p, resp, rest, req, seqno);
21861    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
21862       switch(resp) {
21863       case 100:   /* 100 Trying */
21864       case 101:   /* 101 Dialog establishment */
21865       case 183:   /* 183 Session Progress */
21866       case 180:   /* 180 Ringing */
21867       case 182:   /* 182 Queued */
21868       case 181:   /* 181 Call Is Being Forwarded */
21869          if (sipmethod == SIP_INVITE)
21870             handle_response_invite(p, resp, rest, req, seqno);
21871          break;
21872       case 200:   /* 200 OK */
21873          p->authtries = 0; /* Reset authentication counter */
21874          if (sipmethod == SIP_INVITE) {
21875             handle_response_invite(p, resp, rest, req, seqno);
21876          } else if (sipmethod == SIP_REGISTER) {
21877             handle_response_register(p, resp, rest, req, seqno);
21878          } else if (sipmethod == SIP_SUBSCRIBE) {
21879             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21880             handle_response_subscribe(p, resp, rest, req, seqno);
21881          } else if (sipmethod == SIP_BYE) {     /* Ok, we're ready to go */
21882             pvt_set_needdestroy(p, "received 200 response");
21883             ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21884          }
21885          break;
21886       case 401: /* Not www-authorized on SIP method */
21887       case 407: /* Proxy auth required */
21888          if (sipmethod == SIP_INVITE)
21889             handle_response_invite(p, resp, rest, req, seqno);
21890          else if (sipmethod == SIP_SUBSCRIBE)
21891             handle_response_subscribe(p, resp, rest, req, seqno);
21892          else if (p->registry && sipmethod == SIP_REGISTER)
21893             handle_response_register(p, resp, rest, req, seqno);
21894          else if (sipmethod == SIP_UPDATE) {
21895             handle_response_update(p, resp, rest, req, seqno);
21896          } else if (sipmethod == SIP_BYE) {
21897             if (p->options)
21898                p->options->auth_type = resp;
21899             if (ast_strlen_zero(p->authname)) {
21900                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n",
21901                      msg, ast_sockaddr_stringify(&p->recv));
21902                pvt_set_needdestroy(p, "unable to authenticate BYE");
21903             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp,  sipmethod, 0)) {
21904                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, sip_get_header(&p->initreq, "From"));
21905                pvt_set_needdestroy(p, "failed to authenticate BYE");
21906             }
21907          } else {
21908             ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, sip_get_header(req, "To"));
21909             pvt_set_needdestroy(p, "received 407 response");
21910          }
21911          break;
21912       case 403: /* Forbidden - we failed authentication */
21913          if (sipmethod == SIP_INVITE)
21914             handle_response_invite(p, resp, rest, req, seqno);
21915          else if (sipmethod == SIP_SUBSCRIBE)
21916             handle_response_subscribe(p, resp, rest, req, seqno);
21917          else if (p->registry && sipmethod == SIP_REGISTER)
21918             handle_response_register(p, resp, rest, req, seqno);
21919          else {
21920             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
21921             pvt_set_needdestroy(p, "received 403 response");
21922          }
21923          break;
21924       case 404: /* Not found */
21925          if (p->registry && sipmethod == SIP_REGISTER)
21926             handle_response_register(p, resp, rest, req, seqno);
21927          else if (sipmethod == SIP_INVITE)
21928             handle_response_invite(p, resp, rest, req, seqno);
21929          else if (sipmethod == SIP_SUBSCRIBE)
21930             handle_response_subscribe(p, resp, rest, req, seqno);
21931          else if (owner)
21932             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
21933          break;
21934       case 423: /* Interval too brief */
21935          if (sipmethod == SIP_REGISTER)
21936             handle_response_register(p, resp, rest, req, seqno);
21937          break;
21938       case 408: /* Request timeout - terminate dialog */
21939          if (sipmethod == SIP_INVITE)
21940             handle_response_invite(p, resp, rest, req, seqno);
21941          else if (sipmethod == SIP_REGISTER)
21942             handle_response_register(p, resp, rest, req, seqno);
21943          else if (sipmethod == SIP_BYE) {
21944             pvt_set_needdestroy(p, "received 408 response");
21945             ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
21946          } else {
21947             if (owner)
21948                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
21949             pvt_set_needdestroy(p, "received 408 response");
21950          }
21951          break;
21952 
21953       case 428:
21954       case 422: /* Session-Timers: Session Interval Too Small */
21955          if (sipmethod == SIP_INVITE) {
21956             handle_response_invite(p, resp, rest, req, seqno);
21957          }
21958          break;
21959 
21960       case 481: /* Call leg does not exist */
21961          if (sipmethod == SIP_INVITE) {
21962             handle_response_invite(p, resp, rest, req, seqno);
21963          } else if (sipmethod == SIP_SUBSCRIBE) {
21964             handle_response_subscribe(p, resp, rest, req, seqno);
21965          } else if (sipmethod == SIP_BYE) {
21966             /* The other side has no transaction to bye,
21967             just assume it's all right then */
21968             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
21969          } else if (sipmethod == SIP_CANCEL) {
21970             /* The other side has no transaction to cancel,
21971             just assume it's all right then */
21972             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
21973          } else {
21974             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
21975             /* Guessing that this is not an important request */
21976          }
21977          break;
21978       case 487:
21979          if (sipmethod == SIP_INVITE)
21980             handle_response_invite(p, resp, rest, req, seqno);
21981          break;
21982       case 415: /* Unsupported media type */
21983       case 488: /* Not acceptable here - codec error */
21984       case 606: /* Not Acceptable */
21985          if (sipmethod == SIP_INVITE)
21986             handle_response_invite(p, resp, rest, req, seqno);
21987          break;
21988       case 491: /* Pending */
21989          if (sipmethod == SIP_INVITE)
21990             handle_response_invite(p, resp, rest, req, seqno);
21991          else {
21992             ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
21993             pvt_set_needdestroy(p, "received 491 response");
21994          }
21995          break;
21996       case 405: /* Method not allowed */
21997       case 501: /* Not Implemented */
21998          mark_method_unallowed(&p->allowed_methods, sipmethod);
21999          if (p->relatedpeer) {
22000             mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod);
22001          }
22002          if (sipmethod == SIP_INVITE)
22003             handle_response_invite(p, resp, rest, req, seqno);
22004          else
22005             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg);
22006          break;
22007       default:
22008          if ((resp >= 200) && (resp < 300)) { /* on any 2XX response do the following */
22009             if (sipmethod == SIP_INVITE) {
22010                handle_response_invite(p, resp, rest, req, seqno);
22011             }
22012          } else if ((resp >= 300) && (resp < 700)) {
22013             /* Fatal response */
22014             if ((resp != 487))
22015                ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
22016    
22017             if (sipmethod == SIP_INVITE)
22018                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
22019 
22020             /* XXX Locking issues?? XXX */
22021             switch(resp) {
22022             case 300: /* Multiple Choices */
22023             case 301: /* Moved permanently */
22024             case 302: /* Moved temporarily */
22025             case 305: /* Use Proxy */
22026                if (p->owner) {
22027                   struct ast_party_redirecting redirecting;
22028                   struct ast_set_party_redirecting update_redirecting;
22029 
22030                   ast_party_redirecting_init(&redirecting);
22031                   change_redirecting_information(p, req, &redirecting,
22032                      &update_redirecting, TRUE);
22033                   ast_channel_set_redirecting(p->owner, &redirecting,
22034                      &update_redirecting);
22035                   ast_party_redirecting_free(&redirecting);
22036                }
22037                /* Fall through */
22038             case 486: /* Busy here */
22039             case 600: /* Busy everywhere */
22040             case 603: /* Decline */
22041                if (p->owner) {
22042                   sip_handle_cc(p, req, AST_CC_CCBS);
22043                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
22044                }
22045                break;
22046             case 482: /* Loop Detected */
22047             case 480: /* Temporarily Unavailable */
22048             case 404: /* Not Found */
22049             case 410: /* Gone */
22050             case 400: /* Bad Request */
22051             case 500: /* Server error */
22052                if (sipmethod == SIP_SUBSCRIBE) {
22053                   handle_response_subscribe(p, resp, rest, req, seqno);
22054                   break;
22055                }
22056                /* Fall through */
22057             case 502: /* Bad gateway */
22058             case 503: /* Service Unavailable */
22059             case 504: /* Server Timeout */
22060                if (owner)
22061                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
22062                break;
22063             case 484: /* Address Incomplete */
22064                if (owner && sipmethod != SIP_BYE) {
22065                   switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
22066                   case SIP_PAGE2_ALLOWOVERLAP_YES:
22067                      ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp));
22068                      break;
22069                   default:
22070                      ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(404));
22071                      break;
22072                   }
22073                }
22074                break;
22075             default:
22076                /* Send hangup */ 
22077                if (owner && sipmethod != SIP_BYE)
22078                   ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
22079                break;
22080             }
22081             /* ACK on invite */
22082             if (sipmethod == SIP_INVITE)
22083                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
22084             sip_alreadygone(p);
22085             if (!p->owner) {
22086                pvt_set_needdestroy(p, "transaction completed");
22087             }
22088          } else if ((resp >= 100) && (resp < 200)) {
22089             if (sipmethod == SIP_INVITE) {
22090                if (!req->ignore && sip_cancel_destroy(p))
22091                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
22092                if (find_sdp(req))
22093                   process_sdp(p, req, SDP_T38_NONE);
22094                if (p->owner) {
22095                   /* Queue a progress frame */
22096                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
22097                }
22098             }
22099          } else
22100             ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? ast_channel_name(p->owner) : ast_sockaddr_stringify(&p->sa));
22101       }
22102    } else { 
22103       /* Responses to OUTGOING SIP requests on INCOMING calls
22104          get handled here. As well as out-of-call message responses */
22105       if (req->debug)
22106          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
22107 
22108       if (sipmethod == SIP_INVITE && resp == 200) {
22109          /* Tags in early session is replaced by the tag in 200 OK, which is
22110          the final reply to our INVITE */
22111          char tag[128];
22112 
22113          gettag(req, "To", tag, sizeof(tag));
22114          ast_string_field_set(p, theirtag, tag);
22115       }
22116 
22117       switch(resp) {
22118       case 200:
22119          if (sipmethod == SIP_INVITE) {
22120             handle_response_invite(p, resp, rest, req, seqno);
22121          } else if (sipmethod == SIP_CANCEL) {
22122             ast_debug(1, "Got 200 OK on CANCEL\n");
22123 
22124             /* Wait for 487, then destroy */
22125          } else if (sipmethod == SIP_BYE) {
22126             pvt_set_needdestroy(p, "transaction completed");
22127          }
22128          break;
22129       case 401:   /* www-auth */
22130       case 407:
22131          if (sipmethod == SIP_INVITE)
22132             handle_response_invite(p, resp, rest, req, seqno);
22133          else if (sipmethod == SIP_BYE) {
22134             if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) {
22135                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, sip_get_header(&p->initreq, "From"));
22136                pvt_set_needdestroy(p, "failed to authenticate BYE");
22137             }
22138          }
22139          break;
22140       case 481:   /* Call leg does not exist */
22141          if (sipmethod == SIP_INVITE) {
22142             /* Re-invite failed */
22143             handle_response_invite(p, resp, rest, req, seqno);
22144          } else if (sipmethod == SIP_BYE) {
22145             pvt_set_needdestroy(p, "received 481 response");
22146          } else if (sipdebug) {
22147             ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
22148          }
22149          break;
22150       case 501: /* Not Implemented */
22151          if (sipmethod == SIP_INVITE)
22152             handle_response_invite(p, resp, rest, req, seqno);
22153          break;
22154       default: /* Errors without handlers */
22155          if ((resp >= 100) && (resp < 200)) {
22156             if (sipmethod == SIP_INVITE) {   /* re-invite */
22157                if (!req->ignore && sip_cancel_destroy(p))
22158                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
22159             }
22160          } else if ((resp >= 200) && (resp < 300)) { /* on any unrecognized 2XX response do the following */
22161             if (sipmethod == SIP_INVITE) {
22162                handle_response_invite(p, resp, rest, req, seqno);
22163             }
22164          } else if ((resp >= 300) && (resp < 700)) {
22165             if ((resp != 487))
22166                ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
22167             switch(resp) {
22168             case 415: /* Unsupported media type */
22169             case 488: /* Not acceptable here - codec error */
22170             case 603: /* Decline */
22171             case 500: /* Server error */
22172             case 502: /* Bad gateway */
22173             case 503: /* Service Unavailable */
22174             case 504: /* Server timeout */
22175 
22176                /* re-invite failed */
22177                if (sipmethod == SIP_INVITE && sip_cancel_destroy(p))
22178                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
22179                break;
22180             }
22181          }
22182          break;
22183       }
22184    }
22185 }

static void handle_response_info ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Definition at line 21614 of file chan_sip.c.

References ast_log(), ast_sockaddr_stringify(), ast_verb, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), sip_methods, text, and cfsip_methods::text.

Referenced by handle_response().

21615 {
21616    int sipmethod = SIP_INFO;
21617 
21618    switch (resp) {
21619    case 401: /* Not www-authorized on SIP method */
21620    case 407: /* Proxy auth required */
21621       ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n",
21622          ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text);
21623       break;
21624    case 405: /* Method not allowed */
21625    case 501: /* Not Implemented */
21626       mark_method_unallowed(&p->allowed_methods, sipmethod);
21627       if (p->relatedpeer) {
21628          mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod);
21629       }
21630       ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n",
21631          ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text);
21632       break;
21633    default:
21634       if (300 <= resp && resp < 700) {
21635          ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n",
21636             sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa));
21637       }
21638       break;
21639    }
21640 }

static void handle_response_invite ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Handle SIP response to INVITE dialogue.

Definition at line 20699 of file chan_sip.c.

References append_history, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_name(), ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), ast_channel_uniqueid(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UPDATE_RTP_PEER, ast_debug, ast_log(), ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_instance_activate(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_route(), change_redirecting_information(), change_t38_state(), check_pendings(), connected, do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), get_rpid(), ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_NOTICE, LOG_WARNING, manager_event, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_ok_contact(), parse_session_expires(), ast_party_name::presentation, ast_party_number::presentation, proc_422_rsp(), process_sdp(), pvt_set_needdestroy(), set_address_from_contact(), set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_get_header(), sip_handle_cc(), sip_reinvite_retry(), sip_scheddestroy(), ast_party_connected_line::source, st_get_mode(), start_session_timer(), ast_party_name::str, ast_party_number::str, ast_party_id::tag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_response().

20700 {
20701    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
20702    int res = 0;
20703    int xmitres = 0;
20704    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
20705    char *p_hdrval;
20706    int rtn;
20707    struct ast_party_connected_line connected;
20708    struct ast_set_party_connected_line update_connected;
20709 
20710    if (reinvite) {
20711       ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
20712    } else {
20713       ast_debug(4, "SIP response %d to standard invite\n", resp);
20714    }
20715 
20716    if (p->alreadygone) { /* This call is already gone */
20717       ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
20718       return;
20719    }
20720 
20721    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
20722    /* Don't auto congest anymore since we've gotten something useful back */
20723    AST_SCHED_DEL_UNREF(sched, p->initid, dialog_unref(p, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr"));
20724 
20725    /* RFC3261 says we must treat every 1xx response (but not 100)
20726       that we don't recognize as if it was 183.
20727    */
20728    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183) {
20729       resp = 183;
20730    }
20731 
20732    /* For INVITE, treat all 2XX responses as we would a 200 response */
20733    if ((resp >= 200) && (resp < 300)) {
20734       resp = 200;
20735    }
20736 
20737    /* Any response between 100 and 199 is PROCEEDING */
20738    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) {
20739       p->invitestate = INV_PROCEEDING;
20740    }
20741 
20742    /* Final response, not 200 ? */
20743    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) {
20744       p->invitestate = INV_COMPLETED;
20745    }
20746    
20747    /* Final response, clear out pending invite */
20748    if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) {
20749       p->pendinginvite = 0;
20750    }
20751 
20752    /* If this is a response to our initial INVITE, we need to set what we can use
20753     * for this peer.
20754     */
20755    if (!reinvite) {
20756       set_pvt_allowed_methods(p, req);
20757    }
20758 
20759    switch (resp) {
20760    case 100:   /* Trying */
20761    case 101:   /* Dialog establishment */
20762       if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) {
20763          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20764       }
20765       check_pendings(p);
20766       break;
20767 
20768    case 180:   /* 180 Ringing */
20769    case 182:       /* 182 Queued */
20770       if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) {
20771          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20772       }
20773       /* Store Route-set from provisional SIP responses so
20774        * early-dialog request can be routed properly
20775        * */
20776       parse_ok_contact(p, req);
20777       if (!reinvite) {
20778          build_route(p, req, 1);
20779       }
20780       if (!req->ignore && p->owner) {
20781          if (get_rpid(p, req)) {
20782             /* Queue a connected line update */
20783             ast_party_connected_line_init(&connected);
20784             memset(&update_connected, 0, sizeof(update_connected));
20785 
20786             update_connected.id.number = 1;
20787             connected.id.number.valid = 1;
20788             connected.id.number.str = (char *) p->cid_num;
20789             connected.id.number.presentation = p->callingpres;
20790 
20791             update_connected.id.name = 1;
20792             connected.id.name.valid = 1;
20793             connected.id.name.str = (char *) p->cid_name;
20794             connected.id.name.presentation = p->callingpres;
20795 
20796             connected.id.tag = (char *) p->cid_tag;
20797             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
20798             ast_channel_queue_connected_line_update(p->owner, &connected,
20799                &update_connected);
20800          }
20801          sip_handle_cc(p, req, AST_CC_CCNR);
20802          ast_queue_control(p->owner, AST_CONTROL_RINGING);
20803          if (p->owner->_state != AST_STATE_UP) {
20804             ast_setstate(p->owner, AST_STATE_RINGING);
20805          }
20806       }
20807       if (find_sdp(req)) {
20808          if (p->invitestate != INV_CANCELLED) {
20809             p->invitestate = INV_EARLY_MEDIA;
20810          }
20811          res = process_sdp(p, req, SDP_T38_NONE);
20812          if (!req->ignore && p->owner) {
20813             /* Queue a progress frame only if we have SDP in 180 or 182 */
20814             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
20815          }
20816          ast_rtp_instance_activate(p->rtp);
20817       }
20818       check_pendings(p);
20819       break;
20820 
20821    case 181:   /* Call Is Being Forwarded */
20822       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
20823          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20824       /* Store Route-set from provisional SIP responses so
20825        * early-dialog request can be routed properly
20826        * */
20827       parse_ok_contact(p, req);
20828       if (!reinvite) {
20829          build_route(p, req, 1);
20830       }
20831       if (!req->ignore && p->owner) {
20832          struct ast_party_redirecting redirecting;
20833          struct ast_set_party_redirecting update_redirecting;
20834 
20835          ast_party_redirecting_init(&redirecting);
20836          memset(&update_redirecting, 0, sizeof(update_redirecting));
20837          change_redirecting_information(p, req, &redirecting, &update_redirecting,
20838             FALSE);
20839          ast_channel_queue_redirecting_update(p->owner, &redirecting,
20840             &update_redirecting);
20841          ast_party_redirecting_free(&redirecting);
20842          sip_handle_cc(p, req, AST_CC_CCNR);
20843       }
20844       check_pendings(p);
20845       break;
20846 
20847    case 183:   /* Session progress */
20848       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) {
20849          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20850       }
20851       /* Store Route-set from provisional SIP responses so
20852        * early-dialog request can be routed properly
20853        * */
20854       parse_ok_contact(p, req);
20855       if (!reinvite) {
20856          build_route(p, req, 1);
20857       }
20858       if (!req->ignore && p->owner) {
20859          if (get_rpid(p, req)) {
20860             /* Queue a connected line update */
20861             ast_party_connected_line_init(&connected);
20862             memset(&update_connected, 0, sizeof(update_connected));
20863 
20864             update_connected.id.number = 1;
20865             connected.id.number.valid = 1;
20866             connected.id.number.str = (char *) p->cid_num;
20867             connected.id.number.presentation = p->callingpres;
20868 
20869             update_connected.id.name = 1;
20870             connected.id.name.valid = 1;
20871             connected.id.name.str = (char *) p->cid_name;
20872             connected.id.name.presentation = p->callingpres;
20873 
20874             connected.id.tag = (char *) p->cid_tag;
20875             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
20876             ast_channel_queue_connected_line_update(p->owner, &connected,
20877                &update_connected);
20878          }
20879          sip_handle_cc(p, req, AST_CC_CCNR);
20880       }
20881       if (find_sdp(req)) {
20882          if (p->invitestate != INV_CANCELLED) {
20883             p->invitestate = INV_EARLY_MEDIA;
20884          }
20885          res = process_sdp(p, req, SDP_T38_NONE);
20886          if (!req->ignore && p->owner) {
20887             /* Queue a progress frame */
20888             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
20889          }
20890          ast_rtp_instance_activate(p->rtp);
20891       } else {
20892          /* Alcatel PBXs are known to send 183s with no SDP after sending
20893           * a 100 Trying response. We're just going to treat this sort of thing
20894           * the same as we would treat a 180 Ringing
20895           */
20896          if (!req->ignore && p->owner) {
20897             ast_queue_control(p->owner, AST_CONTROL_RINGING);
20898          }
20899       }
20900       check_pendings(p);
20901       break;
20902 
20903    case 200:   /* 200 OK on invite - someone's answering our call */
20904       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) {
20905          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20906       }
20907       p->authtries = 0;
20908       if (find_sdp(req)) {
20909          if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore)
20910             if (!reinvite)
20911                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
20912                /* For re-invites, we try to recover */
20913                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
20914          ast_rtp_instance_activate(p->rtp);
20915       }
20916 
20917       if (!req->ignore && p->owner) {
20918          int rpid_changed;
20919 
20920          rpid_changed = get_rpid(p, req);
20921          if (rpid_changed || !reinvite) {
20922             /* Queue a connected line update */
20923             ast_party_connected_line_init(&connected);
20924             memset(&update_connected, 0, sizeof(update_connected));
20925             if (rpid_changed
20926                || !ast_strlen_zero(p->cid_num)
20927                || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
20928                update_connected.id.number = 1;
20929                connected.id.number.valid = 1;
20930                connected.id.number.str = (char *) p->cid_num;
20931                connected.id.number.presentation = p->callingpres;
20932             }
20933             if (rpid_changed
20934                || !ast_strlen_zero(p->cid_name)
20935                || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
20936                update_connected.id.name = 1;
20937                connected.id.name.valid = 1;
20938                connected.id.name.str = (char *) p->cid_name;
20939                connected.id.name.presentation = p->callingpres;
20940             }
20941             if (update_connected.id.number || update_connected.id.name) {
20942                connected.id.tag = (char *) p->cid_tag;
20943                connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
20944                ast_channel_queue_connected_line_update(p->owner, &connected,
20945                   &update_connected);
20946             }
20947          }
20948       }
20949 
20950       /* Parse contact header for continued conversation */
20951       /* When we get 200 OK, we know which device (and IP) to contact for this call */
20952       /* This is important when we have a SIP proxy between us and the phone */
20953       if (outgoing) {
20954          update_call_counter(p, DEC_CALL_RINGING);
20955          parse_ok_contact(p, req);
20956          /* Save Record-Route for any later requests we make on this dialogue */
20957          if (!reinvite) {
20958             build_route(p, req, 1);
20959          }
20960 
20961          if(set_address_from_contact(p)) {
20962             /* Bad contact - we don't know how to reach this device */
20963             /* We need to ACK, but then send a bye */
20964             if (!p->route && !req->ignore) {
20965                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
20966             }
20967          }
20968 
20969       }
20970 
20971       if (!req->ignore && p->owner) {
20972          if (!reinvite) {
20973             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
20974             if (sip_cfg.callevents) {
20975                manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
20976                   "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
20977                   ast_channel_name(p->owner), "SIP", ast_channel_uniqueid(p->owner), p->callid, p->fullcontact, p->peername);
20978             }
20979          } else { /* RE-invite */
20980             if (p->t38.state == T38_DISABLED || p->t38.state == T38_REJECTED) {
20981                ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER);
20982             } else {
20983                ast_queue_frame(p->owner, &ast_null_frame);
20984             }
20985          }
20986       } else {
20987           /* It's possible we're getting an 200 OK after we've tried to disconnect
20988               by sending CANCEL */
20989          /* First send ACK, then send bye */
20990          if (!req->ignore) {
20991             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
20992          }
20993       }
20994 
20995       /* Check for Session-Timers related headers */
20996       if (st_get_mode(p, 0) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) {
20997          p_hdrval = (char*)sip_get_header(req, "Session-Expires");
20998          if (!ast_strlen_zero(p_hdrval)) {
20999             /* UAS supports Session-Timers */
21000             enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO;
21001             int tmp_st_interval = 0;
21002             rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &tmp_st_ref);
21003             if (rtn != 0) {
21004                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
21005             }
21006             if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC ||
21007                tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) {
21008                p->stimer->st_ref = tmp_st_ref;
21009             }
21010             if (tmp_st_interval) {
21011                p->stimer->st_interval = tmp_st_interval;
21012             }
21013             p->stimer->st_active = TRUE;
21014             p->stimer->st_active_peer_ua = TRUE;
21015             start_session_timer(p);
21016          } else {
21017             /* UAS doesn't support Session-Timers */
21018             if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) {
21019                p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC;
21020                p->stimer->st_active_peer_ua = FALSE;
21021                start_session_timer(p);
21022             }
21023          }
21024       }
21025 
21026 
21027       /* If I understand this right, the branch is different for a non-200 ACK only */
21028       p->invitestate = INV_TERMINATED;
21029       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21030       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
21031       check_pendings(p);
21032       break;
21033 
21034    case 407: /* Proxy authentication */
21035    case 401: /* Www auth */
21036       /* First we ACK */
21037       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21038       if (p->options) {
21039          p->options->auth_type = resp;
21040       }
21041 
21042       /* Then we AUTH */
21043       ast_string_field_set(p, theirtag, NULL);  /* forget their old tag, so we don't match tags when getting response */
21044       if (!req->ignore) {
21045          if (p->authtries < MAX_AUTHTRIES) {
21046             p->invitestate = INV_CALLING;
21047          }
21048          if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) {
21049             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", sip_get_header(&p->initreq, "From"));
21050             pvt_set_needdestroy(p, "failed to authenticate on INVITE");
21051             sip_alreadygone(p);
21052             if (p->owner) {
21053                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
21054             }
21055          }
21056       }
21057       break;
21058 
21059    case 403: /* Forbidden */
21060       /* First we ACK */
21061       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21062       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", sip_get_header(&p->initreq, "From"));
21063       if (!req->ignore && p->owner) {
21064          ast_set_hangupsource(p->owner, ast_channel_name(p->owner), 0);
21065          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
21066       }
21067       break;
21068 
21069    case 404: /* Not found */
21070       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21071       if (p->owner && !req->ignore) {
21072          ast_set_hangupsource(p->owner, ast_channel_name(p->owner), 0);
21073          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
21074       }
21075       break;
21076 
21077    case 408: /* Request timeout */
21078    case 481: /* Call leg does not exist */
21079       /* Could be REFER caused INVITE with replaces */
21080       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
21081       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21082       if (p->owner) {
21083          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
21084       }
21085       break;
21086 
21087    case 422: /* Session-Timers: Session interval too small */
21088       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21089       ast_string_field_set(p, theirtag, NULL);
21090       proc_422_rsp(p, req);
21091       break;
21092 
21093    case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */
21094       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21095       append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk.");
21096       ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid);
21097       if (p->owner && !req->ignore) {
21098          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
21099       }
21100       break;
21101 
21102    case 487: /* Cancelled transaction */
21103       /* We have sent CANCEL on an outbound INVITE
21104          This transaction is already scheduled to be killed by sip_hangup().
21105       */
21106       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21107       if (p->owner && !req->ignore) {
21108          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING);
21109          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
21110       } else if (!req->ignore) {
21111          update_call_counter(p, DEC_CALL_LIMIT);
21112          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
21113       }
21114       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21115       break;
21116    case 415: /* Unsupported media type */
21117    case 488: /* Not acceptable here */
21118    case 606: /* Not Acceptable */
21119       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21120       if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
21121          change_t38_state(p, T38_REJECTED);
21122          /* Try to reset RTP timers */
21123          /* XXX Why is this commented away??? */
21124          //ast_rtp_set_rtptimers_onhold(p->rtp);
21125 
21126          /* Trigger a reinvite back to audio */
21127          transmit_reinvite_with_sdp(p, FALSE, FALSE);
21128       } else {
21129          /* We can't set up this call, so give up */
21130          if (p->owner && !req->ignore) {
21131             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
21132          }
21133       }
21134       break;
21135    case 491: /* Pending */
21136       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21137       if (p->owner && !req->ignore) {
21138          if (p->owner->_state != AST_STATE_UP) {
21139             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
21140          } else {
21141             /* This is a re-invite that failed. */
21142             /* Reset the flag after a while
21143              */
21144             int wait;
21145             /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds,
21146              * if not owner of call, wait 0 to 2 seconds */
21147             if (p->outgoing_call) {
21148                wait = 2100 + ast_random() % 2000;
21149             } else {
21150                wait = ast_random() % 2000;
21151             }
21152             p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, dialog_ref(p, "passing dialog ptr into sched structure based on waitid for sip_reinvite_retry."));
21153             ast_log(LOG_WARNING, "just did sched_add waitid(%d) for sip_reinvite_retry for dialog %s in handle_response_invite\n", p->waitid, p->callid);
21154             ast_debug(2, "Reinvite race. Waiting %d secs before retry\n", wait);
21155          }
21156       }
21157       break;
21158 
21159    case 405: /* Not allowed */
21160    case 501: /* Not implemented */
21161       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
21162       if (p->owner) {
21163          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
21164       }
21165       break;
21166    }
21167    if (xmitres == XMIT_ERROR) {
21168       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
21169    }
21170 }

static void handle_response_message ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Definition at line 21688 of file chan_sip.c.

References ast_log(), ast_sockaddr_stringify(), ast_test_flag, ast_verb, do_message_auth(), LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), pvt_set_needdestroy(), sip_methods, text, and cfsip_methods::text.

Referenced by handle_response().

21689 {
21690    int sipmethod = SIP_MESSAGE;
21691    int in_dialog = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21692 
21693    switch (resp) {
21694    case 401: /* Not www-authorized on SIP method */
21695    case 407: /* Proxy auth required */
21696       if (do_message_auth(p, resp, rest, req, seqno) && !in_dialog) {
21697          pvt_set_needdestroy(p, "MESSAGE authentication failed");
21698       }
21699       break;
21700    case 405: /* Method not allowed */
21701    case 501: /* Not Implemented */
21702       mark_method_unallowed(&p->allowed_methods, sipmethod);
21703       if (p->relatedpeer) {
21704          mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod);
21705       }
21706       ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n",
21707          ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text);
21708       if (!in_dialog) {
21709          pvt_set_needdestroy(p, "MESSAGE not implemented or allowed");
21710       }
21711       break;
21712    default:
21713       if (100 <= resp && resp < 200) {
21714          /* Must allow provisional responses for out-of-dialog requests. */
21715       } else if (200 <= resp && resp < 300) {
21716          p->authtries = 0; /* Reset authentication counter */
21717          if (!in_dialog) {
21718             pvt_set_needdestroy(p, "MESSAGE delivery accepted");
21719          }
21720       } else if (300 <= resp && resp < 700) {
21721          ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n",
21722             sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa));
21723          if (!in_dialog) {
21724             pvt_set_needdestroy(p, (300 <= resp && resp < 600)
21725                ? "MESSAGE delivery failed" : "MESSAGE delivery refused");
21726          }
21727       }
21728       break;
21729    }
21730 }

static void handle_response_notify ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Definition at line 21175 of file chan_sip.c.

References ast_channel_name(), ast_clear_flag, ast_debug, ast_log(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cb_extensionstate(), do_proxy_auth(), LOG_NOTICE, LOG_WARNING, NONE, pvt_set_needdestroy(), and sip_get_header().

Referenced by handle_response().

21176 {
21177    switch (resp) {
21178    case 200:   /* Notify accepted */
21179       /* They got the notify, this is the end */
21180       if (p->owner) {
21181          if (p->refer) {
21182             ast_log(LOG_NOTICE, "Got OK on REFER Notify message\n");
21183          } else {
21184             ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", ast_channel_name(p->owner));
21185          }
21186       } else {
21187          if (p->subscribed == NONE && !p->refer) {
21188             ast_debug(4, "Got 200 accepted on NOTIFY %s\n", p->callid);
21189             pvt_set_needdestroy(p, "received 200 response");
21190          }
21191          if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
21192             /* Ready to send the next state we have on queue */
21193             ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
21194             cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
21195          }
21196       }
21197       break;
21198    case 401:   /* Not www-authorized on SIP method */
21199    case 407:   /* Proxy auth */
21200       if (!p->notify) {
21201          break; /* Only device notify can use NOTIFY auth */
21202       }
21203       ast_string_field_set(p, theirtag, NULL);
21204       if (ast_strlen_zero(p->authname)) {
21205          ast_log(LOG_WARNING, "Asked to authenticate NOTIFY to %s but we have no matching peer or realm auth!\n", ast_sockaddr_stringify(&p->recv));
21206          pvt_set_needdestroy(p, "unable to authenticate NOTIFY");
21207       }
21208       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) {
21209          ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", sip_get_header(&p->initreq, "From"));
21210          pvt_set_needdestroy(p, "failed to authenticate NOTIFY");
21211       }
21212       break;
21213    case 481: /* Call leg does not exist */
21214       pvt_set_needdestroy(p, "Received 481 response for NOTIFY");
21215       break;
21216    }
21217 }

static void handle_response_peerpoke ( struct sip_pvt *  p,
int  resp,
struct sip_request *  req 
) [static]

Handle qualification responses (OPTIONS).

Definition at line 21547 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, pvt_set_needdestroy(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), sip_ref_peer(), sip_unref_peer(), and TRUE.

Referenced by handle_response().

21548 {
21549    struct sip_peer *peer = /* sip_ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */
21550    int statechanged, is_reachable, was_reachable;
21551    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
21552 
21553    /*
21554     * Compute the response time to a ping (goes in peer->lastms.)
21555     * -1 means did not respond, 0 means unknown,
21556     * 1..maxms is a valid response, >maxms means late response.
21557     */
21558    if (pingtime < 1) {  /* zero = unknown, so round up to 1 */
21559       pingtime = 1;
21560    }
21561 
21562    if (!peer->maxms) { /* this should never happens */
21563       pvt_set_needdestroy(p, "got OPTIONS response but qualify is not enabled");
21564       return;
21565    }
21566 
21567    /* Now determine new state and whether it has changed.
21568     * Use some helper variables to simplify the writing
21569     * of the expressions.
21570     */
21571    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
21572    is_reachable = pingtime <= peer->maxms;
21573    statechanged = peer->lastms == 0 /* yes, unknown before */
21574       || was_reachable != is_reachable;
21575 
21576    peer->lastms = pingtime;
21577    peer->call = dialog_unref(peer->call, "unref dialog peer->call");
21578    if (statechanged) {
21579       const char *s = is_reachable ? "Reachable" : "Lagged";
21580       char str_lastms[20];
21581       snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime);
21582 
21583       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
21584          peer->name, s, pingtime, peer->maxms);
21585       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
21586       if (sip_cfg.peer_rtupdate) {
21587          ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
21588       }
21589       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
21590          "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
21591          peer->name, s, pingtime);
21592       if (is_reachable && sip_cfg.regextenonqualify)
21593          register_peer_exten(peer, TRUE);
21594    }
21595 
21596    pvt_set_needdestroy(p, "got OPTIONS response");
21597 
21598    /* Try again eventually */
21599    AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
21600          is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK,
21601          sip_poke_peer_s, peer,
21602          sip_unref_peer(_data, "removing poke peer ref"),
21603          sip_unref_peer(peer, "removing poke peer ref"),
21604          sip_ref_peer(peer, "adding poke peer ref"));
21605 }

static void handle_response_publish ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Definition at line 20648 of file chan_sip.c.

References ast_assert, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), do_proxy_auth(), LOG_NOTICE, mark_method_unallowed(), pvt_set_needdestroy(), sip_alreadygone(), and sip_get_header().

Referenced by handle_response().

20649 {
20650    struct sip_epa_entry *epa_entry = p->epa_entry;
20651    const char *etag = sip_get_header(req, "Sip-ETag");
20652 
20653    ast_assert(epa_entry != NULL);
20654 
20655    if (resp == 401 || resp == 407) {
20656       ast_string_field_set(p, theirtag, NULL);
20657       if (p->options) {
20658          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
20659       }
20660       if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) {
20661          ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", sip_get_header(&p->initreq, "From"));
20662          pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH");
20663          sip_alreadygone(p);
20664       }
20665       return;
20666    }
20667 
20668    if (resp == 501 || resp == 405) {
20669       mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH);
20670    }
20671 
20672    if (resp == 200) {
20673       p->authtries = 0;
20674       /* If I've read section 6, item 6 of RFC 3903 correctly,
20675        * an ESC will only generate a new etag when it sends a 200 OK
20676        */
20677       if (!ast_strlen_zero(etag)) {
20678          ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag));
20679       }
20680       /* The nominal case. Everything went well. Everybody is happy.
20681        * Each EPA will have a specific action to take as a result of this
20682        * development, so ... callbacks!
20683        */
20684       if (epa_entry->static_data->handle_ok) {
20685          epa_entry->static_data->handle_ok(p, req, epa_entry);
20686       }
20687    } else {
20688       /* Rather than try to make individual callbacks for each error
20689        * type, there is just a single error callback. The callback
20690        * can distinguish between error messages and do what it needs to
20691        */
20692       if (epa_entry->static_data->handle_error) {
20693          epa_entry->static_data->handle_error(p, resp, req, epa_entry);
20694       }
20695    }
20696 }

static void handle_response_refer ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Definition at line 21303 of file chan_sip.c.

References AST_CONTROL_CONGESTION, AST_CONTROL_TRANSFER, ast_debug, ast_log(), ast_queue_control(), ast_queue_control_data(), ast_sockaddr_stringify(), ast_strlen_zero(), AST_TRANSFER_FAILED, do_proxy_auth(), LOG_NOTICE, LOG_WARNING, pvt_set_needdestroy(), and sip_get_header().

Referenced by handle_response().

21304 {
21305    enum ast_control_transfer message = AST_TRANSFER_FAILED;
21306 
21307    /* If no refer structure exists, then do nothing */
21308    if (!p->refer)
21309       return;
21310 
21311    switch (resp) {
21312    case 202:   /* Transfer accepted */
21313       /* We need  to do something here */
21314       /* The transferee is now sending INVITE to target */
21315       p->refer->status = REFER_ACCEPTED;
21316       /* Now wait for next message */
21317       ast_debug(3, "Got 202 accepted on transfer\n");
21318       /* We should hang along, waiting for NOTIFY's here */
21319       break;
21320 
21321    case 401:   /* Not www-authorized on SIP method */
21322    case 407:   /* Proxy auth */
21323       if (ast_strlen_zero(p->authname)) {
21324          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n",
21325             ast_sockaddr_stringify(&p->recv));
21326          if (p->owner) {
21327             ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
21328          }
21329          pvt_set_needdestroy(p, "unable to authenticate REFER");
21330       }
21331       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) {
21332          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", sip_get_header(&p->initreq, "From"));
21333          p->refer->status = REFER_NOAUTH;
21334          if (p->owner) {
21335             ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
21336          }
21337          pvt_set_needdestroy(p, "failed to authenticate REFER");
21338       }
21339       break;
21340    
21341    case 405:   /* Method not allowed */
21342       /* Return to the current call onhold */
21343       /* Status flag needed to be reset */
21344       ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to);
21345       pvt_set_needdestroy(p, "received 405 response");
21346       p->refer->status = REFER_FAILED;
21347       if (p->owner) {
21348          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
21349       }
21350       break;
21351 
21352    case 481: /* Call leg does not exist */
21353 
21354       /* A transfer with Replaces did not work */
21355       /* OEJ: We should Set flag, cancel the REFER, go back
21356       to original call - but right now we can't */
21357       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
21358       if (p->owner)
21359          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
21360       pvt_set_needdestroy(p, "received 481 response");
21361       break;
21362 
21363    case 500:   /* Server error */
21364    case 501:   /* Method not implemented */
21365       /* Return to the current call onhold */
21366       /* Status flag needed to be reset */
21367       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
21368       pvt_set_needdestroy(p, "received 500/501 response");
21369       p->refer->status = REFER_FAILED;
21370       if (p->owner) {
21371          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
21372       }
21373       break;
21374    case 603:   /* Transfer declined */
21375       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
21376       p->refer->status = REFER_FAILED;
21377       pvt_set_needdestroy(p, "received 603 response");
21378       if (p->owner) {
21379          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
21380       }
21381       break;
21382    default:
21383       /* We should treat unrecognized 9xx as 900.  400 is actually
21384          specified as a possible response, but any 4-6xx is 
21385          theoretically possible. */
21386 
21387       if (resp < 299) { /* 1xx cases don't get here */
21388          ast_log(LOG_WARNING, "SIP transfer to %s had unxpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp);
21389       } else {
21390          ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp);
21391       }
21392 
21393       p->refer->status = REFER_FAILED;
21394       pvt_set_needdestroy(p, "received failure response");
21395       if (p->owner) {
21396          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
21397       }
21398       break;
21399    }
21400 }

static int handle_response_register ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Handle responses on REGISTER to services.

Definition at line 21403 of file chan_sip.c.

References __get_header(), ast_debug, ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_strlen_zero(), ast_tvnow(), do_register_auth(), EVENT_FLAG_SYSTEM, LOG_NOTICE, LOG_WARNING, manager_event, MAX, pvt_set_needdestroy(), REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, registry_addref(), registry_unref(), regstate2str(), S_OR, sip_get_header(), sip_reregister(), sip_scheddestroy(), strcasestr(), and transmit_register().

Referenced by handle_response().

21404 {
21405    int expires, expires_ms;
21406    struct sip_registry *r;
21407    r=p->registry;
21408    
21409    switch (resp) {
21410    case 401:   /* Unauthorized */
21411       if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
21412          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
21413          pvt_set_needdestroy(p, "failed to authenticate REGISTER");
21414       }
21415       break;
21416    case 403:   /* Forbidden */
21417       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
21418       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403"));
21419       r->regstate = REG_STATE_NOAUTH;
21420       pvt_set_needdestroy(p, "received 403 response");
21421       break;
21422    case 404:   /* Not found */
21423       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname);
21424       pvt_set_needdestroy(p, "received 404 response");
21425       if (r->call)
21426          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404");
21427       r->regstate = REG_STATE_REJECTED;
21428       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404"));
21429       break;
21430    case 407:   /* Proxy auth */
21431       if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
21432          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", sip_get_header(&p->initreq, "From"), p->authtries);
21433          pvt_set_needdestroy(p, "failed to authenticate REGISTER");
21434       }
21435       break;
21436    case 408:   /* Request timeout */
21437       /* Got a timeout response, so reset the counter of failed responses */
21438       if (r) {
21439          r->regattempts = 0;
21440       } else {
21441          ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid);
21442       }
21443       break;
21444    case 423:   /* Interval too brief */
21445       r->expiry = atoi(sip_get_header(req, "Min-Expires"));
21446       ast_log(LOG_WARNING, "Got 423 Interval too brief for service %s@%s, minimum is %d seconds\n", p->registry->username, p->registry->hostname, r->expiry);
21447       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423"));
21448       if (r->call) {
21449          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423");
21450          pvt_set_needdestroy(p, "received 423 response");
21451       }
21452       if (r->expiry > max_expiry) {
21453          ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname);
21454          r->expiry = r->configured_expiry;
21455          r->regstate = REG_STATE_REJECTED;
21456       } else {
21457          r->regstate = REG_STATE_UNREGISTERED;
21458          transmit_register(r, SIP_REGISTER, NULL, NULL);
21459       }
21460       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
21461       break;
21462    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
21463       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname);
21464       pvt_set_needdestroy(p, "received 479 response");
21465       if (r->call)
21466          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479");
21467       r->regstate = REG_STATE_REJECTED;
21468       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479"));
21469       break;
21470    case 200:   /* 200 OK */
21471       if (!r) {
21472          ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username));
21473          pvt_set_needdestroy(p, "received erroneous 200 response");
21474          return 0;
21475       }
21476 
21477       r->regstate = REG_STATE_REGISTERED;
21478       r->regtime = ast_tvnow();     /* Reset time of last successful registration */
21479       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
21480       r->regattempts = 0;
21481       ast_debug(1, "Registration successful\n");
21482       if (r->timeout > -1) {
21483          ast_debug(1, "Cancelling timeout %d\n", r->timeout);
21484       }
21485       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200"));
21486       if (r->call)
21487          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200");
21488       p->registry = registry_unref(p->registry, "unref registry entry p->registry");
21489       /* Let this one hang around until we have all the responses */
21490       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21491       /* p->needdestroy = 1; */
21492 
21493       /* set us up for re-registering
21494        * figure out how long we got registered for
21495        * according to section 6.13 of RFC, contact headers override
21496        * expires headers, so check those first */
21497       expires = 0;
21498 
21499       /* XXX todo: try to save the extra call */
21500       if (!ast_strlen_zero(sip_get_header(req, "Contact"))) {
21501          const char *contact = NULL;
21502          const char *tmptmp = NULL;
21503          int start = 0;
21504          for(;;) {
21505             contact = __get_header(req, "Contact", &start);
21506             /* this loop ensures we get a contact header about our register request */
21507             if(!ast_strlen_zero(contact)) {
21508                if( (tmptmp=strstr(contact, p->our_contact))) {
21509                   contact=tmptmp;
21510                   break;
21511                }
21512             } else
21513                break;
21514          }
21515          tmptmp = strcasestr(contact, "expires=");
21516          if (tmptmp) {
21517             if (sscanf(tmptmp + 8, "%30d;", &expires) != 1)
21518                expires = 0;
21519          }
21520          
21521       }
21522       if (!expires)
21523          expires=atoi(sip_get_header(req, "expires"));
21524       if (!expires)
21525          expires=default_expiry;
21526       
21527       expires_ms = expires * 1000;
21528       if (expires <= EXPIRY_GUARD_LIMIT)
21529          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN);
21530       else
21531          expires_ms -= EXPIRY_GUARD_SECS * 1000;
21532       if (sipdebug)
21533          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000);
21534       
21535       r->refresh= (int) expires_ms / 1000;
21536       
21537       /* Schedule re-registration before we expire */
21538       AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r,
21539                         registry_unref(_data,"unref in REPLACE del fail"),
21540                         registry_unref(r,"unref in REPLACE add fail"),
21541                         registry_addref(r,"The Addition side of REPLACE"));
21542    }
21543    return 1;
21544 }

static void handle_response_subscribe ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Definition at line 21220 of file chan_sip.c.

References ao2_callback, ast_cc_monitor_failed(), ast_debug, ast_free, ast_log(), ast_sched_add(), ast_string_field_set, ASTOBJ_REF, ASTOBJ_UNREF, do_proxy_auth(), find_sip_monitor_instance_by_subscription_pvt(), LOG_NOTICE, LOG_WARNING, pvt_set_needdestroy(), set_pvt_allowed_methods(), sip_alreadygone(), sip_get_header(), sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and transmit_response_with_date().

Referenced by handle_response().

21221 {
21222    if (p->subscribed == CALL_COMPLETION) {
21223       struct sip_monitor_instance *monitor_instance;
21224 
21225       if (resp < 300) {
21226          return;
21227       }
21228 
21229       /* Final failure response received. */
21230       monitor_instance = ao2_callback(sip_monitor_instances, 0,
21231          find_sip_monitor_instance_by_subscription_pvt, p);
21232       if (monitor_instance) {
21233          ast_cc_monitor_failed(monitor_instance->core_id,
21234             monitor_instance->device_name,
21235             "Received error response to our SUBSCRIBE");
21236       }
21237       return;
21238    }
21239 
21240    if (p->subscribed != MWI_NOTIFICATION) {
21241       return;
21242    }
21243    if (!p->mwi) {
21244       return;
21245    }
21246 
21247    switch (resp) {
21248    case 200: /* Subscription accepted */
21249       ast_debug(3, "Got 200 OK on subscription for MWI\n");
21250       set_pvt_allowed_methods(p, req);
21251       if (p->options) {
21252          ast_free(p->options);
21253          p->options = NULL;
21254       }
21255       p->mwi->subscribed = 1;
21256       if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) {
21257          ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
21258       }
21259       break;
21260    case 401:
21261    case 407:
21262       ast_string_field_set(p, theirtag, NULL);
21263       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) {
21264          ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", sip_get_header(&p->initreq, "From"));
21265          p->mwi->call = NULL;
21266          ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
21267          pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE");
21268       }
21269       break;
21270    case 403:
21271       transmit_response_with_date(p, "200 OK", req);
21272       ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n");
21273       p->mwi->call = NULL;
21274       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
21275       pvt_set_needdestroy(p, "received 403 response");
21276       sip_alreadygone(p);
21277       break;
21278    case 404:
21279       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n");
21280       p->mwi->call = NULL;
21281       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
21282       pvt_set_needdestroy(p, "received 404 response");
21283       break;
21284    case 481:
21285       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n");
21286       p->mwi->call = NULL;
21287       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
21288       pvt_set_needdestroy(p, "received 481 response");
21289       break;
21290    case 500:
21291    case 501:
21292       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n");
21293       p->mwi->call = NULL;
21294       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
21295       pvt_set_needdestroy(p, "received 500/501 response");
21296       break;
21297    }
21298 }

static void handle_response_update ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
uint32_t  seqno 
) [static]

Handle authentication challenge for SIP UPDATE.

This function is only called upon the receipt of a 401/407 response to an UPDATE.

Definition at line 20588 of file chan_sip.c.

References ast_log(), do_proxy_auth(), LOG_NOTICE, and sip_get_header().

Referenced by handle_response().

20589 {
20590    if (p->options) {
20591       p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
20592    }
20593    if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) {
20594       ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", sip_get_header(&p->initreq, "From"));
20595    }
20596 }

static int handle_sip_publish_initial ( struct sip_pvt *  p,
struct sip_request *  req,
struct event_state_compositor esc,
const int  expires 
) [static]

Definition at line 25239 of file chan_sip.c.

References ao2_ref, event_state_compositor::callbacks, create_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

25240 {
25241    struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires);
25242    int res = 0;
25243 
25244    if (!esc_entry) {
25245       transmit_response(p, "503 Internal Server Failure", req);
25246       return -1;
25247    }
25248 
25249    if (esc->callbacks->initial_handler) {
25250       res = esc->callbacks->initial_handler(p, req, esc, esc_entry);
25251    }
25252 
25253    if (!res) {
25254       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0);
25255    }
25256 
25257    ao2_ref(esc_entry, -1);
25258    return res;
25259 }

static int handle_sip_publish_modify ( struct sip_pvt *  p,
struct sip_request *  req,
struct event_state_compositor esc,
const char *const   etag,
const int  expires 
) [static]

Definition at line 25289 of file chan_sip.c.

References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

25290 {
25291    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
25292    int expires_ms = expires * 1000;
25293    int res = 0;
25294 
25295    if (!esc_entry) {
25296       transmit_response(p, "412 Conditional Request Failed", req);
25297       return -1;
25298    }
25299 
25300    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
25301          ao2_ref(_data, -1),
25302          ao2_ref(esc_entry, -1),
25303          ao2_ref(esc_entry, +1));
25304 
25305    if (esc->callbacks->modify_handler) {
25306       res = esc->callbacks->modify_handler(p, req, esc, esc_entry);
25307    }
25308 
25309    if (!res) {
25310       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
25311    }
25312 
25313    ao2_ref(esc_entry, -1);
25314    return res;
25315 }

static int handle_sip_publish_refresh ( struct sip_pvt *  p,
struct sip_request *  req,
struct event_state_compositor esc,
const char *const   etag,
const int  expires 
) [static]

Definition at line 25261 of file chan_sip.c.

References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

25262 {
25263    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
25264    int expires_ms = expires * 1000;
25265    int res = 0;
25266 
25267    if (!esc_entry) {
25268       transmit_response(p, "412 Conditional Request Failed", req);
25269       return -1;
25270    }
25271 
25272    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
25273          ao2_ref(_data, -1),
25274          ao2_ref(esc_entry, -1),
25275          ao2_ref(esc_entry, +1));
25276 
25277    if (esc->callbacks->refresh_handler) {
25278       res = esc->callbacks->refresh_handler(p, req, esc, esc_entry);
25279    }
25280 
25281    if (!res) {
25282       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
25283    }
25284 
25285    ao2_ref(esc_entry, -1);
25286    return res;
25287 }

static int handle_sip_publish_remove ( struct sip_pvt *  p,
struct sip_request *  req,
struct event_state_compositor esc,
const char *const   etag 
) [static]

Definition at line 25317 of file chan_sip.c.

References ao2_ref, ao2_unlink, AST_SCHED_DEL, event_state_compositor::callbacks, event_state_compositor::compositor, get_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

25318 {
25319    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
25320    int res = 0;
25321 
25322    if (!esc_entry) {
25323       transmit_response(p, "412 Conditional Request Failed", req);
25324       return -1;
25325    }
25326 
25327    AST_SCHED_DEL(sched, esc_entry->sched_id);
25328    /* Scheduler's ref of the esc_entry */
25329    ao2_ref(esc_entry, -1);
25330 
25331    if (esc->callbacks->remove_handler) {
25332       res = esc->callbacks->remove_handler(p, req, esc, esc_entry);
25333    }
25334 
25335    if (!res) {
25336       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
25337    }
25338 
25339    /* Ref from finding the esc_entry earlier in function */
25340    ao2_unlink(esc->compositor, esc_entry);
25341    ao2_ref(esc_entry, -1);
25342    return res;
25343 }

static int handle_t38_options ( struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v,
int *  maxdatagram 
) [static]

Handle T.38 configuration options common to users and peers.

Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 27709 of file chan_sip.c.

References ast_clear_flag, ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, strsep(), ast_variable::value, and word.

Referenced by build_peer(), and reload_config().

27711 {
27712    int res = 1;
27713 
27714    if (!strcasecmp(v->name, "t38pt_udptl")) {
27715       char *buf = ast_strdupa(v->value);
27716       char *word, *next = buf;
27717 
27718       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT);
27719 
27720       while ((word = strsep(&next, ","))) {
27721          if (ast_true(word) || !strcasecmp(word, "fec")) {
27722             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27723             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC);
27724          } else if (!strcasecmp(word, "redundancy")) {
27725             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27726             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY);
27727          } else if (!strcasecmp(word, "none")) {
27728             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27729             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL);
27730          } else if (!strncasecmp(word, "maxdatagram=", 12)) {
27731             if (sscanf(&word[12], "%30u", maxdatagram) != 1) {
27732                ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config);
27733                *maxdatagram = global_t38_maxdatagram;
27734             }
27735          }
27736       }
27737    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
27738       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
27739       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
27740    } else {
27741       res = 0;
27742    }
27743 
27744    return res;
27745 }

const char* hangup_cause2sip ( int  cause  ) 

Convert Asterisk hangup causes to SIP codes.

 Possible values from causes.h
        AST_CAUSE_NOTDEFINED    AST_CAUSE_NORMAL        AST_CAUSE_BUSY
        AST_CAUSE_FAILURE       AST_CAUSE_CONGESTION    AST_CAUSE_UNALLOCATED

	In addition to these, a lot of PRI codes is defined in causes.h
	...should we take care of them too ?

	Quote RFC 3398

   ISUP Cause value                        SIP response
   ----------------                        ------------
   1  unallocated number                   404 Not Found
   2  no route to network                  404 Not found
   3  no route to destination              404 Not found
   16 normal call clearing                 --- (*)
   17 user busy                            486 Busy here
   18 no user responding                   408 Request Timeout
   19 no answer from the user              480 Temporarily unavailable
   20 subscriber absent                    480 Temporarily unavailable
   21 call rejected                        403 Forbidden (+)
   22 number changed (w/o diagnostic)      410 Gone
   22 number changed (w/ diagnostic)       301 Moved Permanently
   23 redirection to new destination       410 Gone
   26 non-selected user clearing           404 Not Found (=)
   27 destination out of order             502 Bad Gateway
   28 address incomplete                   484 Address incomplete
   29 facility rejected                    501 Not implemented
   31 normal unspecified                   480 Temporarily unavailable

Definition at line 6269 of file chan_sip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, and ast_debug.

Referenced by sip_hangup().

06270 {
06271    switch (cause) {
06272       case AST_CAUSE_UNALLOCATED:      /* 1 */
06273       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
06274       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
06275          return "404 Not Found";
06276       case AST_CAUSE_CONGESTION:    /* 34 */
06277       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
06278          return "503 Service Unavailable";
06279       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
06280          return "408 Request Timeout";
06281       case AST_CAUSE_NO_ANSWER:     /* 19 */
06282       case AST_CAUSE_UNREGISTERED:        /* 20 */
06283          return "480 Temporarily unavailable";
06284       case AST_CAUSE_CALL_REJECTED:    /* 21 */
06285          return "403 Forbidden";
06286       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
06287          return "410 Gone";
06288       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
06289          return "480 Temporarily unavailable";
06290       case AST_CAUSE_INVALID_NUMBER_FORMAT:
06291          return "484 Address incomplete";
06292       case AST_CAUSE_USER_BUSY:
06293          return "486 Busy here";
06294       case AST_CAUSE_FAILURE:
06295          return "500 Server internal failure";
06296       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
06297          return "501 Not Implemented";
06298       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
06299          return "503 Service Unavailable";
06300       /* Used in chan_iax2 */
06301       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
06302          return "502 Bad Gateway";
06303       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
06304          return "488 Not Acceptable Here";
06305       case AST_CAUSE_INTERWORKING:  /* Unspecified Interworking issues */
06306          return "500 Network error";
06307 
06308       case AST_CAUSE_NOTDEFINED:
06309       default:
06310          ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause);
06311          return NULL;
06312    }
06313 
06314    /* Never reached */
06315    return 0;
06316 }

int hangup_sip2cause ( int  cause  ) 

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 6147 of file chan_sip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by __transmit_response(), and handle_response().

06148 {
06149    /* Possible values taken from causes.h */
06150 
06151    switch(cause) {
06152       case 401:   /* Unauthorized */
06153          return AST_CAUSE_CALL_REJECTED;
06154       case 403:   /* Not found */
06155          return AST_CAUSE_CALL_REJECTED;
06156       case 404:   /* Not found */
06157          return AST_CAUSE_UNALLOCATED;
06158       case 405:   /* Method not allowed */
06159          return AST_CAUSE_INTERWORKING;
06160       case 407:   /* Proxy authentication required */
06161          return AST_CAUSE_CALL_REJECTED;
06162       case 408:   /* No reaction */
06163          return AST_CAUSE_NO_USER_RESPONSE;
06164       case 409:   /* Conflict */
06165          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
06166       case 410:   /* Gone */
06167          return AST_CAUSE_NUMBER_CHANGED;
06168       case 411:   /* Length required */
06169          return AST_CAUSE_INTERWORKING;
06170       case 413:   /* Request entity too large */
06171          return AST_CAUSE_INTERWORKING;
06172       case 414:   /* Request URI too large */
06173          return AST_CAUSE_INTERWORKING;
06174       case 415:   /* Unsupported media type */
06175          return AST_CAUSE_INTERWORKING;
06176       case 420:   /* Bad extension */
06177          return AST_CAUSE_NO_ROUTE_DESTINATION;
06178       case 480:   /* No answer */
06179          return AST_CAUSE_NO_ANSWER;
06180       case 481:   /* No answer */
06181          return AST_CAUSE_INTERWORKING;
06182       case 482:   /* Loop detected */
06183          return AST_CAUSE_INTERWORKING;
06184       case 483:   /* Too many hops */
06185          return AST_CAUSE_NO_ANSWER;
06186       case 484:   /* Address incomplete */
06187          return AST_CAUSE_INVALID_NUMBER_FORMAT;
06188       case 485:   /* Ambiguous */
06189          return AST_CAUSE_UNALLOCATED;
06190       case 486:   /* Busy everywhere */
06191          return AST_CAUSE_BUSY;
06192       case 487:   /* Request terminated */
06193          return AST_CAUSE_INTERWORKING;
06194       case 488:   /* No codecs approved */
06195          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
06196       case 491:   /* Request pending */
06197          return AST_CAUSE_INTERWORKING;
06198       case 493:   /* Undecipherable */
06199          return AST_CAUSE_INTERWORKING;
06200       case 500:   /* Server internal failure */
06201          return AST_CAUSE_FAILURE;
06202       case 501:   /* Call rejected */
06203          return AST_CAUSE_FACILITY_REJECTED;
06204       case 502:
06205          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
06206       case 503:   /* Service unavailable */
06207          return AST_CAUSE_CONGESTION;
06208       case 504:   /* Gateway timeout */
06209          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
06210       case 505:   /* SIP version not supported */
06211          return AST_CAUSE_INTERWORKING;
06212       case 600:   /* Busy everywhere */
06213          return AST_CAUSE_USER_BUSY;
06214       case 603:   /* Decline */
06215          return AST_CAUSE_CALL_REJECTED;
06216       case 604:   /* Does not exist anywhere */
06217          return AST_CAUSE_UNALLOCATED;
06218       case 606:   /* Not acceptable */
06219          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
06220       default:
06221          if (cause < 500 && cause >= 400) {
06222             /* 4xx class error that is unknown - someting wrong with our request */
06223             return AST_CAUSE_INTERWORKING;
06224          } else if (cause < 600 && cause >= 500) {
06225             /* 5xx class error - problem in the remote end */
06226             return AST_CAUSE_CONGESTION;
06227          } else if (cause < 700 && cause >= 600) {
06228             /* 6xx - global errors in the 4xx class */
06229             return AST_CAUSE_INTERWORKING;
06230          }
06231          return AST_CAUSE_NORMAL;
06232    }
06233    /* Never reached */
06234    return 0;
06235 }

static int init_req ( struct sip_request *  req,
int  sipmethod,
const char *  recip 
) [static]

Initialize SIP request.

Definition at line 10427 of file chan_sip.c.

References ast_free, ast_str_create(), ast_str_set(), sip_methods, and cfsip_methods::text.

10428 {
10429    /* Initialize a request */
10430    memset(req, 0, sizeof(*req));
10431    if (!(req->data = ast_str_create(SIP_MIN_PACKET)))
10432       goto e_return;
10433    if (!(req->content = ast_str_create(SIP_MIN_PACKET)))
10434       goto e_free_data;
10435    req->method = sipmethod;
10436    req->header[0] = 0;
10437    ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
10438    req->headers++;
10439    return 0;
10440 
10441 e_free_data:
10442    ast_free(req->data);
10443    req->data = NULL;
10444 e_return:
10445    return -1;
10446 }

static int init_resp ( struct sip_request *  resp,
const char *  msg 
) [static]

Initialize SIP response, based on SIP request.

Definition at line 10405 of file chan_sip.c.

References ast_free, ast_str_create(), and ast_str_set().

10406 {
10407    /* Initialize a response */
10408    memset(resp, 0, sizeof(*resp));
10409    resp->method = SIP_RESPONSE;
10410    if (!(resp->data = ast_str_create(SIP_MIN_PACKET)))
10411       goto e_return;
10412    if (!(resp->content = ast_str_create(SIP_MIN_PACKET)))
10413       goto e_free_data;
10414    resp->header[0] = 0;
10415    ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg);
10416    resp->headers++;
10417    return 0;
10418 
10419 e_free_data:
10420    ast_free(resp->data);
10421    resp->data = NULL;
10422 e_return:
10423    return -1;
10424 }

static int initialize_escs ( void   )  [static]

Definition at line 1072 of file chan_sip.c.

References ao2_container_alloc, ARRAY_LEN, esc_cmp_fn(), esc_hash_fn(), and event_state_compositors.

Referenced by load_module().

01073 {
01074    int i, res = 0;
01075    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01076       if (!((event_state_compositors[i].compositor) =
01077                ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) {
01078          res = -1;
01079       }
01080    }
01081    return res;
01082 }

static void initialize_initreq ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.

Definition at line 3093 of file chan_sip.c.

References ast_debug, ast_verbose, copy_request(), parse_request(), sip_methods, and cfsip_methods::text.

Referenced by transmit_invite(), transmit_message(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and update_connectedline().

03094 {
03095    if (p->initreq.headers) {
03096       ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
03097    } else {
03098       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
03099    }
03100    /* Use this as the basis */
03101    copy_request(&p->initreq, req);
03102    parse_request(&p->initreq);
03103    if (req->debug) {
03104       ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
03105    }
03106 }

static int initialize_udptl ( struct sip_pvt *  p  )  [static]

Definition at line 6887 of file chan_sip.c.

References ast_channel_set_fd(), ast_clear_flag, ast_debug, ast_log(), AST_LOG_WARNING, ast_test_flag, ast_udptl_fd(), ast_udptl_new_with_bindaddr(), ast_udptl_setnat(), ast_udptl_setqos(), bindaddr, and set_t38_capabilities().

Referenced by process_sdp(), process_sdp_a_image(), and sip_indicate().

06888 {
06889    int natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
06890 
06891    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
06892       return 1;
06893    }
06894 
06895    /* If we've already initialized T38, don't take any further action */
06896    if (p->udptl) {
06897       return 0;
06898    }
06899 
06900    /* T38 can be supported by this dialog, create it and set the derived properties */
06901    if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) {
06902       if (p->owner) {
06903          ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl));
06904       }
06905 
06906       ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio);
06907       p->t38_maxdatagram = p->relatedpeer ? p->relatedpeer->t38_maxdatagram : global_t38_maxdatagram;
06908       set_t38_capabilities(p);
06909 
06910       ast_debug(1, "Setting NAT on UDPTL to %s\n", natflags ? "On" : "Off");
06911       ast_udptl_setnat(p->udptl, natflags);
06912    } else {
06913       ast_log(AST_LOG_WARNING, "UDPTL creation failed - disabling T38 for this dialog\n");
06914       ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT);
06915       return 1;
06916    }
06917 
06918    return 0;
06919 }

static void initreqprep ( struct sip_request *  req,
struct sip_pvt *  p,
int  sipmethod,
const char *const   explicit_uri 
) [static]

Initiate new SIP request to peer/user.

Todo:
Need to add back the VXML URL here at some point, possibly use build_string for all this junk

Definition at line 12335 of file chan_sip.c.

References add_header(), add_header_max_forwards(), add_route(), AST_DIGIT_ANYNUM, ast_escape_quoted(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_set(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), ast_uri_sip_user, build_contact(), exten, init_req(), ourport, S_OR, sip_cfg, sip_methods, sip_standard_port(), and cfsip_methods::text.

Referenced by transmit_invite(), transmit_message(), and transmit_notify_with_mwi().

12336 {
12337    struct ast_str *invite = ast_str_alloca(256);
12338    char from[256];
12339    char to[256];
12340    char tmp_n[SIPBUFSIZE/2];  /* build a local copy of 'n' if needed */
12341    char tmp_l[SIPBUFSIZE/2];  /* build a local copy of 'l' if needed */
12342    const char *l = NULL;   /* XXX what is this, exactly ? */
12343    const char *n = NULL;   /* XXX what is this, exactly ? */
12344    const char *d = NULL;   /* domain in from header */
12345    const char *urioptions = "";
12346    int ourport;
12347    int cid_has_name = 1;
12348    int cid_has_num = 1;
12349 
12350    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
12351       const char *s = p->username;  /* being a string field, cannot be NULL */
12352 
12353       /* Test p->username against allowed characters in AST_DIGIT_ANY
12354          If it matches the allowed characters list, then sipuser = ";user=phone"
12355          If not, then sipuser = ""
12356       */
12357       /* + is allowed in first position in a tel: uri */
12358       if (*s == '+')
12359          s++;
12360       for (; *s; s++) {
12361          if (!strchr(AST_DIGIT_ANYNUM, *s) )
12362             break;
12363       }
12364       /* If we have only digits, add ;user=phone to the uri */
12365       if (!*s)
12366          urioptions = ";user=phone";
12367    }
12368 
12369 
12370    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
12371 
12372    d = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip));
12373    if (p->owner) {
12374       if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
12375          l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL;
12376          n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL;
12377       } else {
12378          /* Even if we are using RPID, we shouldn't leak information in the From if the user wants
12379           * their callerid restricted */
12380          l = CALLERID_UNKNOWN;
12381          n = l;
12382          d = FROMDOMAIN_INVALID;
12383       }
12384    }
12385 
12386    /* Hey, it's a NOTIFY! See if they've configured a mwi_from.
12387     * XXX Right now, this logic works because the only place that mwi_from
12388     * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then
12389     * we might end up putting the mwi_from setting into other types of NOTIFY
12390     * messages as well.
12391     */
12392    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) {
12393       l = p->mwi_from;
12394    }
12395 
12396    if (ast_strlen_zero(l)) {
12397       cid_has_num = 0;
12398       l = default_callerid;
12399    }
12400    if (ast_strlen_zero(n)) {
12401       cid_has_name = 0;
12402       n = l;
12403    }
12404 
12405    /* Allow user to be overridden */
12406    if (!ast_strlen_zero(p->fromuser))
12407       l = p->fromuser;
12408    else /* Save for any further attempts */
12409       ast_string_field_set(p, fromuser, l);
12410 
12411    /* Allow user to be overridden */
12412    if (!ast_strlen_zero(p->fromname))
12413       n = p->fromname;
12414    else /* Save for any further attempts */
12415       ast_string_field_set(p, fromname, n);
12416 
12417    if (sip_cfg.pedanticsipchecking) {
12418       ast_escape_quoted(n, tmp_n, sizeof(tmp_n));
12419       n = tmp_n;
12420       ast_uri_encode(l, tmp_l, sizeof(tmp_l), ast_uri_sip_user);
12421       l = tmp_l;
12422    }
12423 
12424    ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
12425 
12426    /* If a caller id name was specified, add a display name. */
12427    if (cid_has_name || !cid_has_num) {
12428       snprintf(from, sizeof(from), "\"%s\" ", n);
12429    } else {
12430       from[0] = '\0';
12431    }
12432 
12433    if (!sip_standard_port(p->socket.type, ourport)) {
12434       size_t offset = strlen(from);
12435       snprintf(&from[offset], sizeof(from) - offset, "<sip:%s@%s:%d>;tag=%s", l, d, ourport, p->tag);
12436    } else {
12437       size_t offset = strlen(from);
12438       snprintf(&from[offset], sizeof(from) - offset, "<sip:%s@%s>;tag=%s", l, d, p->tag);
12439    }
12440 
12441    if (!ast_strlen_zero(explicit_uri)) {
12442       ast_str_set(&invite, 0, "%s", explicit_uri);
12443    } else {
12444       /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
12445       if (!ast_strlen_zero(p->fullcontact)) {
12446          /* If we have full contact, trust it */
12447          ast_str_append(&invite, 0, "%s", p->fullcontact);
12448       } else {
12449          /* Otherwise, use the username while waiting for registration */
12450          ast_str_append(&invite, 0, "sip:");
12451          if (!ast_strlen_zero(p->username)) {
12452             n = p->username;
12453             if (sip_cfg.pedanticsipchecking) {
12454                ast_uri_encode(n, tmp_n, sizeof(tmp_n), ast_uri_sip_user);
12455                n = tmp_n;
12456             }
12457             ast_str_append(&invite, 0, "%s@", n);
12458          }
12459          ast_str_append(&invite, 0, "%s", p->tohost);
12460          if (p->portinuri) {
12461             ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa));
12462          }
12463          ast_str_append(&invite, 0, "%s", urioptions);
12464       }
12465    }
12466 
12467    /* If custom URI options have been provided, append them */
12468    if (p->options && !ast_strlen_zero(p->options->uri_options))
12469       ast_str_append(&invite, 0, ";%s", p->options->uri_options);
12470    
12471    /* This is the request URI, which is the next hop of the call
12472       which may or may not be the destination of the call
12473    */
12474    ast_string_field_set(p, uri, invite->str);
12475 
12476    if (!ast_strlen_zero(p->todnid)) {
12477       /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
12478       if (!strchr(p->todnid, '@')) {
12479          /* We have no domain in the dnid */
12480          snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
12481       } else {
12482          snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
12483       }
12484    } else {
12485       if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
12486          /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
12487          snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag);
12488       } else if (p->options && p->options->vxml_url) {
12489          /* If there is a VXML URL append it to the SIP URL */
12490          snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
12491       } else {
12492          snprintf(to, sizeof(to), "<%s>", p->uri);
12493       }
12494    }
12495 
12496    init_req(req, sipmethod, p->uri);
12497    /* now tmp_n is available so reuse it to build the CSeq */
12498    snprintf(tmp_n, sizeof(tmp_n), "%u %s", ++p->ocseq, sip_methods[sipmethod].text);
12499 
12500    add_header(req, "Via", p->via);
12501    add_header_max_forwards(p, req);
12502    /* This will be a no-op most of the time. However, under certain circumstances,
12503     * NOTIFY messages will use this function for preparing the request and should
12504     * have Route headers present.
12505     */
12506    add_route(req, p->route);
12507 
12508    add_header(req, "From", from);
12509    add_header(req, "To", to);
12510    ast_string_field_set(p, exten, l);
12511    build_contact(p);
12512    add_header(req, "Contact", p->our_contact);
12513    add_header(req, "Call-ID", p->callid);
12514    add_header(req, "CSeq", tmp_n);
12515    if (!ast_strlen_zero(global_useragent)) {
12516       add_header(req, "User-Agent", global_useragent);
12517    }
12518 }

static const char * insecure2str ( int  mode  )  [static]

Convert Insecure setting to printable string.

Definition at line 17642 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer().

17643 {
17644    return map_x_s(insecurestr, mode, "<error>");
17645 }

static int interpret_t38_parameters ( struct sip_pvt *  p,
const struct ast_control_t38_parameters parameters 
) [static]

Helper function which updates T.38 capability information and triggers a reinvite.

Definition at line 6795 of file chan_sip.c.

References AST_CONTROL_T38_PARAMETERS, ast_queue_control_data(), AST_SCHED_DEL_UNREF, ast_set_flag, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_PARMS, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, ast_udptl_get_far_max_ifp(), ast_udptl_set_local_max_ifp(), change_t38_state(), FALSE, ast_control_t38_parameters::fill_bit_removal, ast_control_t38_parameters::max_ifp, MIN, ast_control_t38_parameters::request_response, transmit_reinvite_with_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), and TRUE.

Referenced by sip_indicate().

06796 {
06797    int res = 0;
06798 
06799    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) {
06800       return -1;
06801    }
06802    switch (parameters->request_response) {
06803    case AST_T38_NEGOTIATED:
06804    case AST_T38_REQUEST_NEGOTIATE:         /* Request T38 */
06805       /* Negotiation can not take place without a valid max_ifp value. */
06806       if (!parameters->max_ifp) {
06807          if (p->t38.state == T38_PEER_REINVITE) {
06808             AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06809             transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
06810          }
06811          change_t38_state(p, T38_REJECTED);
06812          break;
06813       } else if (p->t38.state == T38_PEER_REINVITE) {
06814          AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06815          p->t38.our_parms = *parameters;
06816          /* modify our parameters to conform to the peer's parameters,
06817           * based on the rules in the ITU T.38 recommendation
06818           */
06819          if (!p->t38.their_parms.fill_bit_removal) {
06820             p->t38.our_parms.fill_bit_removal = FALSE;
06821          }
06822          if (!p->t38.their_parms.transcoding_mmr) {
06823             p->t38.our_parms.transcoding_mmr = FALSE;
06824          }
06825          if (!p->t38.their_parms.transcoding_jbig) {
06826             p->t38.our_parms.transcoding_jbig = FALSE;
06827          }
06828          p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version);
06829          p->t38.our_parms.rate_management = p->t38.their_parms.rate_management;
06830          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
06831          change_t38_state(p, T38_ENABLED);
06832          transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
06833       } else if (p->t38.state != T38_ENABLED) {
06834          p->t38.our_parms = *parameters;
06835          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
06836          change_t38_state(p, T38_LOCAL_REINVITE);
06837          if (!p->pendinginvite) {
06838             transmit_reinvite_with_sdp(p, TRUE, FALSE);
06839          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
06840             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
06841          }
06842       }
06843       break;
06844    case AST_T38_TERMINATED:
06845    case AST_T38_REFUSED:
06846    case AST_T38_REQUEST_TERMINATE:         /* Shutdown T38 */
06847       if (p->t38.state == T38_PEER_REINVITE) {
06848          AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06849          change_t38_state(p, T38_REJECTED);
06850          transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
06851       } else if (p->t38.state == T38_ENABLED)
06852          transmit_reinvite_with_sdp(p, FALSE, FALSE);
06853       break;
06854    case AST_T38_REQUEST_PARMS: {    /* Application wants remote's parameters re-sent */
06855       struct ast_control_t38_parameters parameters = p->t38.their_parms;
06856 
06857       if (p->t38.state == T38_PEER_REINVITE) {
06858          AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06859          parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
06860          parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
06861          ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
06862          /* we need to return a positive value here, so that applications that
06863           * send this request can determine conclusively whether it was accepted or not...
06864           * older versions of chan_sip would just silently accept it and return zero.
06865           */
06866          res = AST_T38_REQUEST_PARMS;
06867       }
06868       break;
06869    }
06870    default:
06871       res = -1;
06872       break;
06873    }
06874 
06875    return res;
06876 }

static int is_method_allowed ( unsigned int *  allowed_methods,
enum sipmethod  method 
) [static]

Check if method is allowed for a device or a dialog.

Definition at line 8577 of file chan_sip.c.

Referenced by sip_sendtext(), and update_connectedline().

08578 {
08579    return ((*allowed_methods) >> method) & 1;
08580 }

static void list_route ( struct sip_route *  route  )  [static]

List all routes - mostly for debugging.

Definition at line 14625 of file chan_sip.c.

References ast_verbose.

Referenced by build_route().

14626 {
14627    if (!route) {
14628       ast_verbose("list_route: no route\n");
14629    } else {
14630       for (;route; route = route->next)
14631          ast_verbose("list_route: hop: <%s>\n", route->hop);
14632    }
14633 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 31394 of file chan_sip.c.

References ao2_container_alloc, ao2_t_container_alloc, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_check_realtime(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_format_cap_add_all_by_type(), ast_format_cap_alloc(), AST_FORMAT_TYPE_AUDIO, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_msg_tech_register(), ast_realtime_require_field(), ast_register_application_xml, ast_rtp_glue_register, ast_sched_context_create(), ast_sched_context_destroy(), AST_TEST_REGISTER, ast_udptl_proto_register(), ast_verbose, ASTOBJ_CONTAINER_INIT, ast_channel_tech::capabilities, CHANNEL_MODULE_LOAD, dialog_cmp_cb(), dialog_hash_cb(), EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, initialize_escs(), io_context_create(), io_context_destroy(), LOG_ERROR, manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), network_change_event_subscribe(), peer_cmp_cb(), peer_hash_cb(), peer_ipcmp_cb(), peer_iphash_cb(), regl, reload_config(), restart_monitor(), RQ_CHAR, RQ_INTEGER4, RQ_UINTEGER2, ast_channel_tech::send_digit_begin, SENTINEL, sip_addheader(), sip_cfg, sip_dtmfmode(), sip_epa_register(), sip_is_xml_parsable(), sip_monitor_instance_cmp_fn(), sip_monitor_instance_hash_fn(), sip_poke_all_peers(), sip_register_tests(), sip_removeheader(), sip_reqresp_parser_init(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), sip_tech_info, submwil, threadt_cmp_cb(), and threadt_hash_cb().

31395 {
31396    ast_verbose("SIP channel loading...\n");
31397 
31398    if (!(sip_tech.capabilities = ast_format_cap_alloc())) {
31399       return AST_MODULE_LOAD_FAILURE;
31400    }
31401 
31402    /* the fact that ao2_containers can't resize automatically is a major worry! */
31403    /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
31404    peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers");
31405    peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip");
31406    dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs");
31407    dialogs_needdestroy = ao2_t_container_alloc(1, NULL, NULL, "allocate dialogs_needdestroy");
31408    dialogs_rtpcheck = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs for rtpchecks");
31409    threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
31410    if (!peers || !peers_by_ip || !dialogs || !dialogs_needdestroy || !dialogs_rtpcheck
31411       || !threadt) {
31412       ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n");
31413       return AST_MODULE_LOAD_FAILURE;
31414    }
31415 
31416    if (!(sip_cfg.caps = ast_format_cap_alloc())) {
31417       return AST_MODULE_LOAD_FAILURE;
31418    }
31419    ast_format_cap_add_all_by_type(sip_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
31420 
31421    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
31422    ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
31423 
31424    if (!(sched = ast_sched_context_create())) {
31425       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
31426       return AST_MODULE_LOAD_FAILURE;
31427    }
31428 
31429    if (!(io = io_context_create())) {
31430       ast_log(LOG_ERROR, "Unable to create I/O context\n");
31431       ast_sched_context_destroy(sched);
31432       return AST_MODULE_LOAD_FAILURE;
31433    }
31434 
31435    sip_reloadreason = CHANNEL_MODULE_LOAD;
31436 
31437    can_parse_xml = sip_is_xml_parsable();
31438    if (reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */
31439       return AST_MODULE_LOAD_DECLINE;
31440    }
31441 
31442    /* Prepare the version that does not require DTMF BEGIN frames.
31443     * We need to use tricks such as memcpy and casts because the variable
31444     * has const fields.
31445     */
31446    memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
31447    memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
31448 
31449    if (ast_msg_tech_register(&sip_msg_tech)) {
31450       /* LOAD_FAILURE stops Asterisk, so cleanup is a moot point. */
31451       return AST_MODULE_LOAD_FAILURE;
31452    }
31453 
31454    /* Make sure we can register our sip channel type */
31455    if (ast_channel_register(&sip_tech)) {
31456       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
31457       io_context_destroy(io);
31458       ast_sched_context_destroy(sched);
31459       return AST_MODULE_LOAD_FAILURE;
31460    }
31461 
31462 #ifdef TEST_FRAMEWORK
31463    AST_TEST_REGISTER(test_sip_peers_get);
31464    AST_TEST_REGISTER(test_sip_mwi_subscribe_parse);
31465 #endif
31466 
31467    /* Register AstData providers */
31468    ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers));
31469 
31470    /* Register all CLI functions for SIP */
31471    ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip));
31472 
31473    /* Tell the UDPTL subdriver that we're here */
31474    ast_udptl_proto_register(&sip_udptl);
31475 
31476    /* Tell the RTP engine about our RTP glue */
31477    ast_rtp_glue_register(&sip_rtp_glue);
31478 
31479    /* Register dialplan applications */
31480    ast_register_application_xml(app_dtmfmode, sip_dtmfmode);
31481    ast_register_application_xml(app_sipaddheader, sip_addheader);
31482    ast_register_application_xml(app_sipremoveheader, sip_removeheader);
31483 
31484    /* Register dialplan functions */
31485    ast_custom_function_register(&sip_header_function);
31486    ast_custom_function_register(&sippeer_function);
31487    ast_custom_function_register(&sipchaninfo_function);
31488    ast_custom_function_register(&checksipdomain_function);
31489 
31490    /* Register manager commands */
31491    ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers);
31492    ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer);
31493    ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer);
31494    ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry);
31495    ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify);
31496    sip_poke_all_peers();   
31497    sip_send_all_registers();
31498    sip_send_all_mwi_subscriptions();
31499    initialize_escs();
31500 
31501    if (sip_epa_register(&cc_epa_static_data)) {
31502       return AST_MODULE_LOAD_DECLINE;
31503    }
31504 
31505    if (sip_reqresp_parser_init() == -1) {
31506       ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n");
31507       return AST_MODULE_LOAD_DECLINE;
31508    }
31509 
31510    if (can_parse_xml) {
31511       /* SIP CC agents require the ability to parse XML PIDF bodies
31512        * in incoming PUBLISH requests
31513        */
31514       if (ast_cc_agent_register(&sip_cc_agent_callbacks)) {
31515          return AST_MODULE_LOAD_DECLINE;
31516       }
31517    }
31518    if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) {
31519       return AST_MODULE_LOAD_DECLINE;
31520    }
31521    if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) {
31522       return AST_MODULE_LOAD_DECLINE;
31523    }
31524 
31525    /* And start the monitor for the first time */
31526    restart_monitor();
31527 
31528    ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
31529       "name", RQ_CHAR, 10,
31530       "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1,
31531       "port", RQ_UINTEGER2, 5,
31532       "regseconds", RQ_INTEGER4, 11,
31533       "defaultuser", RQ_CHAR, 10,
31534       "fullcontact", RQ_CHAR, 35,
31535       "regserver", RQ_CHAR, 20,
31536       "useragent", RQ_CHAR, 20,
31537       "lastms", RQ_INTEGER4, 11,
31538       SENTINEL);
31539 
31540 
31541    sip_register_tests();
31542    network_change_event_subscribe();
31543 
31544    return AST_MODULE_LOAD_SUCCESS;
31545 }

static int local_attended_transfer ( struct sip_pvt *  transferer,
struct sip_dual *  current,
struct sip_request *  req,
uint32_t  seqno,
int *  nounlock 
) [static]

Find all call legs and bridge transferee with target called from handle_request_refer.

Note:
this function assumes two locks to begin with, sip_pvt transferer and current.chan1 (the pvt's owner)... 2 additional locks are held at the beginning of the function, targetcall_pvt, and targetcall_pvt's owner channel (which is stored in target.chan1). These 2 locks _MUST_ be let go by the end of the function. Do not be confused into thinking a pvt's owner is the same thing as the channels locked at the beginning of this function, after the masquerade this may not be true. Be consistent and unlock only the exact same pointers that were locked to begin with.
If this function is successful, only the transferer pvt lock will remain on return. Setting nounlock indicates to handle_request_do() that the pvt's owner it locked does not require an unlock.

Definition at line 23895 of file chan_sip.c.

References ao2_t_ref, append_history, ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, ast_cel_report_event(), ast_channel_language(), ast_channel_linkedid(), ast_channel_name(), ast_channel_queue_connected_line_update(), ast_channel_ref, ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_connected_line_build_data(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_READ_ACTION, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_do_masquerade(), AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, ast_indicate(), ast_manager_event_multichan, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_queue_control_data(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_streamfile(), ast_strlen_zero(), ast_waitstream(), attempt_transfer(), EVENT_FLAG_CALL, frame_size, get_sip_pvt_byid_locked(), pbx_builtin_getvar_helper(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, transmit_notify_with_sipfrag(), TRUE, and xfersound.

Referenced by handle_request_refer().

23896 {
23897    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
23898                /* Chan 2: Call from Asterisk to target */
23899    int res = 0;
23900    struct sip_pvt *targetcall_pvt;
23901    struct ast_party_connected_line connected_to_transferee;
23902    struct ast_party_connected_line connected_to_target;
23903    char transferer_linkedid[32];
23904    struct ast_channel *chans[2];
23905 
23906    /* Check if the call ID of the replaces header does exist locally */
23907    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag,
23908       transferer->refer->replaces_callid_fromtag))) {
23909       if (transferer->refer->localtransfer) {
23910          /* We did not find the refered call. Sorry, can't accept then */
23911          /* Let's fake a response from someone else in order
23912             to follow the standard */
23913          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
23914          append_history(transferer, "Xfer", "Refer failed");
23915          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
23916          transferer->refer->status = REFER_FAILED;
23917          return -1;
23918       }
23919       /* Fall through for remote transfers that we did not find locally */
23920       ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
23921       return 0;
23922    }
23923 
23924    /* Ok, we can accept this transfer */
23925    append_history(transferer, "Xfer", "Refer accepted");
23926    if (!targetcall_pvt->owner) { /* No active channel */
23927       ast_debug(4, "SIP attended transfer: Error: No owner of target call\n");
23928       /* Cancel transfer */
23929       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
23930       append_history(transferer, "Xfer", "Refer failed");
23931       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
23932       transferer->refer->status = REFER_FAILED;
23933       sip_pvt_unlock(targetcall_pvt);
23934       if (targetcall_pvt)
23935          ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer");
23936       return -1;
23937    }
23938 
23939    /* We have a channel, find the bridge */
23940    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
23941    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
23942 
23943    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
23944       /* Wrong state of new channel */
23945       if (target.chan2)
23946          ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
23947       else if (target.chan1->_state != AST_STATE_RING)
23948          ast_debug(4, "SIP attended transfer: Error: No target channel\n");
23949       else
23950          ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n");
23951    }
23952 
23953    /* Transfer */
23954    if (sipdebug) {
23955       if (current->chan2)  /* We have two bridges */
23956          ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", ast_channel_name(target.chan1), ast_channel_name(current->chan2));
23957       else        /* One bridge, propably transfer of IVR/voicemail etc */
23958          ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", ast_channel_name(target.chan1), ast_channel_name(current->chan1));
23959    }
23960 
23961    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
23962 
23963    ast_copy_string(transferer_linkedid, ast_channel_linkedid(transferer->owner), sizeof(transferer_linkedid));
23964 
23965    /* Perform the transfer */
23966    chans[0] = transferer->owner;
23967    chans[1] = target.chan1;
23968    ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans,
23969       "TransferMethod: SIP\r\n"
23970       "TransferType: Attended\r\n"
23971       "Channel: %s\r\n"
23972       "Uniqueid: %s\r\n"
23973       "SIP-Callid: %s\r\n"
23974       "TargetChannel: %s\r\n"
23975       "TargetUniqueid: %s\r\n",
23976       ast_channel_name(transferer->owner),
23977       ast_channel_uniqueid(transferer->owner),
23978       transferer->callid,
23979       ast_channel_name(target.chan1),
23980       ast_channel_uniqueid(target.chan1));
23981    ast_party_connected_line_init(&connected_to_transferee);
23982    ast_party_connected_line_init(&connected_to_target);
23983    /* No need to lock current->chan1 here since it was locked in sipsock_read */
23984    ast_party_connected_line_copy(&connected_to_transferee, &current->chan1->connected);
23985    /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */
23986    ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected);
23987    connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
23988    res = attempt_transfer(current, &target);
23989    if (res) {
23990       /* Failed transfer */
23991       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
23992       append_history(transferer, "Xfer", "Refer failed");
23993       ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
23994       /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */
23995       sip_pvt_unlock(targetcall_pvt);
23996       ast_channel_unlock(target.chan1);
23997    } else {
23998       /* Transfer succeeded! */
23999       const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND");
24000 
24001       /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */
24002       ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2);
24003 
24004       /* Tell transferer that we're done. */
24005       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
24006       append_history(transferer, "Xfer", "Refer succeeded");
24007       transferer->refer->status = REFER_200OK;
24008       if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, ast_channel_language(target.chan2)) >= 0) {
24009          ast_waitstream(target.chan2, "");
24010       }
24011 
24012       /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then
24013        * can queue connected line updates where they need to go.
24014        *
24015        * before a masquerade, all channel and pvt locks must be unlocked.  Any recursive
24016        * channel locks held before this function invalidates channel container locking order.
24017        * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1)
24018        * it is possible for current.chan1 to be destroyed in the pbx thread.  To prevent this
24019        * we must give c a reference before any unlocking takes place.
24020        */
24021 
24022       ast_channel_ref(current->chan1);
24023       ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/
24024       ast_channel_unlock(target.chan1);
24025       *nounlock = 1;  /* we just unlocked the dialog's channel and have no plans of locking it again. */
24026       sip_pvt_unlock(targetcall_pvt);
24027       sip_pvt_unlock(transferer);
24028 
24029       ast_do_masquerade(target.chan1);
24030 
24031       ast_indicate(target.chan1, AST_CONTROL_UNHOLD);
24032       if (target.chan2) {
24033          ast_indicate(target.chan2, AST_CONTROL_UNHOLD);
24034       }
24035 
24036       if (current->chan2 && current->chan2->_state == AST_STATE_RING) {
24037          ast_indicate(target.chan1, AST_CONTROL_RINGING);
24038       }
24039 
24040       if (target.chan2) {
24041          ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
24042          ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL);
24043       } else {
24044          /* Since target.chan1 isn't actually connected to another channel, there is no way for us
24045           * to queue a frame so that its connected line status will be updated.
24046           *
24047           * Instead, we use the somewhat hackish approach of using a special control frame type that
24048           * instructs ast_read to perform a specific action. In this case, the frame we queue tells
24049           * ast_read to call the connected line interception macro configured for target.chan1.
24050           */
24051          struct ast_control_read_action_payload *frame_payload;
24052          int payload_size;
24053          int frame_size;
24054          unsigned char connected_line_data[1024];
24055          payload_size = ast_connected_line_build_data(connected_line_data,
24056             sizeof(connected_line_data), &connected_to_target, NULL);
24057          frame_size = payload_size + sizeof(*frame_payload);
24058          if (payload_size != -1 && (frame_payload = alloca(frame_size))) {
24059             frame_payload->payload_size = payload_size;
24060             memcpy(frame_payload->payload, connected_line_data, payload_size);
24061             frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
24062             ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size);
24063          }
24064          /* In addition to queueing the read action frame so that target.chan1's connected line info
24065           * will be updated, we also are going to queue a plain old connected line update on target.chan1. This
24066           * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel.
24067           */
24068          ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
24069 
24070       }
24071       sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */
24072 
24073       ast_channel_unref(current->chan1);
24074    }
24075 
24076    /* at this point if the transfer is successful only the transferer pvt should be locked. */
24077    ast_party_connected_line_free(&connected_to_target);
24078    ast_party_connected_line_free(&connected_to_transferee);
24079    if (targetcall_pvt)
24080       ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt");
24081    return 1;
24082 }

static void lws2sws ( struct ast_str msgbuf  )  [static]

Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.

Definition at line 8665 of file chan_sip.c.

References ast_str_strlen(), and len().

Referenced by handle_request_do().

08666 {
08667    char *msgbuf = data->str;
08668    int len = ast_str_strlen(data);
08669    int h = 0, t = 0;
08670    int lws = 0;
08671 
08672    for (; h < len;) {
08673       /* Eliminate all CRs */
08674       if (msgbuf[h] == '\r') {
08675          h++;
08676          continue;
08677       }
08678       /* Check for end-of-line */
08679       if (msgbuf[h] == '\n') {
08680          /* Check for end-of-message */
08681          if (h + 1 == len)
08682             break;
08683          /* Check for a continuation line */
08684          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') {
08685             /* Merge continuation line */
08686             h++;
08687             continue;
08688          }
08689          /* Propagate LF and start new line */
08690          msgbuf[t++] = msgbuf[h++];
08691          lws = 0;
08692          continue;
08693       }
08694       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') {
08695          if (lws) {
08696             h++;
08697             continue;
08698          }
08699          msgbuf[t++] = msgbuf[h++];
08700          lws = 1;
08701          continue;
08702       }
08703       msgbuf[t++] = msgbuf[h++];
08704       if (lws)
08705          lws = 0;
08706    }
08707    msgbuf[t] = '\0';
08708    data->used = t;
08709 }

static void make_our_tag ( char *  tagbuf,
size_t  len 
) [static]

Make our SIP dialog tag.

Definition at line 7758 of file chan_sip.c.

References ast_random().

Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), transmit_register(), and transmit_response_using_temp().

07759 {
07760    snprintf(tagbuf, len, "as%08lx", ast_random());
07761 }

static int manager_show_registry ( struct mansession s,
const struct message m 
) [static]

Show SIP registrations in the manager API.

Definition at line 17253 of file chan_sip.c.

References ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, regl, regstate2str(), S_OR, and total.

Referenced by load_module().

17254 {
17255    const char *id = astman_get_header(m, "ActionID");
17256    char idtext[256] = "";
17257    int total = 0;
17258 
17259    if (!ast_strlen_zero(id))
17260       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
17261 
17262    astman_send_listack(s, m, "Registrations will follow", "start");
17263 
17264    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17265       ASTOBJ_RDLOCK(iterator);
17266       astman_append(s,
17267          "Event: RegistryEntry\r\n"
17268          "%s"
17269          "Host: %s\r\n"
17270          "Port: %d\r\n"
17271          "Username: %s\r\n"
17272          "Domain: %s\r\n"
17273          "DomainPort: %d\r\n"
17274          "Refresh: %d\r\n"
17275          "State: %s\r\n"
17276          "RegistrationTime: %ld\r\n"
17277          "\r\n",
17278          idtext,
17279          iterator->hostname,
17280          iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
17281          iterator->username,
17282          S_OR(iterator->regdomain,iterator->hostname),
17283          iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT,
17284          iterator->refresh,
17285          regstate2str(iterator->regstate),
17286          (long) iterator->regtime.tv_sec);
17287       ASTOBJ_UNLOCK(iterator);
17288       total++;
17289    } while(0));
17290 
17291    astman_append(s,
17292       "Event: RegistrationsComplete\r\n"
17293       "EventList: Complete\r\n"
17294       "ListItems: %d\r\n"
17295       "%s"
17296       "\r\n", total, idtext);
17297    
17298    return 0;
17299 }

static int manager_sip_qualify_peer ( struct mansession s,
const struct message m 
) [static]

Qualify SIP peers in the manager API.

Definition at line 18030 of file chan_sip.c.

References _sip_qualify_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().

Referenced by load_module().

18031 {
18032    const char *a[4];
18033    const char *peer;
18034 
18035    peer = astman_get_header(m, "Peer");
18036    if (ast_strlen_zero(peer)) {
18037       astman_send_error(s, m, "Peer: <name> missing.");
18038       return 0;
18039    }
18040    a[0] = "sip";
18041    a[1] = "qualify";
18042    a[2] = "peer";
18043    a[3] = peer;
18044 
18045    _sip_qualify_peer(1, -1, s, m, 4, a);
18046    astman_append(s, "\r\n\r\n" );
18047    return 0;
18048 }

static int manager_sip_show_peer ( struct mansession s,
const struct message m 
) [static]

Show SIP peers in the manager API.

Definition at line 17971 of file chan_sip.c.

References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().

Referenced by load_module().

17972 {
17973    const char *a[4];
17974    const char *peer;
17975 
17976    peer = astman_get_header(m, "Peer");
17977    if (ast_strlen_zero(peer)) {
17978       astman_send_error(s, m, "Peer: <name> missing.");
17979       return 0;
17980    }
17981    a[0] = "sip";
17982    a[1] = "show";
17983    a[2] = "peer";
17984    a[3] = peer;
17985 
17986    _sip_show_peer(1, -1, s, m, 4, a);
17987    astman_append(s, "\r\n" );
17988    return 0;
17989 }

static int manager_sip_show_peers ( struct mansession s,
const struct message m 
) [static]

Show SIP peers in the manager API.

Definition at line 17303 of file chan_sip.c.

References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.

Referenced by load_module().

17304 {
17305    const char *id = astman_get_header(m, "ActionID");
17306    const char *a[] = {"sip", "show", "peers"};
17307    char idtext[256] = "";
17308    int total = 0;
17309 
17310    if (!ast_strlen_zero(id))
17311       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
17312 
17313    astman_send_listack(s, m, "Peer status list will follow", "start");
17314    /* List the peers in separate manager events */
17315    _sip_show_peers(-1, &total, s, m, 3, a);
17316    /* Send final confirmation */
17317    astman_append(s,
17318    "Event: PeerlistComplete\r\n"
17319    "EventList: Complete\r\n"
17320    "ListItems: %d\r\n"
17321    "%s"
17322    "\r\n", total, idtext);
17323    return 0;
17324 }

static int manager_sipnotify ( struct mansession s,
const struct message m 
) [static]

Definition at line 13329 of file chan_sip.c.

References ast_log(), ast_set_flag, ast_str_append(), ast_str_strlen(), ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), create_addr(), dialog_unlink_all(), LOG_WARNING, ast_variable::name, ast_variable::next, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), ast_variable::value, and var.

Referenced by load_module().

13330 {
13331    const char *channame = astman_get_header(m, "Channel");
13332    struct ast_variable *vars = astman_get_variables(m);
13333    struct sip_pvt *p;
13334    struct ast_variable *header, *var;
13335 
13336    if (ast_strlen_zero(channame)) {
13337       astman_send_error(s, m, "SIPNotify requires a channel name");
13338       return 0;
13339    }
13340 
13341    if (!strncasecmp(channame, "sip/", 4)) {
13342       channame += 4;
13343    }
13344 
13345    if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
13346       astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
13347       return 0;
13348    }
13349 
13350    if (create_addr(p, channame, NULL, 0, NULL)) {
13351       /* Maybe they're not registered, etc. */
13352       dialog_unlink_all(p);
13353       dialog_unref(p, "unref dialog inside for loop" );
13354       /* sip_destroy(p); */
13355       astman_send_error(s, m, "Could not create address");
13356       return 0;
13357    }
13358 
13359    /* Notify is outgoing call */
13360    ast_set_flag(&p->flags[0], SIP_OUTGOING);
13361    sip_notify_allocate(p);
13362 
13363    p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
13364 
13365    for (var = vars; var; var = var->next) {
13366       if (!strcasecmp(var->name, "Content")) {
13367          if (ast_str_strlen(p->notify->content))
13368             ast_str_append(&p->notify->content, 0, "\r\n");
13369          ast_str_append(&p->notify->content, 0, "%s", var->value);
13370       } else if (!strcasecmp(var->name, "Content-Length")) {
13371          ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring");
13372       } else {
13373          header->next = ast_variable_new(var->name, var->value, "");
13374          header = header->next;
13375       }
13376    }
13377 
13378    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
13379    transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
13380    dialog_unref(p, "bump down the count of p since we're done with it.");
13381 
13382    astman_send_ack(s, m, "Notify Sent");
13383    ast_variables_destroy(vars);
13384    return 0;
13385 }

static int map_s_x ( const struct _map_x_s *  table,
const char *  s,
int  errorvalue 
) [static]

map from a string to an integer value, case insensitive. If no match is found, return errorvalue.

Definition at line 2278 of file chan_sip.c.

Referenced by str2dtmfmode(), str2stmode(), and str2strefresher().

02279 {
02280    const struct _map_x_s *cur;
02281 
02282    for (cur = table; cur->s; cur++) {
02283       if (!strcasecmp(cur->s, s)) {
02284          return cur->x;
02285       }
02286    }
02287    return errorvalue;
02288 }

static const char* map_x_s ( const struct _map_x_s *  table,
int  x,
const char *  errorstring 
) [static]

map from an integer value to a string. If no match is found, return errorstring

Definition at line 2263 of file chan_sip.c.

Referenced by allowoverlap2str(), autocreatepeer2str(), dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), and strefresher2str().

02264 {
02265    const struct _map_x_s *cur;
02266 
02267    for (cur = table; cur->s; cur++) {
02268       if (cur->x == x) {
02269          return cur->s;
02270       }
02271    }
02272    return errorstring;
02273 }

static void mark_method_allowed ( unsigned int *  allowed_methods,
enum sipmethod  method 
) [static]

Definition at line 8566 of file chan_sip.c.

Referenced by handle_response(), handle_response_info(), handle_response_message(), mark_parsed_methods(), and set_pvt_allowed_methods().

08567 {
08568    (*allowed_methods) |= (1 << method);
08569 }

static void mark_method_unallowed ( unsigned int *  allowed_methods,
enum sipmethod  method 
) [static]

Definition at line 8571 of file chan_sip.c.

Referenced by handle_response(), handle_response_info(), handle_response_message(), and handle_response_publish().

08572 {
08573    (*allowed_methods) &= ~(1 << method);
08574 }

static void mark_parsed_methods ( unsigned int *  methods,
char *  methods_str 
) [static]

Definition at line 8582 of file chan_sip.c.

References ast_skip_blanks(), ast_strlen_zero(), find_sip_method(), mark_method_allowed(), and strsep().

Referenced by build_peer(), parse_allowed_methods(), and reload_config().

08583 {
08584    char *method;
08585    for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) {
08586       int id = find_sip_method(ast_skip_blanks(method));
08587       if (id == SIP_UNKNOWN) {
08588          continue;
08589       }
08590       mark_method_allowed(methods, id);
08591    }
08592 }

static int match_and_cleanup_peer_sched ( void *  peerobj,
void *  arg,
int  flags 
) [static]

Definition at line 2893 of file chan_sip.c.

References ast_dnsmgr_release(), CMP_MATCH, peer_sched_cleanup(), SIP_PEERS_ALL, and sip_unref_peer().

Referenced by unlink_peers_from_tables().

02894 {
02895    struct sip_peer *peer = peerobj;
02896    peer_unlink_flag_t which = *(peer_unlink_flag_t *)arg;
02897 
02898    if (which == SIP_PEERS_ALL || peer->the_mark) {
02899       peer_sched_cleanup(peer);
02900       if (peer->dnsmgr) {
02901          ast_dnsmgr_release(peer->dnsmgr);
02902          peer->dnsmgr = NULL;
02903          sip_unref_peer(peer, "Release peer from dnsmgr");
02904       }
02905       return CMP_MATCH;
02906    }
02907    return 0;
02908 }

static enum match_req_res match_req_to_dialog ( struct sip_pvt *  sip_pvt_ptr,
struct match_req_args arg 
) [static]

Definition at line 8012 of file chan_sip.c.

References ast_strlen_zero(), ast_test_flag, match_req_args::authentication_present, match_req_args::callid, match_req_args::fromtag, match_req_args::method, match_req_args::respid, match_req_args::ruri, match_req_args::seqno, SIP_REQ_FORKED, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, sip_uri_cmp(), match_req_args::totag, match_req_args::viabranch, and match_req_args::viasentby.

Referenced by find_call().

08013 {
08014    const char *init_ruri = NULL;
08015    if (sip_pvt_ptr->initreq.headers) {
08016       init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2);
08017    }
08018 
08019    /*
08020     * Match Tags and call-id to Dialog
08021     */
08022    if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) {
08023       /* call-id does not match. */
08024       return SIP_REQ_NOT_MATCH;
08025    }
08026    if (arg->method == SIP_RESPONSE) {
08027       /* Verify fromtag of response matches the tag we gave them. */
08028       if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) {
08029          /* fromtag from response does not match our tag */
08030          return SIP_REQ_NOT_MATCH;
08031       }
08032 
08033       /* Verify totag if we have one stored for this dialog, but never be strict about this for
08034        * a response until the dialog is established */
08035       if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
08036          if (ast_strlen_zero(arg->totag)) {
08037             /* missing totag when they already gave us one earlier */
08038             return SIP_REQ_NOT_MATCH;
08039          }
08040          /* compare the totag of response with the tag we have stored for them */
08041          if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) {
08042             /* totag did not match what we had stored for them. */
08043             char invite_branch[32] = { 0, };
08044             if (sip_pvt_ptr->invite_branch) {
08045                snprintf(invite_branch, sizeof(invite_branch), "z9hG4bK%08x", (int) sip_pvt_ptr->invite_branch);
08046             }
08047             /* Forked Request Detection
08048              *
08049              * If this is a 200ok response and the totags do not match, this
08050              * might be a forked response to an outgoing Request. Detection of
08051              * a forked response must meet the criteria below.
08052              *
08053              * 1. must be a 2xx Response
08054              * 2. call-d equal to call-id of Request. this is done earlier
08055              * 3. from-tag equal to from-tag of Request. this is done earlier
08056              * 4. branch parameter equal to branch of inital Request
08057              * 5. to-tag _NOT_ equal to previous 2xx response that already established the dialog.
08058              */
08059             if ((arg->respid == 200) &&
08060                !ast_strlen_zero(invite_branch) &&
08061                !ast_strlen_zero(arg->viabranch) &&
08062                !strcmp(invite_branch, arg->viabranch)) {
08063                return SIP_REQ_FORKED;
08064             }
08065 
08066             /* The totag did not match the one we had stored, and this is not a Forked Request. */
08067             return SIP_REQ_NOT_MATCH;
08068          }
08069       }
08070    } else {
08071       /* Verify the fromtag of Request matches the tag they provided earlier.
08072        * If this is a Request with authentication credentials, forget their old
08073        * tag as it is not valid after the 401 or 407 response. */
08074       if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) {
08075          /* their tag does not match the one was have stored for them */
08076          return SIP_REQ_NOT_MATCH;
08077       }
08078       /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */
08079       if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) {
08080          /* totag from Request does not match our tag */
08081          return SIP_REQ_NOT_MATCH;
08082       }
08083    }
08084 
08085    /*
08086     * Compare incoming request against initial transaction.
08087     * 
08088     * This is a best effort attempt at distinguishing forked requests from
08089     * our initial transaction.  If all the elements are NOT in place to evaluate
08090     * this, this block is ignored and the dialog match is made regardless.
08091     * Once the totag is established after the dialog is confirmed, this is not necessary.
08092     *
08093     * CRITERIA required for initial transaction matching.
08094     * 
08095     * 1. Is a Request
08096     * 2. Callid and theirtag match (this is done in the dialog matching block)
08097     * 3. totag is NOT present
08098     * 4. CSeq matchs our initial transaction's cseq number
08099     * 5. pvt has init via branch parameter stored
08100     */
08101    if ((arg->method != SIP_RESPONSE) &&                 /* must be a Request */
08102       ast_strlen_zero(arg->totag) &&                   /* must not have a totag */
08103       (sip_pvt_ptr->init_icseq == arg->seqno) &&       /* the cseq must be the same as this dialogs initial cseq */
08104       !ast_strlen_zero(sip_pvt_ptr->initviabranch) &&  /* The dialog must have started with a RFC3261 compliant branch tag */
08105       init_ruri) {                                     /* the dialog must have an initial request uri associated with it */
08106       /* This Request matches all the criteria required for Loop/Merge detection.
08107        * Now we must go down the path of comparing VIA's and RURIs. */
08108       if (ast_strlen_zero(arg->viabranch) ||
08109          strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) ||
08110          ast_strlen_zero(arg->viasentby) ||
08111          strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) {
08112          /* At this point, this request does not match this Dialog.*/
08113 
08114          /* if methods are different this is just a mismatch */
08115          if ((sip_pvt_ptr->method != arg->method)) {
08116             return SIP_REQ_NOT_MATCH;
08117          }
08118 
08119          /* If RUIs are different, this is a forked request to a separate URI.
08120           * Returning a mismatch allows this Request to be processed separately. */
08121          if (sip_uri_cmp(init_ruri, arg->ruri)) {
08122             /* not a match, request uris are different */
08123             return SIP_REQ_NOT_MATCH;
08124          }
08125 
08126          /* Loop/Merge Detected
08127           *
08128           * ---Current Matches to Initial Request---
08129           * request uri
08130           * Call-id
08131           * their-tag
08132           * no totag present
08133           * method
08134           * cseq
08135           *
08136           * --- Does not Match Initial Request ---
08137           * Top Via
08138           *
08139           * Without the same Via, this can not match our initial transaction for this dialog,
08140           * but given that this Request matches everything else associated with that initial
08141           * Request this is most certainly a Forked request in which we have already received
08142           * part of the fork.
08143           */
08144          return SIP_REQ_LOOP_DETECTED;
08145       }
08146    } /* end of Request Via check */
08147 
08148    /* Match Authentication Request.
08149     *
08150     * A Request with an Authentication header must come back with the
08151     * same Request URI.  Otherwise it is not a match.
08152     */
08153    if ((arg->method != SIP_RESPONSE) &&      /* Must be a Request type to even begin checking this */
08154       ast_strlen_zero(arg->totag) &&        /* no totag is present to match */
08155       arg->authentication_present &&        /* Authentication header is present in Request */
08156       sip_uri_cmp(init_ruri, arg->ruri)) {  /* Compare the Request URI of both the last Request and this new one */
08157 
08158       /* Authentication was provided, but the Request URI did not match the last one on this dialog. */
08159       return SIP_REQ_NOT_MATCH;
08160    }
08161 
08162    return SIP_REQ_MATCH;
08163 }

static int method_match ( enum sipmethod  id,
const char *  name 
) [static]

returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send

Definition at line 3180 of file chan_sip.c.

References len(), sip_methods, and text.

Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().

03181 {
03182    int len = strlen(sip_methods[id].text);
03183    int l_name = name ? strlen(name) : 0;
03184    /* true if the string is long enough, and ends with whitespace, and matches */
03185    return (l_name >= len && name[len] < 33 &&
03186       !strncasecmp(sip_methods[id].text, name, len));
03187 }

static void mwi_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Receive MWI events that we have subscribed to.

Definition at line 14965 of file chan_sip.c.

References sip_send_mwi_to_peer().

14966 {
14967    struct sip_peer *peer = userdata;
14968 
14969    sip_send_mwi_to_peer(peer, 0);
14970 }

static void network_change_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Definition at line 14995 of file chan_sip.c.

References ast_debug, ast_sched_add(), and network_change_event_sched_cb().

14996 {
14997    ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n");
14998    if (network_change_event_sched_id == -1) {
14999       network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
15000    }
15001 }

static int network_change_event_sched_cb ( const void *  data  )  [static]

Definition at line 14987 of file chan_sip.c.

References sip_send_all_mwi_subscriptions(), and sip_send_all_registers().

14988 {
14989    network_change_event_sched_id = -1;
14990    sip_send_all_registers();
14991    sip_send_all_mwi_subscriptions();
14992    return 0;
14993 }

static void network_change_event_subscribe ( void   )  [static]

static void network_change_event_unsubscribe ( void   )  [static]

static struct sip_proxy* obproxy_get ( struct sip_pvt *  dialog,
struct sip_peer *  peer 
) [static, read]

Get default outbound proxy or global proxy.

Definition at line 3152 of file chan_sip.c.

References append_history, ast_debug, and sip_cfg.

Referenced by __sip_subscribe_mwi_do(), create_addr(), create_addr_from_peer(), and transmit_register().

03153 {
03154    if (peer && peer->outboundproxy) {
03155       if (sipdebug) {
03156          ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n");
03157       }
03158       append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name);
03159       return peer->outboundproxy;
03160    }
03161    if (sip_cfg.outboundproxy.name[0]) {
03162       if (sipdebug) {
03163          ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n");
03164       }
03165       append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name);
03166       return &sip_cfg.outboundproxy;
03167    }
03168    if (sipdebug) {
03169       ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n");
03170    }
03171    return NULL;
03172 }

static void on_dns_update_mwi ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
) [static]

Definition at line 12838 of file chan_sip.c.

References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), and ast_strdupa.

Referenced by __sip_subscribe_mwi_do().

12839 {
12840    struct sip_subscription_mwi *mwi = data;
12841    const char *old_str;
12842 
12843    /* This shouldn't happen, but just in case */
12844    if (ast_sockaddr_isnull(new)) {
12845       ast_debug(1, "Empty sockaddr change...ignoring!\n");
12846       return;
12847    }
12848 
12849    old_str = ast_strdupa(ast_sockaddr_stringify(old));
12850    ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, old_str, ast_sockaddr_stringify(new));
12851    ast_sockaddr_copy(&mwi->us, new);
12852 }

static void on_dns_update_peer ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
) [static]

Definition at line 12809 of file chan_sip.c.

References ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, and default_sip_port().

Referenced by build_peer(), and transmit_register().

12810 {
12811    struct sip_peer *peer = data;
12812    const char *old_str;
12813 
12814    /* This shouldn't happen, but just in case */
12815    if (ast_sockaddr_isnull(new)) {
12816       ast_debug(1, "Empty sockaddr change...ignoring!\n");
12817       return;
12818    }
12819 
12820    if (!ast_sockaddr_isnull(&peer->addr)) {
12821       ao2_unlink(peers_by_ip, peer);
12822    }
12823 
12824    if (!ast_sockaddr_port(new)) {
12825       ast_sockaddr_set_port(new, default_sip_port(peer->socket.type));
12826    }
12827 
12828    old_str = ast_strdupa(ast_sockaddr_stringify(old));
12829    ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, old_str, ast_sockaddr_stringify(new));
12830 
12831    ao2_lock(peer);
12832    ast_sockaddr_copy(&peer->addr, new);
12833    ao2_unlock(peer);
12834 
12835    ao2_link(peers_by_ip, peer);
12836 }

static void on_dns_update_registry ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
) [static]

Definition at line 12788 of file chan_sip.c.

References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, and S_OR.

Referenced by transmit_register().

12789 {
12790    struct sip_registry *reg = data;
12791    const char *old_str;
12792 
12793    /* This shouldn't happen, but just in case */
12794    if (ast_sockaddr_isnull(new)) {
12795       ast_debug(1, "Empty sockaddr change...ignoring!\n");
12796       return;
12797    }
12798 
12799    if (!ast_sockaddr_port(new)) {
12800       ast_sockaddr_set_port(new, reg->portno);
12801    }
12802 
12803    old_str = ast_strdupa(ast_sockaddr_stringify(old));
12804 
12805    ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), old_str, ast_sockaddr_stringify(new));
12806    ast_sockaddr_copy(&reg->us, new);
12807 }

static unsigned int parse_allowed_methods ( struct sip_request *  req  )  [static]

parse the Allow header to see what methods the endpoint we are communicating with allows.

We parse the allow header on incoming Registrations and save the result to the SIP peer that is registering. When the registration expires, we clear what we know about the peer's allowed methods. When the peer re-registers, we once again parse to see if the list of allowed methods has changed.

For peers that do not register, we parse the first message we receive during a call to see what is allowed, and save the information for the duration of the call.

Parameters:
req The SIP request we are parsing
Return values:
The methods allowed

Definition at line 8609 of file chan_sip.c.

References ast_strdupa, ast_strip_quoted(), ast_strlen_zero(), mark_parsed_methods(), and sip_get_header().

Referenced by set_pvt_allowed_methods().

08610 {
08611    char *allow = ast_strdupa(sip_get_header(req, "Allow"));
08612    unsigned int allowed_methods = SIP_UNKNOWN;
08613 
08614    if (ast_strlen_zero(allow)) {
08615       /* I have witnessed that REGISTER requests from Polycom phones do not
08616        * place the phone's allowed methods in an Allow header. Instead, they place the
08617        * allowed methods in a methods= parameter in the Contact header.
08618        */
08619       char *contact = ast_strdupa(sip_get_header(req, "Contact"));
08620       char *methods = strstr(contact, ";methods=");
08621 
08622       if (ast_strlen_zero(methods)) {
08623          /* RFC 3261 states:
08624           *
08625           * "The absence of an Allow header field MUST NOT be
08626           * interpreted to mean that the UA sending the message supports no
08627           * methods.   Rather, it implies that the UA is not providing any
08628           * information on what methods it supports."
08629           *
08630           * For simplicity, we'll assume that the peer allows all known
08631           * SIP methods if they have no Allow header. We can then clear out the necessary
08632           * bits if the peer lets us know that we have sent an unsupported method.
08633           */
08634          return UINT_MAX;
08635       }
08636       allow = ast_strip_quoted(methods + 9, "\"", "\"");
08637    }
08638    mark_parsed_methods(&allowed_methods, allow);
08639    return allowed_methods;
08640 }

static void parse_copy ( struct sip_request *  dst,
const struct sip_request *  src 
) [static]

Copy SIP request, parse it.

Definition at line 4101 of file chan_sip.c.

References copy_request(), and parse_request().

Referenced by send_request(), and send_response().

04102 {
04103    copy_request(dst, src);
04104    parse_request(dst);
04105 }

int parse_minse ( const char *  p_hdrval,
int *const   p_interval 
) [static]

Session-Timers: Function for parsing Min-SE header.

Definition at line 27063 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), ast_strlen_zero(), and LOG_WARNING.

Referenced by handle_request_invite(), and proc_422_rsp().

27064 {
27065    if (ast_strlen_zero(p_hdrval)) {
27066       ast_log(LOG_WARNING, "Null Min-SE header\n");
27067       return -1;
27068    }
27069 
27070    *p_interval = 0;
27071    p_hdrval = ast_skip_blanks(p_hdrval);
27072    if (!sscanf(p_hdrval, "%30d", p_interval)) {
27073       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
27074       return -1;
27075    }
27076 
27077    ast_debug(2, "Received Min-SE: %d\n", *p_interval);
27078    return 0;
27079 }

static void parse_moved_contact ( struct sip_pvt *  p,
struct sip_request *  req,
char **  name,
char **  number,
int  set_call_forward 
) [static]

Parse 302 Moved temporalily response.

Todo:
XXX Doesn't redirect over TLS on sips: uri's. If we get a redirect to a SIPS: uri, this needs to be going back to the dialplan (this is a request for a secure signalling path). Note that transport=tls is deprecated, but we need to support it on incoming requests.

Definition at line 20409 of file chan_sip.c.

References ao2_ref, ast_copy_string(), ast_debug, ast_log(), ast_strdup, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_uri_sip_user, find_closing_quote(), get_in_brackets(), LOG_NOTICE, pbx_builtin_setvar_helper(), remove_uri_parameters(), set_socket_transport(), sip_get_header(), sip_get_transport(), and strcasestr().

Referenced by change_redirecting_information().

20410 {
20411    char contact[SIPBUFSIZE];
20412    char *contact_name = NULL;
20413    char *contact_number = NULL;
20414    char *separator, *trans;
20415    char *domain;
20416    enum sip_transport transport = SIP_TRANSPORT_UDP;
20417 
20418    ast_copy_string(contact, sip_get_header(req, "Contact"), sizeof(contact));
20419    if ((separator = strchr(contact, ',')))
20420       *separator = '\0';
20421 
20422    contact_number = get_in_brackets(contact);
20423    if ((trans = strcasestr(contact_number, ";transport="))) {
20424       trans += 11;
20425 
20426       if ((separator = strchr(trans, ';')))
20427          *separator = '\0';
20428 
20429       if (!strncasecmp(trans, "tcp", 3))
20430          transport = SIP_TRANSPORT_TCP;
20431       else if (!strncasecmp(trans, "tls", 3))
20432          transport = SIP_TRANSPORT_TLS;
20433       else {
20434          if (strncasecmp(trans, "udp", 3))
20435             ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number);
20436          /* This will assume UDP for all unknown transports */
20437          transport = SIP_TRANSPORT_UDP;
20438       }
20439    }
20440    contact_number = remove_uri_parameters(contact_number);
20441 
20442    if (p->socket.tcptls_session) {
20443       ao2_ref(p->socket.tcptls_session, -1);
20444       p->socket.tcptls_session = NULL;
20445    }
20446 
20447    set_socket_transport(&p->socket, transport);
20448 
20449    if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
20450       char *host = NULL;
20451       if (!strncasecmp(contact_number, "sip:", 4))
20452          contact_number += 4;
20453       else if (!strncasecmp(contact_number, "sips:", 5))
20454          contact_number += 5;
20455       separator = strchr(contact_number, '/');
20456       if (separator)
20457          *separator = '\0';
20458       if ((host = strchr(contact_number, '@'))) {
20459          *host++ = '\0';
20460          ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, sip_get_transport(transport), host);
20461          if (p->owner)
20462             ast_channel_call_forward_build(p->owner, "SIP/%s::::%s@%s", contact_number, sip_get_transport(transport), host);
20463       } else {
20464          ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", sip_get_transport(transport), contact_number);
20465          if (p->owner)
20466             ast_channel_call_forward_build(p->owner, "SIP/::::%s@%s", sip_get_transport(transport), contact_number);
20467       }
20468    } else {
20469       separator = strchr(contact, '@');
20470       if (separator) {
20471          *separator++ = '\0';
20472          domain = separator;
20473       } else {
20474          /* No username part */
20475          domain = contact;
20476       }
20477       separator = strchr(contact, '/');   /* WHEN do we hae a forward slash in the URI? */
20478       if (separator)
20479          *separator = '\0';
20480 
20481       if (!strncasecmp(contact_number, "sip:", 4))
20482          contact_number += 4;
20483       else if (!strncasecmp(contact_number, "sips:", 5))
20484          contact_number += 5;
20485       separator = strchr(contact_number, ';');  /* And username ; parameters? */
20486       if (separator)
20487          *separator = '\0';
20488       ast_uri_decode(contact_number, ast_uri_sip_user);
20489       if (set_call_forward) {
20490          ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain);
20491          if (p->owner) {
20492             pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
20493             ast_channel_call_forward_set(p->owner, contact_number);
20494          }
20495       }
20496    }
20497 
20498    /* We've gotten the number for the contact, now get the name */
20499 
20500    if (*contact == '\"') {
20501       contact_name = contact + 1;
20502       if (!(separator = (char *)find_closing_quote(contact_name, NULL))) {
20503          ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact);
20504       }
20505       *separator = '\0';
20506    }
20507 
20508    if (name && !ast_strlen_zero(contact_name)) {
20509       *name = ast_strdup(contact_name);
20510    }
20511    if (number) {
20512       *number = ast_strdup(contact_number);
20513    }
20514 }

static int parse_ok_contact ( struct sip_pvt *  pvt,
struct sip_request *  req 
) [static]

Save contact header for 200 OK on INVITE.

Definition at line 14297 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, get_in_brackets(), sip_get_header(), and TRUE.

Referenced by forked_invite_init(), handle_request_invite(), handle_request_subscribe(), and handle_response_invite().

14298 {
14299    char contact[SIPBUFSIZE];
14300    char *c;
14301 
14302    /* Look for brackets */
14303    ast_copy_string(contact, sip_get_header(req, "Contact"), sizeof(contact));
14304    c = get_in_brackets(contact);
14305 
14306    /* Save full contact to call pvt for later bye or re-invite */
14307    ast_string_field_set(pvt, fullcontact, c);
14308 
14309    /* Save URI for later ACKs, BYE or RE-invites */
14310    ast_string_field_set(pvt, okcontacturi, c);
14311 
14312    /* We should return false for URI:s we can't handle,
14313       like tel:, mailto:,ldap: etc */
14314    return TRUE;      
14315 }

static enum parse_register_result parse_register_contact ( struct sip_pvt *  pvt,
struct sip_peer *  p,
struct sip_request *  req 
) [static]

Parse contact header and save registration (peer registration).

Todo:
Check NAPTR/SRV if we have not got a port in the URI

Definition at line 14404 of file chan_sip.c.

References __get_header(), ao2_t_link, ao2_t_unlink, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_sched_when(), AST_SENSE_ALLOW, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, copy_socket_data(), default_sip_port(), EVENT_FLAG_SYSTEM, expire_register(), FALSE, get_in_brackets(), get_transport_str2enum(), LOG_NOTICE, LOG_WARNING, manager_event, parse_uri_legacy_check(), register_peer_exten(), set_socket_transport(), sip_cfg, sip_get_header(), sip_poke_peer(), sip_ref_peer(), sip_unref_peer(), strcasestr(), strsep(), and TRUE.

Referenced by register_verify().

14405 {
14406    char contact[SIPBUFSIZE];
14407    char data[SIPBUFSIZE];
14408    const char *expires = sip_get_header(req, "Expires");
14409    int expire = atoi(expires);
14410    char *curi = NULL, *hostport = NULL, *transport = NULL;
14411    int transport_type;
14412    const char *useragent;
14413    struct ast_sockaddr oldsin, testsa;
14414    char *firstcuri = NULL;
14415    int start = 0;
14416    int wildcard_found = 0;
14417    int single_binding_found = 0;
14418 
14419    ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
14420 
14421    if (ast_strlen_zero(expires)) {  /* No expires header, try look in Contact: */
14422       char *s = strcasestr(contact, ";expires=");
14423       if (s) {
14424          expires = strsep(&s, ";"); /* trim ; and beyond */
14425          if (sscanf(expires + 9, "%30d", &expire) != 1) {
14426             expire = default_expiry;
14427          }
14428       } else {
14429          /* Nothing has been specified */
14430          expire = default_expiry;
14431       }
14432    }
14433 
14434    copy_socket_data(&pvt->socket, &req->socket);
14435 
14436    do {
14437       /* Look for brackets */
14438       curi = contact;
14439       if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
14440          strsep(&curi, ";");  /* This is Header options, not URI options */
14441       curi = get_in_brackets(contact);
14442       if (!firstcuri) {
14443          firstcuri = ast_strdupa(curi);
14444       }
14445 
14446       if (!strcasecmp(curi, "*")) {
14447          wildcard_found = 1;
14448       } else {
14449          single_binding_found = 1;
14450       }
14451 
14452       if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) {
14453          /* Contact header parameter "*" detected, so punt if: Expires header is missing,
14454           * Expires value is not zero, or another Contact header is present. */
14455          return PARSE_REGISTER_FAILED;
14456       }
14457 
14458       ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
14459    } while (!ast_strlen_zero(contact));
14460    curi = firstcuri;
14461 
14462    /* if they did not specify Contact: or Expires:, they are querying
14463       what we currently have stored as their contact address, so return
14464       it
14465    */
14466    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
14467       /* If we have an active registration, tell them when the registration is going to expire */
14468       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) {
14469          pvt->expiry = ast_sched_when(sched, peer->expire);
14470       }
14471       return PARSE_REGISTER_QUERY;
14472    } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */
14473       /* This means remove all registrations and return OK */
14474       AST_SCHED_DEL_UNREF(sched, peer->expire,
14475             sip_unref_peer(peer, "remove register expire ref"));
14476       ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
14477       expire_register(sip_ref_peer(peer,"add ref for explicit expire_register"));
14478       return PARSE_REGISTER_UPDATE;
14479    }
14480 
14481    /* Store whatever we got as a contact from the client */
14482    ast_string_field_set(peer, fullcontact, curi);
14483 
14484    /* For the 200 OK, we should use the received contact */
14485    ast_string_field_build(pvt, our_contact, "<%s>", curi);
14486 
14487    /* Make sure it's a SIP URL */
14488    if (ast_strlen_zero(curi) || parse_uri_legacy_check(curi, "sip:,sips:", &curi, NULL, &hostport, &transport)) {
14489       ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n");
14490    }
14491 
14492    /* handle the transport type specified in Contact header. */
14493    if (!(transport_type = get_transport_str2enum(transport))) {
14494       transport_type = pvt->socket.type;
14495    }
14496 
14497    /* if the peer's socket type is different than the Registration
14498     * transport type, change it.  If it got this far, it is a
14499     * supported type, but check just in case */
14500    if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) {
14501       set_socket_transport(&peer->socket, transport_type);
14502    }
14503 
14504    oldsin = peer->addr;
14505 
14506    /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */
14507    if (!ast_sockaddr_isnull(&peer->addr) && (!peer->is_realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))) {
14508       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
14509    }
14510 
14511    if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) {
14512        /* use the data provided in the Contact header for call routing */
14513       ast_debug(1, "Store REGISTER's Contact header for call routing.\n");
14514       /* XXX This could block for a long time XXX */
14515       /*! \todo Check NAPTR/SRV if we have not got a port in the URI */
14516       if (ast_sockaddr_resolve_first(&testsa, hostport, 0)) {
14517          ast_log(LOG_WARNING, "Invalid hostport '%s'\n", hostport);
14518          ast_string_field_set(peer, fullcontact, "");
14519          ast_string_field_set(pvt, our_contact, "");
14520          return PARSE_REGISTER_FAILED;
14521       }
14522 
14523       /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records.
14524          The hostport part is actually a host. */
14525       peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE;
14526 
14527       if (!ast_sockaddr_port(&testsa)) {
14528          ast_sockaddr_set_port(&testsa, default_sip_port(transport_type));
14529       }
14530 
14531       ast_sockaddr_copy(&peer->addr, &testsa);
14532    } else {
14533       /* Don't trust the contact field.  Just use what they came to us
14534          with */
14535       ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n");
14536       peer->addr = pvt->recv;
14537    }
14538 
14539    /* Check that they're allowed to register at this IP */
14540    if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW ||
14541          ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) {
14542       ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", hostport,
14543          ast_sockaddr_stringify_addr(&testsa));
14544       ast_string_field_set(peer, fullcontact, "");
14545       ast_string_field_set(pvt, our_contact, "");
14546       return PARSE_REGISTER_DENIED;
14547    }
14548 
14549    /* if the Contact header information copied into peer->addr matches the
14550     * received address, and the transport types are the same, then copy socket
14551     * data into the peer struct */
14552    if ((peer->socket.type == pvt->socket.type) &&
14553       !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) {
14554       copy_socket_data(&peer->socket, &pvt->socket);
14555    }
14556 
14557    /* Now that our address has been updated put ourselves back into the container for lookups */
14558    if (!peer->is_realtime || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
14559       ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table");
14560    }
14561 
14562    /* Save SIP options profile */
14563    peer->sipoptions = pvt->sipoptions;
14564 
14565    if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) {
14566       ast_string_field_set(peer, username, curi);
14567    }
14568 
14569    AST_SCHED_DEL_UNREF(sched, peer->expire,
14570          sip_unref_peer(peer, "remove register expire ref"));
14571 
14572    if (expire > max_expiry) {
14573       expire = max_expiry;
14574    }
14575    if (expire < min_expiry) {
14576       expire = min_expiry;
14577    }
14578    if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
14579       peer->expire = -1;
14580    } else {
14581       peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register,
14582             sip_ref_peer(peer, "add registration ref"));
14583       if (peer->expire == -1) {
14584          sip_unref_peer(peer, "remote registration ref");
14585       }
14586    }
14587    pvt->expiry = expire;
14588    snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr),
14589        expire, peer->username, peer->fullcontact);
14590    /* We might not immediately be able to reconnect via TCP, but try caching it anyhow */
14591    if (!peer->rt_fromcontact || !sip_cfg.peer_rtupdate)
14592       ast_db_put("SIP/Registry", peer->name, data);
14593    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name,  ast_sockaddr_stringify(&peer->addr));
14594 
14595    /* Is this a new IP address for us? */
14596    if (ast_sockaddr_cmp(&peer->addr, &oldsin)) {
14597       ast_verb(3, "Registered SIP '%s' at %s\n", peer->name,
14598          ast_sockaddr_stringify(&peer->addr));
14599    }
14600    sip_poke_peer(peer, 0);
14601    register_peer_exten(peer, 1);
14602 
14603    /* Save User agent */
14604    useragent = sip_get_header(req, "User-Agent");
14605    if (strcasecmp(useragent, peer->useragent)) {
14606       ast_string_field_set(peer, useragent, useragent);
14607       ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);
14608    }
14609    return PARSE_REGISTER_UPDATE;
14610 }

static int parse_request ( struct sip_request *  req  )  [static]

Parse a SIP message.

Note:
this function is used both on incoming and outgoing packets

Definition at line 8714 of file chan_sip.c.

References ast_debug, ast_log(), ast_str_strlen(), ast_strlen_zero(), determine_firstline_parts(), and LOG_WARNING.

Referenced by _sip_tcp_helper_thread(), handle_request_do(), initialize_initreq(), and parse_copy().

08715 {
08716    char *c = req->data->str;
08717    ptrdiff_t *dst = req->header;
08718    int i = 0, lim = SIP_MAX_HEADERS - 1;
08719    unsigned int skipping_headers = 0;
08720    ptrdiff_t current_header_offset = 0;
08721    char *previous_header = "";
08722 
08723    req->header[0] = 0;
08724    req->headers = -1;   /* mark that we are working on the header */
08725    for (; *c; c++) {
08726       if (*c == '\r') {    /* remove \r */
08727          *c = '\0';
08728       } else if (*c == '\n') {   /* end of this line */
08729          *c = '\0';
08730          current_header_offset = (c + 1) - req->data->str;
08731          previous_header = req->data->str + dst[i];
08732          if (skipping_headers) {
08733             /* check to see if this line is blank; if so, turn off
08734                the skipping flag, so the next line will be processed
08735                as a body line */
08736             if (ast_strlen_zero(previous_header)) {
08737                skipping_headers = 0;
08738             }
08739             dst[i] = current_header_offset; /* record start of next line */
08740             continue;
08741          }
08742          if (sipdebug) {
08743             ast_debug(4, "%7s %2d [%3d]: %s\n",
08744                  req->headers < 0 ? "Header" : "Body",
08745                  i, (int) strlen(previous_header), previous_header);
08746          }
08747          if (ast_strlen_zero(previous_header) && req->headers < 0) {
08748             req->headers = i; /* record number of header lines */
08749             dst = req->line;  /* start working on the body */
08750             i = 0;
08751             lim = SIP_MAX_LINES - 1;
08752          } else { /* move to next line, check for overflows */
08753             if (i++ == lim) {
08754                /* if we're processing headers, then skip any remaining
08755                   headers and move on to processing the body, otherwise
08756                   we're done */
08757                if (req->headers != -1) {
08758                   break;
08759                } else {
08760                   req->headers = i;
08761                   dst = req->line;
08762                   i = 0;
08763                   lim = SIP_MAX_LINES - 1;
08764                   skipping_headers = 1;
08765                }
08766             }
08767          }
08768          dst[i] = current_header_offset; /* record start of next line */
08769       }
08770    }
08771 
08772    /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF,
08773       but since some devices send without, we'll be generous in what we accept. However,
08774       if we've already reached the maximum number of lines for portion of the message
08775       we were parsing, we can't accept any more, so just ignore it.
08776    */
08777    previous_header = req->data->str + dst[i];
08778    if ((i < lim) && !ast_strlen_zero(previous_header)) {
08779       if (sipdebug) {
08780          ast_debug(4, "%7s %2d [%3d]: %s\n",
08781               req->headers < 0 ? "Header" : "Body",
08782               i, (int) strlen(previous_header), previous_header );
08783       }
08784       i++;
08785    }
08786 
08787    /* update count of header or body lines */
08788    if (req->headers >= 0) {   /* we are in the body */
08789       req->lines = i;
08790    } else {       /* no body */
08791       req->headers = i;
08792       req->lines = 0;
08793       /* req->data->used will be a NULL byte */
08794       req->line[0] = ast_str_strlen(req->data);
08795    }
08796 
08797    if (*c) {
08798       ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c);
08799    }
08800 
08801    /* Split up the first line parts */
08802    return determine_firstline_parts(req);
08803 }

int parse_session_expires ( const char *  p_hdrval,
int *const   p_interval,
enum st_refresher *const   p_ref 
) [static]

Session-Timers: Function for parsing Session-Expires header.

Definition at line 27083 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, and strsep().

Referenced by handle_request_invite(), and handle_response_invite().

27084 {
27085    char *p_token;
27086    int  ref_idx;
27087    char *p_se_hdr;
27088 
27089    if (ast_strlen_zero(p_hdrval)) {
27090       ast_log(LOG_WARNING, "Null Session-Expires header\n");
27091       return -1;
27092    }
27093 
27094    *p_ref = SESSION_TIMER_REFRESHER_AUTO;
27095    *p_interval = 0;
27096 
27097    p_se_hdr = ast_strdupa(p_hdrval);
27098    p_se_hdr = ast_skip_blanks(p_se_hdr);
27099 
27100    while ((p_token = strsep(&p_se_hdr, ";"))) {
27101       p_token = ast_skip_blanks(p_token);
27102       if (!sscanf(p_token, "%30d", p_interval)) {
27103          ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n");
27104          return -1;
27105       }
27106 
27107       ast_debug(2, "Session-Expires: %d\n", *p_interval);
27108 
27109       if (!p_se_hdr)
27110          continue;
27111 
27112       p_se_hdr = ast_skip_blanks(p_se_hdr);
27113       ref_idx = strlen("refresher=");
27114       if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
27115          p_se_hdr += ref_idx;
27116          p_se_hdr = ast_skip_blanks(p_se_hdr);
27117 
27118          if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) {
27119             *p_ref = SESSION_TIMER_REFRESHER_UAC;
27120             ast_debug(2, "Refresher: UAC\n");
27121          } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) {
27122             *p_ref = SESSION_TIMER_REFRESHER_UAS;
27123             ast_debug(2, "Refresher: UAS\n");
27124          } else {
27125             ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr);
27126             return -1;
27127          }
27128          break;
27129       }
27130    }
27131    return 0;
27132 }

static int parse_uri_legacy_check ( char *  uri,
const char *  scheme,
char **  user,
char **  pass,
char **  hostport,
char **  transport 
) [static]

parse uri in a way that allows semicolon stripping if legacy mode is enabled

Note:
This calls parse_uri which has the unexpected property that passing more arguments results in more splitting. Most common is to leave out the pass argument, causing user to contain user:pass if available.

Definition at line 14323 of file chan_sip.c.

References parse_uri(), and sip_cfg.

Referenced by __set_address_from_contact(), check_user_full(), get_also_info(), get_destination(), parse_register_contact(), and register_verify().

14324 {
14325    int ret = parse_uri(uri, scheme, user, pass, hostport, transport);
14326    if (sip_cfg.legacy_useroption_parsing) { /* if legacy mode is active, strip semis from the user field */
14327       char *p;
14328       if ((p = strchr(uri, (int)';'))) {
14329          *p = '\0';
14330       }
14331    }
14332    return ret;
14333 }

static int peer_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Note:
The only member of the peer used here is the name field

Definition at line 30832 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

30833 {
30834    struct sip_peer *peer = obj, *peer2 = arg;
30835 
30836    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
30837 }

static int peer_dump_func ( void *  userobj,
void *  arg,
int  flags 
) [static]

Definition at line 17553 of file chan_sip.c.

References ao2_t_ref, ast_cli(), and ast_cli_args::fd.

Referenced by sip_show_objects().

17554 {
17555    struct sip_peer *peer = userobj;
17556    int refc = ao2_t_ref(userobj, 0, "");
17557    struct ast_cli_args *a = (struct ast_cli_args *) arg;
17558    
17559    ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n",
17560       peer->name, 0, refc);
17561    return 0;
17562 }

static int peer_hash_cb ( const void *  obj,
const int  flags 
) [static]

Note:
The only member of the peer used here is the name field

Definition at line 30822 of file chan_sip.c.

References ast_str_case_hash().

30823 {
30824    const struct sip_peer *peer = obj;
30825 
30826    return ast_str_case_hash(peer->name);
30827 }