Fri Apr 15 20:39:16 2016

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 "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"

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  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  event_state_compositor
 The Event State Compositors. More...
struct  invstate2stringtable
 Readable descriptions of device states. More...
struct  match_req_args
struct  show_peers_context
 Used in the sip_show_peers functions to pass parameters. More...
struct  sip_reasons
 Diversion header reasons. More...

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_retry_403
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_param 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]

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 BOGUS_PEER_MD5SECRET   "intentionally_invalid_md5_string"
 We can recognise the bogus peer by this invalid MD5 hash.
#define CHECK_AUTH_BUF_INITLEN   256
#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   "%-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 PEERS_FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\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 }
enum  message_integrity { MESSAGE_INVALID, MESSAGE_FRAGMENT, MESSAGE_FRAGMENT_COMPLETE, MESSAGE_COMPLETE }
 

Indication of a TCP message's integrity.

More...
enum  peer_unlink_flag_t { SIP_PEERS_MARKED, SIP_PEERS_ALL }
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 sip_auth_container * authl = NULL
 Authentication container for realm authentication.
struct ast_sockaddr bindaddr
static struct sip_peer * bogus_peer
 A bogus peer, to be used when authentication should fail.
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
 Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items.
struct ao2_containerdialogs_to_destroy
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 unsigned 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 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 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 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 strefresher_params []
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 _map_x_s trust_id_outboundstr []
static char used_context [AST_MAX_CONTEXT]
static const char * __get_header (const struct sip_request *req, const char *name, int *start)
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 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 struct sip_peer * _sip_show_peers_one (int fd, struct mansession *s, struct show_peers_context *cont, struct sip_peer *peer)
 Emit informations for one peer during sip show peers command.
static void * _sip_tcp_helper_thread (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, format_t codec, 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_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_required_respheader (struct sip_request *req)
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, int codec, 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, const char *text)
 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, format_t codec, 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 int addr_is_multicast (const struct ast_sockaddr *addr)
 Check if an ip is an multicast IP. addr the address to check.
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 *p1, struct sip_pvt *p2, const char *op)
 AST_DATA_STRUCTURE (sip_peer, DATA_EXPORT_SIP_PEER)
 AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history)
 AST_LIST_HEAD_STATIC (epa_static_data_list, epa_backend)
static AST_LIST_HEAD_STATIC (domain_list, domain)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DRIVER,.nonoptreq="res_crypto,chan_local",)
 AST_MUTEX_DEFINE_STATIC (authl_lock)
 Global authentication container protection while adjusting the references.
 AST_MUTEX_DEFINE_STATIC (sip_reload_lock)
 AST_MUTEX_DEFINE_STATIC (monlock)
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
 AST_MUTEX_DEFINE_STATIC (netlock)
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 ast_sockaddr_resolve_first_transport (struct ast_sockaddr *addr, const char *name, int flag, unsigned int transport)
 Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
 AST_THREADSTORAGE (check_auth_buf)
 AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup)
 A per-thread temporary pvt structure.
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 void 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 auto_congest (const void *arg)
 Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.
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 void build_localtag_registry (struct sip_registry *reg)
 Build SIP From tag value for REGISTER.
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, int resp)
 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 (char *context, char *exten, int 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 message_integrity check_message_integrity (struct ast_str **request, struct ast_str **overflow)
 Check that a message received over TCP is a full message.
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 void 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, const 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)
 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_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_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, 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.
static int dialog_unlink_callback (void *obj, void *arg, int flags)
struct sip_pvt * dialog_unref_debug (struct sip_pvt *p, 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 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 struct sip_peer * 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_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 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 (unsigned int transport)
 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_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 const char * get_header (const struct sip_request *req, const char *name)
 Get header from SIP request.
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 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 (enum sip_transport t)
 Return transport as string.
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_invite_st (struct sip_pvt *p, struct sip_request *req, const char *required, int reinvite)
static int handle_request_message (struct sip_pvt *p, struct sip_request *req)
 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, unsigned 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 (struct sip_pvt *pvt)
 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_param *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_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 media 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 struct sip_proxy * proxy_from_config (const char *proxy, int sipconf_lineno, struct sip_proxy *dest)
 Parse proxy string and return an ao2_alloc'd proxy. If dest is non-NULL, no allocation is performed and dest is used instead. On error NULL is returned.
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 int read_raw_content_length (const char *message)
 Get the content length from an unparsed SIP message.
static struct sip_peer * realtime_peer (const char *newpeername, struct ast_sockaddr *addr, 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, 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)
 Receive SIP MESSAGE method messages.
static struct sip_peer * ref_peer (struct sip_peer *peer, char *tag)
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 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 reinvite_timeout (const void *data)
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 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
static int sip_call (struct ast_channel *ast, 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 (void *data)
 Part of PBX channel interface.
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)
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 format_t sip_get_codec (struct ast_channel *chan)
static enum ast_rtp_glue_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
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 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 void sip_queue_hangup_cause (struct sip_pvt *p, int cause)
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)
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, format_t format, const struct ast_channel *requestor, void *data, 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 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, format_t codecs, 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_read (struct sip_request *req, struct ast_tcptls_session_instance *tcptls_session, int authenticated, time_t start)
 Read SIP request or response from a TCP/TLS connection.
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.
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 str2strefresherparam (const char *s)
static const char * strefresher2str (enum st_refresher r)
static const char * strefresherparam2str (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, 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_with_text (struct sip_pvt *p, const char *text)
 Transmit text 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 const char * transport2str (enum sip_transport transport)
static const char * trust_id_outbound2str (int mode)
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_peers_from_tables (peer_unlink_flag_t flag)
static int unload_module (void)
 PBX unload module API.
static void * unref_peer (struct sip_peer *peer, char *tag)
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_peer_lastmsgssent (struct sip_peer *peer, int value, int locked)
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.

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

VIA branch tag transaction checking

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 BOGUS_PEER_MD5SECRET   "intentionally_invalid_md5_string"

We can recognise the bogus peer by this invalid MD5 hash.

Definition at line 1105 of file chan_sip.c.

Referenced by check_auth(), load_module(), and sip_reload().

#define CHECK_AUTH_BUF_INITLEN   256

Definition at line 14832 of file chan_sip.c.

Referenced by check_auth(), and transmit_fake_auth_response().

#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 2302 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 7876 of file chan_sip.c.

Referenced by change_callid_pvt().

#define DATA_EXPORT_SIP_PEER ( MEMBER   ) 

Definition at line 31649 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 18980 of file chan_sip.c.

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

Definition at line 18980 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 18980 of file chan_sip.c.

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

Definition at line 18980 of file chan_sip.c.

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

Definition at line 18980 of file chan_sip.c.

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

Definition at line 18980 of file chan_sip.c.

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

Definition at line 18980 of file chan_sip.c.

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

Definition at line 18980 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 18979 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 18979 of file chan_sip.c.

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

Definition at line 18979 of file chan_sip.c.

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

Definition at line 18979 of file chan_sip.c.

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

Definition at line 18979 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 18978 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 18977 of file chan_sip.c.

Referenced by show_channels_cb().

#define PEERS_FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"

Definition at line 17288 of file chan_sip.c.

Referenced by _sip_show_peers(), and _sip_show_peers_one().

#define SIP_PEDANTIC_DECODE ( str   ) 
Value:
if (sip_cfg.pedanticsipchecking && !ast_strlen_zero(str)) { \
      ast_uri_decode(str); \
   }  \

Definition at line 690 of file chan_sip.c.

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

#define sip_pvt_lock (  )     ao2_lock(x)
#define sip_pvt_trylock (  )     ao2_trylock(x)
#define sip_pvt_unlock (  )     ao2_unlock(x)
#define UNLINK ( element,
head,
prev   ) 

some list management macros.

Definition at line 1196 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 

Definition at line 8173 of file chan_sip.c.

08173                    {
08174    SIP_REQ_MATCH,
08175    SIP_REQ_NOT_MATCH,
08176    SIP_REQ_LOOP_DETECTED,
08177 };

Indication of a TCP message's integrity.

Enumerator:
MESSAGE_INVALID 

The message has an error in it with regards to its Content-Length header

MESSAGE_FRAGMENT 

The message is incomplete

MESSAGE_FRAGMENT_COMPLETE 

The data contains a complete message plus a fragment of another.

MESSAGE_COMPLETE 

The message is complete

Definition at line 2504 of file chan_sip.c.

02504                        {
02505    /*!
02506     * The message has an error in it with
02507     * regards to its Content-Length header
02508     */
02509    MESSAGE_INVALID,
02510    /*!
02511     * The message is incomplete
02512     */
02513    MESSAGE_FRAGMENT,
02514    /*!
02515     * The data contains a complete message
02516     * plus a fragment of another.
02517     */
02518    MESSAGE_FRAGMENT_COMPLETE,
02519    /*!
02520     * The message is complete
02521     */
02522    MESSAGE_COMPLETE,
02523 };

Enumerator:
SIP_PEERS_MARKED 
SIP_PEERS_ALL 

Definition at line 3004 of file chan_sip.c.

03004              {
03005    SIP_PEERS_MARKED,
03006    SIP_PEERS_ALL,
03007 } 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 7644 of file chan_sip.c.

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

Referenced by build_route(), copy_all_header(), copy_via_headers(), func_header_read(), get_header(), handle_incoming(), handle_request_invite(), handle_request_subscribe(), handle_response_register(), and parse_register_contact().

07645 {
07646    /*
07647     * Technically you can place arbitrary whitespace both before and after the ':' in
07648     * a header, although RFC3261 clearly says you shouldn't before, and place just
07649     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was
07650     * a good idea to say you can do it, and if you can do it, why in the hell would.
07651     * you say you shouldn't.
07652     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
07653     * and we always allow spaces after that for compatibility.
07654     */
07655    const char *sname = find_alias(name, NULL);
07656    int x, len = strlen(name), slen = (sname ? 1 : 0);
07657    for (x = *start; x < req->headers; x++) {
07658       const char *header = REQ_OFFSET_TO_STR(req, header[x]);
07659       int smatch = 0, match = !strncasecmp(header, name, len);
07660       if (slen) {
07661          smatch = !strncasecmp(header, sname, slen);
07662       }
07663       if (match || smatch) {
07664          /* skip name */
07665          const char *r = header + (match ? len : slen );
07666          if (sip_cfg.pedanticsipchecking) {
07667             r = ast_skip_blanks(r);
07668          }
07669 
07670          if (*r == ':') {
07671             *start = x+1;
07672             return ast_skip_blanks(r+1);
07673          }
07674       }
07675    }
07676 
07677    /* Don't return NULL, so get_header is always a valid pointer */
07678    return "";
07679 }

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

Definition at line 14394 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), 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().

14395 {
14396    char *hostport, *transport;
14397    char contact_buf[256];
14398    char *contact;
14399 
14400    /* Work on a copy */
14401    ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
14402    contact = contact_buf;
14403 
14404    /* 
14405     * We have only the part in <brackets> here so we just need to parse a SIP URI.
14406     *
14407     * Note: The outbound proxy could be using UDP between the proxy and Asterisk.
14408     * We still need to be able to send to the remote agent through the proxy.
14409     */
14410 
14411    if (parse_uri_legacy_check(contact, "sip:,sips:", &contact, NULL, &hostport,
14412             &transport)) {
14413       ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact);
14414    }
14415 
14416    /* XXX This could block for a long time XXX */
14417    /* We should only do this if it's a name, not an IP */
14418    /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records
14419       to find transport, port address and hostname. If there's a port number, we have to
14420       assume that the hostport part is a host name and only look for an A/AAAA record in DNS.
14421    */
14422 
14423    /* If we took in an invalid URI, hostport may not have been initialized */
14424    /* ast_sockaddr_resolve requires an initialized hostport string. */
14425    if (ast_strlen_zero(hostport)) {
14426       ast_log(LOG_WARNING, "Invalid URI: parse_uri failed to acquire hostport\n");
14427       return -1;
14428    }
14429 
14430    if (ast_sockaddr_resolve_first_transport(addr, hostport, 0, get_transport_str2enum(transport))) {
14431       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't "
14432          "resolve in DNS) : '%s'\n", hostport);
14433       return -1;
14434    }
14435 
14436    /* set port */
14437    if (!ast_sockaddr_port(addr)) {
14438       ast_sockaddr_set_port(addr,
14439                   (get_transport_str2enum(transport) ==
14440                    SIP_TRANSPORT_TLS ||
14441                    !strncasecmp(fullcontact, "sips", 4)) ?
14442                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
14443    }
14444 
14445    return 0;
14446 }

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 4154 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().

04155 {
04156    struct sip_pkt *cur, *prev = NULL;
04157    const char *msg = "Not Found";   /* used only for debugging */
04158    int res = FALSE;
04159 
04160    /* If we have an outbound proxy for this dialog, then delete it now since
04161      the rest of the requests in this dialog needs to follow the routing.
04162      If obforcing is set, we will keep the outbound proxy during the whole
04163      dialog, regardless of what the SIP rfc says
04164    */
04165    if (p->outboundproxy && !p->outboundproxy->force) {
04166       ref_proxy(p, NULL);
04167    }
04168 
04169    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
04170       if (cur->seqno != seqno || cur->is_resp != resp) {
04171          continue;
04172       }
04173       if (cur->is_resp || cur->method == sipmethod) {
04174          res = TRUE;
04175          msg = "Found";
04176          if (!resp && (seqno == p->pendinginvite)) {
04177             ast_debug(1, "Acked pending invite %u\n", p->pendinginvite);
04178             p->pendinginvite = 0;
04179          }
04180          if (cur->retransid > -1) {
04181             if (sipdebug)
04182                ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
04183          }
04184          /* This odd section is designed to thwart a
04185           * race condition in the packet scheduler. There are
04186           * two conditions under which deleting the packet from the
04187           * scheduler can fail.
04188           *
04189           * 1. The packet has been removed from the scheduler because retransmission
04190           * is being attempted. The problem is that if the packet is currently attempting
04191           * retransmission and we are at this point in the code, then that MUST mean
04192           * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
04193           * lock temporarily to allow retransmission.
04194           *
04195           * 2. The packet has reached its maximum number of retransmissions and has
04196           * been permanently removed from the packet scheduler. If this is the case, then
04197           * the packet's retransid will be set to -1. The atomicity of the setting and checking
04198           * of the retransid to -1 is ensured since in both cases p's lock is held.
04199           */
04200          while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
04201             sip_pvt_unlock(p);
04202             usleep(1);
04203             sip_pvt_lock(p);
04204          }
04205          UNLINK(cur, p->packets, prev);
04206          dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt");
04207          if (cur->data) {
04208             ast_free(cur->data);
04209          }
04210          ast_free(cur);
04211          break;
04212       }
04213    }
04214    ast_debug(1, "Stopping retransmission on '%s' of %s %u: Match %s\n",
04215       p->callid, resp ? "Response" : "Request", seqno, msg);
04216    return res;
04217 }

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 4017 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().

04018 {
04019    struct sip_pvt *p = (struct sip_pvt *)data;
04020    struct ast_channel *owner;
04021 
04022    /* If this is a subscription, tell the phone that we got a timeout */
04023    if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) {
04024       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
04025       p->subscribed = NONE;
04026       append_history(p, "Subscribestatus", "timeout");
04027       ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>");
04028       return 10000;  /* Reschedule this destruction so that we know that it's gone */
04029    }
04030 
04031    /* If there are packets still waiting for delivery, delay the destruction */
04032    if (p->packets) {
04033       if (!p->needdestroy) {
04034          char method_str[31];
04035          ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
04036          append_history(p, "ReliableXmit", "timeout");
04037          if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
04038             if (p->ongoing_reinvite || method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
04039                pvt_set_needdestroy(p, "autodestruct");
04040             }
04041          }
04042          return 10000;
04043       } else {
04044          /* They've had their chance to respond. Time to bail */
04045          __sip_pretend_ack(p);
04046       }
04047    }
04048 
04049    /* Reset schedule ID */
04050    p->autokillid = -1;
04051 
04052    /*
04053     * Lock both the pvt and the channel safely so that we can queue up a frame.
04054     */
04055    owner = sip_pvt_lock_full(p);
04056    if (owner) {
04057       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner %s in place (Method: %s). Rescheduling destruction for 10000 ms\n", p->callid, owner->name, sip_methods[p->method].text);
04058       ast_queue_hangup_with_cause(owner, AST_CAUSE_PROTOCOL_ERROR);
04059       ast_channel_unlock(owner);
04060       ast_channel_unref(owner);
04061       sip_pvt_unlock(p);
04062       return 10000;
04063    } else if (p->refer && !p->alreadygone) {
04064       ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
04065       stop_media_flows(p);
04066       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
04067       append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid);
04068       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
04069    } else {
04070       append_history(p, "AutoDestroy", "%s", p->callid);
04071       ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid);
04072       sip_pvt_unlock(p);
04073       dialog_unlink_all(p); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */
04074       sip_pvt_lock(p);
04075       /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */
04076       /* sip_destroy(p); */      /* Go ahead and destroy dialog. All attempts to recover is done */
04077       /* sip_destroy also absorbs the reference */
04078    }
04079 
04080    sip_pvt_unlock(p);
04081 
04082    dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
04083 
04084    return 0;
04085 }

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 5964 of file chan_sip.c.

References ao2_ref, ao2_t_ref, ast_cc_config_params_destroy(), ast_channel_lock, ast_channel_unlock, ast_debug, 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(), free_old_route(), ref_proxy(), registry_unref(), sip_debug_test_pvt(), sip_dump_history(), sip_methods, sip_srtp_destroy(), stop_session_timer(), cfsip_methods::text, unref_peer(), and update_call_counter().

Referenced by sip_destroy().

05965 {
05966    struct sip_request *req;
05967 
05968    /* Destroy Session-Timers if allocated */
05969    if (p->stimer) {
05970       p->stimer->quit_flag = 1;
05971       stop_session_timer(p);
05972       ast_free(p->stimer);
05973       p->stimer = NULL;
05974    }
05975 
05976    if (sip_debug_test_pvt(p))
05977       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
05978 
05979    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05980       update_call_counter(p, DEC_CALL_LIMIT);
05981       ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
05982    }
05983 
05984    /* Unlink us from the owner if we have one */
05985    if (p->owner) {
05986       if (lockowner)
05987          ast_channel_lock(p->owner);
05988       ast_debug(1, "Detaching from %s\n", p->owner->name);
05989       p->owner->tech_pvt = NULL;
05990       /* Make sure that the channel knows its backend is going away */
05991       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05992       if (lockowner)
05993          ast_channel_unlock(p->owner);
05994       /* Give the channel a chance to react before deallocation */
05995       usleep(1);
05996    }
05997 
05998    /* Remove link from peer to subscription of MWI */
05999    if (p->relatedpeer && p->relatedpeer->mwipvt == p)
06000       p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
06001    if (p->relatedpeer && p->relatedpeer->call == p)
06002       p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
06003    
06004    if (p->relatedpeer)
06005       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy");
06006    
06007    if (p->registry) {
06008       if (p->registry->call == p)
06009          p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all");
06010       p->registry = registry_unref(p->registry, "delete p->registry");
06011    }
06012    
06013    if (p->mwi) {
06014       p->mwi->call = NULL;
06015       p->mwi = NULL;
06016    }
06017 
06018    if (dumphistory)
06019       sip_dump_history(p);
06020 
06021    if (p->options) {
06022       if (p->options->outboundproxy) {
06023          ao2_ref(p->options->outboundproxy, -1);
06024       }
06025       ast_free(p->options);
06026       p->options = NULL;
06027    }
06028 
06029    if (p->outboundproxy) {
06030       ref_proxy(p, NULL);
06031    }
06032 
06033    if (p->notify) {
06034       ast_variables_destroy(p->notify->headers);
06035       ast_free(p->notify->content);
06036       ast_free(p->notify);
06037       p->notify = NULL;
06038    }
06039    if (p->rtp) {
06040       ast_rtp_instance_destroy(p->rtp);
06041       p->rtp = NULL;
06042    }
06043    if (p->vrtp) {
06044       ast_rtp_instance_destroy(p->vrtp);
06045       p->vrtp = NULL;
06046    }
06047    if (p->trtp) {
06048       ast_rtp_instance_destroy(p->trtp);
06049       p->trtp = NULL;
06050    }
06051    if (p->udptl) {
06052       ast_udptl_destroy(p->udptl);
06053       p->udptl = NULL;
06054    }
06055    if (p->refer) {
06056       if (p->refer->refer_call) {
06057          p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
06058       }
06059       ast_free(p->refer);
06060       p->refer = NULL;
06061    }
06062    if (p->route) {
06063       free_old_route(p->route);
06064       p->route = NULL;
06065    }
06066    deinit_req(&p->initreq);
06067 
06068    /* Clear history */
06069    if (p->history) {
06070       struct sip_history *hist;
06071       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
06072          ast_free(hist);
06073          p->history_entries--;
06074       }
06075       ast_free(p->history);
06076       p->history = NULL;
06077    }
06078 
06079    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
06080       ast_free(req);
06081    }
06082 
06083    if (p->chanvars) {
06084       ast_variables_destroy(p->chanvars);
06085       p->chanvars = NULL;
06086    }
06087 
06088    if (p->srtp) {
06089       sip_srtp_destroy(p->srtp);
06090       p->srtp = NULL;
06091    }
06092 
06093    if (p->vsrtp) {
06094       sip_srtp_destroy(p->vsrtp);
06095       p->vsrtp = NULL;
06096    }
06097 
06098    if (p->tsrtp) {
06099       sip_srtp_destroy(p->tsrtp);
06100       p->tsrtp = NULL;
06101    }
06102 
06103    if (p->directmediaha) {
06104       ast_free_ha(p->directmediaha);
06105       p->directmediaha = NULL;
06106    }
06107 
06108    ast_string_field_free_memory(p);
06109 
06110    ast_cc_config_params_destroy(p->cc_params);
06111    p->cc_params = NULL;
06112 
06113    if (p->epa_entry) {
06114       ao2_ref(p->epa_entry, -1);
06115       p->epa_entry = NULL;
06116    }
06117 
06118    if (p->socket.tcptls_session) {
06119       ao2_ref(p->socket.tcptls_session, -1);
06120       p->socket.tcptls_session = NULL;
06121    }
06122 
06123    if (p->peerauth) {
06124       ao2_t_ref(p->peerauth, -1, "Removing active peer authentication");
06125       p->peerauth = NULL;
06126    }
06127 }

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

Register with SIP proxy.

Returns:
see __sip_xmit

Definition at line 13598 of file chan_sip.c.

References transmit_register().

Referenced by sip_reregister().

13599 {
13600    int res;
13601 
13602    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
13603    return res;
13604 }

void __sip_pretend_ack ( struct sip_pvt *  p  ) 

Pretend to ack all packets called with p locked.

Definition at line 4221 of file chan_sip.c.

References __sip_ack(), ast_log(), ast_str_buffer(), 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().

04222 {
04223    struct sip_pkt *cur = NULL;
04224 
04225    while (p->packets) {
04226       int method;
04227       if (cur == p->packets) {
04228          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
04229          return;
04230       }
04231       cur = p->packets;
04232       method = (cur->method) ? cur->method : find_sip_method(ast_str_buffer(cur->data));
04233       __sip_ack(p, cur->seqno, cur->is_resp, method);
04234    }
04235 }

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 3926 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().

03927 {
03928    struct sip_pkt *pkt = NULL;
03929    int siptimer_a = DEFAULT_RETRANS;
03930    int xmitres = 0;
03931    unsigned respid;
03932 
03933    if (sipmethod == SIP_INVITE) {
03934       /* Note this is a pending invite */
03935       p->pendinginvite = seqno;
03936    }
03937 
03938    /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */
03939    /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */
03940    /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */
03941    if (!(p->socket.type & SIP_TRANSPORT_UDP)) {
03942       xmitres = __sip_xmit(p, data);   /* Send packet */
03943       if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03944          append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)");
03945          return AST_FAILURE;
03946       } else {
03947          return AST_SUCCESS;
03948       }
03949    }
03950 
03951    if (!(pkt = ast_calloc(1, sizeof(*pkt)))) {
03952       return AST_FAILURE;
03953    }
03954    /* copy data, add a terminator and save length */
03955    if (!(pkt->data = ast_str_create(ast_str_strlen(data)))) {
03956       ast_free(pkt);
03957       return AST_FAILURE;
03958    }
03959    ast_str_set(&pkt->data, 0, "%s%s", ast_str_buffer(data), "\0");
03960    /* copy other parameters from the caller */
03961    pkt->method = sipmethod;
03962    pkt->seqno = seqno;
03963    pkt->is_resp = resp;
03964    pkt->is_fatal = fatal;
03965    pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner");
03966    pkt->next = p->packets;
03967    p->packets = pkt; /* Add it to the queue */
03968    if (resp) {
03969       /* Parse out the response code */
03970       if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) {
03971          pkt->response_code = respid;
03972       }
03973    }
03974    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
03975    pkt->retransid = -1;
03976    if (pkt->timer_t1) {
03977       siptimer_a = pkt->timer_t1;
03978    }
03979 
03980    pkt->time_sent = ast_tvnow(); /* time packet was sent */
03981    pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */
03982 
03983    /* Schedule retransmission */
03984    AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1);
03985    if (sipdebug) {
03986       ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
03987    }
03988 
03989    xmitres = __sip_xmit(pkt->owner, pkt->data); /* Send packet */
03990 
03991    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03992       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03993       ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n");
03994       AST_SCHED_DEL(sched, pkt->retransid);
03995       p->packets = pkt->next;
03996       pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03997       ast_free(pkt->data);
03998       ast_free(pkt);
03999       return AST_FAILURE;
04000    } else {
04001       /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread
04002        * only wakes up every 1000ms by default, we have to poke the thread here to make
04003        * sure it successfully detects this must be retransmitted in less time than
04004        * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */
04005       if (monitor_thread != AST_PTHREADT_NULL) {
04006          pthread_kill(monitor_thread, SIGURG);
04007       }
04008       return AST_SUCCESS;
04009    }
04010 }

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 4238 of file chan_sip.c.

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

Referenced by handle_response(), and sip_hangup().

04239 {
04240    struct sip_pkt *cur;
04241    int res = FALSE;
04242 
04243    for (cur = p->packets; cur; cur = cur->next) {
04244       if (cur->seqno == seqno && cur->is_resp == resp &&
04245          (cur->is_resp || method_match(sipmethod, ast_str_buffer(cur->data)))) {
04246          /* this is our baby */
04247          if (cur->retransid > -1) {
04248             if (sipdebug)
04249                ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
04250          }
04251          AST_SCHED_DEL(sched, cur->retransid);
04252          res = TRUE;
04253          break;
04254       }
04255    }
04256    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");
04257    return res;
04258 }

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

Actually setup an MWI subscription or resubscribe.

Definition at line 12862 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, 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().

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

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

Definition at line 3521 of file chan_sip.c.

References ast_debug, ast_log(), ast_sendto(), ast_sockaddr_stringify(), ast_str_buffer(), 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().

03522 {
03523    int res = 0;
03524    const struct ast_sockaddr *dst = sip_real_dst(p);
03525 
03526    ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", ast_str_buffer(data), get_transport_pvt(p), ast_sockaddr_stringify(dst));
03527 
03528    if (sip_prepare_socket(p) < 0) {
03529       return XMIT_ERROR;
03530    }
03531 
03532    if (p->socket.type == SIP_TRANSPORT_UDP) {
03533       res = ast_sendto(p->socket.fd, ast_str_buffer(data), ast_str_strlen(data), 0, dst);
03534    } else if (p->socket.tcptls_session) {
03535       res = sip_tcptls_write(p->socket.tcptls_session, ast_str_buffer(data), ast_str_strlen(data));
03536    } else {
03537       ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n");
03538       return XMIT_ERROR;
03539    }
03540 
03541    if (res == -1) {
03542       switch (errno) {
03543       case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
03544       case EHOSTUNREACH:   /* Host can't be reached */
03545       case ENETDOWN:       /* Interface down */
03546       case ENETUNREACH: /* Network failure */
03547       case ECONNREFUSED:      /* ICMP port unreachable */
03548          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
03549       }
03550    }
03551    if (res != ast_str_strlen(data)) {
03552       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));
03553    }
03554 
03555    return res;
03556 }

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 10843 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, get_header(), hangup_sip2cause(), LOG_WARNING, respprep(), and send_response().

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

10844 {
10845    struct sip_request resp;
10846    uint32_t seqno = 0;
10847 
10848    if (reliable && (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1)) {
10849       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
10850       return -1;
10851    }
10852    respprep(&resp, p, msg, req);
10853 
10854    if (ast_test_flag(&p->flags[0], SIP_SENDRPID)
10855          && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND)
10856          && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) {
10857       ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND);
10858       add_rpid(&resp, p);
10859    }
10860    if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) {
10861       add_cc_call_info_to_response(p, &resp);
10862    }
10863 
10864    /* If we are sending a 302 Redirect we can add a diversion header if the redirect information is set */
10865    if (!strncmp(msg, "302", 3)) {
10866       add_diversion_header(&resp, p);
10867    }
10868 
10869    /* If we are cancelling an incoming invite for some reason, add information
10870       about the reason why we are doing this in clear text */
10871    if (p->method == SIP_INVITE && msg[0] != '1') {
10872       char buf[20];
10873 
10874       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) {
10875          int hangupcause = 0;
10876 
10877          if (p->owner && p->owner->hangupcause) {
10878             hangupcause = p->owner->hangupcause;
10879          } else if (p->hangupcause) {
10880             hangupcause = p->hangupcause;
10881          } else {
10882             int respcode;
10883             if (sscanf(msg, "%30d ", &respcode))
10884                hangupcause = hangup_sip2cause(respcode);
10885          }
10886 
10887          if (hangupcause) {
10888             sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f);
10889             add_header(&resp, "Reason", buf);
10890          }
10891       }
10892 
10893       if (p->owner && p->owner->hangupcause) {
10894          add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
10895          snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
10896          add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
10897       }
10898    }
10899    return send_response(p, &resp, reliable, seqno);
10900 }

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 17976 of file chan_sip.c.

References ast_cli(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, find_peer(), sip_poke_peer(), TRUE, and unref_peer().

Referenced by manager_sip_qualify_peer(), and sip_qualify_peer().

17977 {
17978    struct sip_peer *peer;
17979    int load_realtime;
17980 
17981    if (argc < 4)
17982       return CLI_SHOWUSAGE;
17983 
17984    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
17985    if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) {
17986       sip_poke_peer(peer, 1);
17987       unref_peer(peer, "qualify: done with peer");
17988    } else if (type == 0) {
17989       ast_cli(fd, "Peer '%s' not found\n", argv[3]);
17990    } else {
17991       astman_send_error(s, m, "Peer not found");
17992    }
17993    return CLI_SUCCESS;
17994 }

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 18061 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_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_str_buffer(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, dtmfmode2str(), FALSE, faxec2str(), find_peer(), get_transport(), 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, status, stmode2str(), strefresherparam2str(), text, transfermode2str(), TRUE, trust_id_outbound2str(), unref_peer(), and ast_variable::value.

Referenced by manager_sip_show_peer(), and sip_show_peer().

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

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 17303 of file chan_sip.c.

References _sip_show_peers_one(), ao2_callback, ao2_container_count(), ao2_iterator_destroy(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_calloc, ast_check_realtime(), ast_cli(), ast_free, ast_log(), AST_LOG_ERROR, ast_strlen_zero(), astman_get_header(), CLI_FAILURE, CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, show_peers_context::havepattern, id, show_peers_context::idtext, OBJ_MULTIPLE, peercomparefunc(), PEERS_FORMAT2, show_peers_context::peers_mon_offline, show_peers_context::peers_mon_online, show_peers_context::peers_unmon_offline, show_peers_context::peers_unmon_online, show_peers_context::realtimepeers, show_peers_context::regexbuf, TRUE, and unref_peer().

Referenced by manager_sip_show_peers(), and sip_show_peers().

17304 {
17305    struct show_peers_context cont = {
17306       .havepattern = FALSE,
17307       .idtext = "",
17308 
17309       .peers_mon_online = 0,
17310       .peers_mon_offline = 0,
17311       .peers_unmon_online = 0,
17312       .peers_unmon_offline = 0,
17313    };
17314    struct sip_peer *peer;
17315    struct ao2_iterator* it_peers;
17316 
17317    int total_peers = 0;
17318    const char *id;
17319    struct sip_peer **peerarray;
17320    int k;
17321 
17322    cont.realtimepeers = ast_check_realtime("sippeers");
17323 
17324    if (s) { /* Manager - get ActionID */
17325       id = astman_get_header(m, "ActionID");
17326       if (!ast_strlen_zero(id)) {
17327          snprintf(cont.idtext, sizeof(cont.idtext), "ActionID: %s\r\n", id);
17328       }
17329    }
17330 
17331    switch (argc) {
17332    case 5:
17333       if (!strcasecmp(argv[3], "like")) {
17334          if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
17335             return CLI_SHOWUSAGE;
17336          cont.havepattern = TRUE;
17337       } else
17338          return CLI_SHOWUSAGE;
17339    case 3:
17340       break;
17341    default:
17342       return CLI_SHOWUSAGE;
17343    }
17344 
17345    if (!s) {
17346       /* Normal list */
17347       ast_cli(fd, PEERS_FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (cont.realtimepeers ? "Realtime" : ""));
17348    }
17349 
17350    ao2_lock(peers);
17351    if (!(it_peers = ao2_callback(peers, OBJ_MULTIPLE, NULL, NULL))) {
17352       ast_log(AST_LOG_ERROR, "Unable to create iterator for peers container for sip show peers\n");
17353       ao2_unlock(peers);
17354       return CLI_FAILURE;
17355    }
17356    if (!(peerarray = ast_calloc(sizeof(struct sip_peer *), ao2_container_count(peers)))) {
17357       ast_log(AST_LOG_ERROR, "Unable to allocate peer array for sip show peers\n");
17358       ao2_iterator_destroy(it_peers);
17359       ao2_unlock(peers);
17360       return CLI_FAILURE;
17361    }
17362    ao2_unlock(peers);
17363 
17364    while ((peer = ao2_t_iterator_next(it_peers, "iterate thru peers table"))) {
17365       ao2_lock(peer);
17366 
17367       if (!(peer->type & SIP_TYPE_PEER)) {
17368          ao2_unlock(peer);
17369          unref_peer(peer, "unref peer because it's actually a user");
17370          continue;
17371       }
17372 
17373       if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) {
17374          ao2_unlock(peer);
17375          unref_peer(peer, "toss iterator peer ptr before continue");
17376          continue;
17377       }
17378 
17379       peerarray[total_peers++] = peer;
17380       ao2_unlock(peer);
17381    }
17382    ao2_iterator_destroy(it_peers);
17383 
17384    qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc);
17385 
17386    for(k = 0; k < total_peers; k++) {
17387       peerarray[k] = _sip_show_peers_one(fd, s, &cont, peerarray[k]);
17388    }
17389 
17390    if (!s) {
17391       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
17392               total_peers, cont.peers_mon_online, cont.peers_mon_offline, cont.peers_unmon_online, cont.peers_unmon_offline);
17393    }
17394 
17395    if (cont.havepattern) {
17396       regfree(&cont.regexbuf);
17397    }
17398 
17399    if (total) {
17400       *total = total_peers;
17401    }
17402 
17403    ast_free(peerarray);
17404 
17405    return CLI_SUCCESS;
17406 }

static struct sip_peer * _sip_show_peers_one ( int  fd,
struct mansession s,
struct show_peers_context cont,
struct sip_peer *  peer 
) [static, read]

Emit informations for one peer during sip show peers command.

Definition at line 17409 of file chan_sip.c.

References ao2_lock, ao2_unlock, ast_cli(), ast_copy_string(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_strlen_zero(), ast_test_flag, astman_append(), show_peers_context::havepattern, show_peers_context::idtext, name, peer_status(), PEERS_FORMAT2, show_peers_context::peers_mon_offline, show_peers_context::peers_mon_online, show_peers_context::peers_unmon_offline, show_peers_context::peers_unmon_online, show_peers_context::realtimepeers, show_peers_context::regexbuf, status, and unref_peer().

Referenced by _sip_show_peers().

17410 {
17411    /* _sip_show_peers_one() is separated from _sip_show_peers() to properly free the ast_strdupa
17412     * (this is executed in a loop in _sip_show_peers() )
17413     */
17414 
17415    char name[256];
17416    char status[20] = "";
17417    char pstatus;
17418 
17419    /*
17420     * tmp_port and tmp_host store copies of ast_sockaddr_stringify strings since the
17421     * string pointers for that function aren't valid between subsequent calls to
17422     * ast_sockaddr_stringify functions
17423     */
17424    char *tmp_port;
17425    char *tmp_host;
17426 
17427    tmp_port = ast_sockaddr_isnull(&peer->addr) ?
17428       "0" : ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
17429 
17430    tmp_host = ast_sockaddr_isnull(&peer->addr) ?
17431       "(Unspecified)" : ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
17432 
17433    ao2_lock(peer);
17434    if (cont->havepattern && regexec(&cont->regexbuf, peer->name, 0, NULL, 0)) {
17435       ao2_unlock(peer);
17436       return unref_peer(peer, "toss iterator peer ptr no match");
17437    }
17438 
17439    if (!ast_strlen_zero(peer->username) && !s) {
17440       snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
17441    } else {
17442       ast_copy_string(name, peer->name, sizeof(name));
17443    }
17444 
17445    pstatus = peer_status(peer, status, sizeof(status));
17446    if (pstatus == 1) {
17447       cont->peers_mon_online++;
17448    } else if (pstatus == 0) {
17449       cont->peers_mon_offline++;
17450    } else {
17451       if (ast_sockaddr_isnull(&peer->addr) ||
17452           !ast_sockaddr_port(&peer->addr)) {
17453          cont->peers_unmon_offline++;
17454       } else {
17455          cont->peers_unmon_online++;
17456       }
17457    }
17458 
17459    if (!s) { /* Normal CLI list */
17460       ast_cli(fd, PEERS_FORMAT2, name,
17461       tmp_host,
17462       peer->host_dynamic ? " D " : "   ", /* Dynamic or not? */
17463       ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : "   ", /* NAT=yes? */
17464       peer->ha ? " A " : "   ",       /* permit/deny */
17465       tmp_port, status,
17466       cont->realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
17467    } else { /* Manager format */
17468       /* The names here need to be the same as other channels */
17469       astman_append(s,
17470       "Event: PeerEntry\r\n%s"
17471       "Channeltype: SIP\r\n"
17472       "ObjectName: %s\r\n"
17473       "ChanObjectType: peer\r\n" /* "peer" or "user" */
17474       "IPaddress: %s\r\n"
17475       "IPport: %s\r\n"
17476       "Dynamic: %s\r\n"
17477       "Forcerport: %s\r\n"
17478       "VideoSupport: %s\r\n"
17479       "TextSupport: %s\r\n"
17480       "ACL: %s\r\n"
17481       "Status: %s\r\n"
17482       "RealtimeDevice: %s\r\n\r\n",
17483       cont->idtext,
17484       peer->name,
17485       ast_sockaddr_isnull(&peer->addr) ? "-none-" : tmp_host,
17486       ast_sockaddr_isnull(&peer->addr) ? "0" : tmp_port,
17487       peer->host_dynamic ? "yes" : "no",  /* Dynamic or not? */
17488       ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no",  /* NAT=yes? */
17489       ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no",  /* VIDEOSUPPORT=yes? */
17490       ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no",   /* TEXTSUPPORT=yes? */
17491       peer->ha ? "yes" : "no",       /* permit/deny */
17492       status,
17493       cont->realtimepeers ? (peer->is_realtime ? "yes":"no") : "no");
17494    }
17495    ao2_unlock(peer);
17496 
17497    return unref_peer(peer, "toss iterator peer ptr");
17498 }

static void * _sip_tcp_helper_thread ( 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.

Definition at line 2728 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_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_tcptls_client_start(), ast_tcptls_close_session_file(), ast_tcptls_server_write(), ast_tcptls_stream_set_exclusive_input(), ast_tcptls_stream_set_timeout_disable(), ast_tcptls_stream_set_timeout_sequence(), ast_tvnow(), cleanup(), ast_tcptls_session_instance::client, deinit_req(), errno, ast_tcptls_session_instance::fd, handle_request_do(), ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, OBJ_POINTER, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::parent, ast_tcptls_session_instance::remote_address, set_socket_transport(), sip_check_authtimeout(), sip_tcptls_read(), sip_threadinfo_create(), ast_tcptls_session_instance::ssl, and ast_tcptls_session_instance::stream_cookie.

Referenced by sip_tcp_worker_fn().

02729 {
02730    int res, timeout = -1, authenticated = 0, flags;
02731    time_t start;
02732    struct sip_request req = { 0, } , reqcpy = { 0, };
02733    struct sip_threadinfo *me = NULL;
02734    char buf[1024] = "";
02735    struct pollfd fds[2] = { { 0 }, { 0 }, };
02736    struct ast_tcptls_session_args *ca = NULL;
02737 
02738    /* If this is a server session, then the connection has already been
02739     * setup. Check if the authlimit has been reached and if not create the
02740     * threadinfo object so we can access this thread for writing.
02741     *
02742     * if this is a client connection more work must be done.
02743     * 1. We own the parent session args for a client connection.  This pointer needs
02744     *    to be held on to so we can decrement it's ref count on thread destruction.
02745     * 2. The threadinfo object was created before this thread was launched, however
02746     *    it must be found within the threadt table.
02747     * 3. Last, the tcptls_session must be started.
02748     */
02749    if (!tcptls_session->client) {
02750       if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
02751          /* unauth_sessions is decremented in the cleanup code */
02752          goto cleanup;
02753       }
02754 
02755       if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) {
02756          ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
02757          goto cleanup;
02758       }
02759 
02760       flags |= O_NONBLOCK;
02761       if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) {
02762          ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
02763          goto cleanup;
02764       }
02765 
02766       if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) {
02767          goto cleanup;
02768       }
02769       ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread");
02770    } else {
02771       struct sip_threadinfo tmp = {
02772          .tcptls_session = tcptls_session,
02773       };
02774 
02775       if ((!(ca = tcptls_session->parent)) ||
02776          (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) ||
02777          (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) {
02778          goto cleanup;
02779       }
02780    }
02781 
02782    flags = 1;
02783    if (setsockopt(tcptls_session->fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) {
02784       ast_log(LOG_ERROR, "error enabling TCP keep-alives on sip socket: %s\n", strerror(errno));
02785       goto cleanup;
02786    }
02787 
02788    me->threadid = pthread_self();
02789    ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP");
02790 
02791    /* set up pollfd to watch for reads on both the socket and the alert_pipe */
02792    fds[0].fd = tcptls_session->fd;
02793    fds[1].fd = me->alert_pipe[0];
02794    fds[0].events = fds[1].events = POLLIN | POLLPRI;
02795 
02796    if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
02797       goto cleanup;
02798    }
02799    if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) {
02800       goto cleanup;
02801    }
02802 
02803    if(time(&start) == -1) {
02804       ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
02805       goto cleanup;
02806    }
02807 
02808    /*
02809     * We cannot let the stream exclusively wait for data to arrive.
02810     * We have to wake up the task to send outgoing messages.
02811     */
02812    ast_tcptls_stream_set_exclusive_input(tcptls_session->stream_cookie, 0);
02813 
02814    ast_tcptls_stream_set_timeout_sequence(tcptls_session->stream_cookie, ast_tvnow(),
02815       tcptls_session->client ? -1 : (authtimeout * 1000));
02816 
02817    for (;;) {
02818       struct ast_str *str_save;
02819 
02820       if (!tcptls_session->client && req.authenticated && !authenticated) {
02821          authenticated = 1;
02822          ast_tcptls_stream_set_timeout_disable(tcptls_session->stream_cookie);
02823          ast_atomic_fetchadd_int(&unauth_sessions, -1);
02824       }
02825 
02826       /* calculate the timeout for unauthenticated server sessions */
02827       if (!tcptls_session->client && !authenticated ) {
02828          if ((timeout = sip_check_authtimeout(start)) < 0) {
02829             goto cleanup;
02830          }
02831 
02832          if (timeout == 0) {
02833             ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP");
02834             goto cleanup;
02835          }
02836       } else {
02837          timeout = -1;
02838       }
02839 
02840       if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
02841          res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */
02842          if (res < 0) {
02843             ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "TLS": "TCP", res);
02844             goto cleanup;
02845          } else if (res == 0) {
02846             /* timeout */
02847             ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP");
02848             goto cleanup;
02849          }
02850       }
02851 
02852       /* 
02853        * handle the socket event, check for both reads from the socket fd or TCP overflow buffer,
02854        * and writes from alert_pipe fd.
02855        */
02856       if (fds[0].revents || (ast_str_strlen(tcptls_session->overflow_buf) > 0)) { /* there is data on the socket to be read */
02857          fds[0].revents = 0;
02858 
02859          /* clear request structure */
02860          str_save = req.data;
02861          memset(&req, 0, sizeof(req));
02862          req.data = str_save;
02863          ast_str_reset(req.data);
02864 
02865          str_save = reqcpy.data;
02866          memset(&reqcpy, 0, sizeof(reqcpy));
02867          reqcpy.data = str_save;
02868          ast_str_reset(reqcpy.data);
02869 
02870          memset(buf, 0, sizeof(buf));
02871 
02872          if (tcptls_session->ssl) {
02873             set_socket_transport(&req.socket, SIP_TRANSPORT_TLS);
02874             req.socket.port = htons(ourport_tls);
02875          } else {
02876             set_socket_transport(&req.socket, SIP_TRANSPORT_TCP);
02877             req.socket.port = htons(ourport_tcp);
02878          }
02879          req.socket.fd = tcptls_session->fd;
02880 
02881          res = sip_tcptls_read(&req, tcptls_session, authenticated, start);
02882          if (res < 0) {
02883             goto cleanup;
02884          }
02885 
02886          req.socket.tcptls_session = tcptls_session;
02887          handle_request_do(&req, &tcptls_session->remote_address);
02888       }
02889 
02890       if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */
02891          enum sip_tcptls_alert alert;
02892          struct tcptls_packet *packet;
02893 
02894          fds[1].revents = 0;
02895 
02896          if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) {
02897             ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02898             continue;
02899          }
02900 
02901          switch (alert) {
02902          case TCPTLS_ALERT_STOP:
02903             goto cleanup;
02904          case TCPTLS_ALERT_DATA:
02905             ao2_lock(me);
02906             if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) {
02907                ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty\n");
02908             }
02909             ao2_unlock(me);
02910 
02911             if (packet) {
02912                if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) {
02913                   ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n");
02914                }
02915                ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed");
02916             }
02917             break;
02918          default:
02919             ast_log(LOG_ERROR, "Unknown tcptls thread alert '%u'\n", alert);
02920          }
02921       }
02922    }
02923 
02924    ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP");
02925 
02926 cleanup:
02927    if (tcptls_session && !tcptls_session->client && !authenticated) {
02928       ast_atomic_fetchadd_int(&unauth_sessions, -1);
02929    }
02930 
02931    if (me) {
02932       ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
02933       ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
02934    }
02935    deinit_req(&reqcpy);
02936    deinit_req(&req);
02937 
02938    /* if client, we own the parent session arguments and must decrement ref */
02939    if (ca) {
02940       ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments");
02941    }
02942 
02943    if (tcptls_session) {
02944       ast_mutex_lock(&tcptls_session->lock);
02945       ast_tcptls_close_session_file(tcptls_session);
02946       tcptls_session->parent = NULL;
02947       ast_mutex_unlock(&tcptls_session->lock);
02948 
02949       ao2_ref(tcptls_session, -1);
02950       tcptls_session = NULL;
02951    }
02952    return NULL;
02953 }

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

add a blank line if no body

Definition at line 4269 of file chan_sip.c.

References ast_str_append().

Referenced by send_request(), and send_response().

04270 {
04271    if (!req->lines) {
04272       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
04273       ast_str_append(&req->data, 0, "\r\n");
04274    }
04275 }

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

Definition at line 12134 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().

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

static void add_codec_to_sdp ( const struct sip_pvt *  p,
format_t  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 11385 of file chan_sip.c.

References ast_codec_pref_getsize(), AST_FORMAT_G719, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, 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, ast_format_list::cur_ms, and ast_rtp_codecs::pref.

Referenced by add_sdp().

11388 {
11389    int rtp_code;
11390    struct ast_format_list fmt;
11391 
11392 
11393    if (debug)
11394       ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", (uint64_t)codec, ast_getformatname(codec));
11395    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1)
11396       return;
11397 
11398    if (p->rtp) {
11399       struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
11400       fmt = ast_codec_pref_getsize(pref, codec);
11401    } 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 */
11402       return;
11403    ast_str_append(m_buf, 0, " %d", rtp_code);
11404    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code,
11405              ast_rtp_lookup_mime_subtype2(1, codec,
11406                      ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
11407              ast_rtp_lookup_sample_rate2(1, codec));
11408 
11409    switch (codec) {
11410    case AST_FORMAT_G729A:
11411       /* Indicate that we don't support VAD (G.729 annex B) */
11412       ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
11413       break;
11414    case AST_FORMAT_G723_1:
11415       /* Indicate that we don't support VAD (G.723.1 annex A) */
11416       ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
11417       break;
11418    case AST_FORMAT_ILBC:
11419       /* Add information about us using only 20/30 ms packetization */
11420       ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
11421       break;
11422    case AST_FORMAT_SIREN7:
11423       /* Indicate that we only expect 32Kbps */
11424       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code);
11425       break;
11426    case AST_FORMAT_SIREN14:
11427       /* Indicate that we only expect 48Kbps */
11428       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code);
11429       break;
11430    case AST_FORMAT_G719:
11431       /* Indicate that we only expect 64Kbps */
11432       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code);
11433       break;
11434    }
11435 
11436    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
11437       *min_packet_size = fmt.cur_ms;
11438 
11439    /* Our first codec packetization processed cannot be zero */
11440    if ((*min_packet_size)==0 && fmt.cur_ms)
11441       *min_packet_size = fmt.cur_ms;
11442 }

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

Add content (not header) to SIP message.

Definition at line 10276 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().

10277 {
10278    if (req->lines) {
10279       ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n");
10280       return -1;
10281    }
10282 
10283    ast_str_append(&req->content, 0, "%s", line);
10284    return 0;
10285 }

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 11214 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_info_with_digit().

11215 {
11216    char tmp[256];
11217    int event;
11218    if (mode) {
11219       /* Application/dtmf short version used by some implementations */
11220       if ('0' <= digit && digit <= '9') {
11221          event = digit - '0';
11222       } else if (digit == '*') {
11223          event = 10;
11224       } else if (digit == '#') {
11225          event = 11;
11226       } else if ('A' <= digit && digit <= 'D') {
11227          event = 12 + digit - 'A';
11228       } else if ('a' <= digit && digit <= 'd') {
11229          event = 12 + digit - 'a';
11230       } else {
11231          /* Unknown digit */
11232          event = 0;
11233       }
11234       snprintf(tmp, sizeof(tmp), "%d\r\n", event);
11235       add_header(req, "Content-Type", "application/dtmf");
11236       add_content(req, tmp);
11237    } else {
11238       /* Application/dtmf-relay as documented by Cisco */
11239       snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
11240       add_header(req, "Content-Type", "application/dtmf-relay");
11241       add_content(req, tmp);
11242    }
11243    return 0;
11244 }

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 12529 of file chan_sip.c.

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

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

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

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

Add header to SIP message.

Definition at line 10218 of file chan_sip.c.

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

Referenced by __transmit_response(), add_cc_call_info_to_response(), add_digit(), add_diversion_header(), add_header_max_forwards(), add_required_respheader(), add_route(), add_rpid(), add_sdp(), add_supported_header(), add_text(), add_vidupdate(), append_date(), copy_all_header(), copy_header(), copy_via_headers(), finalize_content(), initreqprep(), reqprep(), respprep(), transmit_cc_notify(), transmit_info_with_aoc(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sip_etag(), transmit_response_with_unsupported(), transmit_state_notify(), and update_connectedline().

10219 {
10220    if (req->headers == SIP_MAX_HEADERS) {
10221       ast_log(LOG_WARNING, "Out of SIP header space\n");
10222       return -1;
10223    }
10224 
10225    if (req->lines) {
10226       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
10227       return -1;
10228    }
10229 
10230    if (sip_cfg.compactheaders) {
10231       var = find_alias(var, var);
10232    }
10233 
10234    ast_str_append(&req->data, 0, "%s: %s\r\n", var, value);
10235    req->header[req->headers] = ast_str_strlen(req->data);
10236 
10237    req->headers++;
10238 
10239    return 0;   
10240 }

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 10246 of file chan_sip.c.

References add_header().

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

10247 {
10248    char clen[10];
10249 
10250    snprintf(clen, sizeof(clen), "%d", dialog->maxforwards);
10251 
10252    return add_header(req, "Max-Forwards", clen);
10253 }

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 11523 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().

11526 {
11527    int rtp_code;
11528 
11529    if (debug)
11530       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", (unsigned)format, ast_rtp_lookup_mime_subtype2(0, format, 0));
11531    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1)
11532       return;
11533 
11534    ast_str_append(m_buf, 0, " %d", rtp_code);
11535    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code,
11536              ast_rtp_lookup_mime_subtype2(0, format, 0),
11537              ast_rtp_lookup_sample_rate2(0, format));
11538    if (format == AST_RTP_DTMF)   /* Indicate we support DTMF and FLASH... */
11539       ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
11540 }

static void add_peer_mailboxes ( struct sip_peer *  peer,
const char *  value 
) [static]
Todo:
document this function

Definition at line 28042 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(), and S_OR.

Referenced by build_peer().

28043 {
28044    char *next, *mbox, *context;
28045 
28046    next = ast_strdupa(value);
28047 
28048    while ((mbox = context = strsep(&next, ","))) {
28049       struct sip_mailbox *mailbox;
28050       int duplicate = 0;
28051       /* remove leading/trailing whitespace from mailbox string */
28052       mbox = ast_strip(mbox);
28053       strsep(&context, "@");
28054 
28055       if (ast_strlen_zero(mbox)) {
28056          continue;
28057       }
28058 
28059       /* Check whether the mailbox is already in the list */
28060       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
28061          if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) {
28062             duplicate = 1;
28063             break;
28064          }
28065       }
28066       if (duplicate) {
28067          continue;
28068       }
28069 
28070       if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) {
28071          continue;
28072       }
28073 
28074       if (!ast_strlen_zero(context)) {
28075          mailbox->context = mailbox->mailbox + strlen(mbox) + 1;
28076          strcpy(mailbox->context, context); /* SAFE */
28077       }
28078       strcpy(mailbox->mailbox, mbox); /* SAFE */
28079 
28080       AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
28081    }
28082 }

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

Definition at line 25293 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().

25294 {
25295    struct sip_mailbox *mailbox;
25296 
25297    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
25298       if (mailbox->event_sub) {
25299          ast_event_unsubscribe(mailbox->event_sub);
25300       }
25301 
25302       mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer,
25303          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
25304          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
25305          AST_EVENT_IE_END);
25306    }
25307 }

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

Definition at line 27842 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().

27843 {
27844    char *authcopy;
27845    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
27846    struct sip_auth *auth;
27847 
27848    if (ast_strlen_zero(configuration)) {
27849       /* Nothing to add */
27850       return;
27851    }
27852 
27853    ast_debug(1, "Auth config ::  %s\n", configuration);
27854 
27855    authcopy = ast_strdupa(configuration);
27856    username = authcopy;
27857 
27858    /* split user[:secret] and relm */
27859    realm = strrchr(username, '@');
27860    if (realm)
27861       *realm++ = '\0';
27862    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
27863       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
27864       return;
27865    }
27866 
27867    /* parse username at ':' for secret, or '#" for md5secret */
27868    if ((secret = strchr(username, ':'))) {
27869       *secret++ = '\0';
27870    } else if ((md5secret = strchr(username, '#'))) {
27871       *md5secret++ = '\0';
27872    }
27873 
27874    /* Create the continer if needed. */
27875    if (!*credentials) {
27876       *credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication,
27877          "Create realm auth container.");
27878       if (!*credentials) {
27879          /* Failed to create the credentials container. */
27880          return;
27881       }
27882    }
27883 
27884    /* Create the authentication credential entry. */
27885    auth = ast_calloc(1, sizeof(*auth));
27886    if (!auth) {
27887       return;
27888    }
27889    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
27890    ast_copy_string(auth->username, username, sizeof(auth->username));
27891    if (secret)
27892       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
27893    if (md5secret)
27894       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
27895 
27896    /* Add credential to container list. */
27897    AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node);
27898 
27899    ast_verb(3, "Added authentication for realm %s\n", realm);
27900 }

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

Definition at line 4347 of file chan_sip.c.

References add_header(), ARRAY_LEN, ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_strlen(), str, and text.

Referenced by transmit_response_with_sdp().

04348 {
04349    struct ast_str *str;
04350    int i;
04351 
04352    if (!req->reqsipoptions) {
04353       return;
04354    }
04355 
04356    str = ast_str_create(32);
04357 
04358    for (i = 0; i < ARRAY_LEN(sip_options); ++i) {
04359       if (!(req->reqsipoptions & sip_options[i].id)) {
04360          continue;
04361       }
04362       if (ast_str_strlen(str) > 0) {
04363          ast_str_append(&str, 0, ", ");
04364       }
04365       ast_str_append(&str, 0, "%s", sip_options[i].text);
04366    }
04367 
04368    if (ast_str_strlen(str) > 0) {
04369       add_header(req, "Require", ast_str_buffer(str));
04370    }
04371 
04372    ast_free(str);
04373 }

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

Add route header into request per learned route.

Definition at line 10387 of file chan_sip.c.

References add_header(), and ast_copy_string().

Referenced by initreqprep(), and reqprep().

10388 {
10389    char r[SIPBUFSIZE*2], *p;
10390    int n, rem = sizeof(r);
10391 
10392    if (!route)
10393       return;
10394 
10395    p = r;
10396    for (;route ; route = route->next) {
10397       n = strlen(route->hop);
10398       if (rem < n+3) /* we need room for ",<route>" */
10399          break;
10400       if (p != r) {  /* add a separator after fist route */
10401          *p++ = ',';
10402          --rem;
10403       }
10404       *p++ = '<';
10405       ast_copy_string(p, route->hop, rem); /* cannot fail */
10406       p += n;
10407       *p++ = '>';
10408       rem -= (n+2);
10409    }
10410    *p = '\0';
10411    add_header(req, "Route", r);
10412 }

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 11250 of file chan_sip.c.

References add_header(), ast_escape_quoted(), 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(), and S_COR.

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

11251 {
11252    struct ast_str *tmp = ast_str_alloca(256);
11253    char tmp2[256];
11254    char lid_name_buf[128];
11255    char *lid_num;
11256    char *lid_name;
11257    int lid_pres;
11258    const char *fromdomain;
11259    const char *privacy = NULL;
11260    const char *screen = NULL;
11261    const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>";
11262 
11263    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
11264       return 0;
11265    }
11266 
11267    if (!p->owner) {
11268       return 0;
11269    }
11270    lid_num = S_COR(p->owner->connected.id.number.valid,
11271       p->owner->connected.id.number.str,
11272       NULL);
11273    if (!lid_num) {
11274       return 0;
11275    }
11276    lid_name = S_COR(p->owner->connected.id.name.valid,
11277       p->owner->connected.id.name.str,
11278       NULL);
11279    if (!lid_name) {
11280       lid_name = lid_num;
11281    }
11282    ast_escape_quoted(lid_name, lid_name_buf, sizeof(lid_name_buf));
11283    lid_pres = ast_party_id_presentation(&p->owner->connected.id);
11284 
11285    if (((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) &&
11286          (ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) == SIP_PAGE2_TRUST_ID_OUTBOUND_NO)) {
11287       /* If pres is not allowed and we don't trust the peer, we don't apply an RPID header */
11288       return 0;
11289    }
11290 
11291    fromdomain = p->fromdomain;
11292    if (!fromdomain ||
11293          ((ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) == SIP_PAGE2_TRUST_ID_OUTBOUND_YES) &&
11294          !strcmp("anonymous.invalid", fromdomain))) {
11295       /* If the fromdomain is NULL or if it was set to anonymous.invalid due to privacy settings and we trust the peer,
11296        * use the host IP address */
11297       fromdomain = ast_sockaddr_stringify_host_remote(&p->ourip);
11298    }
11299 
11300    lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 0);
11301 
11302    if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) {
11303       if (ast_test_flag(&p->flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND) != SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY) {
11304          /* trust_id_outbound = yes - Always give full information even if it's private, but append a privacy header
11305           * When private data is included */
11306          ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name_buf, lid_num, fromdomain);
11307          if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
11308             add_header(req, "Privacy", "id");
11309          }
11310       } else {
11311          /* trust_id_outbound = legacy - behave in a non RFC-3325 compliant manner and send anonymized data when
11312           * when handling private data. */
11313          if ((lid_pres & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
11314             ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name_buf, lid_num, fromdomain);
11315          } else {
11316             ast_str_set(&tmp, -1, "%s", anonymous_string);
11317          }
11318       }
11319       add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp));
11320    } else {
11321       ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name_buf, lid_num, fromdomain, p->outgoing_call ? "calling" : "called");
11322 
11323       switch (lid_pres) {
11324       case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
11325       case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
11326          privacy = "off";
11327          screen = "no";
11328          break;
11329       case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
11330       case AST_PRES_ALLOWED_NETWORK_NUMBER:
11331          privacy = "off";
11332          screen = "yes";
11333          break;
11334       case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
11335       case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
11336          privacy = "full";
11337          screen = "no";
11338          break;
11339       case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
11340       case AST_PRES_PROHIB_NETWORK_NUMBER:
11341          privacy = "full";
11342          screen = "yes";
11343          break;
11344       case AST_PRES_NUMBER_NOT_AVAILABLE:
11345          break;
11346       default:
11347          if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
11348             privacy = "full";
11349          }
11350          else
11351             privacy = "off";
11352          screen = "no";
11353          break;
11354       }
11355 
11356       if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) {
11357          ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen);
11358       }
11359 
11360       add_header(req, "Remote-Party-ID", ast_str_buffer(tmp));
11361    }
11362    return 0;
11363 }

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 11661 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(), ast_codec_pref_index(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), 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_str_buffer(), ast_str_size(), ast_str_strlen(), 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, capability, FALSE, get_crypto_attrib(), get_our_media_address(), LOG_WARNING, sip_debug_test_pvt(), t38_get_rate(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and version.

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

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

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 27751 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().

27752 {
27753    struct domain *d;
27754 
27755    if (ast_strlen_zero(domain)) {
27756       ast_log(LOG_WARNING, "Zero length domain.\n");
27757       return 1;
27758    }
27759 
27760    if (!(d = ast_calloc(1, sizeof(*d))))
27761       return 0;
27762 
27763    ast_copy_string(d->domain, domain, sizeof(d->domain));
27764 
27765    if (!ast_strlen_zero(context))
27766       ast_copy_string(d->context, context, sizeof(d->context));
27767 
27768    d->mode = mode;
27769 
27770    AST_LIST_LOCK(&domain_list);
27771    AST_LIST_INSERT_TAIL(&domain_list, d, list);
27772    AST_LIST_UNLOCK(&domain_list);
27773 
27774    if (sipdebug)  
27775       ast_debug(1, "Added local SIP domain '%s'\n", domain);
27776 
27777    return 1;
27778 }

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 10206 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().

10207 {
10208    int res;
10209    if (st_get_mode(pvt, 0) != SESSION_TIMER_MODE_REFUSE) {
10210       res = add_header(req, "Supported", "replaces, timer");
10211    } else {
10212       res = add_header(req, "Supported", "replaces");
10213    }
10214    return res;
10215 }

static void add_tcodec_to_sdp ( const struct sip_pvt *  p,
int  codec,
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 11469 of file chan_sip.c.

References 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(), and ast_verbose.

Referenced by add_sdp().

11472 {
11473    int rtp_code;
11474 
11475    if (!p->trtp)
11476       return;
11477 
11478    if (debug)
11479       ast_verbose("Adding text codec 0x%x (%s) to SDP\n", (unsigned)codec, ast_getformatname(codec));
11480 
11481    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1)
11482       return;
11483 
11484    ast_str_append(m_buf, 0, " %d", rtp_code);
11485    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code,
11486              ast_rtp_lookup_mime_subtype2(1, codec, 0),
11487              ast_rtp_lookup_sample_rate2(1, codec));
11488    /* Add fmtp code here */
11489 
11490    if (codec == AST_FORMAT_T140RED) {
11491       int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140);
11492       ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
11493           t140code,
11494           t140code,
11495           t140code);
11496 
11497    }
11498 }

static int add_text ( struct sip_request *  req,
const char *  text 
) [static]

Add text body to SIP message.

Definition at line 11202 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_message_with_text().

11203 {
11204    /* XXX Convert \n's to \r\n's XXX */
11205    add_header(req, "Content-Type", "text/plain;charset=UTF-8");
11206    add_content(req, text);
11207    return 0;
11208 }

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

implement the setvar config line

Definition at line 27931 of file chan_sip.c.

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

Referenced by build_peer().

27932 {
27933    struct ast_variable *tmpvar = NULL;
27934    char *varname = ast_strdupa(buf), *varval = NULL;
27935    
27936    if ((varval = strchr(varname, '='))) {
27937       *varval++ = '\0';
27938       if ((tmpvar = ast_variable_new(varname, varval, ""))) {
27939          tmpvar->next = list;
27940          list = tmpvar;
27941       }
27942    }
27943    return list;
27944 }

static void add_vcodec_to_sdp ( const struct sip_pvt *  p,
format_t  codec,
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 11446 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(), and ast_verbose.

Referenced by add_sdp().

11449 {
11450    int rtp_code;
11451 
11452    if (!p->vrtp)
11453       return;
11454 
11455    if (debug)
11456       ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", (uint64_t)codec, ast_getformatname(codec));
11457 
11458    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1)
11459       return;
11460 
11461    ast_str_append(m_buf, 0, " %d", rtp_code);
11462    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code,
11463              ast_rtp_lookup_mime_subtype2(1, codec, 0),
11464              ast_rtp_lookup_sample_rate2(1, codec));
11465    /* Add fmtp code here */
11466 }

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 11367 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_info_with_vidupdate().

11368 {
11369    const char *xml_is_a_huge_waste_of_space =
11370       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
11371       " <media_control>\r\n"
11372       "  <vc_primitive>\r\n"
11373       "   <to_encoder>\r\n"
11374       "    <picture_fast_update>\r\n"
11375       "    </picture_fast_update>\r\n"
11376       "   </to_encoder>\r\n"
11377       "  </vc_primitive>\r\n"
11378       " </media_control>\r\n";
11379    add_header(req, "Content-Type", "application/media_control+xml");
11380    add_content(req, xml_is_a_huge_waste_of_space);
11381    return 0;
11382 }

static int addr_is_multicast ( const struct ast_sockaddr addr  )  [static]

Check if an ip is an multicast IP. addr the address to check.

This function checks if an address is in the 224.0.0.0/4 network block.

Returns:
non-zero if this is a multicast address

Definition at line 8108 of file chan_sip.c.

References ast_sockaddr_ipv4().

Referenced by process_via().

08109 {
08110    return ((ast_sockaddr_ipv4(addr) & 0xf0000000) == 0xe0000000);
08111 }

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

Convert AllowOverlap setting to printable string.

Definition at line 17603 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

17604 {
17605    return map_x_s(allowoverlapstr, mode, "<error>");
17606 }

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

Append date to SIP message.

Definition at line 11025 of file chan_sip.c.

References add_header().

Referenced by transmit_invite(), transmit_response_with_date(), transmit_response_with_minse(), and transmit_response_with_unsupported().

11026 {
11027    char tmpdat[256];
11028    struct tm tm;
11029    time_t t = time(NULL);
11030 
11031    gmtime_r(&t, &tm);
11032    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
11033    add_header(req, "Date", tmpdat);
11034 }

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

Append to SIP dialog history with arg list.

Definition at line 3710 of file chan_sip.c.

References append_history_va().

03711 {
03712    va_list ap;
03713 
03714    if (!p) {
03715       return;
03716    }
03717 
03718    if (!p->do_history && !recordhistory && !dumphistory) {
03719       return;
03720    }
03721 
03722    va_start(ap, fmt);
03723    append_history_va(p, fmt, ap);
03724    va_end(ap);
03725 
03726    return;
03727 }

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 3682 of file chan_sip.c.

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, and AST_LIST_REMOVE_HEAD.

Referenced by append_history_full().

03683 {
03684    char buf[80], *c = buf; /* max history length */
03685    struct sip_history *hist;
03686    int l;
03687 
03688    vsnprintf(buf, sizeof(buf), fmt, ap);
03689    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
03690    l = strlen(buf) + 1;
03691    if (!(hist = ast_calloc(1, sizeof(*hist) + l))) {
03692       return;
03693    }
03694    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
03695       ast_free(hist);
03696       return;
03697    }
03698    memcpy(hist->event, buf, l);
03699    if (p->history_entries == MAX_HISTORY_ENTRIES) {
03700       struct sip_history *oldest;
03701       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
03702       p->history_entries--;
03703       ast_free(oldest);
03704    }
03705    AST_LIST_INSERT_TAIL(p->history, hist, list);
03706    p->history_entries++;
03707 }

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

Definition at line 29869 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().

29870 {
29871    struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
29872    int res = AST_SENSE_ALLOW;
29873 
29874    ast_rtp_instance_get_remote_address(p1->rtp, &them);
29875    ast_rtp_instance_get_local_address(p1->rtp, &us);
29876 
29877    /* If p2 is a guest call, there will be no peer. If there is no peer, there
29878     * is no directmediaha, so go ahead and allow it */
29879    if (!p2->relatedpeer) {
29880       return res;
29881    }
29882 
29883    if ((res = ast_apply_ha(p2->relatedpeer->directmediaha, &them)) == AST_SENSE_DENY) {
29884       const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us));
29885       const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them));
29886 
29887       ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
29888          op, them_addr, us_addr);
29889    }
29890 
29891    return res;
29892 }

AST_DATA_STRUCTURE ( sip_peer  ,
DATA_EXPORT_SIP_PEER   
)
AST_LIST_HEAD_NOLOCK ( sip_history_head  ,
sip_history   
)

history list, entry in sip_pvt

AST_LIST_HEAD_STATIC ( epa_static_data_list  ,
epa_backend   
)
static AST_LIST_HEAD_STATIC ( domain_list  ,
domain   
) [static]

The SIP domain list

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_LOAD_ORDER  ,
"Session Initiation Protocol (SIP)"  ,
load = load_module,
unload = unload_module,
reload = reload,
load_pri = AST_MODPRI_CHANNEL_DRIVER,
nonoptreq = "res_crypto,chan_local" 
)
AST_MUTEX_DEFINE_STATIC ( authl_lock   ) 

Global authentication container protection while adjusting the references.

AST_MUTEX_DEFINE_STATIC ( sip_reload_lock   ) 
AST_MUTEX_DEFINE_STATIC ( monlock   ) 

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

AST_MUTEX_DEFINE_STATIC ( netlock   ) 
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 22352 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().

22353 {
22354    if (chan && chan->_state == AST_STATE_UP) {
22355       if (ast_test_flag(chan, AST_FLAG_MOH))
22356          ast_moh_stop(chan);
22357       else if (chan->generatordata)
22358          ast_deactivate_generator(chan);
22359    }
22360 }

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 3578 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, get_transport(), internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, and sip_cfg.

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

03579 {
03580    struct ast_sockaddr theirs;
03581 
03582    /* Set want_remap to non-zero if we want to remap 'us' to an externally
03583     * reachable IP address and port. This is done if:
03584     * 1. we have a localaddr list (containing 'internal' addresses marked
03585     *    as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them,
03586     *    and AST_SENSE_ALLOW on 'external' ones);
03587     * 2. externaddr is set, so we know what to use as the
03588     *    externally visible address;
03589     * 3. the remote address, 'them', is external;
03590     * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY
03591     *    when passed to ast_apply_ha() so it does need to be remapped.
03592     *    This fourth condition is checked later.
03593     */
03594    int want_remap = 0;
03595 
03596    ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */
03597    /* now ask the system what would it use to talk to 'them' */
03598    ast_ouraddrfor(them, us);
03599    ast_sockaddr_copy(&theirs, them);
03600 
03601    if (ast_sockaddr_is_ipv6(&theirs)) {
03602       if (localaddr && !ast_sockaddr_isnull(&externaddr) && !ast_sockaddr_is_any(&bindaddr)) {
03603          ast_log(LOG_WARNING, "Address remapping activated in sip.conf "
03604             "but we're using IPv6, which doesn't need it. Please "
03605             "remove \"localnet\" and/or \"externaddr\" settings.\n");
03606       }
03607    } else {
03608       want_remap = localaddr &&
03609          !ast_sockaddr_isnull(&externaddr) &&
03610          ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
03611    }
03612 
03613    if (want_remap &&
03614        (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) {
03615       /* if we used externhost, see if it is time to refresh the info */
03616       if (externexpire && time(NULL) >= externexpire) {
03617          if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
03618             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
03619          }
03620          externexpire = time(NULL) + externrefresh;
03621       }
03622       if (!ast_sockaddr_isnull(&externaddr)) {
03623          ast_sockaddr_copy(us, &externaddr);
03624          switch (p->socket.type) {
03625          case SIP_TRANSPORT_TCP:
03626             if (!externtcpport && ast_sockaddr_port(&externaddr)) {
03627                /* for consistency, default to the externaddr port */
03628                externtcpport = ast_sockaddr_port(&externaddr);
03629             }
03630             ast_sockaddr_set_port(us, externtcpport);
03631             break;
03632          case SIP_TRANSPORT_TLS:
03633             ast_sockaddr_set_port(us, externtlsport);
03634             break;
03635          case SIP_TRANSPORT_UDP:
03636             if (!ast_sockaddr_port(&externaddr)) {
03637                ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
03638             }
03639             break;
03640          default:
03641             break;
03642          }
03643       }
03644       ast_debug(1, "Target address %s is not local, substituting externaddr\n",
03645            ast_sockaddr_stringify(them));
03646    } else {
03647       /* no remapping, but we bind to a specific address, so use it. */
03648       switch (p->socket.type) {
03649       case SIP_TRANSPORT_TCP:
03650          if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) {
03651             ast_sockaddr_copy(us,
03652                     &sip_tcp_desc.local_address);
03653          } else {
03654             ast_sockaddr_set_port(us,
03655                         ast_sockaddr_port(&sip_tcp_desc.local_address));
03656          }
03657          break;
03658       case SIP_TRANSPORT_TLS:
03659          if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) {
03660             ast_sockaddr_copy(us,
03661                     &sip_tls_desc.local_address);
03662          } else {
03663             ast_sockaddr_set_port(us,
03664                         ast_sockaddr_port(&sip_tls_desc.local_address));
03665          }
03666          break;
03667       case SIP_TRANSPORT_UDP:
03668          /* fall through on purpose */
03669       default:
03670          if (!ast_sockaddr_is_any(&bindaddr)) {
03671             ast_sockaddr_copy(us, &bindaddr);
03672          }
03673          if (!ast_sockaddr_port(us)) {
03674             ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
03675          }
03676       }
03677    }
03678    ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us));
03679 }

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 30707 of file chan_sip.c.

References ast_sockaddr_resolve_first_af(), and get_address_family_filter().

Referenced by ast_sip_ouraddrfor(), check_via(), and reload_config().

30709 {
30710    return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(SIP_TRANSPORT_UDP));
30711 }

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 30683 of file chan_sip.c.

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

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

30685 {
30686    struct ast_sockaddr *addrs;
30687    int addrs_cnt;
30688 
30689    addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
30690    if (addrs_cnt <= 0) {
30691       return 1;
30692    }
30693    if (addrs_cnt > 1) {
30694       ast_debug(1, "Multiple addresses, using the first one only\n");
30695    }
30696 
30697    ast_sockaddr_copy(addr, &addrs[0]);
30698 
30699    ast_free(addrs);
30700    return 0;
30701 }

static int ast_sockaddr_resolve_first_transport ( struct ast_sockaddr addr,
const char *  name,
int  flag,
unsigned int  transport 
) [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 30717 of file chan_sip.c.

References ast_sockaddr_resolve_first_af(), and get_address_family_filter().

Referenced by __set_address_from_contact(), create_addr(), parse_register_contact(), process_via(), and set_destination().

30719 {
30720         return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(transport));
30721 }

AST_THREADSTORAGE ( check_auth_buf   ) 
AST_THREADSTORAGE_CUSTOM ( ts_temp_pvt  ,
temp_pvt_init  ,
temp_pvt_cleanup   
)

A per-thread temporary pvt structure.

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 22364 of file chan_sip.c.

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

Referenced by local_attended_transfer().

22365 {
22366    int res = 0;
22367    struct ast_channel *peera = NULL,   
22368       *peerb = NULL,
22369       *peerc = NULL,
22370       *peerd = NULL;
22371 
22372 
22373    /* We will try to connect the transferee with the target and hangup
22374       all channels to the transferer */   
22375    ast_debug(4, "Sip transfer:--------------------\n");
22376    if (transferer->chan1)
22377       ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
22378    else
22379       ast_debug(4, "-- No transferer first channel - odd??? \n");
22380    if (target->chan1)
22381       ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
22382    else
22383       ast_debug(4, "-- No target first channel ---\n");
22384    if (transferer->chan2)
22385       ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
22386    else
22387       ast_debug(4, "-- No bridged call to transferee\n");
22388    if (target->chan2)
22389       ast_debug(4, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)");
22390    else
22391       ast_debug(4, "-- No target second channel ---\n");
22392    ast_debug(4, "-- END Sip transfer:--------------------\n");
22393    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
22394       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
22395       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
22396       peerc = transferer->chan2; /* Asterisk to Transferee */
22397       peerd = target->chan2;     /* Asterisk to Target */
22398       ast_debug(3, "SIP transfer: Four channels to handle\n");
22399    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
22400       peera = target->chan1;     /* Transferer to PBX -> target channel */
22401       peerb = transferer->chan1; /* Transferer to IVR*/
22402       peerc = target->chan2;     /* Asterisk to Target */
22403       peerd = transferer->chan2; /* Nothing */
22404       ast_debug(3, "SIP transfer: Three channels to handle\n");
22405    }
22406 
22407    if (peera && peerb && peerc && (peerb != peerc)) {
22408       ast_quiet_chan(peera);     /* Stop generators */
22409       /* no need to quiet peerb since it should be hungup after the
22410          transfer and the masquerade needs to be able to see if MOH is
22411          playing on it */
22412       ast_quiet_chan(peerc);
22413       if (peerd)
22414          ast_quiet_chan(peerd);
22415 
22416       ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
22417       if (ast_channel_masquerade(peerb, peerc)) {
22418          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
22419          res = -1;
22420       } else
22421          ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n");
22422       return res;
22423    } else {
22424       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
22425       if (transferer->chan1)
22426          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
22427       if (target->chan1)
22428          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
22429       return -1;
22430    }
22431    return 0;
22432 }

static void auth_headers ( enum sip_auth_type  code,
char **  header,
char **  respheader 
) [static]

return the request and response header for a 401 or 407 code

Definition at line 14135 of file chan_sip.c.

References ast_verbose.

Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().

14136 {
14137    if (code == WWW_AUTH) {       /* 401 */
14138       *header = "WWW-Authenticate";
14139       *respheader = "Authorization";
14140    } else if (code == PROXY_AUTH) { /* 407 */
14141       *header = "Proxy-Authenticate";
14142       *respheader = "Proxy-Authorization";
14143    } else {
14144       ast_verbose("-- wrong response code %u\n", code);
14145       *header = *respheader = "Invalid";
14146    }
14147 }

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 5734 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().

Referenced by sip_call(), and sip_show_sched().

05735 {
05736    struct sip_pvt *p = (struct sip_pvt *)arg;
05737 
05738    sip_pvt_lock(p);
05739    p->initid = -1;   /* event gone, will not be rescheduled */
05740    if (p->owner) {
05741       /* XXX fails on possible deadlock */
05742       if (!ast_channel_trylock(p->owner)) {
05743          append_history(p, "Cong", "Auto-congesting (timer)");
05744          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
05745          ast_channel_unlock(p->owner);
05746       }
05747 
05748       /* Give the channel a chance to act before we proceed with destruction */
05749       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05750    }
05751    sip_pvt_unlock(p);
05752    dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)");
05753    return 0;
05754 }

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 7867 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().

07868 {
07869    char buf[33];
07870    const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify_remote(&pvt->ourip));
07871 
07872    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
07873 }

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 7922 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().

07923 {
07924    char buf[33];
07925 
07926    const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host_remote(ourip));
07927 
07928    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
07929 }

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

Build contact header - the contact header we send out.

Definition at line 12329 of file chan_sip.c.

References ast_sockaddr_stringify_remote(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), and 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().

12330 {
12331    char tmp[SIPBUFSIZE];
12332    char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 0);
12333 
12334    if (p->socket.type == SIP_TRANSPORT_UDP) {
12335       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user,
12336          ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip));
12337    } else {
12338       ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user,
12339          ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip),
12340          get_transport(p->socket.type));
12341    }
12342 }

static void build_localtag_registry ( struct sip_registry *  reg  )  [static]

Build SIP From tag value for REGISTER.

Definition at line 7932 of file chan_sip.c.

References ast_random(), and ast_string_field_build.

Referenced by transmit_register().

07933 {
07934    ast_string_field_build(reg, localtag, "as%08lx", (unsigned long)ast_random());
07935 }

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 28085 of file chan_sip.c.

References __set_address_from_contact(), accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), ao2_lock, ao2_t_alloc, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, ast_append_ha(), ast_asprintf, 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_free, ast_free_ha(), ast_get_cc_agent_policy(), ast_get_group(), 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_true(), ast_variables_destroy(), cid_name, cid_num, context, DEFAULT_MAXMS, destroy_association(), destroy_mailbox(), ast_tls_config::enabled, 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_from_config(), ref_peer(), reg_source_db(), secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), sip_poke_peer(), sip_register(), sip_send_mwi_to_peer(), srvlookup, str2stmode(), str2strefresherparam(), TRUE, unref_peer(), and ast_variable::value.

Referenced by realtime_peer(), and reload_config().

28086 {
28087    struct sip_peer *peer = NULL;
28088    struct ast_ha *oldha = NULL;
28089    struct ast_ha *olddirectmediaha = NULL;
28090    int found = 0;
28091    int firstpass = 1;
28092    uint16_t port = 0;
28093    int format = 0;      /* Ama flags */
28094    int timerb_set = 0, timert1_set = 0;
28095    time_t regseconds = 0;
28096    struct ast_flags peerflags[3] = {{(0)}};
28097    struct ast_flags mask[3] = {{(0)}};
28098    char callback[256] = "";
28099    struct sip_peer tmp_peer;
28100    const char *srvlookup = NULL;
28101    static int deprecation_warning = 1;
28102    int alt_fullcontact = alt ? 1 : 0, headercount = 0;
28103    struct ast_str *fullcontact = ast_str_alloca(512);
28104 
28105    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
28106       /* Note we do NOT use find_peer here, to avoid realtime recursion */
28107       /* We also use a case-sensitive comparison (unlike find_peer) so
28108          that case changes made to the peer name will be properly handled
28109          during reload
28110       */
28111       ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name));
28112       peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table");
28113    }
28114 
28115    if (peer) {
28116       /* Already in the list, remove it and it will be added back (or FREE'd)  */
28117       found++;
28118       /* we've unlinked the peer from the peers container but not unlinked from the peers_by_ip container yet
28119         this leads to a wrong refcounter and the peer object is never destroyed */
28120       if (!ast_sockaddr_isnull(&peer->addr)) {
28121          ao2_t_unlink(peers_by_ip, peer, "ao2_unlink peer from peers_by_ip table");
28122       }
28123       if (!(peer->the_mark))
28124          firstpass = 0;
28125    } else {
28126       if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
28127          return NULL;
28128 
28129       if (ast_string_field_init(peer, 512)) {
28130          ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
28131          return NULL;
28132       }
28133 
28134       if (!(peer->cc_params = ast_cc_config_params_init())) {
28135          ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
28136          return NULL;
28137       }
28138 
28139       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
28140          ast_atomic_fetchadd_int(&rpeerobjs, 1);
28141          ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs);
28142       } else
28143          ast_atomic_fetchadd_int(&speerobjs, 1);
28144    }
28145 
28146    /* Note that our peer HAS had its reference count increased */
28147    if (firstpass) {
28148       peer->lastmsgssent = -1;
28149       oldha = peer->ha;
28150       peer->ha = NULL;
28151       olddirectmediaha = peer->directmediaha;
28152       peer->directmediaha = NULL;
28153       set_peer_defaults(peer);   /* Set peer defaults */
28154       peer->type = 0;
28155    }
28156 
28157    /* in case the case of the peer name has changed, update the name */
28158    ast_copy_string(peer->name, name, sizeof(peer->name));
28159 
28160    /* If we have channel variables, remove them (reload) */
28161    if (peer->chanvars) {
28162       ast_variables_destroy(peer->chanvars);
28163       peer->chanvars = NULL;
28164       /* XXX should unregister ? */
28165    }
28166 
28167    if (found)
28168       peer->portinuri = 0;
28169 
28170    /* If we have realm authentication information, remove them (reload) */
28171    ao2_lock(peer);
28172    if (peer->auth) {
28173       ao2_t_ref(peer->auth, -1, "Removing old peer authentication");
28174       peer->auth = NULL;
28175    }
28176    ao2_unlock(peer);
28177 
28178    /* clear the transport information.  We will detect if a default value is required after parsing the config */
28179    peer->default_outbound_transport = 0;
28180    peer->transports = 0;
28181 
28182    if (!devstate_only) {
28183       struct sip_mailbox *mailbox;
28184       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
28185          mailbox->delme = 1;
28186       }
28187    }
28188 
28189    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
28190       if (!devstate_only) {
28191          if (handle_common_options(&peerflags[0], &mask[0], v)) {
28192             continue;
28193          }
28194          if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) {
28195             continue;
28196          }
28197          if (!strcasecmp(v->name, "transport")) {
28198             char *val = ast_strdupa(v->value);
28199             char *trans;
28200 
28201             peer->transports = peer->default_outbound_transport = 0;
28202             while ((trans = strsep(&val, ","))) {
28203                trans = ast_skip_blanks(trans);
28204 
28205                if (!strncasecmp(trans, "udp", 3)) {
28206                   peer->transports |= SIP_TRANSPORT_UDP;
28207                } else if (sip_cfg.tcp_enabled && !strncasecmp(trans, "tcp", 3)) {
28208                   peer->transports |= SIP_TRANSPORT_TCP;
28209                } else if (default_tls_cfg.enabled && !strncasecmp(trans, "tls", 3)) {
28210                   peer->transports |= SIP_TRANSPORT_TLS;
28211                } else if (!strncasecmp(trans, "tcp", 3) || !strncasecmp(trans, "tls", 3)) {
28212                   ast_log(LOG_WARNING, "'%.3s' is not a valid transport type when %.3senable=no. If no other is specified, the defaults from general will be used.\n", trans, trans);
28213                } else {
28214                   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);
28215                }
28216 
28217                if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */
28218                   peer->default_outbound_transport = peer->transports;
28219                }
28220             }
28221          } else if (realtime && !strcasecmp(v->name, "regseconds")) {
28222             ast_get_time_t(v->value, &regseconds, 0, NULL);
28223          } else if (realtime && !strcasecmp(v->name, "name")) {
28224             ast_copy_string(peer->name, v->value, sizeof(peer->name));
28225          } else if (realtime && !strcasecmp(v->name, "useragent")) {
28226             ast_string_field_set(peer, useragent, v->value);
28227          } else if (!strcasecmp(v->name, "type")) {
28228             if (!strcasecmp(v->value, "peer")) {
28229                peer->type |= SIP_TYPE_PEER;
28230             } else if (!strcasecmp(v->value, "user")) {
28231                peer->type |= SIP_TYPE_USER;
28232             } else if (!strcasecmp(v->value, "friend")) {
28233                peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
28234             }
28235          } else if (!strcasecmp(v->name, "remotesecret")) {
28236             ast_string_field_set(peer, remotesecret, v->value);
28237          } else if (!strcasecmp(v->name, "secret")) {
28238             ast_string_field_set(peer, secret, v->value);
28239          } else if (!strcasecmp(v->name, "md5secret")) {
28240             ast_string_field_set(peer, md5secret, v->value);
28241          } else if (!strcasecmp(v->name, "auth")) {
28242             add_realm_authentication(&peer->auth, v->value, v->lineno);
28243          } else if (!strcasecmp(v->name, "callerid")) {
28244             char cid_name[80] = { '\0' }, cid_num[80] = { '\0' };
28245 
28246             ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
28247             ast_string_field_set(peer, cid_name, cid_name);
28248             ast_string_field_set(peer, cid_num, cid_num);
28249          } else if (!strcasecmp(v->name, "mwi_from")) {
28250             ast_string_field_set(peer, mwi_from, v->value);
28251          } else if (!strcasecmp(v->name, "fullname")) {
28252             ast_string_field_set(peer, cid_name, v->value);
28253          } else if (!strcasecmp(v->name, "trunkname")) {
28254             /* This is actually for a trunk, so we don't want to override callerid */
28255             ast_string_field_set(peer, cid_name, "");
28256          } else if (!strcasecmp(v->name, "cid_number")) {
28257             ast_string_field_set(peer, cid_num, v->value);
28258          } else if (!strcasecmp(v->name, "cid_tag")) {
28259             ast_string_field_set(peer, cid_tag, v->value);
28260          } else if (!strcasecmp(v->name, "context")) {
28261             ast_string_field_set(peer, context, v->value);
28262             ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT);
28263          } else if (!strcasecmp(v->name, "subscribecontext")) {
28264             ast_string_field_set(peer, subscribecontext, v->value);
28265          } else if (!strcasecmp(v->name, "fromdomain")) {
28266             char *fromdomainport;
28267             ast_string_field_set(peer, fromdomain, v->value);
28268             if ((fromdomainport = strchr(peer->fromdomain, ':'))) {
28269                *fromdomainport++ = '\0';
28270                if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) {
28271                   ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
28272                }
28273             } else {
28274                peer->fromdomainport = STANDARD_SIP_PORT;
28275             }
28276          } else if (!strcasecmp(v->name, "usereqphone")) {
28277             ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
28278          } else if (!strcasecmp(v->name, "fromuser")) {
28279             ast_string_field_set(peer, fromuser, v->value);
28280          } else if (!strcasecmp(v->name, "outboundproxy")) {
28281             struct sip_proxy *proxy;
28282             if (ast_strlen_zero(v->value)) {
28283                ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno);
28284                continue;
28285             }
28286             proxy = proxy_from_config(v->value, v->lineno, peer->outboundproxy);
28287             if (!proxy) {
28288                ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno);
28289                continue;
28290             }
28291             peer->outboundproxy = proxy;
28292          } else if (!strcasecmp(v->name, "host")) {
28293             if (!strcasecmp(v->value, "dynamic")) {
28294                /* They'll register with us */
28295                if ((!found && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) || !peer->host_dynamic) {
28296                   /* Initialize stuff if this is a new peer, or if it used to
28297                    * not be dynamic before the reload. */
28298                   ast_sockaddr_setnull(&peer->addr);
28299                }
28300                peer->host_dynamic = TRUE;
28301             } else {
28302                /* Non-dynamic.  Make sure we become that way if we're not */
28303                AST_SCHED_DEL_UNREF(sched, peer->expire,
28304                      unref_peer(peer, "removing register expire ref"));
28305                peer->host_dynamic = FALSE;
28306                srvlookup = v->value;
28307             }
28308          } else if (!strcasecmp(v->name, "defaultip")) {
28309             if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) {
28310                unref_peer(peer, "unref_peer: from build_peer defaultip");
28311                return NULL;
28312             }
28313          } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
28314             int ha_error = 0;
28315             if (!ast_strlen_zero(v->value)) {
28316                peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
28317             }
28318             if (ha_error) {
28319                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
28320             }
28321          } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
28322             int ha_error = 0;
28323             if (!ast_strlen_zero(v->value)) {
28324                peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error);
28325             }
28326             if (ha_error) {
28327                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
28328             }
28329          } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) {
28330             int ha_error = 0;
28331             peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error);
28332             if (ha_error) {
28333                ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value);
28334             }
28335          } else if (!strcasecmp(v->name, "port")) {
28336             peer->portinuri = 1;
28337             if (!(port = port_str2int(v->value, 0))) {
28338                if (realtime) {
28339                   /* If stored as integer, could be 0 for some DBs (notably MySQL) */
28340                   peer->portinuri = 0;
28341                } else {
28342                   ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value);
28343                }
28344             }
28345          } else if (!strcasecmp(v->name, "callingpres")) {
28346             peer->callingpres = ast_parse_caller_presentation(v->value);
28347             if (peer->callingpres == -1) {
28348                peer->callingpres = atoi(v->value);
28349             }
28350          } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) {   /* "username" is deprecated */
28351             ast_string_field_set(peer, username, v->value);
28352             if (!strcasecmp(v->name, "username")) {
28353                if (deprecation_warning) {
28354                   ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n");
28355                   deprecation_warning = 0;
28356                }
28357                peer->deprecated_username = 1;
28358             }
28359          } else if (!strcasecmp(v->name, "language")) {
28360             ast_string_field_set(peer, language, v->value);
28361          } else if (!strcasecmp(v->name, "regexten")) {
28362             ast_string_field_set(peer, regexten, v->value);
28363          } else if (!strcasecmp(v->name, "callbackextension")) {
28364             ast_copy_string(callback, v->value, sizeof(callback));
28365          } else if (!strcasecmp(v->name, "amaflags")) {
28366             format = ast_cdr_amaflags2int(v->value);
28367             if (format < 0) {
28368                ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
28369             } else {
28370                peer->amaflags = format;
28371             }
28372          } else if (!strcasecmp(v->name, "maxforwards")) {
28373             if (sscanf(v->value, "%30d", &peer->maxforwards) != 1
28374                || peer->maxforwards < 1 || 255 < peer->maxforwards) {
28375                ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d.  Using default.\n", v->value, v->lineno);
28376                peer->maxforwards = sip_cfg.default_max_forwards;
28377             }
28378          } else if (!strcasecmp(v->name, "accountcode")) {
28379             ast_string_field_set(peer, accountcode, v->value);
28380          } else if (!strcasecmp(v->name, "mohinterpret")) {
28381             ast_string_field_set(peer, mohinterpret, v->value);
28382          } else if (!strcasecmp(v->name, "mohsuggest")) {
28383             ast_string_field_set(peer, mohsuggest, v->value);
28384          } else if (!strcasecmp(v->name, "parkinglot")) {
28385             ast_string_field_set(peer, parkinglot, v->value);
28386          } else if (!strcasecmp(v->name, "rtp_engine")) {
28387             ast_string_field_set(peer, engine, v->value);
28388          } else if (!strcasecmp(v->name, "mailbox")) {
28389             add_peer_mailboxes(peer, v->value);
28390          } else if (!strcasecmp(v->name, "hasvoicemail")) {
28391             /* People expect that if 'hasvoicemail' is set, that the mailbox will
28392              * be also set, even if not explicitly specified. */
28393             if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) {
28394                add_peer_mailboxes(peer, name);
28395             }
28396          } else if (!strcasecmp(v->name, "subscribemwi")) {
28397             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
28398          } else if (!strcasecmp(v->name, "vmexten")) {
28399             ast_string_field_set(peer, vmexten, v->value);
28400          } else if (!strcasecmp(v->name, "callgroup")) {
28401             peer->callgroup = ast_get_group(v->value);
28402          } else if (!strcasecmp(v->name, "allowtransfer")) {
28403             peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
28404          } else if (!strcasecmp(v->name, "pickupgroup")) {
28405             peer->pickupgroup = ast_get_group(v->value);
28406          } else if (!strcasecmp(v->name, "allow")) {
28407             int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE);
28408             if (error) {
28409                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
28410             }
28411          } else if (!strcasecmp(v->name, "disallow")) {
28412             int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE);
28413             if (error) {
28414                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
28415             }
28416          } else if (!strcasecmp(v->name, "preferred_codec_only")) {
28417             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
28418          } else if (!strcasecmp(v->name, "autoframing")) {
28419             peer->autoframing = ast_true(v->value);
28420          } else if (!strcasecmp(v->name, "rtptimeout")) {
28421             if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
28422                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
28423                peer->rtptimeout = global_rtptimeout;
28424             }
28425          } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
28426             if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
28427                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
28428                peer->rtpholdtimeout = global_rtpholdtimeout;
28429             }
28430          } else if (!strcasecmp(v->name, "rtpkeepalive")) {
28431             if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
28432                ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
28433                peer->rtpkeepalive = global_rtpkeepalive;
28434             }
28435          } else if (!strcasecmp(v->name, "timert1")) {
28436             if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) {
28437                ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d.  Using default.\n", v->value, v->lineno);
28438                peer->timer_t1 = global_t1min;
28439             }
28440             timert1_set = 1;
28441          } else if (!strcasecmp(v->name, "timerb")) {
28442             if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) {
28443                ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d.  Using default.\n", v->value, v->lineno);
28444                peer->timer_b = global_timer_b;
28445             }
28446             timerb_set = 1;
28447          } else if (!strcasecmp(v->name, "setvar")) {
28448             peer->chanvars = add_var(v->value, peer->chanvars);
28449          } else if (!strcasecmp(v->name, "header")) {
28450             char tmp[4096];
28451             snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value);
28452             peer->chanvars = add_var(tmp, peer->chanvars);
28453          } else if (!strcasecmp(v->name, "qualifyfreq")) {
28454             int i;
28455             if (sscanf(v->value, "%30d", &i) == 1) {
28456                peer->qualifyfreq = i * 1000;
28457             } else {
28458                ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
28459                peer->qualifyfreq = global_qualifyfreq;
28460             }
28461          } else if (!strcasecmp(v->name, "maxcallbitrate")) {
28462             peer->maxcallbitrate = atoi(v->value);
28463             if (peer->maxcallbitrate < 0) {
28464                peer->maxcallbitrate = default_maxcallbitrate;
28465             }
28466          } else if (!strcasecmp(v->name, "session-timers")) {
28467             int i = (int) str2stmode(v->value);
28468             if (i < 0) {
28469                ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
28470                peer->stimer.st_mode_oper = global_st_mode;
28471             } else {
28472                peer->stimer.st_mode_oper = i;
28473             }
28474          } else if (!strcasecmp(v->name, "session-expires")) {
28475             if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) {
28476                ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
28477                peer->stimer.st_max_se = global_max_se;
28478             }
28479          } else if (!strcasecmp(v->name, "session-minse")) {
28480             if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) {
28481                ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
28482                peer->stimer.st_min_se = global_min_se;
28483             }
28484             if (peer->stimer.st_min_se < DEFAULT_MIN_SE) {
28485                ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < %d secs\n", v->value, v->lineno, config, DEFAULT_MIN_SE);
28486                peer->stimer.st_min_se = global_min_se;
28487             }
28488          } else if (!strcasecmp(v->name, "session-refresher")) {
28489             int i = (int) str2strefresherparam(v->value);
28490             if (i < 0) {
28491                ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
28492                peer->stimer.st_ref = global_st_refresher;
28493             } else {
28494                peer->stimer.st_ref = i;
28495             }
28496          } else if (!strcasecmp(v->name, "disallowed_methods")) {
28497             char *disallow = ast_strdupa(v->value);
28498             mark_parsed_methods(&peer->disallowed_methods, disallow);
28499          } else if (!strcasecmp(v->name, "unsolicited_mailbox")) {
28500             ast_string_field_set(peer, unsolicited_mailbox, v->value);
28501          } else if (!strcasecmp(v->name, "use_q850_reason")) {
28502             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
28503          } else if (!strcasecmp(v->name, "encryption")) {
28504             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP);
28505          } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
28506             ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
28507          }
28508       }
28509 
28510       /* These apply to devstate lookups */
28511       if (realtime && !strcasecmp(v->name, "lastms")) {
28512          sscanf(v->value, "%30d", &peer->lastms);
28513       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
28514          ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID);
28515       } else if (realtime && !strcasecmp(v->name, "fullcontact")) {
28516          if (alt_fullcontact && !alt) {
28517             /* Reset, because the alternate also has a fullcontact and we
28518              * do NOT want the field value to be doubled. It might be
28519              * tempting to skip this, but the first table might not have
28520              * fullcontact and since we're here, we know that the alternate
28521              * absolutely does. */
28522             alt_fullcontact = 0;
28523             ast_str_reset(fullcontact);
28524          }
28525          /* Reconstruct field, because realtime separates our value at the ';' */
28526          if (ast_str_strlen(fullcontact) > 0) {
28527             ast_str_append(&fullcontact, 0, ";%s", v->value);
28528          } else {
28529             ast_str_set(&fullcontact, 0, "%s", v->value);
28530          }
28531       } else if (!strcasecmp(v->name, "qualify")) {
28532          if (!strcasecmp(v->value, "no")) {
28533             peer->maxms = 0;
28534          } else if (!strcasecmp(v->value, "yes")) {
28535             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
28536          } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
28537             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);
28538             peer->maxms = 0;
28539          }
28540          if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
28541             /* This would otherwise cause a network storm, where the
28542              * qualify response refreshes the peer from the database,
28543              * which in turn causes another qualify to be sent, ad
28544              * infinitum. */
28545             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);
28546             peer->maxms = 0;
28547          }
28548       } else if (!strcasecmp(v->name, "callcounter")) {
28549          peer->call_limit = ast_true(v->value) ? INT_MAX : 0;
28550       } else if (!strcasecmp(v->name, "call-limit")) {
28551          peer->call_limit = atoi(v->value);
28552          if (peer->call_limit < 0) {
28553             peer->call_limit = 0;
28554          }
28555       } else if (!strcasecmp(v->name, "busylevel")) {
28556          peer->busy_level = atoi(v->value);
28557          if (peer->busy_level < 0) {
28558             peer->busy_level = 0;
28559          }
28560       } else if (ast_cc_is_config_param(v->name)) {
28561          ast_cc_set_param(peer->cc_params, v->name, v->value);
28562       }
28563    }
28564 
28565    if (!devstate_only) {
28566       struct sip_mailbox *mailbox;
28567       AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) {
28568          if (mailbox->delme) {
28569             AST_LIST_REMOVE_CURRENT(entry);
28570             destroy_mailbox(mailbox);
28571          }
28572       }
28573       AST_LIST_TRAVERSE_SAFE_END;
28574    }
28575 
28576    if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) {
28577       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);
28578       ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER);
28579    }
28580 
28581    /* Note that Timer B is dependent upon T1 and MUST NOT be lower
28582     * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */
28583    if (peer->timer_b < peer->timer_t1 * 64) {
28584       if (timerb_set && timert1_set) {
28585          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);
28586       } else if (timerb_set) {
28587          if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) {
28588             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);
28589             peer->timer_t1 = global_t1min;
28590             peer->timer_b = peer->timer_t1 * 64;
28591          }
28592          peer->timer_t1 = peer->timer_b / 64;
28593       } else {
28594          peer->timer_b = peer->timer_t1 * 64;
28595       }
28596    }
28597 
28598    if (!peer->default_outbound_transport) {
28599       /* Set default set of transports */
28600       peer->transports = default_transports;
28601       /* Set default primary transport */
28602       peer->default_outbound_transport = default_primary_transport;
28603    }
28604 
28605    /* The default transport type set during build_peer should only replace the socket.type when...
28606     * 1. Registration is not present and the socket.type and default transport types are different.
28607     * 2. The socket.type is not an acceptable transport type after rebuilding peer.
28608     * 3. The socket.type is not set yet. */
28609    if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) ||
28610       !(peer->socket.type & peer->transports) || !(peer->socket.type)) {
28611 
28612       set_socket_transport(&peer->socket, peer->default_outbound_transport);
28613    }
28614 
28615    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
28616    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
28617    ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags);
28618 
28619    if (ast_str_strlen(fullcontact)) {
28620       ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact));
28621       peer->rt_fromcontact = TRUE;
28622       /* We have a hostname in the fullcontact, but if we don't have an
28623        * address listed on the entry (or if it's 'dynamic'), then we need to
28624        * parse the entry to obtain the IP address, so a dynamic host can be
28625        * contacted immediately after reload (as opposed to waiting for it to
28626        * register once again). But if we have an address for this peer and NAT was
28627        * specified, use that address instead. */
28628       /* XXX May need to revisit the final argument; does the realtime DB store whether
28629        * the original contact was over TLS or not? XXX */
28630       if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) || ast_sockaddr_isnull(&peer->addr)) {
28631          __set_address_from_contact(ast_str_buffer(fullcontact), &peer->addr, 0);
28632       }
28633    }
28634 
28635    if (srvlookup && peer->dnsmgr == NULL) {
28636       char transport[MAXHOSTNAMELEN];
28637       char _srvlookup[MAXHOSTNAMELEN];
28638       char *params;
28639 
28640       ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup));
28641       if ((params = strchr(_srvlookup, ';'))) {
28642          *params++ = '\0';
28643       }
28644 
28645       snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type));
28646 
28647       peer->addr.ss.ss_family = get_address_family_filter(peer->socket.type); /* Filter address family */
28648       if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL,
28649                on_dns_update_peer, ref_peer(peer, "Store peer on dnsmgr"))) {
28650          ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
28651          unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref");
28652          unref_peer(peer, "getting rid of a peer pointer");
28653          return NULL;
28654       }
28655       if (!peer->dnsmgr) {
28656          /* dnsmgr refresh disabeld, release reference */
28657          unref_peer(peer, "dnsmgr disabled, unref peer");
28658       }
28659 
28660       ast_string_field_set(peer, tohost, srvlookup);
28661 
28662       if (global_dynamic_exclude_static && !ast_sockaddr_isnull(&peer->addr)) {
28663          int ha_error = 0;
28664          sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 
28665                      sip_cfg.contact_ha, &ha_error);
28666          if (ha_error) {
28667             ast_log(LOG_ERROR, "Bad or unresolved host/IP entry in configuration for peer %s, cannot add to contact ACL\n", peer->name);
28668          }
28669       }
28670    } else if (peer->dnsmgr && !peer->host_dynamic) {
28671       /* force a refresh here on reload if dnsmgr already exists and host is set. */
28672       ast_dnsmgr_refresh(peer->dnsmgr);
28673    }
28674 
28675    if (port && !realtime && peer->host_dynamic) {
28676       ast_sockaddr_set_port(&peer->defaddr, port);
28677    } else if (port) {
28678       ast_sockaddr_set_port(&peer->addr, port);
28679    }
28680 
28681    if (ast_sockaddr_port(&peer->addr) == 0) {
28682       ast_sockaddr_set_port(&peer->addr,
28683                   (peer->socket.type & SIP_TRANSPORT_TLS) ?
28684                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
28685    }
28686    if (ast_sockaddr_port(&peer->defaddr) == 0) {
28687       ast_sockaddr_set_port(&peer->defaddr,
28688                   (peer->socket.type & SIP_TRANSPORT_TLS) ?
28689                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
28690    }
28691    if (!peer->socket.port) {
28692       peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
28693    }
28694 
28695    if (realtime) {
28696       int enablepoke = 1;
28697 
28698       if (!sip_cfg.ignore_regexpire && peer->host_dynamic) {
28699          time_t nowtime = time(NULL);
28700 
28701          if ((nowtime - regseconds) > 0) {
28702             destroy_association(peer);
28703             memset(&peer->addr, 0, sizeof(peer->addr));
28704             peer->lastms = -1;
28705             enablepoke = 0;
28706             ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
28707          }
28708       }
28709 
28710       /* Startup regular pokes */
28711       if (!devstate_only && enablepoke) {
28712          sip_poke_peer(peer, 0);
28713       }
28714    }
28715 
28716    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
28717       sip_cfg.allowsubscribe = TRUE;   /* No global ban any more */
28718    }
28719    /* If read-only RT backend, then refresh from local DB cache */
28720    if (peer->host_dynamic && (!peer->is_realtime || !sip_cfg.peer_rtupdate)) {
28721       reg_source_db(peer);
28722    }
28723 
28724    /* If they didn't request that MWI is sent *only* on subscribe, go ahead and
28725     * subscribe to it now. */
28726    if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
28727       !AST_LIST_EMPTY(&peer->mailboxes)) {
28728       add_peer_mwi_subs(peer);
28729       /* Send MWI from the event cache only.  This is so we can send initial
28730        * MWI if app_voicemail got loaded before chan_sip.  If it is the other
28731        * way, then we will get events when app_voicemail gets loaded. */
28732       sip_send_mwi_to_peer(peer, 1);
28733    }
28734 
28735    peer->the_mark = 0;
28736 
28737    ast_free_ha(oldha);
28738    ast_free_ha(olddirectmediaha);
28739    if (!ast_strlen_zero(callback)) { /* build string from peer info */
28740       char *reg_string;
28741       if (ast_asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, callback) >= 0) {
28742          sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
28743          ast_free(reg_string);
28744       }
28745    }
28746    return peer;
28747 }

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 19923 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(), find_realm_authentication(), secret, sip_methods, and text.

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

19924 {
19925    char a1[256];
19926    char a2[256];
19927    char a1_hash[256];
19928    char a2_hash[256];
19929    char resp[256];
19930    char resp_hash[256];
19931    char uri[256];
19932    char opaque[256] = "";
19933    char cnonce[80];
19934    const char *username;
19935    const char *secret;
19936    const char *md5secret;
19937    struct sip_auth *auth;  /* Realm authentication credential */
19938    struct sip_auth_container *credentials;
19939 
19940    if (!ast_strlen_zero(p->domain))
19941       snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->domain);
19942    else if (!ast_strlen_zero(p->uri))
19943       ast_copy_string(uri, p->uri, sizeof(uri));
19944    else
19945       snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa));
19946 
19947    snprintf(cnonce, sizeof(cnonce), "%08lx", (unsigned long)ast_random());
19948 
19949    /* Check if we have peer credentials */
19950    ao2_lock(p);
19951    credentials = p->peerauth;
19952    if (credentials) {
19953       ao2_t_ref(credentials, +1, "Ref peer auth for digest");
19954    }
19955    ao2_unlock(p);
19956    auth = find_realm_authentication(credentials, p->realm);
19957    if (!auth) {
19958       /* If not, check global credentials */
19959       if (credentials) {
19960          ao2_t_ref(credentials, -1, "Unref peer auth for digest");
19961       }
19962       ast_mutex_lock(&authl_lock);
19963       credentials = authl;
19964       if (credentials) {
19965          ao2_t_ref(credentials, +1, "Ref global auth for digest");
19966       }
19967       ast_mutex_unlock(&authl_lock);
19968       auth = find_realm_authentication(credentials, p->realm);
19969    }
19970 
19971    if (auth) {
19972       ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
19973       username = auth->username;
19974       secret = auth->secret;
19975       md5secret = auth->md5secret;
19976       if (sipdebug)
19977          ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid);
19978    } else {
19979       /* No authentication, use peer or register= config */
19980       username = p->authname;
19981       secret = p->relatedpeer 
19982          && !ast_strlen_zero(p->relatedpeer->remotesecret)
19983             ? p->relatedpeer->remotesecret : p->peersecret;
19984       md5secret = p->peermd5secret;
19985    }
19986    if (ast_strlen_zero(username)) {
19987       /* We have no authentication */
19988       if (credentials) {
19989          ao2_t_ref(credentials, -1, "Unref auth for digest");
19990       }
19991       return -1;
19992    }
19993 
19994    /* Calculate SIP digest response */
19995    snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
19996    snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri);
19997    if (!ast_strlen_zero(md5secret))
19998       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
19999    else
20000       ast_md5_hash(a1_hash, a1);
20001    ast_md5_hash(a2_hash, a2);
20002 
20003    p->noncecount++;
20004    if (!ast_strlen_zero(p->qop))
20005       snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, (unsigned)p->noncecount, cnonce, "auth", a2_hash);
20006    else
20007       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash);
20008    ast_md5_hash(resp_hash, resp);
20009 
20010    /* only include the opaque string if it's set */
20011    if (!ast_strlen_zero(p->opaque)) {
20012       snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
20013    }
20014 
20015    /* XXX We hard code our qop to "auth" for now.  XXX */
20016    if (!ast_strlen_zero(p->qop))
20017       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, (unsigned)p->noncecount);
20018    else
20019       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);
20020 
20021    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
20022 
20023    if (credentials) {
20024       ao2_t_ref(credentials, -1, "Unref auth for digest");
20025    }
20026    return 0;
20027 }

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

Build route list from Record-Route header.

Parameters:
resp the SIP response code or 0 for a request

Definition at line 14699 of file chan_sip.c.

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

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

14700 {
14701    struct sip_route *thishop, *head, *tail;
14702    int start = 0;
14703    int len;
14704    const char *rr, *c;
14705 
14706    /* Once a persistent route is set, don't fool with it */
14707    if (p->route && p->route_persistent) {
14708       ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop);
14709       return;
14710    }
14711 
14712    if (p->route) {
14713       free_old_route(p->route);
14714       p->route = NULL;
14715    }
14716 
14717    /* We only want to create the route set the first time this is called except
14718       it is called from a provisional response.*/
14719    if ((resp < 100) || (resp > 199)) {
14720       p->route_persistent = 1;
14721    }
14722 
14723    /* Build a tailq, then assign it to p->route when done.
14724     * If backwards, we add entries from the head so they end up
14725     * in reverse order. However, we do need to maintain a correct
14726     * tail pointer because the contact is always at the end.
14727     */
14728    head = NULL;
14729    tail = head;
14730    /* 1st we pass through all the hops in any Record-Route headers */
14731    for (;;) {
14732       /* Each Record-Route header */
14733       int len = 0;
14734       const char *uri;
14735       rr = __get_header(req, "Record-Route", &start);
14736       if (*rr == '\0') {
14737          break;
14738       }
14739       while (!get_in_brackets_const(rr, &uri, &len)) {
14740          len++;
14741          rr = strchr(rr, ',');
14742          if(rr >= uri && rr < (uri + len)) {
14743             /* comma inside brackets*/
14744             const char *next_br = strchr(rr, '<');
14745             if (next_br && next_br < (uri + len)) {
14746                rr++;
14747                continue;
14748             }
14749             continue;
14750          }
14751          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
14752             ast_copy_string(thishop->hop, uri, len);
14753             ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop);
14754             /* Link in */
14755             if (backwards) {
14756                /* Link in at head so they end up in reverse order */
14757                thishop->next = head;
14758                head = thishop;
14759                /* If this was the first then it'll be the tail */
14760                if (!tail) {
14761                   tail = thishop;
14762                }
14763             } else {
14764                thishop->next = NULL;
14765                /* Link in at the end */
14766                if (tail) {
14767                   tail->next = thishop;
14768                } else {
14769                   head = thishop;
14770                }
14771                tail = thishop;
14772             }
14773          }
14774          rr = strchr(uri + len, ',');
14775          if (rr == NULL) {
14776             /* No more field-values, we're done with this header */
14777             break;
14778          }
14779          /* Advance past comma */
14780          rr++;
14781       }
14782    }
14783 
14784    /* Only append the contact if we are dealing with a strict router */
14785    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) {
14786       /* 2nd append the Contact: if there is one */
14787       /* Can be multiple Contact headers, comma separated values - we just take the first */
14788       char *contact = ast_strdupa(get_header(req, "Contact"));
14789       if (!ast_strlen_zero(contact)) {
14790          ast_debug(2, "build_route: Contact hop: %s\n", contact);
14791          /* Look for <: delimited address */
14792          c = get_in_brackets(contact);
14793          len = strlen(c) + 1;
14794          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
14795             /* ast_calloc is not needed because all fields are initialized in this block */
14796             ast_copy_string(thishop->hop, c, len);
14797             thishop->next = NULL;
14798             /* Goes at the end */
14799             if (tail) {
14800                tail->next = thishop;
14801             } else {
14802                head = thishop;
14803             }
14804          }
14805       }
14806    }
14807 
14808    /* Store as new route */
14809    p->route = head;
14810 
14811    /* For debugging dump what we ended up with */
14812    if (sip_debug_test_pvt(p)) {
14813       list_route(p->route);
14814    }
14815 }

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

Build a Via header for a request.

Definition at line 3559 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_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().

03560 {
03561    /* Work around buggy UNIDEN UIP200 firmware */
03562    const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : "";
03563 
03564    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
03565    snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s",
03566        get_transport_pvt(p),
03567        ast_sockaddr_stringify_remote(&p->ourip),
03568        (unsigned)p->branch, rport);
03569 }

static int cb_extensionstate ( char *  context,
char *  exten,
int  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 15097 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().

15098 {
15099    struct sip_pvt *p = data;
15100 
15101    sip_pvt_lock(p);
15102 
15103    switch(state) {
15104    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
15105    case AST_EXTENSION_REMOVED:   /* Extension is gone */
15106       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
15107       ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
15108       p->subscribed = NONE;
15109       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
15110       break;
15111    default: /* Tell user */
15112       p->laststate = state;
15113       break;
15114    }
15115    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
15116       if (!p->pendinginvite) {
15117          transmit_state_notify(p, state, 1, FALSE);
15118       } else {
15119          /* We already have a NOTIFY sent that is not answered. Queue the state up.
15120             if many state changes happen meanwhile, we will only send a notification of the last one */
15121          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
15122       }
15123    }
15124    ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
15125          ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
15126 
15127    sip_pvt_unlock(p);
15128 
15129    return 0;
15130 }

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

Definition at line 15087 of file chan_sip.c.

Referenced by handle_request_subscribe().

15088 {
15089    struct sip_pvt *p = data;
15090 
15091    dialog_unref(p, "the extensionstate containing this dialog ptr was destroyed");
15092 }

static void cc_epa_destructor ( void *  data  )  [static]

Definition at line 880 of file chan_sip.c.

References ast_free.

00881 {
00882    struct sip_epa_entry *epa_entry = data;
00883    struct cc_epa_entry *cc_entry = epa_entry->instance_data;
00884    ast_free(cc_entry);
00885 }

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 20556 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(), get_header(), LOG_WARNING, and transmit_invite().

20557 {
20558    struct cc_epa_entry *cc_entry = epa_entry->instance_data;
20559    struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
20560          find_sip_monitor_instance_by_suspension_entry, epa_entry);
20561    const char *min_expires;
20562 
20563    if (!monitor_instance) {
20564       ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry);
20565       return;
20566    }
20567 
20568    if (resp != 423) {
20569       ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
20570             "Received error response to our PUBLISH");
20571       ao2_ref(monitor_instance, -1);
20572       return;
20573    }
20574 
20575    /* Allrighty, the other end doesn't like our Expires value. They think it's
20576     * too small, so let's see if they've provided a more sensible value. If they
20577     * haven't, then we'll just double our Expires value and see if they like that
20578     * instead.
20579     *
20580     * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE,
20581     * PUBLISH, and REGISTER could all benefit from the same shared code.
20582     */
20583    min_expires = get_header(req, "Min-Expires");
20584    if (ast_strlen_zero(min_expires)) {
20585       pvt->expiry *= 2;
20586       if (pvt->expiry < 0) {
20587          /* You dork! You overflowed! */
20588          ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
20589                "PUBLISH expiry overflowed");
20590          ao2_ref(monitor_instance, -1);
20591          return;
20592       }
20593    } else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) {
20594       ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
20595             "Min-Expires has non-numeric value");
20596       ao2_ref(monitor_instance, -1);
20597       return;
20598    }
20599    /* At this point, we have most certainly changed pvt->expiry, so try transmitting
20600     * again
20601     */
20602    transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL);
20603    ao2_ref(monitor_instance, -1);
20604 }

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

Definition at line 7898 of file chan_sip.c.

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

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

07899 {
07900    int in_dialog_container;
07901    char *oldid = ast_strdupa(pvt->callid);
07902 
07903    ao2_lock(dialogs);
07904    in_dialog_container = CONTAINER_UNLINK(dialogs, pvt,
07905       "About to change the callid -- remove the old name");
07906    if (callid) {
07907       ast_string_field_set(pvt, callid, callid);
07908    } else {
07909       build_callid_pvt(pvt);
07910    }
07911    if (in_dialog_container) {
07912       ao2_t_link(dialogs, pvt, "New dialog callid -- inserted back into table");
07913    }
07914    ao2_unlock(dialogs);
07915 
07916    if (strcmp(oldid, pvt->callid)) {
07917       ast_debug(1, "SIP call-id changed from '%s' to '%s'\n", oldid, pvt->callid);
07918    }
07919 }

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 8987 of file chan_sip.c.

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

Referenced by handle_request_invite(), and process_sdp().

08988 {
08989    if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
08990       sip_peer_hold(dialog, holdstate);
08991    if (sip_cfg.callevents)
08992       manager_event(EVENT_FLAG_CALL, "Hold",
08993                "Status: %s\r\n"
08994                "Channel: %s\r\n"
08995                "Uniqueid: %s\r\n",
08996                holdstate ? "On" : "Off",
08997                dialog->owner->name,
08998                dialog->owner->uniqueid);
08999    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", ast_str_buffer(req->data));
09000    if (!holdstate) { /* Put off remote hold */
09001       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
09002       return;
09003    }
09004    /* No address for RTP, we're on hold */
09005 
09006    /* Ensure hold flags are cleared so that overlapping flags do not conflict */
09007    ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);
09008 
09009    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
09010       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
09011    else if (sendonly == 2) /* Inactive stream */
09012       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
09013    else
09014       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
09015    return;
09016 }

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 20285 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_header(), 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, 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().

20288 {
20289    char *redirecting_from_name = NULL;
20290    char *redirecting_from_number = NULL;
20291    char *redirecting_to_name = NULL;
20292    char *redirecting_to_number = NULL;
20293    int reason = AST_REDIRECTING_REASON_UNCONDITIONAL;
20294    int is_response = req->method == SIP_RESPONSE;
20295    int res = 0;
20296 
20297    res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason);
20298    if (res == -1) {
20299       if (is_response) {
20300          get_name_and_number(get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number);
20301       } else {
20302          return;
20303       }
20304    }
20305 
20306    /* At this point, all redirecting "from" info should be filled in appropriately
20307     * on to the "to" info
20308     */
20309 
20310    if (is_response) {
20311       parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward);
20312    } else {
20313       get_name_and_number(get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number);
20314    }
20315 
20316    if (!ast_strlen_zero(redirecting_from_number)) {
20317       ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number);
20318       update_redirecting->from.number = 1;
20319       redirecting->from.number.valid = 1;
20320       ast_free(redirecting->from.number.str);
20321       redirecting->from.number.str = redirecting_from_number;
20322    }
20323    if (!ast_strlen_zero(redirecting_from_name)) {
20324       ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name);
20325       update_redirecting->from.name = 1;
20326       redirecting->from.name.valid = 1;
20327       ast_free(redirecting->from.name.str);
20328       redirecting->from.name.str = redirecting_from_name;
20329    }
20330    if (!ast_strlen_zero(p->cid_tag)) {
20331       ast_free(redirecting->from.tag);
20332       redirecting->from.tag = ast_strdup(p->cid_tag);
20333       ast_free(redirecting->to.tag);
20334       redirecting->to.tag = ast_strdup(p->cid_tag);
20335    }
20336    if (!ast_strlen_zero(redirecting_to_number)) {
20337       ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number);
20338       update_redirecting->to.number = 1;
20339       redirecting->to.number.valid = 1;
20340       ast_free(redirecting->to.number.str);
20341       redirecting->to.number.str = redirecting_to_number;
20342    }
20343    if (!ast_strlen_zero(redirecting_to_name)) {
20344       ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number);
20345       update_redirecting->to.name = 1;
20346       redirecting->to.name.valid = 1;
20347       ast_free(redirecting->to.name.str);
20348       redirecting->to.name.str = redirecting_to_name;
20349    }
20350    redirecting->reason = reason;
20351 }

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

Change the T38 state on a SIP dialog.

Definition at line 5337 of file chan_sip.c.

References 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().

05338 {
05339    int old = p->t38.state;
05340    struct ast_channel *chan = p->owner;
05341    struct ast_control_t38_parameters parameters = { .request_response = 0 };
05342 
05343    /* Don't bother changing if we are already in the state wanted */
05344    if (old == state)
05345       return;
05346 
05347    p->t38.state = state;
05348    ast_debug(2, "T38 state changed to %u on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
05349 
05350    /* If no channel was provided we can't send off a control frame */
05351    if (!chan)
05352       return;
05353 
05354    /* Given the state requested and old state determine what control frame we want to queue up */
05355    switch (state) {
05356    case T38_PEER_REINVITE:
05357       parameters = p->t38.their_parms;
05358       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
05359       parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
05360       ast_udptl_set_tag(p->udptl, "%s", chan->name);
05361       break;
05362    case T38_ENABLED:
05363       parameters = p->t38.their_parms;
05364       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
05365       parameters.request_response = AST_T38_NEGOTIATED;
05366       ast_udptl_set_tag(p->udptl, "%s", chan->name);
05367       break;
05368    case T38_DISABLED:
05369       if (old == T38_ENABLED) {
05370          parameters.request_response = AST_T38_TERMINATED;
05371       } else if (old == T38_LOCAL_REINVITE) {
05372          parameters.request_response = AST_T38_REFUSED;
05373       }
05374       break;
05375    case T38_LOCAL_REINVITE:
05376       /* wait until we get a peer response before responding to local reinvite */
05377       break;
05378    }
05379 
05380    /* Woot we got a message, create a control frame and send it on! */
05381    if (parameters.request_response)
05382       ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
05383 }

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 14839 of file chan_sip.c.

References append_history, ast_copy_string(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), auth_headers(), BOGUS_PEER_MD5SECRET, CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), LOG_NOTICE, LOG_WARNING, S_OR, set_nonce_randdata(), sip_methods, sip_scheddestroy(), text, transmit_response_with_auth(), and TRUE.

Referenced by check_peer_ok(), and register_verify().

14842 {
14843    const char *response;
14844    char *reqheader, *respheader;
14845    const char *authtoken;
14846    char a1_hash[256];
14847    char resp_hash[256]="";
14848    char *c;
14849    int is_bogus_peer = 0;
14850    int  wrongnonce = FALSE;
14851    int  good_response;
14852    const char *usednonce = p->randdata;
14853    struct ast_str *buf;
14854    int res;
14855 
14856    /* table of recognised keywords, and their value in the digest */
14857    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
14858    struct x {
14859       const char *key;
14860       const char *s;
14861    } *i, keys[] = {
14862       [K_RESP] = { "response=", "" },
14863       [K_URI] = { "uri=", "" },
14864       [K_USER] = { "username=", "" },
14865       [K_NONCE] = { "nonce=", "" },
14866       [K_LAST] = { NULL, NULL}
14867    };
14868 
14869    /* Always OK if no secret */
14870    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
14871       return AUTH_SUCCESSFUL;
14872 
14873    /* Always auth with WWW-auth since we're NOT a proxy */
14874    /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */
14875    response = "401 Unauthorized";
14876 
14877    /*
14878     * Note the apparent swap of arguments below, compared to other
14879     * usages of auth_headers().
14880     */
14881    auth_headers(WWW_AUTH, &respheader, &reqheader);
14882 
14883    authtoken =  get_header(req, reqheader);  
14884    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
14885       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
14886          information */
14887       if (!reliable) {
14888          /* Resend message if this was NOT a reliable delivery.   Otherwise the
14889             retransmission should get it */
14890          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
14891          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
14892          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14893       }
14894       return AUTH_CHALLENGE_SENT;
14895    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
14896       /* We have no auth, so issue challenge and request authentication */
14897       set_nonce_randdata(p, 1); /* Create nonce for challenge */
14898       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
14899       /* Schedule auto destroy in 32 seconds */
14900       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14901       return AUTH_CHALLENGE_SENT;
14902    }
14903 
14904    /* --- We have auth, so check it */
14905 
14906    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
14907       an example in the spec of just what it is you're doing a hash on. */
14908 
14909    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
14910       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
14911    }
14912 
14913    /* Make a copy of the response and parse it */
14914    res = ast_str_set(&buf, 0, "%s", authtoken);
14915 
14916    if (res == AST_DYNSTR_BUILD_FAILED) {
14917       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
14918    }
14919 
14920    c = buf->str;
14921 
14922    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
14923       for (i = keys; i->key != NULL; i++) {
14924          const char *separator = ",";  /* default */
14925 
14926          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
14927             continue;
14928          }
14929          /* Found. Skip keyword, take text in quotes or up to the separator. */
14930          c += strlen(i->key);
14931          if (*c == '"') { /* in quotes. Skip first and look for last */
14932             c++;
14933             separator = "\"";
14934          }
14935          i->s = c;
14936          strsep(&c, separator);
14937          break;
14938       }
14939       if (i->key == NULL) { /* not found, jump after space or comma */
14940          strsep(&c, " ,");
14941       }
14942    }
14943 
14944    /* We cannot rely on the bogus_peer having a bad md5 value. Someone could
14945     * use it to construct valid auth. */
14946    if (md5secret && strcmp(md5secret, BOGUS_PEER_MD5SECRET) == 0) {
14947       is_bogus_peer = 1;
14948    }
14949 
14950    /* Verify that digest username matches  the username we auth as */
14951    if (strcmp(username, keys[K_USER].s) && !is_bogus_peer) {
14952       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
14953          username, keys[K_USER].s);
14954       /* Oops, we're trying something here */
14955       return AUTH_USERNAME_MISMATCH;
14956    }
14957 
14958    /* Verify nonce from request matches our nonce, and the nonce has not already been responded to.
14959     * If this check fails, send 401 with new nonce */
14960    if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */
14961       wrongnonce = TRUE;
14962       usednonce = keys[K_NONCE].s;
14963    } else {
14964       p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */
14965    }
14966 
14967    if (!ast_strlen_zero(md5secret)) {
14968       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
14969    } else {
14970       char a1[256];
14971 
14972       snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
14973       ast_md5_hash(a1_hash, a1);
14974    }
14975 
14976    /* compute the expected response to compare with what we received */
14977    {
14978       char a2[256];
14979       char a2_hash[256];
14980       char resp[256];
14981 
14982       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
14983             S_OR(keys[K_URI].s, uri));
14984       ast_md5_hash(a2_hash, a2);
14985       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
14986       ast_md5_hash(resp_hash, resp);
14987    }
14988 
14989    good_response = keys[K_RESP].s &&
14990          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)) &&
14991          !is_bogus_peer; /* lastly, check that the peer isn't the fake peer */
14992    if (wrongnonce) {
14993       if (good_response) {
14994          if (sipdebug)
14995             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From"));
14996          /* We got working auth token, based on stale nonce . */
14997          set_nonce_randdata(p, 0);
14998          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
14999       } else {
15000          /* Everything was wrong, so give the device one more try with a new challenge */
15001          if (!req->ignore) {
15002             if (sipdebug) {
15003                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
15004             }
15005             set_nonce_randdata(p, 1);
15006          } else {
15007             if (sipdebug) {
15008                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
15009             }
15010          }
15011          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
15012       }
15013 
15014       /* Schedule auto destroy in 32 seconds */
15015       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15016       return AUTH_CHALLENGE_SENT;
15017    }
15018    if (good_response) {
15019       append_history(p, "AuthOK", "Auth challenge successful for %s", username);
15020       return AUTH_SUCCESSFUL;
15021    }
15022 
15023    /* Ok, we have a bad username/secret pair */
15024    /* Tell the UAS not to re-send this authentication data, because
15025       it will continue to fail
15026    */
15027 
15028    return AUTH_SECRET_FAILED;
15029 }

static enum message_integrity check_message_integrity ( struct ast_str **  request,
struct ast_str **  overflow 
) [static]

Check that a message received over TCP is a full message.

This will take the information read in and then determine if 1) The message is a full SIP request 2) The message is a partial SIP request 3) The message contains a full SIP request along with another partial request

Parameters:
data The unparsed incoming SIP message.
request The resulting request with extra fragments removed.
overflow If the message contains more than a full request, this is the remainder of the message
Returns:
The resulting integrity of the message

Definition at line 2592 of file chan_sip.c.

References ast_str_append(), ast_str_buffer(), ast_str_strlen(), ast_str_truncate(), MESSAGE_COMPLETE, MESSAGE_FRAGMENT, MESSAGE_FRAGMENT_COMPLETE, MESSAGE_INVALID, and read_raw_content_length().

Referenced by sip_tcptls_read().

02593 {
02594    char *message = ast_str_buffer(*request);
02595    char *body;
02596    int content_length;
02597    int message_len = ast_str_strlen(*request);
02598    int body_len;
02599 
02600    /* Important pieces to search for in a SIP request are \r\n\r\n. This
02601     * marks either
02602     * 1) The division between the headers and body
02603     * 2) The end of the SIP request
02604     */
02605    body = strstr(message, "\r\n\r\n");
02606    if (!body) {
02607       /* This is clearly a partial message since we haven't reached an end
02608        * yet.
02609        */
02610       return MESSAGE_FRAGMENT;
02611    }
02612    body += sizeof("\r\n\r\n") - 1;
02613    body_len = message_len - (body - message);
02614 
02615    body[-1] = '\0';
02616    content_length = read_raw_content_length(message);
02617    body[-1] = '\n';
02618 
02619    if (content_length < 0) {
02620       return MESSAGE_INVALID;
02621    } else if (content_length == 0) {
02622       /* We've definitely received an entire message. We need
02623        * to check if there's also a fragment of another message
02624        * in addition.
02625        */
02626       if (body_len == 0) {
02627          return MESSAGE_COMPLETE;
02628       } else {
02629          ast_str_append(overflow, 0, "%s", body);
02630          ast_str_truncate(*request, message_len - body_len);
02631          return MESSAGE_FRAGMENT_COMPLETE;
02632       }
02633    }
02634    /* Positive content length. Let's see what sort of
02635     * message body we're dealing with.
02636     */
02637    if (body_len < content_length) {
02638       /* We don't have the full message body yet */
02639       return MESSAGE_FRAGMENT;
02640    } else if (body_len > content_length) {
02641       /* We have the full message plus a fragment of a further
02642        * message
02643        */
02644       ast_str_append(overflow, 0, "%s", body + content_length);
02645       ast_str_truncate(*request, message_len - (body_len - content_length));
02646       return MESSAGE_FRAGMENT_COMPLETE;
02647    } else {
02648       /* Yay! Full message with no extra content */
02649       return MESSAGE_COMPLETE;
02650    }
02651 }

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 16511 of file chan_sip.c.

References accountcode, ao2_t_ref, ast_apply_ha(), ast_cc_copy_config_params(), ast_copy_flags, ast_debug, 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(), dialog_initialize_rtp(), do_setnat(), FALSE, find_peer(), get_rpid(), language, mohinterpret, mohsuggest, parkinglot, ref_peer(), set_pvt_allowed_methods(), set_t38_capabilities(), sip_cfg, sip_debug_test_addr(), TRUE, and unref_peer().

Referenced by check_user_full().

16515 {
16516    enum check_auth_result res;
16517    int debug = sip_debug_test_addr(addr);
16518    struct sip_peer *peer;
16519 
16520    if (sipmethod == SIP_SUBSCRIBE) {
16521       /* For subscribes, match on device name only; for other methods,
16522       * match on IP address-port of the incoming request.
16523       */
16524       peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0);
16525    } else {
16526       /* First find devices based on username (avoid all type=peer's) */
16527       peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0);
16528 
16529       /* Then find devices based on IP */
16530       if (!peer) {
16531          peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
16532       }
16533    }
16534 
16535    if (!peer) {
16536       if (debug) {
16537          ast_verbose("No matching peer for '%s' from '%s'\n",
16538             of, ast_sockaddr_stringify(&p->recv));
16539       }
16540 
16541       /* If you don't mind, we can return 404s for devices that do
16542        * not exist: username disclosure. If we allow guests, there
16543        * is no way around that. */
16544       if (sip_cfg.allowguest || !sip_cfg.alwaysauthreject) {
16545          return AUTH_DONT_KNOW;
16546       }
16547 
16548       /* If you do mind, we use a peer that will never authenticate.
16549        * This ensures that we follow the same code path as regular
16550        * auth: less chance for username disclosure. */
16551       peer = bogus_peer;
16552       ref_peer(peer, "ref_peer: check_peer_ok: must ref bogus_peer so unreffing it does not fail");
16553    }
16554 
16555    if (!ast_apply_ha(peer->ha, addr)) {
16556       ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
16557       unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
16558       return AUTH_ACL_FAILED;
16559    }
16560    if (debug && peer != bogus_peer) {
16561       ast_verbose("Found peer '%s' for '%s' from %s\n",
16562          peer->name, of, ast_sockaddr_stringify(&p->recv));
16563    }
16564 
16565    /* XXX what about p->prefs = peer->prefs; ? */
16566    /* Set Frame packetization */
16567    if (p->rtp) {
16568       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
16569       p->autoframing = peer->autoframing;
16570    }
16571 
16572    /* Take the peer */
16573    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
16574    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16575    ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
16576 
16577    if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) {
16578       p->t38_maxdatagram = peer->t38_maxdatagram;
16579       set_t38_capabilities(p);
16580    }
16581 
16582    /* Copy SIP extensions profile to peer */
16583    /* XXX is this correct before a successful auth ? */
16584    if (p->sipoptions)
16585       peer->sipoptions = p->sipoptions;
16586 
16587    do_setnat(p);
16588 
16589    ast_string_field_set(p, peersecret, peer->secret);
16590    ast_string_field_set(p, peermd5secret, peer->md5secret);
16591    ast_string_field_set(p, subscribecontext, peer->subscribecontext);
16592    ast_string_field_set(p, mohinterpret, peer->mohinterpret);
16593    ast_string_field_set(p, mohsuggest, peer->mohsuggest);
16594    if (!ast_strlen_zero(peer->parkinglot)) {
16595       ast_string_field_set(p, parkinglot, peer->parkinglot);
16596    }
16597    ast_string_field_set(p, engine, peer->engine);
16598    p->disallowed_methods = peer->disallowed_methods;
16599    set_pvt_allowed_methods(p, req);
16600    ast_cc_copy_config_params(p->cc_params, peer->cc_params);
16601    if (peer->callingpres)  /* Peer calling pres setting will override RPID */
16602       p->callingpres = peer->callingpres;
16603    if (peer->maxms && peer->lastms)
16604       p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
16605    else
16606       p->timer_t1 = peer->timer_t1;
16607 
16608    /* Set timer B to control transaction timeouts */
16609    if (peer->timer_b)
16610       p->timer_b = peer->timer_b;
16611    else
16612       p->timer_b = 64 * p->timer_t1;
16613 
16614    p->allowtransfer = peer->allowtransfer;
16615 
16616    if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
16617       /* Pretend there is no required authentication */
16618       ast_string_field_set(p, peersecret, NULL);
16619       ast_string_field_set(p, peermd5secret, NULL);
16620    }
16621    if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) {
16622       ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
16623       ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16624       ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
16625       /* If we have a call limit, set flag */
16626       if (peer->call_limit)
16627          ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
16628       ast_string_field_set(p, peername, peer->name);
16629       ast_string_field_set(p, authname, peer->name);
16630 
16631       if (sipmethod == SIP_INVITE) {
16632          /* destroy old channel vars and copy in new ones. */
16633          ast_variables_destroy(p->chanvars);
16634          p->chanvars = copy_vars(peer->chanvars);
16635       }
16636 
16637       if (authpeer) {
16638          ao2_t_ref(peer, 1, "copy pointer into (*authpeer)");
16639          (*authpeer) = peer;  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
16640       }
16641 
16642       if (!ast_strlen_zero(peer->username)) {
16643          ast_string_field_set(p, username, peer->username);
16644          /* Use the default username for authentication on outbound calls */
16645          /* XXX this takes the name from the caller... can we override ? */
16646          ast_string_field_set(p, authname, peer->username);
16647       }
16648       if (!get_rpid(p, req)) {
16649          if (!ast_strlen_zero(peer->cid_num)) {
16650             char *tmp = ast_strdupa(peer->cid_num);
16651             if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
16652                ast_shrink_phone_number(tmp);
16653             ast_string_field_set(p, cid_num, tmp);
16654          }
16655          if (!ast_strlen_zero(peer->cid_name))
16656             ast_string_field_set(p, cid_name, peer->cid_name);
16657          if (peer->callingpres)
16658             p->callingpres = peer->callingpres;
16659       }
16660       if (!ast_strlen_zero(peer->cid_tag)) {
16661          ast_string_field_set(p, cid_tag, peer->cid_tag);
16662       }
16663       ast_string_field_set(p, fullcontact, peer->fullcontact);
16664 
16665       if (!ast_strlen_zero(peer->context)) {
16666          ast_string_field_set(p, context, peer->context);
16667       }
16668       if (!ast_strlen_zero(peer->mwi_from)) {
16669          ast_string_field_set(p, mwi_from, peer->mwi_from);
16670       }
16671 
16672       ast_string_field_set(p, peersecret, peer->secret);
16673       ast_string_field_set(p, peermd5secret, peer->md5secret);
16674       ast_string_field_set(p, language, peer->language);
16675       ast_string_field_set(p, accountcode, peer->accountcode);
16676       p->amaflags = peer->amaflags;
16677       p->callgroup = peer->callgroup;
16678       p->pickupgroup = peer->pickupgroup;
16679       p->capability = peer->capability;
16680       p->prefs = peer->prefs;
16681       p->jointcapability = peer->capability;
16682       if (peer->maxforwards > 0) {
16683          p->maxforwards = peer->maxforwards;
16684       }
16685       if (p->peercapability)
16686          p->jointcapability &= p->peercapability;
16687       p->maxcallbitrate = peer->maxcallbitrate;
16688       if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
16689           (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
16690          p->noncodeccapability |= AST_RTP_DTMF;
16691       else
16692          p->noncodeccapability &= ~AST_RTP_DTMF;
16693       p->jointnoncodeccapability = p->noncodeccapability;
16694       p->rtptimeout = peer->rtptimeout;
16695       p->rtpholdtimeout = peer->rtpholdtimeout;
16696       p->rtpkeepalive = peer->rtpkeepalive;
16697       if (!dialog_initialize_rtp(p)) {
16698          if (p->rtp) {
16699             ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
16700             p->autoframing = peer->autoframing;
16701          }
16702       } else {
16703          res = AUTH_RTP_FAILED;
16704       }
16705    }
16706    unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer");
16707    return res;
16708 }

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 20471 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(), reinvite_timeout(), retrans_pkt(), and sip_reinvite_retry().

20472 {
20473    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
20474       if (p->reinviteid > -1) {
20475          /* Outstanding p->reinviteid timeout, so wait... */
20476          return;
20477       } else if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
20478          /* if we can't BYE, then this is really a pending CANCEL */
20479          p->invitestate = INV_CANCELLED;
20480          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
20481          /* If the cancel occurred on an initial invite, cancel the pending BYE */
20482          if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
20483             ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
20484          }
20485          /* Actually don't destroy us yet, wait for the 487 on our original
20486             INVITE, but do set an autodestruct just in case we never get it. */
20487       } else {
20488          /* We have a pending outbound invite, don't send something
20489           * new in-transaction, unless it is a pending reinvite, then
20490           * by the time we are called here, we should probably just hang up. */
20491          if (p->pendinginvite && !p->ongoing_reinvite)
20492             return;
20493 
20494          if (p->owner) {
20495             ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
20496          }
20497          /* Perhaps there is an SD change INVITE outstanding */
20498          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
20499          ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
20500       }
20501       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20502    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
20503       /* if we can't REINVITE, hold it for later */
20504       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
20505          ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
20506       } else {
20507          ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid);
20508          /* Didn't get to reinvite yet, so do it now */
20509          transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE);
20510          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
20511       }
20512    }
20513 }

static void 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

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 26568 of file chan_sip.c.

References ast_channel_trylock, 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, and LOG_NOTICE.

Referenced by dialog_needdestroy().

26569 {
26570    /* If we have no RTP or no active owner, no need to check timers */
26571    if (!dialog->rtp || !dialog->owner)
26572       return;
26573    /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */
26574 
26575    if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip))
26576       return;
26577 
26578    /* If the call is involved in a T38 fax session do not check RTP timeout */
26579    if (dialog->t38.state == T38_ENABLED)
26580       return;
26581 
26582    /* If we have no timers set, return now */
26583    if (!ast_rtp_instance_get_keepalive(dialog->rtp) && !ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) {
26584       return;
26585    }
26586 
26587    /* Check AUDIO RTP keepalives */
26588    if (dialog->lastrtptx && ast_rtp_instance_get_keepalive(dialog->rtp) &&
26589           (t > dialog->lastrtptx + ast_rtp_instance_get_keepalive(dialog->rtp))) {
26590       /* Need to send an empty RTP packet */
26591       dialog->lastrtptx = time(NULL);
26592       ast_rtp_instance_sendcng(dialog->rtp, 0);
26593    }
26594 
26595    /*! \todo Check video RTP keepalives
26596 
26597       Do we need to move the lastrtptx to the RTP structure to have one for audio and one
26598       for video? It really does belong to the RTP structure.
26599    */
26600 
26601    /* Check AUDIO RTP timers */
26602    if (dialog->lastrtprx && (ast_rtp_instance_get_timeout(dialog->rtp) || ast_rtp_instance_get_hold_timeout(dialog->rtp)) && (t > dialog->lastrtprx + ast_rtp_instance_get_timeout(dialog->rtp))) {
26603       if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (ast_rtp_instance_get_hold_timeout(dialog->rtp) && (t > dialog->lastrtprx + ast_rtp_instance_get_hold_timeout(dialog->rtp)))) {
26604          /* Needs a hangup */
26605          if (ast_rtp_instance_get_timeout(dialog->rtp)) {
26606             if (!dialog->owner || ast_channel_trylock(dialog->owner)) {
26607                /*
26608                 * Don't block, just try again later.
26609                 * If there was no owner, the call is dead already.
26610                 */
26611                return;
26612             }
26613             ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
26614                dialog->owner->name, (long) (t - dialog->lastrtprx));
26615             /* Issue a softhangup */
26616             ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV);
26617             ast_channel_unlock(dialog->owner);
26618             /* forget the timeouts for this call, since a hangup
26619                has already been requested and we don't want to
26620                repeatedly request hangups
26621             */
26622             ast_rtp_instance_set_timeout(dialog->rtp, 0);
26623             ast_rtp_instance_set_hold_timeout(dialog->rtp, 0);
26624             if (dialog->vrtp) {
26625                ast_rtp_instance_set_timeout(dialog->vrtp, 0);
26626                ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0);
26627             }
26628          }
26629       }
26630    }
26631 }

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 27781 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().

27782 {
27783    struct domain *d;
27784    int result = 0;
27785 
27786    AST_LIST_LOCK(&domain_list);
27787    AST_LIST_TRAVERSE(&domain_list, d, list) {
27788       if (strcasecmp(d->domain, domain)) {
27789          continue;
27790       }
27791 
27792       if (len && !ast_strlen_zero(d->context))
27793          ast_copy_string(context, d->context, len);
27794       
27795       result = 1;
27796       break;
27797    }
27798    AST_LIST_UNLOCK(&domain_list);
27799 
27800    return result;
27801 }

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 16847 of file chan_sip.c.

References check_user_full().

Referenced by handle_request_options(), and handle_request_publish().

16848 {
16849    return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL);
16850 }

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 16716 of file chan_sip.c.

References ast_free, ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdup, 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_header(), get_in_brackets(), get_rpid(), LOG_ERROR, LOG_NOTICE, name, parse_uri_legacy_check(), RAII_VAR, sip_cfg, SIP_PEDANTIC_DECODE, and terminate_uri().

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

16719 {
16720    char *of, *name, *unused_password, *domain;
16721    RAII_VAR(char *, ofbuf, NULL, ast_free); /* beware, everyone starts pointing to this */
16722    RAII_VAR(char *, namebuf, NULL, ast_free);
16723    enum check_auth_result res = AUTH_DONT_KNOW;
16724    char calleridname[256];
16725    char *uri2 = ast_strdupa(uri);
16726 
16727    terminate_uri(uri2); /* trim extra stuff */
16728 
16729    ofbuf = ast_strdup(get_header(req, "From"));
16730    /* XXX here tries to map the username for invite things */
16731 
16732    /* strip the display-name portion off the beginning of the FROM header. */
16733    if (!(of = (char *) get_calleridname(ofbuf, calleridname, sizeof(calleridname)))) {
16734       ast_log(LOG_ERROR, "FROM header can not be parsed\n");
16735       return res;
16736    }
16737 
16738    if (calleridname[0]) {
16739       ast_string_field_set(p, cid_name, calleridname);
16740    }
16741 
16742    if (ast_strlen_zero(p->exten)) {
16743       char *t = uri2;
16744       if (!strncasecmp(t, "sip:", 4))
16745          t+= 4;
16746       else if (!strncasecmp(t, "sips:", 5))
16747          t += 5;
16748       ast_string_field_set(p, exten, t);
16749       t = strchr(p->exten, '@');
16750       if (t)
16751          *t = '\0';
16752 
16753       if (ast_strlen_zero(p->our_contact))
16754          build_contact(p);
16755    }
16756 
16757    of = get_in_brackets(of);
16758 
16759    /* save the URI part of the From header */
16760    ast_string_field_set(p, from, of);
16761 
16762    if (parse_uri_legacy_check(of, "sip:,sips:", &name, &unused_password, &domain, NULL)) {
16763       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
16764    }
16765 
16766    SIP_PEDANTIC_DECODE(name);
16767    SIP_PEDANTIC_DECODE(domain);
16768 
16769    extract_host_from_hostport(&domain);
16770 
16771    if (ast_strlen_zero(domain)) {
16772       /* <sip:name@[EMPTY]>, never good */
16773       ast_log(LOG_ERROR, "Empty domain name in FROM header\n");
16774       return res;
16775    }
16776 
16777    if (ast_strlen_zero(name)) {
16778       /* <sip:[EMPTY][@]hostport>. Asterisk 1.4 and 1.6 have always
16779        * treated that as a username, so we continue the tradition:
16780        * uri is now <sip:host@hostport>. */
16781       name = domain;
16782    } else {
16783       /* Non-empty name, try to get caller id from it */
16784       char *tmp = ast_strdupa(name);
16785       /* We need to be able to handle from-headers looking like
16786          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
16787       */
16788       tmp = strsep(&tmp, ";");
16789       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) {
16790          ast_shrink_phone_number(tmp);
16791       }
16792       ast_string_field_set(p, cid_num, tmp);
16793    }
16794 
16795    if (global_match_auth_username) {
16796       /*
16797        * XXX This is experimental code to grab the search key from the
16798        * Auth header's username instead of the 'From' name, if available.
16799        * Do not enable this block unless you understand the side effects (if any!)
16800        * Note, the search for "username" should be done in a more robust way.
16801        * Note2, at the moment we check both fields, though maybe we should
16802        * pick one or another depending on the request ? XXX
16803        */
16804       const char *hdr = get_header(req, "Authorization");
16805       if (ast_strlen_zero(hdr)) {
16806          hdr = get_header(req, "Proxy-Authorization");
16807       }
16808 
16809       if (!ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\""))) {
16810          namebuf = name = ast_strdup(hdr + strlen("username=\""));
16811          name = strsep(&name, "\"");
16812       }
16813    }
16814 
16815    res = check_peer_ok(p, name, req, sipmethod, addr,
16816          authpeer, reliable, calleridname, uri2);
16817    if (res != AUTH_DONT_KNOW) {
16818       return res;
16819    }
16820 
16821    /* Finally, apply the guest policy */
16822    if (sip_cfg.allowguest) {
16823       /* Ignore check_return warning from Coverity for get_rpid below. */
16824       get_rpid(p, req);
16825       p->rtptimeout = global_rtptimeout;
16826       p->rtpholdtimeout = global_rtpholdtimeout;
16827       p->rtpkeepalive = global_rtpkeepalive;
16828       if (!dialog_initialize_rtp(p)) {
16829          res = AUTH_SUCCESSFUL;
16830       } else {
16831          res = AUTH_RTP_FAILED;
16832       }
16833    } else {
16834       res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
16835    }
16836 
16837    if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) {
16838       ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
16839    }
16840 
16841    return res;
16842 }

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

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

Definition at line 16446 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, get_header(), LOG_WARNING, sip_debug_test_pvt(), 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().

16447 {
16448    char via[512];
16449    char *c, *maddr;
16450    struct ast_sockaddr tmp = { { 0, } };
16451    uint16_t port;
16452 
16453    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
16454 
16455    /* Work on the leftmost value of the topmost Via header */
16456    c = strchr(via, ',');
16457    if (c)
16458       *c = '\0';
16459 
16460    /* Check for rport */
16461    c = strstr(via, ";rport");
16462    if (c && (c[6] != '=')) { /* rport query, not answer */
16463       ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT);
16464       ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
16465    }
16466 
16467    /* Check for maddr */
16468    maddr = strstr(via, "maddr=");
16469    if (maddr) {
16470       maddr += 6;
16471       c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz"
16472                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]");
16473       *c = '\0';
16474    }
16475 
16476    c = strchr(via, ';');
16477    if (c)
16478       *c = '\0';
16479 
16480    c = strchr(via, ' ');
16481    if (c) {
16482       *c = '\0';
16483       c = ast_skip_blanks(c+1);
16484       if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) {
16485          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
16486          return;
16487       }
16488 
16489       if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) {
16490          p->sa = p->recv;
16491       }
16492 
16493       if (ast_sockaddr_resolve_first(&tmp, c, 0)) {
16494          ast_log(LOG_WARNING, "Could not resolve socket address for '%s'\n", c);
16495          port = STANDARD_SIP_PORT;
16496       } else if (!(port = ast_sockaddr_port(&tmp))) {
16497          port = STANDARD_SIP_PORT;
16498       }
16499 
16500       ast_sockaddr_set_port(&p->sa, port);
16501 
16502       if (sip_debug_test_pvt(p)) {
16503          ast_verbose("Sending to %s (%s)\n",
16504                 ast_sockaddr_stringify(sip_real_dst(p)),
16505                 sip_nat_mode(p));
16506       }
16507    }
16508 }

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 16416 of file chan_sip.c.

References ast_copy_string(), ast_parse_arg(), ast_sockaddr_set_port, get_header(), and PARSE_ADDR.

16417 {
16418    char via[256];
16419    char *cur, *opts;
16420 
16421    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
16422 
16423    /* Work on the leftmost value of the topmost Via header */
16424    opts = strchr(via, ',');
16425    if (opts)
16426       *opts = '\0';
16427 
16428    /* parse all relevant options */
16429    opts = strchr(via, ';');
16430    if (!opts)
16431       return;  /* no options to parse */
16432    *opts++ = '\0';
16433    while ( (cur = strsep(&opts, ";")) ) {
16434       if (!strncmp(cur, "rport=", 6)) {
16435          int port = strtol(cur+6, NULL, 10);
16436          /* XXX add error checking */
16437          ast_sockaddr_set_port(&p->ourip, port);
16438       } else if (!strncmp(cur, "received=", 9)) {
16439          if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip))
16440             ;  /* XXX add error checking */
16441       }
16442    }
16443 }

static void cleanup_all_regs ( void   )  [static]

Definition at line 28768 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().

28769 {
28770       /* First, destroy all outstanding registry calls */
28771       /* This is needed, since otherwise active registry entries will not be destroyed */
28772       ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {  /* regl is locked */
28773             ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */
28774             if (iterator->call) {
28775                ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
28776                /* This will also remove references to the registry */
28777                dialog_unlink_all(iterator->call);
28778                iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal");
28779             }
28780             if (iterator->expire > -1) {
28781                AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config"));
28782             }
28783             if (iterator->timeout > -1) {
28784                AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config"));
28785             }
28786             if (iterator->dnsmgr) {
28787                ast_dnsmgr_release(iterator->dnsmgr);
28788                iterator->dnsmgr = NULL;
28789                registry_unref(iterator, "reg ptr unref from dnsmgr");
28790             }
28791             ASTOBJ_UNLOCK(iterator);
28792       } while(0));
28793 }

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 17623 of file chan_sip.c.

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

Referenced by reload_config().

17624 {
17625    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
17626 
17627    while ((oldcontext = strsep(&old, "&"))) {
17628       stalecontext = '\0';
17629       ast_copy_string(newlist, new, sizeof(newlist));
17630       stringp = newlist;
17631       while ((newcontext = strsep(&stringp, "&"))) {
17632          if (!strcmp(newcontext, oldcontext)) {
17633             /* This is not the context you're looking for */
17634             stalecontext = '\0';
17635             break;
17636          } else if (strcmp(newcontext, oldcontext)) {
17637             stalecontext = oldcontext;
17638          }
17639          
17640       }
17641       if (stalecontext)
17642          ast_context_destroy(ast_context_find(stalecontext), "SIP");
17643    }
17644 }

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

Destroy all peer-related mailbox subscriptions

Definition at line 4810 of file chan_sip.c.

References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.

Referenced by set_peer_defaults(), and sip_destroy_peer().

04811 {
04812    struct sip_mailbox *mailbox;
04813 
04814    while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry)))
04815       destroy_mailbox(mailbox);
04816 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

Definition at line 27804 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().

27805 {
27806    struct domain *d;
27807 
27808    AST_LIST_LOCK(&domain_list);
27809    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
27810       ast_free(d);
27811    AST_LIST_UNLOCK(&domain_list);
27812 }

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

Do completion on peer name.

Definition at line 19107 of file chan_sip.c.

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

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

19108 {
19109    char *result = NULL;
19110    int wordlen = strlen(word);
19111    int which = 0;
19112    struct ao2_iterator i = ao2_iterator_init(peers, 0);
19113    struct sip_peer *peer;
19114 
19115    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
19116       /* locking of the object is not required because only the name and flags are being compared */
19117       if (!strncasecmp(word, peer->name, wordlen) &&
19118             (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
19119             ++which > state)
19120          result = ast_strdup(peer->name);
19121       unref_peer(peer, "toss iterator peer ptr before break");
19122       if (result) {
19123          break;
19124       }
19125    }
19126    ao2_iterator_destroy(&i);
19127    return result;
19128 }

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

Do completion on registered peer name.

Definition at line 19131 of file chan_sip.c.

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

Referenced by complete_sip_unregister().

19132 {
19133        char *result = NULL;
19134        int wordlen = strlen(word);
19135        int which = 0;
19136        struct ao2_iterator i;
19137        struct sip_peer *peer;
19138        
19139        i = ao2_iterator_init(peers, 0);
19140        while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
19141           if (!strncasecmp(word, peer->name, wordlen) &&
19142          (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
19143          ++which > state && peer->expire > 0)
19144              result = ast_strdup(peer->name);
19145           if (result) {
19146              unref_peer(peer, "toss iterator peer ptr before break");
19147              break;
19148           }
19149           unref_peer(peer, "toss iterator peer ptr");
19150        }
19151        ao2_iterator_destroy(&i);
19152        return result;
19153 }

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 19156 of file chan_sip.c.

References complete_sipch().

Referenced by sip_show_history().

19157 {
19158    if (pos == 3)
19159       return complete_sipch(line, word, pos, state);
19160 
19161    return NULL;
19162 }

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 19165 of file chan_sip.c.

References complete_sip_peer().

Referenced by sip_qualify_peer(), and sip_show_peer().

19166 {
19167    if (pos == 3) {
19168       return complete_sip_peer(word, state, 0);
19169    }
19170 
19171    return NULL;
19172 }

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 18366 of file chan_sip.c.

References complete_sip_user().

Referenced by sip_show_user().

18367 {
18368    if (pos == 3)
18369       return complete_sip_user(word, state);
18370 
18371    return NULL;
18372 }

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 19175 of file chan_sip.c.

References complete_sip_registered_peer().

Referenced by sip_unregister().

19176 {
19177        if (pos == 2)
19178                return complete_sip_registered_peer(word, state, 0);
19179 
19180        return NULL;
19181 }

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

Do completion on user name.

Definition at line 18336 of file chan_sip.c.

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

Referenced by complete_sip_show_user().

18337 {
18338    char *result = NULL;
18339    int wordlen = strlen(word);
18340    int which = 0;
18341    struct ao2_iterator user_iter;
18342    struct sip_peer *user;
18343 
18344    user_iter = ao2_iterator_init(peers, 0);
18345    while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) {
18346       ao2_lock(user);
18347       if (!(user->type & SIP_TYPE_USER)) {
18348          ao2_unlock(user);
18349          unref_peer(user, "complete sip user");
18350          continue;
18351       }
18352       /* locking of the object is not required because only the name and flags are being compared */
18353       if (!strncasecmp(word, user->name, wordlen) && ++which > state) {
18354          result = ast_strdup(user->name);
18355       }
18356       ao2_unlock(user);
18357       unref_peer(user, "complete sip user");
18358       if (result) {
18359          break;
18360       }
18361    }
18362    ao2_iterator_destroy(&user_iter);
18363    return result;
18364 }

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 19077 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().

19078 {
19079    int which=0;
19080    struct sip_pvt *cur;
19081    char *c = NULL;
19082    int wordlen = strlen(word);
19083    struct ao2_iterator i;
19084 
19085    if (pos != 3) {
19086       return NULL;
19087    }
19088 
19089    i = ao2_iterator_init(dialogs, 0);
19090    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
19091       sip_pvt_lock(cur);
19092       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
19093          c = ast_strdup(cur->callid);
19094          sip_pvt_unlock(cur);
19095          dialog_unref(cur, "drop ref in iterator loop break");
19096          break;
19097       }
19098       sip_pvt_unlock(cur);
19099       dialog_unref(cur, "drop ref in iterator loop");
19100    }
19101    ao2_iterator_destroy(&i);
19102    return c;
19103 }

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

Support routine for 'sip notify' CLI.

Definition at line 19184 of file chan_sip.c.

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

Referenced by sip_cli_notify().

19185 {
19186    char *c = NULL;
19187 
19188    if (pos == 2) {
19189       int which = 0;
19190       char *cat = NULL;
19191       int wordlen = strlen(word);
19192 
19193       /* do completion for notify type */
19194 
19195       if (!notify_types)
19196          return NULL;
19197       
19198       while ( (cat = ast_category_browse(notify_types, cat)) ) {
19199          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
19200             c = ast_strdup(cat);
19201             break;
19202          }
19203       }
19204       return c;
19205    }
19206 
19207    if (pos > 2)
19208       return complete_sip_peer(word, state, 0);
19209 
19210    return NULL;
19211 }

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

Definition at line 1950 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().

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

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 10299 of file chan_sip.c.

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

Referenced by respprep().

10300 {
10301    int start = 0;
10302    int copied = 0;
10303    for (;;) {
10304       const char *tmp = __get_header(orig, field, &start);
10305 
10306       if (ast_strlen_zero(tmp))
10307          break;
10308       /* Add what we're responding to */
10309       add_header(req, field, tmp);
10310       copied++;
10311    }
10312    return copied ? 0 : -1;
10313 }

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 10288 of file chan_sip.c.

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

Referenced by reqprep(), and respprep().

10289 {
10290    const char *tmp = get_header(orig, field);
10291 
10292    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
10293       return add_header(req, field, tmp);
10294    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
10295    return -1;
10296 }

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 12105 of file chan_sip.c.

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

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

12106 {
12107    /* XXX this function can encounter memory allocation errors, perhaps it
12108     * should return a value */
12109 
12110    struct ast_str *duplicate = dst->data;
12111    struct ast_str *duplicate_content = dst->content;
12112 
12113    /* copy the entire request then restore the original data and content
12114     * members from the dst request */
12115    *dst = *src;
12116    dst->data = duplicate;
12117    dst->content = duplicate_content;
12118 
12119    /* copy the data into the dst request */
12120    if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1))) {
12121       return;
12122    }
12123    ast_str_copy_string(&dst->data, src->data);
12124 
12125    /* copy the content into the dst request (if it exists) */
12126    if (src->content) {
12127       if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1))) {
12128          return;
12129       }
12130       ast_str_copy_string(&dst->content, src->content);
12131    }
12132 }

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

Definition at line 5399 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().

05400 {
05401    if (to_sock->tcptls_session) {
05402       ao2_ref(to_sock->tcptls_session, -1);
05403       to_sock->tcptls_session = NULL;
05404    }
05405 
05406    if (from_sock->tcptls_session) {
05407       ao2_ref(from_sock->tcptls_session, +1);
05408    }
05409 
05410    *to_sock = *from_sock;
05411 }

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

duplicate a list of channel variables,

Returns:
the copy.

Definition at line 2329 of file chan_sip.c.

References ast_variable_new(), and ast_variable::next.

Referenced by check_peer_ok(), and create_addr_from_peer().

02330 {
02331    struct ast_variable *res = NULL, *tmp, *v = NULL;
02332 
02333    for (v = src ; v ; v = v->next) {
02334       if ((tmp = ast_variable_new(v->name, v->value, v->file))) {
02335          tmp->next = res;
02336          res = tmp;
02337       }
02338    }
02339    return res;
02340 }

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 10323 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().

10324 {
10325    int copied = 0;
10326    int start = 0;
10327 
10328    for (;;) {
10329       char new[512];
10330       const char *oh = __get_header(orig, field, &start);
10331 
10332       if (ast_strlen_zero(oh))
10333          break;
10334 
10335       if (!copied) { /* Only check for empty rport in topmost via header */
10336          char leftmost[512], *others, *rport;
10337 
10338          /* Only work on leftmost value */
10339          ast_copy_string(leftmost, oh, sizeof(leftmost));
10340          others = strchr(leftmost, ',');
10341          if (others)
10342              *others++ = '\0';
10343 
10344          /* Find ;rport;  (empty request) */
10345          rport = strstr(leftmost, ";rport");
10346          if (rport && *(rport+6) == '=')
10347             rport = NULL;     /* We already have a parameter to rport */
10348 
10349          if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) {
10350             /* We need to add received port - rport */
10351             char *end;
10352 
10353             rport = strstr(leftmost, ";rport");
10354 
10355             if (rport) {
10356                end = strchr(rport + 1, ';');
10357                if (end)
10358                   memmove(rport, end, strlen(end) + 1);
10359                else
10360                   *rport = '\0';
10361             }
10362 
10363             /* Add rport to first VIA header if requested */
10364             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
10365                leftmost, ast_sockaddr_stringify_addr_remote(&p->recv),
10366                ast_sockaddr_port(&p->recv),
10367                others ? "," : "", others ? others : "");
10368          } else {
10369             /* We should *always* add a received to the topmost via */
10370             snprintf(new, sizeof(new), "%s;received=%s%s%s",
10371                leftmost, ast_sockaddr_stringify_addr_remote(&p->recv),
10372                others ? "," : "", others ? others : "");
10373          }
10374          oh = new;   /* the header to copy */
10375       }  /* else add the following via headers untouched */
10376       add_header(req, field, oh);
10377       copied++;
10378    }
10379    if (!copied) {
10380       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
10381       return -1;
10382    }
10383    return 0;
10384 }

static int create_addr ( struct sip_pvt *  dialog,
const char *  opeer,
struct ast_sockaddr addr,
int  newdialog 
) [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 5629 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_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_strdupa, ast_string_field_set, bindaddr, create_addr_from_peer(), default_sip_port(), dialog_initialize_rtp(), FALSE, find_peer(), get_srv_protocol(), get_srv_service(), LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), ref_peer(), ref_proxy(), service, set_socket_transport(), sip_cfg, TRUE, and unref_peer().

Referenced by __sip_subscribe_mwi_do(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_request_call(), transmit_publish(), and transmit_register().

05630 {
05631    struct sip_peer *peer;
05632    char *peername, *peername2, *hostn;
05633    char host[MAXHOSTNAMELEN];
05634    char service[MAXHOSTNAMELEN];
05635    int srv_ret = 0;
05636    int tportno;
05637 
05638    AST_DECLARE_APP_ARGS(hostport,
05639       AST_APP_ARG(host);
05640       AST_APP_ARG(port);
05641    );
05642 
05643    peername = ast_strdupa(opeer);
05644    peername2 = ast_strdupa(opeer);
05645    AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':');
05646 
05647    if (hostport.port)
05648       dialog->portinuri = 1;
05649 
05650    dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
05651    dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
05652    peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
05653 
05654    if (peer) {
05655       int res;
05656       if (newdialog) {
05657          set_socket_transport(&dialog->socket, 0);
05658       }
05659       res = create_addr_from_peer(dialog, peer);
05660       dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer");
05661       unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup");
05662       return res;
05663    } else if (ast_check_digits(peername)) {
05664       /* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and
05665        * it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is
05666        * almost certainly not intended. It is much better to just reject purely numeric hostnames */
05667       ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername);
05668       return -1;
05669    } else {
05670       dialog->rtptimeout = global_rtptimeout;
05671       dialog->rtpholdtimeout = global_rtpholdtimeout;
05672       dialog->rtpkeepalive = global_rtpkeepalive;
05673       if (dialog_initialize_rtp(dialog)) {
05674          return -1;
05675       }
05676    }
05677 
05678    ast_string_field_set(dialog, tohost, hostport.host);
05679    dialog->allowed_methods &= ~sip_cfg.disallowed_methods;
05680 
05681    /* Get the outbound proxy information */
05682    ref_proxy(dialog, obproxy_get(dialog, NULL));
05683 
05684    if (addr) {
05685       /* This address should be updated using dnsmgr */
05686       ast_sockaddr_copy(&dialog->sa, addr);
05687    } else {
05688 
05689       /* Let's see if we can find the host in DNS. First try DNS SRV records,
05690          then hostname lookup */
05691       /*! \todo Fix this function. When we ask for SRV, we should check all transports
05692            In the future, we should first check NAPTR to find out transport preference
05693        */
05694       hostn = peername;
05695       /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then
05696        * an A record lookup should be used instead of SRV.
05697        */
05698       if (!hostport.port && sip_cfg.srvlookup) {
05699          snprintf(service, sizeof(service), "_%s._%s.%s", 
05700              get_srv_service(dialog->socket.type),
05701              get_srv_protocol(dialog->socket.type), peername);
05702          if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno,
05703                      service)) > 0) {
05704             hostn = host;
05705          }
05706       }
05707 
05708       if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) {
05709          ast_log(LOG_WARNING, "No such host: %s\n", peername);
05710          return -1;
05711       }
05712 
05713       if (srv_ret > 0) {
05714          ast_sockaddr_set_port(&dialog->sa, tportno);
05715       }
05716    }
05717 
05718    if (!dialog->socket.type)
05719       set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP);
05720    if (!dialog->socket.port) {
05721       dialog->socket.port = htons(ast_sockaddr_port(&bindaddr));
05722    }
05723 
05724    if (!ast_sockaddr_port(&dialog->sa)) {
05725       ast_sockaddr_set_port(&dialog->sa, default_sip_port(dialog->socket.type));
05726    }
05727    ast_sockaddr_copy(&dialog->recv, &dialog->sa);
05728    return 0;
05729 }

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 5474 of file chan_sip.c.

References accountcode, ao2_lock, ao2_t_ref, ao2_unlock, ast_alloca, ast_cc_copy_config_params(), ast_copy_flags, ast_duplicate_ha_list(), 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().

05475 {
05476    struct sip_auth_container *credentials;
05477 
05478    /* this checks that the dialog is contacting the peer on a valid
05479     * transport type based on the peers transport configuration,
05480     * otherwise, this function bails out */
05481    if (dialog->socket.type && check_request_transport(peer, dialog))
05482       return -1;
05483    copy_socket_data(&dialog->socket, &peer->socket);
05484 
05485    if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) &&
05486        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
05487       dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr;
05488       dialog->recv = dialog->sa;
05489    } else
05490       return -1;
05491 
05492    /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */
05493    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
05494    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
05495    ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
05496    dialog->capability = peer->capability;
05497    dialog->prefs = peer->prefs;
05498    dialog->amaflags = peer->amaflags;
05499 
05500    ast_string_field_set(dialog, engine, peer->engine);
05501 
05502    dialog->rtptimeout = peer->rtptimeout;
05503    dialog->rtpholdtimeout = peer->rtpholdtimeout;
05504    dialog->rtpkeepalive = peer->rtpkeepalive;
05505    if (dialog_initialize_rtp(dialog)) {
05506       return -1;
05507    }
05508 
05509    if (dialog->rtp) { /* Audio */
05510       ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
05511       ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
05512       /* Set Frame packetization */
05513       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs);
05514       dialog->autoframing = peer->autoframing;
05515    }
05516 
05517    /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */
05518    ast_string_field_set(dialog, peername, peer->name);
05519    ast_string_field_set(dialog, authname, peer->username);
05520    ast_string_field_set(dialog, username, peer->username);
05521    ast_string_field_set(dialog, peersecret, peer->secret);
05522    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
05523    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
05524    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
05525    ast_string_field_set(dialog, tohost, peer->tohost);
05526    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
05527    ast_string_field_set(dialog, accountcode, peer->accountcode);
05528    ast_string_field_set(dialog, context, peer->context);
05529    ast_string_field_set(dialog, cid_num, peer->cid_num);
05530    ast_string_field_set(dialog, cid_name, peer->cid_name);
05531    ast_string_field_set(dialog, cid_tag, peer->cid_tag);
05532    ast_string_field_set(dialog, mwi_from, peer->mwi_from);
05533    if (!ast_strlen_zero(peer->parkinglot)) {
05534       ast_string_field_set(dialog, parkinglot, peer->parkinglot);
05535    }
05536    ast_string_field_set(dialog, engine, peer->engine);
05537    ref_proxy(dialog, obproxy_get(dialog, peer));
05538    dialog->callgroup = peer->callgroup;
05539    dialog->pickupgroup = peer->pickupgroup;
05540    dialog->allowtransfer = peer->allowtransfer;
05541    dialog->jointnoncodeccapability = dialog->noncodeccapability;
05542 
05543    /* Update dialog authorization credentials */
05544    ao2_lock(peer);
05545    credentials = peer->auth;
05546    if (credentials) {
05547       ao2_t_ref(credentials, +1, "Ref peer auth for dialog");
05548    }
05549    ao2_unlock(peer);
05550    ao2_lock(dialog);
05551    if (dialog->peerauth) {
05552       ao2_t_ref(dialog->peerauth, -1, "Unref old dialog peer auth");
05553    }
05554    dialog->peerauth = credentials;
05555    ao2_unlock(dialog);
05556 
05557    dialog->maxcallbitrate = peer->maxcallbitrate;
05558    dialog->disallowed_methods = peer->disallowed_methods;
05559    ast_cc_copy_config_params(dialog->cc_params, peer->cc_params);
05560    if (ast_strlen_zero(dialog->tohost))
05561       ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host_remote(&dialog->sa));
05562    if (!ast_strlen_zero(peer->fromdomain)) {
05563       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
05564       if (!dialog->initreq.headers) {
05565          char *new_callid;
05566          char *tmpcall = ast_strdupa(dialog->callid);
05567          /* this sure looks to me like we are going to change the callid on this dialog!! */
05568          new_callid = strchr(tmpcall, '@');
05569          if (new_callid) {
05570             int callid_size;
05571 
05572             *new_callid = '\0';
05573 
05574             /* Change the dialog callid. */
05575             callid_size = strlen(tmpcall) + strlen(peer->fromdomain) + 2;
05576             new_callid = ast_alloca(callid_size);
05577             snprintf(new_callid, callid_size, "%s@%s", tmpcall, peer->fromdomain);
05578             change_callid_pvt(dialog, new_callid);
05579          }
05580       }
05581    }
05582    if (!ast_strlen_zero(peer->fromuser))
05583       ast_string_field_set(dialog, fromuser, peer->fromuser);
05584    if (!ast_strlen_zero(peer->language))
05585       ast_string_field_set(dialog, language, peer->language);
05586    /* Set timer T1 to RTT for this peer (if known by qualify=) */
05587    /* Minimum is settable or default to 100 ms */
05588    /* If there is a maxms and lastms from a qualify use that over a manual T1
05589       value. Otherwise, use the peer's T1 value. */
05590    if (peer->maxms && peer->lastms)
05591       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
05592    else
05593       dialog->timer_t1 = peer->timer_t1;
05594 
05595    /* Set timer B to control transaction timeouts, the peer setting is the default and overrides
05596       the known timer */
05597    if (peer->timer_b)
05598       dialog->timer_b = peer->timer_b;
05599    else
05600       dialog->timer_b = 64 * dialog->timer_t1;
05601 
05602    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
05603        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
05604       dialog->noncodeccapability |= AST_RTP_DTMF;
05605    else
05606       dialog->noncodeccapability &= ~AST_RTP_DTMF;
05607    dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha);
05608    if (peer->call_limit)
05609       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
05610    if (!dialog->portinuri)
05611       dialog->portinuri = peer->portinuri;
05612    dialog->chanvars = copy_vars(peer->chanvars);
05613    if (peer->fromdomainport)
05614       dialog->fromdomainport = peer->fromdomainport;
05615    dialog->callingpres = peer->callingpres;
05616 
05617    return 0;
05618 }

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

Definition at line 908 of file chan_sip.c.

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

Referenced by sip_cc_monitor_suspend().

00909 {
00910    struct sip_epa_entry *epa_entry;
00911    const struct epa_static_data *static_data;
00912 
00913    if (!(static_data = find_static_data(event_package))) {
00914       return NULL;
00915    }
00916 
00917    if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) {
00918       return NULL;
00919    }
00920 
00921    epa_entry->static_data = static_data;
00922    ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination));
00923    return epa_entry;
00924 }

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 1034 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().

01035 {
01036    struct sip_esc_entry *esc_entry;
01037    int expires_ms;
01038 
01039    if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) {
01040       return NULL;
01041    }
01042 
01043    esc_entry->event = esc->name;
01044 
01045    expires_ms = expires * 1000;
01046    /* Bump refcount for scheduler */
01047    ao2_ref(esc_entry, +1);
01048    esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry);
01049 
01050    /* Note: This links the esc_entry into the ESC properly */
01051    create_new_sip_etag(esc_entry, 0);
01052 
01053    return esc_entry;
01054 }

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

Definition at line 1021 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().

01022 {
01023    int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1);
01024    struct event_state_compositor *esc = get_esc(esc_entry->event);
01025 
01026    ast_assert(esc != NULL);
01027    if (is_linked) {
01028       ao2_unlink(esc->compositor, esc_entry);
01029    }
01030    snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag);
01031    ao2_link(esc->compositor, esc_entry);
01032 }

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

The default sip port for the given transport.

Definition at line 5621 of file chan_sip.c.

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

05622 {
05623    return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
05624 }

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

Deinitialize SIP response/request.

Definition at line 10540 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().

10541 {
10542    if (req->data) {
10543       ast_free(req->data);
10544       req->data = NULL;
10545    }
10546    if (req->content) {
10547       ast_free(req->content);
10548       req->content = NULL;
10549    }
10550 }

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

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

Definition at line 14187 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().

14188 {
14189    int realtimeregs = ast_check_realtime("sipregs");
14190    char *tablename = (realtimeregs) ? "sipregs" : "sippeers";
14191 
14192    if (!sip_cfg.ignore_regexpire) {
14193       if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
14194          ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "0", SENTINEL);
14195       } else {
14196          ast_db_del("SIP/Registry", peer->name);
14197          ast_db_del("SIP/PeerMethods", peer->name);
14198       }
14199    }
14200 }

static void destroy_escs ( void   )  [static]

Definition at line 1068 of file chan_sip.c.

References ao2_ref, ARRAY_LEN, and event_state_compositors.

Referenced by unload_module().

01069 {
01070    int i;
01071    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01072       ao2_ref(event_state_compositors[i].compositor, -1);
01073    }
01074 }

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

Destroy mailbox subscriptions

Definition at line 4802 of file chan_sip.c.

References ast_event_unsubscribe(), and ast_free.

Referenced by build_peer(), and clear_peer_mailboxes().

04803 {
04804    if (mailbox->event_sub)
04805       ast_event_unsubscribe(mailbox->event_sub);
04806    ast_free(mailbox);
04807 }

static void destroy_realm_authentication ( void *  obj  )  [static]

Definition at line 27822 of file chan_sip.c.

References ast_free, and AST_LIST_REMOVE_HEAD.

Referenced by add_realm_authentication().

27823 {
27824    struct sip_auth_container *credentials = obj;
27825    struct sip_auth *auth;
27826 
27827    while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) {
27828       ast_free(auth);
27829    }
27830 }

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

Parse first line of incoming SIP request.

Definition at line 12205 of file chan_sip.c.

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

Referenced by parse_request().

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

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 24785 of file chan_sip.c.

References ast_assert, and ast_strlen_zero().

Referenced by handle_request_publish().

24786 {
24787    int etag_present = !ast_strlen_zero(etag);
24788    int body_present = req->lines > 0;
24789 
24790    ast_assert(expires_int != NULL);
24791 
24792    if (ast_strlen_zero(expires)) {
24793       /* Section 6, item 4, second bullet point of RFC 3903 says to
24794        * use a locally-configured default expiration if none is provided
24795        * in the request
24796        */
24797       *expires_int = DEFAULT_PUBLISH_EXPIRES;
24798    } else if (sscanf(expires, "%30d", expires_int) != 1) {
24799       return SIP_PUBLISH_UNKNOWN;
24800    }
24801 
24802    if (*expires_int == 0) {
24803       return SIP_PUBLISH_REMOVE;
24804    } else if (!etag_present && body_present) {
24805       return SIP_PUBLISH_INITIAL;
24806    } else if (etag_present && !body_present) {
24807       return SIP_PUBLISH_REFRESH;
24808    } else if (etag_present && body_present) {
24809       return SIP_PUBLISH_MODIFY;
24810    }
24811 
24812    return SIP_PUBLISH_UNKNOWN;
24813 }

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 30847 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

30848 {
30849    struct sip_pvt *pvt = obj, *pvt2 = arg;
30850 
30851    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0;
30852 }

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

Definition at line 17512 of file chan_sip.c.

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

Referenced by sip_show_objects().

17513 {
17514    struct sip_pvt *pvt = userobj;
17515    int refc = ao2_t_ref(userobj, 0, "");
17516    struct ast_cli_args *a = (struct ast_cli_args *) arg;
17517    
17518    ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n",
17519       pvt->callid, 0, refc);
17520    return 0;
17521 }

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 30837 of file chan_sip.c.

References CMP_MATCH.

Referenced by find_call().

30838 {
30839    struct sip_pvt *pvt = obj, *pvt2 = arg;
30840 
30841    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0;
30842 }

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 30827 of file chan_sip.c.

References ast_str_case_hash().

Referenced by load_module().

30828 {
30829    const struct sip_pvt *pvt = obj;
30830 
30831    return ast_str_case_hash(pvt->callid);
30832 }

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 5416 of file chan_sip.c.

References AST_FORMAT_VIDEO_MASK, 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().

05417 {
05418    struct ast_sockaddr bindaddr_tmp;
05419 
05420    if (!sip_methods[dialog->method].need_rtp) {
05421       return 0;
05422    }
05423 
05424    ast_sockaddr_copy(&bindaddr_tmp, &bindaddr);
05425    if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
05426       return -1;
05427    }
05428 
05429    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
05430          (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) {
05431       if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
05432          return -1;
05433       }
05434       ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout);
05435       ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout);
05436       ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive);
05437 
05438       ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1);
05439       ast_rtp_instance_set_qos(dialog->vrtp, global_tos_video, global_cos_video, "SIP VIDEO");
05440    }
05441 
05442    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) {
05443       if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
05444          return -1;
05445       }
05446       /* Do not timeout text as its not constant*/
05447       ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive);
05448 
05449       ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1);
05450    }
05451 
05452    ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout);
05453    ast_rtp_instance_set_hold_timeout(dialog->rtp, dialog->rtpholdtimeout);
05454    ast_rtp_instance_set_keepalive(dialog->rtp, dialog->rtpkeepalive);
05455 
05456    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1);
05457    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
05458    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
05459 
05460    ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP");
05461 
05462    do_setnat(dialog);
05463 
05464    return 0;
05465 }

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 17656 of file chan_sip.c.

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

Referenced by do_monitor().

17657 {
17658    struct sip_pvt *dialog = dialogobj;
17659    time_t *t = arg;
17660 
17661    if (sip_pvt_trylock(dialog)) {
17662       /* Don't block the monitor thread.  This function is called often enough
17663        * that we can wait for the next time around. */
17664       return 0;
17665    }
17666 
17667    /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
17668    check_rtp_timeout(dialog, *t);
17669 
17670    /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
17671    if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
17672       ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
17673       sip_pvt_unlock(dialog);
17674       return 0;
17675    }
17676 
17677    if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) {
17678       ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
17679       sip_pvt_unlock(dialog);
17680       return 0;
17681    }
17682 
17683    /* If we have sessions that needs to be destroyed, do it now */
17684    /* Check if we have outstanding requests not responsed to or an active call
17685       - if that's the case, wait with destruction */
17686    if (dialog->needdestroy && !dialog->packets && !dialog->owner) {
17687       /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
17688       if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
17689          ast_debug(2, "Bridge still active.  Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
17690          sip_pvt_unlock(dialog);
17691          return 0;
17692       }
17693       
17694       if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) {
17695          ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
17696          sip_pvt_unlock(dialog);
17697          return 0;
17698       }
17699 
17700       sip_pvt_unlock(dialog);
17701 
17702       /* This dialog needs to be destroyed. */
17703       ao2_t_link(dialogs_to_destroy, dialog, "Link dialog for destruction");
17704       return 0;
17705    }
17706 
17707    sip_pvt_unlock(dialog);
17708 
17709    return 0;
17710 }

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

Definition at line 2221 of file chan_sip.c.

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

02222 {
02223    if (p)
02224 #ifdef REF_DEBUG
02225       __ao2_ref_debug(p, 1, tag, file, line, func);
02226 #else
02227       ao2_ref(p, 1);
02228 #endif
02229    else
02230       ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
02231    return p;
02232 }

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 3080 of file chan_sip.c.

References ao2_t_unlink, 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_unlink_callback(), handle_request_subscribe(), manager_sipnotify(), sip_cli_notify(), sip_destroy_peer(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and unload_module().

03081 {
03082    struct sip_pkt *cp;
03083    struct ast_channel *owner;
03084 
03085    dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done");
03086 
03087    ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
03088 
03089    /* Unlink us from the owner (channel) if we have one */
03090    owner = sip_pvt_lock_full(dialog);
03091    if (owner) {
03092       ast_debug(1, "Detaching from channel %s\n", owner->name);
03093       owner->tech_pvt = dialog_unref(owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
03094       ast_channel_unlock(owner);
03095       ast_channel_unref(owner);
03096       dialog->owner = NULL;
03097    }
03098    sip_pvt_unlock(dialog);
03099 
03100    if (dialog->registry) {
03101       if (dialog->registry->call == dialog) {
03102          dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
03103       }
03104       dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
03105    }
03106    if (dialog->stateid != -1) {
03107       ast_extension_state_del(dialog->stateid, cb_extensionstate);
03108       dialog->stateid = -1;
03109    }
03110    /* Remove link from peer to subscription of MWI */
03111    if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) {
03112       dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
03113    }
03114    if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) {
03115       dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
03116    }
03117 
03118    /* remove all current packets in this dialog */
03119    while((cp = dialog->packets)) {
03120       dialog->packets = dialog->packets->next;
03121       AST_SCHED_DEL(sched, cp->retransid);
03122       dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy");
03123       if (cp->data) {
03124          ast_free(cp->data);
03125       }
03126       ast_free(cp);
03127    }
03128 
03129    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"));
03130 
03131    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"));
03132    
03133    if (dialog->autokillid > -1) {
03134       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"));
03135    }
03136 
03137    if (dialog->request_queue_sched_id > -1) {
03138       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"));
03139    }
03140 
03141    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"));
03142 
03143    if (dialog->t38id > -1) {
03144       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"));
03145    }
03146 
03147    if (dialog->stimer) {
03148       stop_session_timer(dialog);
03149    }
03150 
03151    dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
03152 }

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

Definition at line 17722 of file chan_sip.c.

References CMP_MATCH, and dialog_unlink_all().

Referenced by do_monitor().

17723 {
17724    struct sip_pvt *dialog = obj;
17725 
17726    dialog_unlink_all(dialog);
17727 
17728    return CMP_MATCH;
17729 }

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

Definition at line 2234 of file chan_sip.c.

References __ao2_ref_debug(), and ao2_ref.

02235 {
02236    if (p)
02237 #ifdef REF_DEBUG
02238       __ao2_ref_debug(p, -1, tag, file, line, func);
02239 #else
02240       ao2_ref(p, -1);
02241 #endif
02242    return NULL;
02243 }

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

Definition at line 4485 of file chan_sip.c.

References ast_dsp_free().

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

04486 {
04487    if (p->dsp) {
04488       ast_dsp_free(p->dsp);
04489       p->dsp = NULL;
04490    }
04491 }

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

Definition at line 28756 of file chan_sip.c.

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

Referenced by reload_config().

28756                                                                                       {
28757    int global_nat, specific_nat;
28758 
28759    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))) {
28760       ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the  global setting can make\n");
28761       ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n");
28762       ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n");
28763       ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n");
28764       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));
28765    }
28766 }

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 22900 of file chan_sip.c.

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

Referenced by handle_request_invite().

22901 {
22902    struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2);
22903    struct ast_app *pickup = pbx_findapp("Pickup");
22904 
22905    if (!pickup) {
22906       ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n");
22907       return -1;
22908    }
22909 
22910    ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context);
22911 
22912    ast_debug(2, "About to call Pickup(%s)\n", ast_str_buffer(str));
22913 
22914    /* There is no point in capturing the return value since pickup_exec
22915       doesn't return anything meaningful unless the passed data is an empty
22916       string (which in our case it will not be) */
22917    pbx_exec(channel, pickup, ast_str_buffer(str));
22918 
22919    return 0;
22920 }

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 26637 of file chan_sip.c.

References ao2_container_count(), ao2_t_callback, ast_debug, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_verb, dialog_needdestroy(), dialog_unlink_callback(), FALSE, LOG_WARNING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sip_do_reload(), and sipsock_read().

Referenced by restart_monitor().

26638 {
26639    int res;
26640    time_t t;
26641    int reloading;
26642 
26643    /* Add an I/O event to our SIP UDP socket */
26644    if (sipsock > -1)
26645       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
26646 
26647    /* From here on out, we die whenever asked */
26648    for(;;) {
26649       /* Check for a reload request */
26650       ast_mutex_lock(&sip_reload_lock);
26651       reloading = sip_reloading;
26652       sip_reloading = FALSE;
26653       ast_mutex_unlock(&sip_reload_lock);
26654       if (reloading) {
26655          ast_verb(1, "Reloading SIP\n");
26656          sip_do_reload(sip_reloadreason);
26657 
26658          /* Change the I/O fd of our UDP socket */
26659          if (sipsock > -1) {
26660             if (sipsock_read_id)
26661                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
26662             else
26663                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
26664          } else if (sipsock_read_id) {
26665             ast_io_remove(io, sipsock_read_id);
26666             sipsock_read_id = NULL;
26667          }
26668       }
26669 
26670       /* Check for dialogs needing to be killed */
26671       t = time(NULL);
26672       /* don't scan the dialogs list if it hasn't been a reasonable period
26673          of time since the last time we did it (when MWI is being sent, we can
26674          get back to this point every millisecond or less)
26675       */
26676       /*
26677        * We cannot hold the dialogs container lock when we destroy a
26678        * dialog because of potential deadlocks.  Instead we link the
26679        * doomed dialog into dialogs_to_destroy and then iterate over
26680        * that container destroying the dialogs.
26681        */
26682       ao2_t_callback(dialogs, OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t,
26683          "callback to monitor dialog status");
26684       if (ao2_container_count(dialogs_to_destroy)) {
26685          /* Now destroy the found dialogs that need to be destroyed. */
26686          ao2_t_callback(dialogs_to_destroy, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE,
26687             dialog_unlink_callback, NULL, "callback to dialog_unlink_all");
26688       }
26689 
26690       /* XXX TODO The scheduler usage in this module does not have sufficient
26691        * synchronization being done between running the scheduler and places
26692        * scheduling tasks.  As it is written, any scheduled item may not run
26693        * any sooner than about  1 second, regardless of whether a sooner time
26694        * was asked for. */
26695 
26696       pthread_testcancel();
26697       /* Wait for sched or io */
26698       res = ast_sched_wait(sched);
26699       if ((res < 0) || (res > 1000))
26700          res = 1000;
26701       res = ast_io_wait(io, res);
26702       if (res > 20)
26703          ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res);
26704       ast_mutex_lock(&monlock);
26705       res = ast_sched_runq(sched);
26706       if (res >= 20)
26707          ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res);
26708       if (global_store_sip_cause && res >= 100)
26709          ast_log(LOG_WARNING, "scheduler delays detected, setting 'storesipcause' to 'no' in %s will improve performance\n", config);
26710       ast_mutex_unlock(&monlock);
26711    }
26712 
26713    /* Never reached */
26714    return NULL;
26715 }

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 19823 of file chan_sip.c.

References ast_calloc, ast_debug, auth_headers(), reply_digest(), 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().

19824 {
19825    char *header, *respheader;
19826    char digest[1024];
19827 
19828    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
19829       return -2;
19830 
19831    p->authtries++;
19832    auth_headers(code, &header, &respheader);
19833    ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
19834    memset(digest, 0, sizeof(digest));
19835    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
19836       /* No way to authenticate */
19837       return -1;
19838    }
19839    /* Now we have a reply digest */
19840    p->options->auth = digest;
19841    p->options->authheader = respheader;
19842    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL);
19843 }

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 19799 of file chan_sip.c.

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

Referenced by handle_response_register().

19800 {
19801    char *header, *respheader;
19802    char digest[1024];
19803 
19804    p->authtries++;
19805    auth_headers(code, &header, &respheader);
19806    memset(digest, 0, sizeof(digest));
19807    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
19808       /* There's nothing to use for authentication */
19809       /* No digest challenge in request */
19810       if (sip_debug_test_pvt(p) && p->registry)
19811          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
19812          /* No old challenge */
19813       return -1;
19814    }
19815    if (p->do_history)
19816       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
19817    if (sip_debug_test_pvt(p) && p->registry)
19818       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
19819    return transmit_register(p->registry, SIP_REGISTER, digest, respheader);
19820 }

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

Set nat mode on the various data sockets.

Definition at line 5310 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().

05311 {
05312    const char *mode;
05313    int natflags;
05314 
05315    natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
05316    mode = natflags ? "On" : "Off";
05317 
05318    if (p->rtp) {
05319       ast_debug(1, "Setting NAT on RTP to %s\n", mode);
05320       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags);
05321    }
05322    if (p->vrtp) {
05323       ast_debug(1, "Setting NAT on VRTP to %s\n", mode);
05324       ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags);
05325    }
05326    if (p->udptl) {
05327       ast_debug(1, "Setting NAT on UDPTL to %s\n", mode);
05328       ast_udptl_setnat(p->udptl, natflags);
05329    }
05330    if (p->trtp) {
05331       ast_debug(1, "Setting NAT on TRTP to %s\n", mode);
05332       ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags);
05333    }
05334 }

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

Print domain mode to cli.

Definition at line 17891 of file chan_sip.c.

Referenced by sip_show_domains().

17892 {
17893    switch (mode) {
17894    case SIP_DOMAIN_AUTO:
17895       return "[Automatic]";
17896    case SIP_DOMAIN_CONFIG:
17897       return "[Configured]";
17898    }
17899 
17900    return "";
17901 }

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

Convert DTMF mode to printable string.

Definition at line 17570 of file chan_sip.c.

References map_x_s().

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

17571 {
17572    return map_x_s(dtmfstr, mode, "<error>");
17573 }

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

Definition at line 4451 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().

04452 {
04453    int features = 0;
04454 
04455    if (p->dsp) {
04456       return;
04457    }
04458 
04459    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
04460        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
04461       if (p->rtp) {
04462          ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND);
04463       }
04464       features |= DSP_FEATURE_DIGIT_DETECT;
04465    }
04466 
04467    if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) {
04468       features |= DSP_FEATURE_FAX_DETECT;
04469    }
04470 
04471    if (!features) {
04472       return;
04473    }
04474 
04475    if (!(p->dsp = ast_dsp_new())) {
04476       return;
04477    }
04478 
04479    ast_dsp_set_features(p->dsp, features);
04480    if (global_relaxdtmf) {
04481       ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
04482    }
04483 }

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

Definition at line 980 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by initialize_escs().

00981 {
00982    struct sip_esc_entry *entry1 = obj;
00983    struct sip_esc_entry *entry2 = arg;
00984 
00985    return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0;
00986 }

static void esc_entry_destructor ( void *  obj  )  [static]

Definition at line 966 of file chan_sip.c.

References AST_SCHED_DEL.

Referenced by create_esc_entry().

00967 {
00968    struct sip_esc_entry *esc_entry = obj;
00969    if (esc_entry->sched_id > -1) {
00970       AST_SCHED_DEL(sched, esc_entry->sched_id);
00971    }
00972 }

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

Definition at line 974 of file chan_sip.c.

References ast_str_hash().

Referenced by initialize_escs().

00975 {
00976    const struct sip_esc_entry *entry = obj;
00977    return ast_str_hash(entry->entity_tag);
00978 }

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

Expire registration of SIP peer.

Definition at line 14216 of file chan_sip.c.

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

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

14217 {
14218    struct sip_peer *peer = (struct sip_peer *)data;
14219 
14220    if (!peer) {      /* Hmmm. We have no peer. Weird. */
14221       return 0;
14222    }
14223 
14224    peer->expire = -1;
14225    peer->portinuri = 0;
14226 
14227    destroy_association(peer); /* remove registration data from storage */
14228    set_socket_transport(&peer->socket, peer->default_outbound_transport);
14229 
14230    if (peer->socket.tcptls_session) {
14231       ao2_ref(peer->socket.tcptls_session, -1);
14232       peer->socket.tcptls_session = NULL;
14233    }
14234 
14235    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
14236    register_peer_exten(peer, FALSE);   /* Remove regexten */
14237    ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
14238 
14239    /* Do we need to release this peer from memory?
14240       Only for realtime peers and autocreated peers
14241    */
14242    if (peer->is_realtime) {
14243       ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
14244    }
14245 
14246    if (peer->selfdestruct ||
14247        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
14248       ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
14249    }
14250    if (!ast_sockaddr_isnull(&peer->addr)) {
14251       /* We still need to unlink the peer from the peers_by_ip table,
14252        * otherwise we end up with multiple copies hanging around each
14253        * time a registration expires and the peer re-registers. */
14254       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
14255    }
14256 
14257    /* Only clear the addr after we check for destruction.  The addr must remain
14258     * in order to unlink from the peers_by_ip container correctly */
14259    memset(&peer->addr, 0, sizeof(peer->addr));
14260 
14261    unref_peer(peer, "removing peer ref for expire_register");
14262 
14263    return 0;
14264 }

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 15252 of file chan_sip.c.

References ast_sockaddr_split_hostport(), and PARSE_PORT_IGNORE.

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

15253 {
15254    char *dont_care;
15255    ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE);
15256 }

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

Check Contact: URI of SIP message.

Definition at line 12313 of file chan_sip.c.

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

Referenced by handle_incoming(), and handle_request_invite().

12314 {
12315    char stripped[SIPBUFSIZE];
12316    char *c;
12317 
12318    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
12319    c = get_in_brackets(stripped);
12320    /* Cut the URI at the at sign after the @, not in the username part */
12321    c = remove_uri_parameters(c);
12322    if (!ast_strlen_zero(c)) {
12323       ast_string_field_set(p, uri, c);
12324    }
12325 
12326 }

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

Definition at line 18055 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

18056 {
18057    return map_x_s(faxecmodes, faxec, "Unknown");
18058 }

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

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

Definition at line 10256 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().

10257 {
10258    char clen[10];
10259 
10260    if (req->lines) {
10261       ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n");
10262       return -1;
10263    }
10264 
10265    snprintf(clen, sizeof(clen), "%zu", ast_str_strlen(req->content));
10266    add_header(req, "Content-Length", clen);
10267 
10268    if (ast_str_strlen(req->content)) {
10269       ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content));
10270    }
10271    req->lines = ast_str_strlen(req->content) ? 1 : 0;
10272    return 0;
10273 }

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

Find compressed SIP alias.

Structure for conversion between compressed SIP and "normal" SIP

Definition at line 7606 of file chan_sip.c.

References aliases, and ARRAY_LEN.

Referenced by __get_header(), and add_header().

07607 {
07608    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
07609    static const struct cfalias {
07610       char * const fullname;
07611       char * const shortname;
07612    } aliases[] = {
07613       { "Content-Type",  "c" },
07614       { "Content-Encoding",    "e" },
07615       { "From",       "f" },
07616       { "Call-ID",       "i" },
07617       { "Contact",       "m" },
07618       { "Content-Length",   "l" },
07619       { "Subject",       "s" },
07620       { "To",         "t" },
07621       { "Supported",     "k" },
07622       { "Refer-To",      "r" },
07623       { "Referred-By",   "b" },
07624       { "Allow-Events",  "u" },
07625       { "Event",      "o" },
07626       { "Via",     "v" },
07627       { "Accept-Contact",      "a" },
07628       { "Reject-Contact",      "j" },
07629       { "Request-Disposition", "d" },
07630       { "Session-Expires",     "x" },
07631       { "Identity",            "y" },
07632       { "Identity-Info",       "n" },
07633    };
07634    int x;
07635 
07636    for (x = 0; x < ARRAY_LEN(aliases); x++) {
07637       if (!strcasecmp(aliases[x].fullname, name))
07638          return aliases[x].shortname;
07639    }
07640 
07641    return _default;
07642 }

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

Definition at line 1684 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().

01685 {
01686    struct ast_cc_agent *agent = obj;
01687    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01688    struct sip_pvt *call_pvt = arg;
01689 
01690    return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0;
01691 }

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

Definition at line 5221 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by find_peer().

05222 {
05223    struct sip_peer *search = obj, *match = arg;
05224    int *which_objects = data;
05225 
05226    /* Usernames in SIP uri's are case sensitive. Domains are not */
05227    if (strcmp(search->name, match->name)) {
05228       return 0;
05229    }
05230 
05231    switch (*which_objects) {
05232    case FINDUSERS:
05233       if (!(search->type & SIP_TYPE_USER)) {
05234          return 0;
05235       }
05236       break;
05237    case FINDPEERS:
05238       if (!(search->type & SIP_TYPE_PEER)) {
05239          return 0;
05240       }
05241       break;
05242    case FINDALLDEVICES:
05243       break;
05244    }
05245 
05246    return CMP_MATCH | CMP_STOP;
05247 }

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

Definition at line 1654 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().

01655 {
01656    struct ast_cc_agent *agent = obj;
01657    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01658    const char *uri = arg;
01659 
01660    return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
01661 }

static int find_by_subscribe_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_subscribe_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->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
01676 }

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 8382 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_next, ao2_t_callback, ao2_t_find, args, ast_debug, ast_strlen_zero(), match_req_args::authentication_present, match_req_args::callid, dialog_find_multiple(), free_via(), match_req_args::fromtag, get_header(), gettag(), match_req_to_dialog(), match_req_args::method, OBJ_MULTIPLE, OBJ_POINTER, parse_via(), match_req_args::ruri, match_req_args::seqno, sip_alloc(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, 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().

08383 {
08384    char totag[128];
08385    char fromtag[128];
08386    const char *callid = get_header(req, "Call-ID");
08387    const char *from = get_header(req, "From");
08388    const char *to = get_header(req, "To");
08389    const char *cseq = get_header(req, "Cseq");
08390    struct sip_pvt *sip_pvt_ptr;
08391    uint32_t seqno;
08392    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
08393    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
08394    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
08395          ast_strlen_zero(from) || ast_strlen_zero(cseq) ||
08396          (sscanf(cseq, "%30u", &seqno) != 1)) {
08397 
08398       /* RFC 3261 section 24.4.1.   Send a 400 Bad Request if the request is malformed. */
08399       if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
08400          transmit_response_using_temp(callid, addr, 1, intended_method,
08401                        req, "400 Bad Request");
08402       }
08403       return NULL;   /* Invalid packet */
08404    }
08405 
08406    if (sip_cfg.pedanticsipchecking) {
08407       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
08408          we need more to identify a branch - so we have to check branch, from
08409          and to tags to identify a call leg.
08410          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
08411          in sip.conf
08412          */
08413       if (gettag(req, "To", totag, sizeof(totag)))
08414          req->has_to_tag = 1; /* Used in handle_request/response */
08415       gettag(req, "From", fromtag, sizeof(fromtag));
08416 
08417       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);
08418 
08419       /* All messages must always have From: tag */
08420       if (ast_strlen_zero(fromtag)) {
08421          ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
08422          return NULL;
08423       }
08424       /* reject requests that must always have a To: tag */
08425       if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) {
08426          ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
08427          return NULL;
08428       }
08429    }
08430 
08431    if (!sip_cfg.pedanticsipchecking) {
08432       struct sip_pvt tmp_dialog = {
08433          .callid = callid,
08434       };
08435       sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs");
08436       if (sip_pvt_ptr) {  /* well, if we don't find it-- what IS in there? */
08437          /* Found the call */
08438          return sip_pvt_ptr;
08439       }
08440    } else { /* in pedantic mode! -- do the fancy search */
08441       struct sip_pvt tmp_dialog = {
08442          .callid = callid,
08443       };
08444       struct match_req_args args = { 0, };
08445       int found;
08446       struct ao2_iterator *iterator = ao2_t_callback(dialogs,
08447          OBJ_POINTER | OBJ_MULTIPLE,
08448          dialog_find_multiple,
08449          &tmp_dialog,
08450          "pedantic ao2_find in dialogs");
08451       struct sip_via *via = NULL;
08452 
08453       args.method = req->method;
08454       args.callid = NULL; /* we already matched this. */
08455       args.totag = totag;
08456       args.fromtag = fromtag;
08457       args.seqno = seqno;
08458 
08459       /* If this is a Request, set the Via and Authorization header arguments */
08460       if (req->method != SIP_RESPONSE) {
08461          args.ruri = REQ_OFFSET_TO_STR(req, rlPart2);
08462          via = parse_via(get_header(req, "Via"));
08463          if (via) {
08464             args.viasentby = via->sent_by;
08465             args.viabranch = via->branch;
08466          }
08467          if (!ast_strlen_zero(get_header(req, "Authorization")) ||
08468             !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) {
08469             args.authentication_present = 1;
08470          }
08471       }
08472 
08473       /* Iterate a list of dialogs already matched by Call-id */
08474       while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) {
08475          sip_pvt_lock(sip_pvt_ptr);
08476          found = match_req_to_dialog(sip_pvt_ptr, &args);
08477          sip_pvt_unlock(sip_pvt_ptr);
08478 
08479          switch (found) {
08480          case SIP_REQ_MATCH:
08481             ao2_iterator_destroy(iterator);
08482             free_via(via);
08483             return sip_pvt_ptr; /* return pvt with ref */
08484          case SIP_REQ_LOOP_DETECTED:
08485             /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
08486             * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
08487             transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
08488             dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search.");
08489             ao2_iterator_destroy(iterator);
08490             free_via(via);
08491             return NULL;
08492          case SIP_REQ_NOT_MATCH:
08493          default:
08494             dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search");
08495             break;
08496          }
08497       }
08498       if (iterator) {
08499          ao2_iterator_destroy(iterator);
08500       }
08501 
08502       free_via(via);
08503    } /* end of pedantic mode Request/Reponse to Dialog matching */
08504 
08505    /* See if the method is capable of creating a dialog */
08506    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
08507       struct sip_pvt *p = NULL;
08508 
08509       if (intended_method == SIP_REFER) {
08510          /* We do support REFER, but not outside of a dialog yet */
08511          transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)");
08512    
08513       /* Ok, time to create a new SIP dialog object, a pvt */
08514       } else if (!(p = sip_alloc(callid, addr, 1, intended_method, req)))  {
08515          /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
08516             getting a dialog from sip_alloc.
08517 
08518             Without a dialog we can't retransmit and handle ACKs and all that, but at least
08519             send an error message.
08520 
08521             Sorry, we apologize for the inconvienience
08522          */
08523          transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error");
08524          ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
08525       }
08526       return p; /* can be NULL */
08527    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
08528       /* A method we do not support, let's take it on the volley */
08529       transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented");
08530       ast_debug(2, "Got a request with unsupported SIP method.\n");
08531    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
08532       /* This is a request outside of a dialog that we don't know about */
08533       transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
08534       ast_debug(2, "That's odd...  Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
08535    }
08536    /* We do not respond to responses for dialogs that we don't know about, we just drop
08537       the session quickly */
08538    if (intended_method == SIP_RESPONSE)
08539       ast_debug(2, "That's odd...  Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>");
08540 
08541    return NULL;
08542 }

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 12948 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().

12949 {
12950    struct ast_channel *c = obj;
12951    struct sip_pvt *p = data;
12952    int res;
12953 
12954    ast_channel_lock(c);
12955 
12956    res = (c->pbx &&
12957          (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) &&
12958          (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context)));
12959 
12960    ast_channel_unlock(c);
12961 
12962    return res ? CMP_MATCH | CMP_STOP : 0;
12963 }

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 4626 of file chan_sip.c.

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

04627 {
04628    char last_char = '\0';
04629    const char *s;
04630    for (s = start; *s && s != lim; last_char = *s++) {
04631       if (*s == '"' && last_char != '\\')
04632          break;
04633    }
04634    return s;
04635 }

static struct sip_peer * find_peer ( const char *  peer,
struct ast_sockaddr addr,
int  realtime,
int  which_objects,
int  devstate_only,
int  transport 
) [static, read]

Locate device by name or ip address.

Parameters:
peer,sin,realtime,devstate_only,transport 
which_objects Define which objects should be matched when doing a lookup by name. Valid options are FINDUSERS, FINDPEERS, or FINDALLDEVICES. Note that this option is not used at all when doing a lookup by IP.

This is used on find matching device on name or ip/port. If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.

Note:
Avoid using this function in new functions if there is a way to avoid it, since it might cause a database lookup.

Definition at line 5262 of file chan_sip.c.

References ao2_t_callback_data, ao2_t_find, ast_copy_string(), ast_set_flag, ast_sockaddr_copy(), find_by_name(), OBJ_POINTER, realtime_peer(), and unref_peer().

Referenced by _sip_qualify_peer(), _sip_show_peer(), check_peer_ok(), create_addr(), function_sippeer(), handle_request_notify(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_show_user(), sip_unregister(), and transmit_register().

05263 {
05264    struct sip_peer *p = NULL;
05265    struct sip_peer tmp_peer;
05266 
05267    if (peer) {
05268       ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
05269       p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table");
05270    } else if (addr) { /* search by addr? */
05271       ast_sockaddr_copy(&tmp_peer.addr, addr);
05272       tmp_peer.flags[0].flags = 0;
05273       tmp_peer.transports = transport;
05274       p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table"); /* WAS:  p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */
05275       if (!p) {
05276          ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT);
05277          p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table 2"); /* WAS:  p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */
05278          if (p) {
05279             return p;
05280          }
05281       }
05282    }
05283 
05284    if (!p && (realtime || devstate_only)) {
05285       p = realtime_peer(peer, addr, devstate_only, which_objects);
05286       if (p) {
05287          switch (which_objects) {
05288          case FINDUSERS:
05289             if (!(p->type & SIP_TYPE_USER)) {
05290                unref_peer(p, "Wrong type of realtime SIP endpoint");
05291                return NULL;
05292             }
05293             break;
05294          case FINDPEERS:
05295             if (!(p->type & SIP_TYPE_PEER)) {
05296                unref_peer(p, "Wrong type of realtime SIP endpoint");
05297                return NULL;
05298             }
05299             break;
05300          case FINDALLDEVICES:
05301             break;
05302          }
05303       }
05304    }
05305 
05306    return p;
05307 }

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

Definition at line 27911 of file chan_sip.c.

References AST_LIST_TRAVERSE.

Referenced by build_reply_digest().

27912 {
27913    struct sip_auth *auth;
27914 
27915    if (credentials) {
27916       AST_LIST_TRAVERSE(&credentials->list, auth, node) {
27917          if (!strcasecmp(auth->realm, realm)) {
27918             break;
27919          }
27920       }
27921    } else {
27922       auth = NULL;
27923    }
27924 
27925    return auth;
27926 }

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 8894 of file chan_sip.c.

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

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

08895 {
08896    const char *content_type;
08897    const char *content_length;
08898    const char *search;
08899    char *boundary;
08900    unsigned int x;
08901    int boundaryisquoted = FALSE;
08902    int found_application_sdp = FALSE;
08903    int found_end_of_headers = FALSE;
08904 
08905    content_length = get_header(req, "Content-Length");
08906 
08907    if (!ast_strlen_zero(content_length)) {
08908       if (sscanf(content_length, "%30u", &x) != 1) {
08909          ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
08910          return 0;
08911       }
08912 
08913       /* Content-Length of zero means there can't possibly be an
08914          SDP here, even if the Content-Type says there is */
08915       if (x == 0)
08916          return 0;
08917    }
08918 
08919    content_type = get_header(req, "Content-Type");
08920 
08921    /* if the body contains only SDP, this is easy */
08922    if (!strncasecmp(content_type, "application/sdp", 15)) {
08923       req->sdp_start = 0;
08924       req->sdp_count = req->lines;
08925       return req->lines ? 1 : 0;
08926    }
08927 
08928    /* if it's not multipart/mixed, there cannot be an SDP */
08929    if (strncasecmp(content_type, "multipart/mixed", 15))
08930       return 0;
08931 
08932    /* if there is no boundary marker, it's invalid */
08933    if ((search = strcasestr(content_type, ";boundary=")))
08934       search += 10;
08935    else if ((search = strcasestr(content_type, "; boundary=")))
08936       search += 11;
08937    else
08938       return 0;
08939 
08940    if (ast_strlen_zero(search))
08941       return 0;
08942 
08943    /* If the boundary is quoted with ", remove quote */
08944    if (*search == '\"')  {
08945       search++;
08946       boundaryisquoted = TRUE;
08947    }
08948 
08949    /* make a duplicate of the string, with two extra characters
08950       at the beginning */
08951    boundary = ast_strdupa(search - 2);
08952    boundary[0] = boundary[1] = '-';
08953    /* Remove final quote */
08954    if (boundaryisquoted)
08955       boundary[strlen(boundary) - 1] = '\0';
08956 
08957    /* search for the boundary marker, the empty line delimiting headers from
08958       sdp part and the end boundry if it exists */
08959 
08960    for (x = 0; x < (req->lines); x++) {
08961       const char *line = REQ_OFFSET_TO_STR(req, line[x]);
08962       if (!strncasecmp(line, boundary, strlen(boundary))){
08963          if (found_application_sdp && found_end_of_headers) {
08964             req->sdp_count = (x - 1) - req->sdp_start;
08965             return 1;
08966          }
08967          found_application_sdp = FALSE;
08968       }
08969       if (!strcasecmp(line, "Content-Type: application/sdp"))
08970          found_application_sdp = TRUE;
08971       
08972       if (ast_strlen_zero(line)) {
08973          if (found_application_sdp && !found_end_of_headers){
08974             req->sdp_start = x;
08975             found_end_of_headers = TRUE;
08976          }
08977       }
08978    }
08979    if (found_application_sdp && found_end_of_headers) {
08980       req->sdp_count = x - req->sdp_start;
08981       return TRUE;
08982    }
08983    return FALSE;
08984 }

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

Definition at line 1663 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_notify_uri_helper().

Referenced by get_destination().

01664 {
01665    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP");
01666    return agent;
01667 }

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

Definition at line 1693 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_callid_helper().

Referenced by add_cc_call_info_to_response().

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

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

Definition at line 1678 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().

Referenced by handle_cc_subscribe().

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

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

find_sip_method: Find SIP method from header

Definition at line 3347 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().

03348 {
03349    int i, res = 0;
03350    
03351    if (ast_strlen_zero(msg)) {
03352       return 0;
03353    }
03354    for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) {
03355       if (method_match(i, msg)) {
03356          res = sip_methods[i].id;
03357       }
03358    }
03359    return res;
03360 }

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

Definition at line 1891 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by handle_cc_notify(), and handle_response_subscribe().

01892 {
01893    struct sip_monitor_instance *monitor_instance = obj;
01894    return monitor_instance->subscription_pvt == arg ? CMP_MATCH | CMP_STOP : 0;
01895 }

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

Definition at line 1897 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by cc_handle_publish_error().

01898 {
01899    struct sip_monitor_instance *monitor_instance = obj;
01900    return monitor_instance->suspension_entry == arg ? CMP_MATCH | CMP_STOP : 0;
01901 }

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

Definition at line 894 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by create_epa_entry().

00895 {
00896    const struct epa_backend *backend = NULL;
00897 
00898    AST_LIST_LOCK(&epa_static_data_list);
00899    AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) {
00900       if (!strcmp(backend->static_data->name, event_package)) {
00901          break;
00902       }
00903    }
00904    AST_LIST_UNLOCK(&epa_static_data_list);
00905    return backend ? backend->static_data : NULL;
00906 }

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

Find subscription type in array.

Definition at line 18958 of file chan_sip.c.

References ARRAY_LEN, subscription_types, and type.

Referenced by transmit_state_notify().

18959 {
18960    int i;
18961 
18962    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
18963       if (subscription_types[i].type == subtype) {
18964          return &subscription_types[i];
18965       }
18966    }
18967    return &subscription_types[0];
18968 }

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

Remove route from route list.

Definition at line 14675 of file chan_sip.c.

References ast_free.

Referenced by __sip_destroy(), and build_route().

14676 {
14677    struct sip_route *next;
14678 
14679    while (route) {
14680       next = route->next;
14681       ast_free(route);
14682       route = next;
14683    }
14684 }

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 20094 of file chan_sip.c.

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

20095 {
20096    if (ast_strlen_zero(data)) {
20097       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
20098       return -1;
20099    }
20100    if (check_sip_domain(data, NULL, 0))
20101       ast_copy_string(buf, data, len);
20102    else
20103       buf[0] = '\0';
20104    return 0;
20105 }

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 20030 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.

20031 {
20032    struct sip_pvt *p;
20033    const char *content = NULL;
20034    AST_DECLARE_APP_ARGS(args,
20035       AST_APP_ARG(header);
20036       AST_APP_ARG(number);
20037    );
20038    int i, number, start = 0;
20039 
20040    if (!chan) {
20041       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
20042       return -1;
20043    }
20044 
20045    if (ast_strlen_zero(data)) {
20046       ast_log(LOG_WARNING, "This function requires a header name.\n");
20047       return -1;
20048    }
20049 
20050    ast_channel_lock(chan);
20051    if (!IS_SIP_TECH(chan->tech)) {
20052       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
20053       ast_channel_unlock(chan);
20054       return -1;
20055    }
20056 
20057    AST_STANDARD_APP_ARGS(args, data);
20058    if (!args.number) {
20059       number = 1;
20060    } else {
20061       sscanf(args.number, "%30d", &number);
20062       if (number < 1)
20063          number = 1;
20064    }
20065 
20066    p = chan->tech_pvt;
20067 
20068    /* If there is no private structure, this channel is no longer alive */
20069    if (!p) {
20070       ast_channel_unlock(chan);
20071       return -1;
20072    }
20073 
20074    for (i = 0; i < number; i++)
20075       content = __get_header(&p->initreq, args.header, &start);
20076 
20077    if (ast_strlen_zero(content)) {
20078       ast_channel_unlock(chan);
20079       return -1;
20080    }
20081 
20082    ast_copy_string(buf, content, len);
20083    ast_channel_unlock(chan);
20084 
20085    return 0;
20086 }

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 20212 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.

20213 {
20214    struct sip_pvt *p;
20215    static int deprecated = 0;
20216 
20217    *buf = 0;
20218 
20219    if (!chan) {
20220       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
20221       return -1;
20222    }
20223 
20224    if (!data) {
20225       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
20226       return -1;
20227    }
20228 
20229    ast_channel_lock(chan);
20230    if (!IS_SIP_TECH(chan->tech)) {
20231       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
20232       ast_channel_unlock(chan);
20233       return -1;
20234    }
20235 
20236    if (deprecated++ % 20 == 0) {
20237       /* Deprecated in 1.6.1 */
20238       ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated.  Please transition to using CHANNEL().\n");
20239    }
20240 
20241    p = chan->tech_pvt;
20242 
20243    /* If there is no private structure, this channel is no longer alive */
20244    if (!p) {
20245       ast_channel_unlock(chan);
20246       return -1;
20247    }
20248 
20249    if (!strcasecmp(data, "peerip")) {
20250       ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len);
20251    } else  if (!strcasecmp(data, "recvip")) {
20252       ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len);
20253    } else  if (!strcasecmp(data, "from")) {
20254       ast_copy_string(buf, p->from, len);
20255    } else  if (!strcasecmp(data, "uri")) {
20256       ast_copy_string(buf, p->uri, len);
20257    } else  if (!strcasecmp(data, "useragent")) {
20258       ast_copy_string(buf, p->useragent, len);
20259    } else  if (!strcasecmp(data, "peername")) {
20260       ast_copy_string(buf, p->peername, len);
20261    } else if (!strcasecmp(data, "t38passthrough")) {
20262       if (p->t38.state == T38_DISABLED) {
20263          ast_copy_string(buf, "0", len);
20264       } else { /* T38 is offered or enabled in this call */
20265          ast_copy_string(buf, "1", len);
20266       }
20267    } else {
20268       ast_channel_unlock(chan);
20269       return -1;
20270    }
20271    ast_channel_unlock(chan);
20272 
20273    return 0;
20274 }

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 20113 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_str_buffer(), ast_test_flag, chanvar, FALSE, find_peer(), LOG_WARNING, ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), TRUE, unref_peer(), and ast_variable::value.

20114 {
20115    struct sip_peer *peer;
20116    char *colname;
20117 
20118    if ((colname = strchr(data, ':'))) {   /*! \todo Will be deprecated after 1.4 */
20119       static int deprecation_warning = 0;
20120       *colname++ = '\0';
20121       if (deprecation_warning++ % 10 == 0)
20122          ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated.  Please use ',' instead.\n");
20123    } else if ((colname = strchr(data, ',')))
20124       *colname++ = '\0';
20125    else
20126       colname = "ip";
20127 
20128    if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0)))
20129       return -1;
20130 
20131    if (!strcasecmp(colname, "ip")) {
20132       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
20133    } else  if (!strcasecmp(colname, "port")) {
20134       snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr));
20135    } else  if (!strcasecmp(colname, "status")) {
20136       peer_status(peer, buf, len);
20137    } else  if (!strcasecmp(colname, "language")) {
20138       ast_copy_string(buf, peer->language, len);
20139    } else  if (!strcasecmp(colname, "regexten")) {
20140       ast_copy_string(buf, peer->regexten, len);
20141    } else  if (!strcasecmp(colname, "limit")) {
20142       snprintf(buf, len, "%d", peer->call_limit);
20143    } else  if (!strcasecmp(colname, "busylevel")) {
20144       snprintf(buf, len, "%d", peer->busy_level);
20145    } else  if (!strcasecmp(colname, "curcalls")) {
20146       snprintf(buf, len, "%d", peer->inUse);
20147    } else if (!strcasecmp(colname, "maxforwards")) {
20148       snprintf(buf, len, "%d", peer->maxforwards);
20149    } else  if (!strcasecmp(colname, "accountcode")) {
20150       ast_copy_string(buf, peer->accountcode, len);
20151    } else  if (!strcasecmp(colname, "callgroup")) {
20152       ast_print_group(buf, len, peer->callgroup);
20153    } else  if (!strcasecmp(colname, "pickupgroup")) {
20154       ast_print_group(buf, len, peer->pickupgroup);
20155    } else  if (!strcasecmp(colname, "useragent")) {
20156       ast_copy_string(buf, peer->useragent, len);
20157    } else  if (!strcasecmp(colname, "mailbox")) {
20158       struct ast_str *mailbox_str = ast_str_alloca(512);
20159       peer_mailboxes_to_str(&mailbox_str, peer);
20160       ast_copy_string(buf, ast_str_buffer(mailbox_str), len);
20161    } else  if (!strcasecmp(colname, "context")) {
20162       ast_copy_string(buf, peer->context, len);
20163    } else  if (!strcasecmp(colname, "expire")) {
20164       snprintf(buf, len, "%d", peer->expire);
20165    } else  if (!strcasecmp(colname, "dynamic")) {
20166       ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len);
20167    } else  if (!strcasecmp(colname, "callerid_name")) {
20168       ast_copy_string(buf, peer->cid_name, len);
20169    } else  if (!strcasecmp(colname, "callerid_num")) {
20170       ast_copy_string(buf, peer->cid_num, len);
20171    } else  if (!strcasecmp(colname, "codecs")) {
20172       ast_getformatname_multiple(buf, len -1, peer->capability);
20173    } else if (!strcasecmp(colname, "encryption")) {
20174       snprintf(buf, len, "%u", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP));
20175    } else  if (!strncasecmp(colname, "chanvar[", 8)) {
20176       char *chanvar=colname + 8;
20177       struct ast_variable *v;
20178    
20179       chanvar = strsep(&chanvar, "]");
20180       for (v = peer->chanvars ; v ; v = v->next) {
20181          if (!strcasecmp(v->name, chanvar)) {
20182             ast_copy_string(buf, v->value, len);
20183          }
20184       }
20185    } else  if (!strncasecmp(colname, "codec[", 6)) {
20186       char *codecnum;
20187       format_t codec = 0;
20188       
20189       codecnum = colname + 6; /* move past the '[' */
20190       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
20191       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
20192          ast_copy_string(buf, ast_getformatname(codec), len);
20193       } else {
20194          buf[0] = '\0';
20195       }
20196    } else {
20197       buf[0] = '\0';
20198    }
20199 
20200    unref_peer(peer, "unref_peer from function_sippeer, just before return");
20201 
20202    return 0;
20203 }

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

Generate 32 byte random string for callid's etc.

Definition at line 7835 of file chan_sip.c.

References ast_random().

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

07836 {
07837    long val[4];
07838    int x;
07839 
07840    for (x=0; x<4; x++)
07841       val[x] = ast_random();
07842    snprintf(buf, size, "%08lx%08lx%08lx%08lx", (unsigned long)val[0], (unsigned long)val[1], (unsigned long)val[2], (unsigned long)val[3]);
07843 
07844    return buf;
07845 }

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

Definition at line 7847 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().

07848 {
07849    struct ast_str *uri = ast_str_alloca(size);
07850    ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:");
07851    /* Here would be a great place to generate a UUID, but for now we'll
07852     * use the handy random string generation function we already have
07853     */
07854    ast_str_append(&uri, 0, "%s", generate_random_string(buf, size));
07855    ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify_remote(&pvt->ourip));
07856    ast_copy_string(buf, ast_str_buffer(uri), size);
07857    return buf;
07858 }

int get_address_family_filter ( unsigned int  transport  )  [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 26286 of file chan_sip.c.

References ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), bindaddr, ast_tcptls_session_args::local_address, and ast_sockaddr::ss.

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

26287 {
26288    const struct ast_sockaddr *addr = NULL;
26289 
26290    if ((transport == SIP_TRANSPORT_UDP) || !transport) {
26291       addr = &bindaddr;
26292    }
26293    else if (transport == SIP_TRANSPORT_TCP) {
26294       addr = &sip_tcp_desc.local_address;
26295    }
26296    else if (transport == SIP_TRANSPORT_TLS) {
26297       addr = &sip_tls_desc.local_address;
26298    }
26299 
26300    if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) {
26301       return 0;
26302    }
26303 
26304    return addr->ss.ss_family;
26305 }

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 16348 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_header(), get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), pbx_builtin_getvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and sip_refer_allocate().

Referenced by handle_request_bye().

16349 {
16350    char tmp[256] = "", *c, *a;
16351    struct sip_request *req = oreq ? oreq : &p->initreq;
16352    struct sip_refer *referdata = NULL;
16353    const char *transfer_context = NULL;
16354    
16355    if (!p->refer && !sip_refer_allocate(p))
16356       return -1;
16357 
16358    referdata = p->refer;
16359 
16360    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
16361    c = get_in_brackets(tmp);
16362 
16363    if (parse_uri_legacy_check(c, "sip:,sips:", &c, NULL, &a, NULL)) {
16364       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
16365       return -1;
16366    }
16367    
16368    SIP_PEDANTIC_DECODE(c);
16369    SIP_PEDANTIC_DECODE(a);
16370 
16371    if (!ast_strlen_zero(a)) {
16372       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
16373    }
16374 
16375    if (sip_debug_test_pvt(p))
16376       ast_verbose("Looking for %s in %s\n", c, p->context);
16377 
16378    /* Determine transfer context */
16379    if (p->owner) {
16380       /* By default, use the context in the channel sending the REFER */
16381       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
16382       if (ast_strlen_zero(transfer_context)) {
16383          transfer_context = p->owner->macrocontext;
16384       }
16385    }
16386    if (ast_strlen_zero(transfer_context)) {
16387       transfer_context = S_OR(p->context, sip_cfg.default_context);
16388    }
16389 
16390    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
16391       /* This is a blind transfer */
16392       ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
16393       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
16394       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
16395       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
16396       /* Set new context */
16397       ast_string_field_set(p, context, transfer_context);
16398       return 0;
16399    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
16400       return 1;
16401    }
16402 
16403    return -1;
16404 }

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

Get a specific line from the message body.

Definition at line 7590 of file chan_sip.c.

References get_body_by_line(), and len().

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

07591 {
07592    int x;
07593    int len = strlen(name);
07594    char *r;
07595 
07596    for (x = 0; x < req->lines; x++) {
07597       r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter);
07598       if (r[0] != '\0')
07599          return r;
07600    }
07601 
07602    return "";
07603 }

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 7535 of file chan_sip.c.

References ast_skip_blanks().

Referenced by get_body(), and get_sdp_iterate().

07536 {
07537    if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter)
07538       return ast_skip_blanks(line + nameLen + 1);
07539 
07540    return "";
07541 }

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 26441 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().

26442 {
26443    struct sip_mailbox *mailbox;
26444    int in_cache;
26445 
26446    in_cache = 0;
26447    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
26448       struct ast_event *event;
26449       event = ast_event_get_cached(AST_EVENT_MWI,
26450          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
26451          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
26452          AST_EVENT_IE_END);
26453       if (!event)
26454          continue;
26455       *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
26456       *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
26457       ast_event_destroy(event);
26458       in_cache = 1;
26459    }
26460 
26461    return in_cache;
26462 }

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

Definition at line 11638 of file chan_sip.c.

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

Referenced by add_sdp().

11639 {
11640    /* Set encryption properties */
11641    if (srtp) {
11642       if (!srtp->crypto) {
11643          srtp->crypto = sdp_crypto_setup();
11644       }
11645       if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) {
11646          *a_crypto = sdp_crypto_attrib(srtp->crypto);
11647       }
11648 
11649       if (!*a_crypto) {
11650          ast_log(LOG_WARNING, "No SRTP key management enabled\n");
11651       }
11652    }
11653 }

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 15892 of file chan_sip.c.

References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_free, ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), 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_header(), get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), ast_cc_agent::private_data, RAII_VAR, S_OR, sip_cfg, sip_debug_test_pvt(), sip_methods, SIP_PEDANTIC_DECODE, and cfsip_methods::text.

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

15893 {
15894    char tmp[256] = "", *uri, *unused_password, *domain;
15895    RAII_VAR(char *, tmpf, NULL, ast_free);
15896    char *from = NULL;
15897    struct sip_request *req;
15898    char *decoded_uri;
15899 
15900    req = oreq;
15901    if (!req) {
15902       req = &p->initreq;
15903    }
15904 
15905    /* Find the request URI */
15906    if (req->rlPart2)
15907       ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp));
15908    
15909    uri = ast_strdupa(get_in_brackets(tmp));
15910 
15911    if (parse_uri_legacy_check(uri, "sip:,sips:", &uri, &unused_password, &domain, NULL)) {
15912       ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
15913       return SIP_GET_DEST_INVALID_URI;
15914    }
15915 
15916    SIP_PEDANTIC_DECODE(domain);
15917    SIP_PEDANTIC_DECODE(uri);
15918 
15919    extract_host_from_hostport(&domain);
15920 
15921    if (ast_strlen_zero(uri)) {
15922       /*
15923        * Either there really was no extension found or the request
15924        * URI had encoded nulls that made the string "empty".  Use "s"
15925        * as the extension.
15926        */
15927       uri = "s";
15928    }
15929 
15930    ast_string_field_set(p, domain, domain);
15931 
15932    /* Now find the From: caller ID and name */
15933    /* XXX Why is this done in get_destination? Isn't it already done?
15934       Needs to be checked
15935         */
15936    tmpf = ast_strdup(get_header(req, "From"));
15937    if (!ast_strlen_zero(tmpf)) {
15938       from = get_in_brackets(tmpf);
15939       if (parse_uri_legacy_check(from, "sip:,sips:", &from, NULL, &domain, NULL)) {
15940          ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from);
15941          return SIP_GET_DEST_INVALID_URI;
15942       }
15943 
15944       SIP_PEDANTIC_DECODE(from);
15945       SIP_PEDANTIC_DECODE(domain);
15946 
15947       extract_host_from_hostport(&domain);
15948 
15949       ast_string_field_set(p, fromdomain, domain);
15950    }
15951 
15952    if (!AST_LIST_EMPTY(&domain_list)) {
15953       char domain_context[AST_MAX_EXTENSION];
15954 
15955       domain_context[0] = '\0';
15956       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
15957          if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
15958             ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
15959             return SIP_GET_DEST_REFUSED;
15960          }
15961       }
15962       /* If we don't have a peer (i.e. we're a guest call),
15963        * overwrite the original context */
15964       if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) {
15965          ast_string_field_set(p, context, domain_context);
15966       }
15967    }
15968 
15969    /* If the request coming in is a subscription and subscribecontext has been specified use it */
15970    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) {
15971       ast_string_field_set(p, context, p->subscribecontext);
15972    }
15973 
15974    if (sip_debug_test_pvt(p)) {
15975       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
15976    }
15977 
15978    /* Since extensions.conf can have unescaped characters, try matching a
15979     * decoded uri in addition to the non-decoded uri. */
15980    decoded_uri = ast_strdupa(uri);
15981    ast_uri_decode(decoded_uri);
15982 
15983    /* If this is a subscription we actually just need to see if a hint exists for the extension */
15984    if (req->method == SIP_SUBSCRIBE) {
15985       char hint[AST_MAX_EXTENSION];
15986       int which = 0;
15987       if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) ||
15988           (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) {
15989          if (!oreq) {
15990             ast_string_field_set(p, exten, which ? decoded_uri : uri);
15991          }
15992          return SIP_GET_DEST_EXTEN_FOUND;
15993       } else {
15994          return SIP_GET_DEST_EXTEN_NOT_FOUND;
15995       }
15996    } else {
15997       struct ast_cc_agent *agent;
15998       /* Check the dialplan for the username part of the request URI,
15999          the domain will be stored in the SIPDOMAIN variable
16000          Return 0 if we have a matching extension */
16001       if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) {
16002          if (!oreq) {
16003             ast_string_field_set(p, exten, uri);
16004          }
16005          return SIP_GET_DEST_EXTEN_FOUND;
16006       }
16007       if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
16008          || !strcmp(decoded_uri, ast_pickup_ext())) {
16009          if (!oreq) {
16010             ast_string_field_set(p, exten, decoded_uri);
16011          }
16012          return SIP_GET_DEST_EXTEN_FOUND;
16013       }
16014       if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) {
16015          struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
16016          /* This is a CC recall. We can set p's extension to the exten from
16017           * the original INVITE
16018           */
16019          ast_string_field_set(p, exten, agent_pvt->original_exten);
16020          /* And we need to let the CC core know that the caller is attempting
16021           * his recall
16022           */
16023          ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall",
16024                agent->device_name);
16025          if (cc_recall_core_id) {
16026             *cc_recall_core_id = agent->core_id;
16027          }
16028          ao2_ref(agent, -1);
16029          return SIP_GET_DEST_EXTEN_FOUND;
16030       }
16031    }
16032 
16033    if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)
16034       && (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))
16035          || ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
16036          || !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri)))) {
16037       /* Overlap dialing is enabled and we need more digits to match an extension. */
16038       return SIP_GET_DEST_EXTEN_MATCHMORE;
16039    }
16040 
16041    return SIP_GET_DEST_EXTEN_NOT_FOUND;
16042 }

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 11104 of file chan_sip.c.

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

Referenced by get_realm().

11105 {
11106    char tmpf[256];
11107    char *a, *from;
11108 
11109    *domain = '\0';
11110    ast_copy_string(tmpf, str, sizeof(tmpf));
11111    from = get_in_brackets(tmpf);
11112    if (!ast_strlen_zero(from)) {
11113       if (strncasecmp(from, "sip:", 4)) {
11114          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
11115          return -1;
11116       }
11117       from += 4;
11118    } else
11119       from = NULL;
11120 
11121    if (from) {
11122       int bracket = 0;
11123 
11124       /* Strip any params or options from user */
11125       if ((a = strchr(from, ';')))
11126          *a = '\0';
11127       /* Strip port from domain if present */
11128       for (a = from; *a != '\0'; ++a) {
11129          if (*a == ':' && bracket == 0) {
11130             *a = '\0';
11131             break;
11132          } else if (*a == '[') {
11133             ++bracket;
11134          } else if (*a == ']') {
11135             --bracket;
11136          }
11137       }
11138       if ((a = strchr(from, '@'))) {
11139          *a = '\0';
11140          ast_copy_string(domain, a + 1, len);
11141       } else
11142          ast_copy_string(domain, from, len);
11143    }
11144 
11145    return ast_strlen_zero(domain);
11146 }

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

Definition at line 988 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().

00988                                                                                 {
00989    int i;
00990    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
00991       if (!strcasecmp(event_package, event_state_compositors[i].name)) {
00992          return &event_state_compositors[i];
00993       }
00994    }
00995    return NULL;
00996 }

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

Definition at line 998 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().

00998                                                                                                         {
00999    struct sip_esc_entry *entry;
01000    struct sip_esc_entry finder;
01001 
01002    ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag));
01003 
01004    entry = ao2_find(esc->compositor, &finder, OBJ_POINTER);
01005 
01006    return entry;
01007 }

static const char * get_header ( const struct sip_request *  req,
const char *  name 
) [static]

Get header from SIP request.

Returns:
Always return something, so don't check for NULL because it won't happen :-)

Definition at line 7684 of file chan_sip.c.

References __get_header().

Referenced by __transmit_response(), build_route(), cc_handle_publish_error(), change_redirecting_information(), check_auth(), check_user_full(), check_via(), check_via_response(), copy_header(), extract_uri(), find_call(), find_sdp(), get_also_info(), get_destination(), get_pai(), get_rdnis(), get_realm(), get_refer_info(), get_rpid(), gettag(), handle_cc_notify(), handle_cc_subscribe(), handle_incoming(), handle_request_bye(), handle_request_do(), handle_request_info(), handle_request_invite(), handle_request_invite_st(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), parse_allowed_methods(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), proc_422_rsp(), process_via(), receive_message(), register_verify(), reply_digest(), reqprep(), respprep(), send_request(), send_response(), sip_alloc(), sip_get_cc_information(), sip_sipredirect(), transmit_fake_auth_response(), transmit_refer(), transmit_response_with_auth(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and transmit_state_notify().

07685 {
07686    int start = 0;
07687    return __get_header(req, name, &start);
07688 }

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

Definition at line 4891 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().

04892 {
04893    struct ast_variable *var = NULL;
04894    struct ast_flags flags = {0};
04895    char *cat = NULL;
04896    const char *insecure;
04897    while ((cat = ast_category_browse(cfg, cat))) {
04898       insecure = ast_variable_retrieve(cfg, cat, "insecure");
04899       set_insecure_flags(&flags, insecure, -1);
04900       if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
04901          var = ast_category_root(cfg, cat);
04902          break;
04903       }
04904    }
04905    return var;
04906 }

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

Definition at line 4908 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().

04909 {
04910    struct ast_config *peerlist;
04911    struct ast_variable *var = NULL;
04912    if ((peerlist = ast_load_realtime_multientry("sippeers", column, value, "insecure LIKE", "%port%", SENTINEL))) {
04913       if ((var = get_insecure_variable_from_config(peerlist))) {
04914          /* Must clone, because var will get freed along with
04915           * peerlist. */
04916          var = ast_variables_dup(var);
04917       }
04918       ast_config_destroy(peerlist);
04919    }
04920    return var;
04921 }

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

Definition at line 4928 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().

04929 {
04930    struct ast_variable *varregs = NULL;
04931    struct ast_config *regs, *peers;
04932    char *regscat;
04933    const char *regname;
04934 
04935    if (!(regs = ast_load_realtime_multientry("sipregs", column, value, SENTINEL))) {
04936       return NULL;
04937    }
04938 
04939    /* Load *all* peers that are probably insecure=port */
04940    if (!(peers = ast_load_realtime_multientry("sippeers", "insecure LIKE", "%port%", SENTINEL))) {
04941       ast_config_destroy(regs);
04942       return NULL;
04943    }
04944 
04945    /* Loop over the sipregs that match IP address and attempt to find an
04946     * insecure=port match to it in sippeers. */
04947    regscat = NULL;
04948    while ((regscat = ast_category_browse(regs, regscat)) && (regname = ast_variable_retrieve(regs, regscat, "name"))) {
04949       char *peerscat;
04950       const char *peername;
04951 
04952       peerscat = NULL;
04953       while ((peerscat = ast_category_browse(peers, peerscat)) && (peername = ast_variable_retrieve(peers, peerscat, "name"))) {
04954          if (!strcasecmp(regname, peername)) {
04955             /* Ensure that it really is insecure=port and
04956              * not something else. */
04957             const char *insecure = ast_variable_retrieve(peers, peerscat, "insecure");
04958             struct ast_flags flags = {0};
04959             set_insecure_flags(&flags, insecure, -1);
04960             if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
04961                /* ENOMEM checks till the bitter end. */
04962                if ((varregs = ast_variables_dup(ast_category_root(regs, regscat)))) {
04963                   if (!(*var = ast_variables_dup(ast_category_root(peers, peerscat)))) {
04964                      ast_variables_destroy(varregs);
04965                      varregs = NULL;
04966                   }
04967                }
04968                goto done;
04969             }
04970          }
04971       }
04972    }
04973 
04974 done:
04975    ast_config_destroy(regs);
04976    ast_config_destroy(peers);
04977    return varregs;
04978 }

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 9019 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().

09020 {
09021    const char *m;
09022    const char *c;
09023    int miterator = req->sdp_start;
09024    int citerator = req->sdp_start;
09025    unsigned int x = 0;
09026    unsigned int numberofports;
09027    int len;
09028    int af;
09029    char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */
09030 
09031    c = get_sdp_iterate(&citerator, req, "c");
09032    if (sscanf(c, "IN %3s %256s", proto, host) != 2) {
09033          ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
09034          /* Continue since there may be a valid host in a c= line specific to the audio stream */
09035    }
09036    /* We only want the m and c lines for audio */
09037    for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) {
09038       if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
09039           (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) ||
09040          (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
09041           (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) {
09042          /* See if there's a c= line for this media stream.
09043           * XXX There is no guarantee that we'll be grabbing the c= line for this
09044           * particular media stream here. However, this is the same logic used in process_sdp.
09045           */
09046          c = get_sdp_iterate(&citerator, req, "c");
09047          if (!ast_strlen_zero(c)) {
09048             sscanf(c, "IN %3s %256s", proto, host);
09049          }
09050          break;
09051       }
09052    }
09053 
09054    if (!strcmp("IP4", proto)) {
09055       af = AF_INET;
09056    } else if (!strcmp("IP6", proto)) {
09057       af = AF_INET6;
09058    } else {
09059       ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
09060       return -1;
09061    }
09062 
09063    if (ast_strlen_zero(host) || x == 0) {
09064       ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video");
09065       return -1;
09066    }
09067 
09068    if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
09069       ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video");
09070       return -1;
09071    }
09072 
09073    return 0;
09074 }

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 16860 of file chan_sip.c.

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

16861 {
16862    int x;
16863    int linelen;
16864 
16865    buf[0] = '\0';
16866    --len; /* reserve strncat null */
16867    for (x = 0; len && x < req->lines; ++x) {
16868       const char *line = REQ_OFFSET_TO_STR(req, line[x]);
16869       strncat(buf, line, len); /* safe */
16870       linelen = strlen(buf);
16871       buf += linelen;
16872       len -= linelen;
16873       if (len) {
16874          strcat(buf, "\n"); /* safe */
16875          ++buf;
16876          --len;
16877       }
16878    }
16879    return 0;
16880 }

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

Definition at line 4980 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().

04981 {
04982    /* Don't expect this to return non-NULL. Both NULL and empty
04983     * values can cause the option to get removed from the variable
04984     * list. This is called on ast_variables gotten from both
04985     * ast_load_realtime and ast_load_realtime_multientry.
04986     * - ast_load_realtime removes options with empty values
04987     * - ast_load_realtime_multientry does not!
04988     * For consistent behaviour, we check for the empty name and
04989     * return NULL instead. */
04990    const struct ast_variable *tmp;
04991    for (tmp = var; tmp; tmp = tmp->next) {
04992       if (!strcasecmp(tmp->name, "name")) {
04993          if (!ast_strlen_zero(tmp->value)) {
04994             return tmp->value;
04995          }
04996          break;
04997       }
04998    }
04999    return NULL;
05000 }

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 11545 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().

11549 {
11550    int use_externip = 0;
11551 
11552    /* First, get our address */
11553    ast_rtp_instance_get_local_address(p->rtp, addr);
11554    if (p->vrtp) {
11555       ast_rtp_instance_get_local_address(p->vrtp, vaddr);
11556    }
11557    if (p->trtp) {
11558       ast_rtp_instance_get_local_address(p->trtp, taddr);
11559    }
11560 
11561    /* If our real IP differs from the local address returned by the RTP engine, use it. */
11562    /* The premise is that if we are already using that IP to communicate with the client, */
11563    /* we should be using it for RTP too. */
11564         use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr);
11565 
11566    /* Now, try to figure out where we want them to send data */
11567    /* Is this a re-invite to move the media out, then use the original offer from caller  */
11568    if (!ast_sockaddr_isnull(&p->redirip)) {  /* If we have a redirection IP, use it */
11569       ast_sockaddr_copy(dest, &p->redirip);
11570    } else {
11571       /*
11572        * Audio Destination IP:
11573        *
11574        * 1. Specifically configured media address.
11575        * 2. Local address as specified by the RTP engine.
11576        * 3. The local IP as defined by chan_sip.
11577        *
11578        * Audio Destination Port:
11579        *
11580        * 1. Provided by the RTP engine.
11581        */
11582       ast_sockaddr_copy(dest,
11583               !ast_sockaddr_isnull(&media_address) ? &media_address :
11584               !ast_sockaddr_is_any(addr) && !use_externip ? addr    :
11585               &p->ourip);
11586       ast_sockaddr_set_port(dest, ast_sockaddr_port(addr));
11587    }
11588 
11589    if (needvideo) {
11590       /* Determine video destination */
11591       if (!ast_sockaddr_isnull(&p->vredirip)) {
11592          ast_sockaddr_copy(vdest, &p->vredirip);
11593       } else {
11594          /*
11595           * Video Destination IP:
11596           *
11597           * 1. Specifically configured media address.
11598           * 2. Local address as specified by the RTP engine.
11599           * 3. The local IP as defined by chan_sip.
11600           *
11601           * Video Destination Port:
11602           *
11603           * 1. Provided by the RTP engine.
11604           */
11605          ast_sockaddr_copy(vdest,
11606                  !ast_sockaddr_isnull(&media_address) ? &media_address :
11607                  !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr  :
11608                  &p->ourip);
11609          ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr));
11610       }
11611    }
11612 
11613    if (needtext) {
11614       /* Determine text destination */
11615       if (!ast_sockaddr_isnull(&p->tredirip)) {
11616          ast_sockaddr_copy(tdest, &p->tredirip);
11617       } else {
11618          /*
11619           * Text Destination IP:
11620           *
11621           * 1. Specifically configured media address.
11622           * 2. Local address as specified by the RTP engine.
11623           * 3. The local IP as defined by chan_sip.
11624           *
11625           * Text Destination Port:
11626           *
11627           * 1. Provided by the RTP engine.
11628           */
11629          ast_sockaddr_copy(tdest,
11630                  !ast_sockaddr_isnull(&media_address) ? &media_address  :
11631                  !ast_sockaddr_is_any(taddr) && !use_externip ? taddr   :
11632                  &p->ourip);
11633          ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr));
11634       }
11635    }
11636 }

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 15599 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_header(), get_in_brackets(), and get_name_and_number().

Referenced by get_rpid().

15600 {
15601    char pai[256];
15602    char privacy[64];
15603    char *cid_num = NULL;
15604    char *cid_name = NULL;
15605    char emptyname[1] = "";
15606    int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
15607    char *uri = NULL;
15608    int is_anonymous = 0, do_update = 1, no_name = 0;
15609 
15610    ast_copy_string(pai, get_header(req, "P-Asserted-Identity"), sizeof(pai));
15611 
15612    if (ast_strlen_zero(pai)) {
15613       return 0;
15614    }
15615 
15616    /* use the reqresp_parser function get_name_and_number*/
15617    if (get_name_and_number(pai, &cid_name, &cid_num)) {
15618       return 0;
15619    }
15620 
15621    if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) {
15622       ast_shrink_phone_number(cid_num);
15623    }
15624 
15625    uri = get_in_brackets(pai);
15626    if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) {
15627       callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
15628       /*XXX Assume no change in cid_num. Perhaps it should be
15629        * blanked?
15630        */
15631       ast_free(cid_num);
15632       is_anonymous = 1;
15633       cid_num = (char *)p->cid_num;
15634    }
15635 
15636    ast_copy_string(privacy, get_header(req, "Privacy"), sizeof(privacy));
15637    if (!ast_strlen_zero(privacy) && !strncmp(privacy, "id", 2)) {
15638       callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
15639    }
15640    if (!cid_name) {
15641       no_name = 1;
15642       cid_name = (char *)emptyname;
15643    }  
15644    /* Only return true if the supplied caller id is different */
15645    if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) {
15646       do_update = 0;
15647    } else {
15648 
15649       ast_string_field_set(p, cid_num, cid_num);
15650       ast_string_field_set(p, cid_name, cid_name);
15651       p->callingpres = callingpres;
15652 
15653       if (p->owner) {
15654          ast_set_callerid(p->owner, cid_num, cid_name, NULL);
15655          p->owner->caller.id.name.presentation = callingpres;
15656          p->owner->caller.id.number.presentation = callingpres;
15657       }
15658    }
15659 
15660    /* get_name_and_number allocates memory for cid_num and cid_name so we have to free it */
15661    if (!is_anonymous) {
15662       ast_free(cid_num);
15663    }
15664    if (!no_name) {
15665       ast_free(cid_name);
15666    }
15667 
15668    return do_update;
15669 }

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 15792 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_strdup, ast_strip_quoted(), ast_strlen_zero(), ast_verbose, exten, get_header(), get_in_brackets(), LOG_WARNING, pbx_builtin_setvar_helper(), S_OR, sip_debug_test_pvt(), sip_reason_str_to_code(), and sip_set_redirstr().

Referenced by change_redirecting_information().

15793 {
15794    char tmp[256], *exten, *rexten, *rdomain, *rname = NULL;
15795    char *params, *reason_param = NULL;
15796    struct sip_request *req;
15797 
15798    req = oreq ? oreq : &p->initreq;
15799 
15800    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
15801    if (ast_strlen_zero(tmp))
15802       return -1;
15803 
15804    if ((params = strchr(tmp, '>'))) {
15805       params = strchr(params, ';');
15806    }
15807 
15808    exten = get_in_brackets(tmp);
15809    if (!strncasecmp(exten, "sip:", 4)) {
15810       exten += 4;
15811    } else if (!strncasecmp(exten, "sips:", 5)) {
15812       exten += 5;
15813    } else {
15814       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", exten);
15815       return -1;
15816    }
15817 
15818    /* Get diversion-reason param if present */
15819    if (params) {
15820       *params = '\0';   /* Cut off parameters  */
15821       params++;
15822       while (*params == ';' || *params == ' ')
15823          params++;
15824       /* Check if we have a reason parameter */
15825       if ((reason_param = strcasestr(params, "reason="))) {
15826          char *end;
15827          reason_param+=7;
15828          if ((end = strchr(reason_param, ';'))) {
15829             *end = '\0';
15830          }
15831          /* Remove enclosing double-quotes */
15832          if (*reason_param == '"')
15833             reason_param = ast_strip_quoted(reason_param, "\"", "\"");
15834          if (!ast_strlen_zero(reason_param)) {
15835             sip_set_redirstr(p, reason_param);
15836             if (p->owner) {
15837                pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause);
15838                pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param);
15839             }
15840          }
15841       }
15842    }
15843 
15844    rdomain = exten;
15845    rexten = strsep(&rdomain, "@");  /* trim anything after @ */
15846    if (p->owner)
15847       pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain);
15848 
15849    if (sip_debug_test_pvt(p))
15850       ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, S_OR(reason_param, ""));
15851 
15852    /*ast_string_field_set(p, rdnis, rexten);*/
15853 
15854    if (*tmp == '\"') {
15855       char *end_quote;
15856       rname = tmp + 1;
15857       end_quote = strchr(rname, '\"');
15858       if (end_quote) {
15859          *end_quote = '\0';
15860       }
15861    }
15862 
15863    if (number) {
15864       *number = ast_strdup(rexten);
15865    }
15866 
15867    if (name && rname) {
15868       *name = ast_strdup(rname);
15869    }
15870 
15871    if (reason && !ast_strlen_zero(reason_param)) {
15872       *reason = sip_reason_str_to_code(reason_param);
15873    }
15874 
15875    return 0;
15876 }

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 11152 of file chan_sip.c.

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

Referenced by transmit_response_with_auth().

11153 {
11154    char domain[MAXHOSTNAMELEN];
11155 
11156    if (!ast_strlen_zero(p->realm))
11157       return;
11158 
11159    if (sip_cfg.domainsasrealm &&
11160        !AST_LIST_EMPTY(&domain_list))
11161    {
11162       /* Check From header first */
11163       if (!get_domain(get_header(req, "From"), domain, sizeof(domain))) {
11164          if (check_sip_domain(domain, NULL, 0)) {
11165             ast_string_field_set(p, realm, domain);
11166             return;
11167          }
11168       }
11169       /* Check To header */
11170       if (!get_domain(get_header(req, "To"), domain, sizeof(domain))) {
11171          if (check_sip_domain(domain, NULL, 0)) {
11172             ast_string_field_set(p, realm, domain);
11173             return;
11174          }
11175       }
11176    }
11177    
11178    /* Use default realm from config file */
11179    ast_string_field_set(p, realm, sip_cfg.realm);
11180 }

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 16139 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_verbose, ast_channel::context, get_header(), get_in_brackets(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), and SIP_PEDANTIC_DECODE.

Referenced by handle_request_refer().

16140 {
16141 
16142    const char *p_referred_by = NULL;
16143    char *h_refer_to = NULL;
16144    char *h_referred_by = NULL;
16145    char *refer_to;
16146    const char *p_refer_to;
16147    char *referred_by_uri = NULL;
16148    char *ptr;
16149    struct sip_request *req = NULL;
16150    const char *transfer_context = NULL;
16151    struct sip_refer *referdata;
16152 
16153 
16154    req = outgoing_req;
16155    referdata = transferer->refer;
16156 
16157    if (!req) {
16158       req = &transferer->initreq;
16159    }
16160 
16161    p_refer_to = get_header(req, "Refer-To");
16162    if (ast_strlen_zero(p_refer_to)) {
16163       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
16164       return -2;  /* Syntax error */
16165    }
16166    h_refer_to = ast_strdupa(p_refer_to);
16167    refer_to = get_in_brackets(h_refer_to);
16168    if (!strncasecmp(refer_to, "sip:", 4)) {
16169       refer_to += 4;       /* Skip sip: */
16170    } else if (!strncasecmp(refer_to, "sips:", 5)) {
16171       refer_to += 5;
16172    } else {
16173       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
16174       return -3;
16175    }
16176 
16177    /* Get referred by header if it exists */
16178    p_referred_by = get_header(req, "Referred-By");
16179 
16180    /* Give useful transfer information to the dialplan */
16181    if (transferer->owner) {
16182       struct ast_channel *peer = ast_bridged_channel(transferer->owner);
16183       if (peer) {
16184          pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context);
16185          pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by);
16186       }
16187    }
16188 
16189    if (!ast_strlen_zero(p_referred_by)) {
16190       char *lessthan;
16191       h_referred_by = ast_strdupa(p_referred_by);
16192 
16193       /* Store referrer's caller ID name */
16194       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
16195       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
16196          *(lessthan - 1) = '\0'; /* Space */
16197       }
16198 
16199       referred_by_uri = get_in_brackets(h_referred_by);
16200 
16201       if (!strncasecmp(referred_by_uri, "sip:", 4)) {
16202          referred_by_uri += 4;      /* Skip sip: */
16203       } else if (!strncasecmp(referred_by_uri, "sips:", 5)) {
16204          referred_by_uri += 5;      /* Skip sips: */
16205       } else {
16206          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
16207          referred_by_uri = NULL;
16208       }
16209    }
16210 
16211    /* Check for arguments in the refer_to header */
16212    if ((ptr = strcasestr(refer_to, "replaces="))) {
16213       char *to = NULL, *from = NULL;
16214       
16215       /* This is an attended transfer */
16216       referdata->attendedtransfer = 1;
16217       ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
16218       ast_uri_decode(referdata->replaces_callid);
16219       if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
16220          *ptr++ = '\0';
16221       }
16222       
16223       if (ptr) {
16224          /* Find the different tags before we destroy the string */
16225          to = strcasestr(ptr, "to-tag=");
16226          from = strcasestr(ptr, "from-tag=");
16227       }
16228       
16229       /* Grab the to header */
16230       if (to) {
16231          ptr = to + 7;
16232          if ((to = strchr(ptr, '&'))) {
16233             *to = '\0';
16234          }
16235          if ((to = strchr(ptr, ';'))) {
16236             *to = '\0';
16237          }
16238          ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
16239       }
16240       
16241       if (from) {
16242          ptr = from + 9;
16243          if ((to = strchr(ptr, '&'))) {
16244             *to = '\0';
16245          }
16246          if ((to = strchr(ptr, ';'))) {
16247             *to = '\0';
16248          }
16249          ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
16250       }
16251 
16252       if (!strcmp(referdata->replaces_callid, transferer->callid) &&
16253          (!sip_cfg.pedanticsipchecking ||
16254          (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) &&
16255          !strcmp(referdata->replaces_callid_totag, transferer->tag)))) {
16256             ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid);
16257             return -4;
16258       }
16259 
16260       if (!sip_cfg.pedanticsipchecking) {
16261          ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
16262       } else {
16263          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>" );
16264       }
16265    }
16266    
16267    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
16268       char *urioption = NULL, *domain;
16269       int bracket = 0;
16270       *ptr++ = '\0';
16271 
16272       if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */
16273          *urioption++ = '\0';
16274       }
16275 
16276       domain = ptr;
16277 
16278       /* Remove :port */
16279       for (; *ptr != '\0'; ++ptr) {
16280          if (*ptr == ':' && bracket == 0) {
16281             *ptr = '\0';
16282             break;
16283          } else if (*ptr == '[') {
16284             ++bracket;
16285          } else if (*ptr == ']') {
16286             --bracket;
16287          }
16288       }
16289 
16290       SIP_PEDANTIC_DECODE(domain);
16291       SIP_PEDANTIC_DECODE(urioption);
16292 
16293       /* Save the domain for the dial plan */
16294       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
16295       if (urioption) {
16296          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
16297       }
16298    }
16299 
16300    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
16301       *ptr = '\0';
16302 
16303    SIP_PEDANTIC_DECODE(refer_to);
16304    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
16305    
16306    if (referred_by_uri) {
16307       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
16308          *ptr = '\0';
16309       SIP_PEDANTIC_DECODE(referred_by_uri);
16310       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
16311    } else {
16312       referdata->referred_by[0] = '\0';
16313    }
16314 
16315    /* Determine transfer context */
16316    if (transferer->owner) {
16317       /* By default, use the context in the channel sending the REFER */
16318       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
16319       if (ast_strlen_zero(transfer_context)) {
16320          transfer_context = transferer->owner->macrocontext;
16321       }
16322    }
16323    if (ast_strlen_zero(transfer_context)) {
16324       transfer_context = S_OR(transferer->context, sip_cfg.default_context);
16325    }
16326 
16327    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
16328    
16329    /* Either an existing extension or the parking extension */
16330    if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
16331       if (sip_debug_test_pvt(transferer)) {
16332          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
16333       }
16334       /* We are ready to transfer to the extension */
16335       return 0;
16336    }
16337    if (sip_debug_test_pvt(transferer))
16338       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
16339 
16340    /* Failure, we can't find this extension */
16341    return -1;
16342 }

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 15675 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_header(), and get_pai().

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

15676 {
15677    char tmp[256];
15678    struct sip_request *req;
15679    char *cid_num = "";
15680    char *cid_name = "";
15681    int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
15682    char *privacy = "";
15683    char *screen = "";
15684    char *start, *end;
15685 
15686    if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID))
15687       return 0;
15688    req = oreq;
15689    if (!req)
15690       req = &p->initreq;
15691    ast_copy_string(tmp, get_header(req, "Remote-Party-ID"), sizeof(tmp));
15692    if (ast_strlen_zero(tmp)) {
15693       return get_pai(p, req);
15694    }
15695 
15696    /*
15697     * RPID is not:
15698     *   rpid = (name-addr / addr-spec) *(SEMI rpi-token)
15699     * But it is:
15700     *   rpid = [display-name] LAQUOT addr-spec RAQUOT *(SEMI rpi-token)
15701     * Ergo, calling parse_name_andor_addr() on it wouldn't be
15702     * correct because that would allow addr-spec style too.
15703     */
15704    start = tmp;
15705    /* Quoted (note that we're not dealing with escapes properly) */
15706    if (*start == '"') {
15707       *start++ = '\0';
15708       end = strchr(start, '"');
15709       if (!end)
15710          return 0;
15711       *end++ = '\0';
15712       cid_name = start;
15713       start = ast_skip_blanks(end);
15714    /* Unquoted */
15715    } else {
15716       cid_name = start;
15717       start = end = strchr(start, '<');
15718       if (!start) {
15719          return 0;
15720       }
15721       /* trim blanks if there are any. the mandatory NUL is done below */
15722       while (--end >= cid_name && *end < 33) {
15723          *end = '\0';
15724       }
15725    }
15726 
15727    if (*start != '<')
15728       return 0;
15729    *start++ = '\0';
15730    end = strchr(start, '@');
15731    if (!end)
15732       return 0;
15733    *end++ = '\0';
15734    if (strncasecmp(start, "sip:", 4))
15735       return 0;
15736    cid_num = start + 4;
15737    if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num))
15738       ast_shrink_phone_number(cid_num);
15739    start = end;
15740 
15741    end = strchr(start, '>');
15742    if (!end)
15743       return 0;
15744    *end++ = '\0';
15745    if (*end) {
15746       start = end;
15747       if (*start != ';')
15748          return 0;
15749       *start++ = '\0';
15750       while (!ast_strlen_zero(start)) {
15751          end = strchr(start, ';');
15752          if (end)
15753             *end++ = '\0';
15754          if (!strncasecmp(start, "privacy=", 8))
15755             privacy = start + 8;
15756          else if (!strncasecmp(start, "screen=", 7))
15757             screen = start + 7;
15758          start = end;
15759       }
15760 
15761       if (!strcasecmp(privacy, "full")) {
15762          if (!strcasecmp(screen, "yes"))
15763             callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
15764          else if (!strcasecmp(screen, "no"))
15765             callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
15766       } else {
15767          if (!strcasecmp(screen, "yes"))
15768             callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
15769          else if (!strcasecmp(screen, "no"))
15770             callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
15771       }
15772    }
15773 
15774    /* Only return true if the supplied caller id is different */
15775    if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres)
15776       return 0;
15777 
15778    ast_string_field_set(p, cid_num, cid_num);
15779    ast_string_field_set(p, cid_name, cid_name);
15780    p->callingpres = callingpres;
15781 
15782    if (p->owner) {
15783       ast_set_callerid(p->owner, cid_num, cid_name, NULL);
15784       p->owner->caller.id.name.presentation = callingpres;
15785       p->owner->caller.id.number.presentation = callingpres;
15786    }
15787 
15788    return 1;
15789 }

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 7547 of file chan_sip.c.

References get_body_by_line(), and len().

Referenced by get_ip_and_port_from_sdp(), and process_sdp().

07548 {
07549    int len = strlen(name);
07550 
07551    while (*start < (req->sdp_start + req->sdp_count)) {
07552       const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '=');
07553       if (r[0] != '\0')
07554          return r;
07555    }
07556 
07557    /* if the line was not found, ensure that *start points past the SDP */
07558    (*start)++;
07559 
07560    return "";
07561 }

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 7568 of file chan_sip.c.

References ast_skip_blanks(), and type.

Referenced by process_sdp().

07569 {
07570    char type = '\0';
07571    const char *line = NULL;
07572 
07573    if (stop > (req->sdp_start + req->sdp_count)) {
07574       stop = req->sdp_start + req->sdp_count;
07575    }
07576 
07577    while (*start < stop) {
07578       line = REQ_OFFSET_TO_STR(req, line[(*start)++]);
07579       if (line[1] == '=') {
07580          type = line[0];
07581          *value = ast_skip_blanks(line + 2);
07582          break;
07583       }
07584    }
07585 
07586    return type;
07587 }

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 16047 of file chan_sip.c.

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

Referenced by handle_request_invite(), and local_attended_transfer().

16048 {
16049    struct sip_pvt *sip_pvt_ptr;
16050    struct sip_pvt tmp_dialog = {
16051       .callid = callid,
16052    };
16053 
16054    if (totag) {
16055       ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
16056    }
16057 
16058    /* Search dialogs and find the match */
16059    
16060    sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table");
16061    if (sip_pvt_ptr) {
16062       /* Go ahead and lock it (and its owner) before returning */
16063       sip_pvt_lock(sip_pvt_ptr);
16064       if (sip_cfg.pedanticsipchecking) {
16065          unsigned char frommismatch = 0, tomismatch = 0;
16066 
16067          if (ast_strlen_zero(fromtag)) {
16068             sip_pvt_unlock(sip_pvt_ptr);
16069             ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n",
16070                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
16071             return NULL;
16072          }
16073 
16074          if (ast_strlen_zero(totag)) {
16075             sip_pvt_unlock(sip_pvt_ptr);
16076             ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n",
16077                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
16078             return NULL;
16079          }
16080          /* RFC 3891
16081           * > 3.  User Agent Server Behavior: Receiving a Replaces Header
16082           * > The Replaces header contains information used to match an existing
16083           * > SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
16084           * > with a Replaces header, the User Agent (UA) attempts to match this
16085           * > information with a confirmed or early dialog.  The User Agent Server
16086           * > (UAS) matches the to-tag and from-tag parameters as if they were tags
16087           * > present in an incoming request.  In other words, the to-tag parameter
16088           * > is compared to the local tag, and the from-tag parameter is compared
16089           * > to the remote tag.
16090           *
16091           * Thus, the totag is always compared to the local tag, regardless if
16092           * this our call is an incoming or outgoing call.
16093           */
16094          frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag);
16095          tomismatch = !!strcmp(totag, sip_pvt_ptr->tag);
16096 
16097                         /* Don't check from if the dialog is not established, due to multi forking the from
16098                          * can change when the call is not answered yet.
16099                          */
16100          if ((frommismatch && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) || tomismatch) {
16101             sip_pvt_unlock(sip_pvt_ptr);
16102             if (frommismatch) {
16103                ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n",
16104                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
16105                     fromtag, sip_pvt_ptr->theirtag);
16106             }
16107             if (tomismatch) {
16108                ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n",
16109                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
16110                     totag, sip_pvt_ptr->tag);
16111             }
16112             return NULL;
16113          }
16114       }
16115       
16116       if (totag)
16117          ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n",
16118                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING",
16119                  sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
16120 
16121       /* deadlock avoidance... */
16122       while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
16123          sip_pvt_unlock(sip_pvt_ptr);
16124          usleep(1);
16125          sip_pvt_lock(sip_pvt_ptr);
16126       }
16127    }
16128    
16129    return sip_pvt_ptr;
16130 }

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

Return protocol string for srv dns query.

Definition at line 3469 of file chan_sip.c.

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

03470 {
03471    switch (t) {
03472    case SIP_TRANSPORT_UDP:
03473       return "udp";
03474    case SIP_TRANSPORT_TLS:
03475    case SIP_TRANSPORT_TCP:
03476       return "tcp";
03477    }
03478 
03479    return "udp";
03480 }

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

Return service string for srv dns query.

Definition at line 3483 of file chan_sip.c.

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

03484 {
03485    switch (t) {
03486    case SIP_TRANSPORT_TCP:
03487    case SIP_TRANSPORT_UDP:
03488       return "sip";
03489    case SIP_TRANSPORT_TLS:
03490       return "sips";
03491    }
03492    return "sip";
03493 }

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

Return transport as string.

Definition at line 3454 of file chan_sip.c.

Referenced by _sip_show_peer(), ast_sip_ouraddrfor(), build_contact(), get_transport_pvt(), handle_request_do(), parse_moved_contact(), sip_show_settings(), sip_show_tcp(), and transmit_notify_with_mwi().

03455 {
03456    switch (t) {
03457    case SIP_TRANSPORT_UDP:
03458       return "UDP";
03459    case SIP_TRANSPORT_TCP:
03460       return "TCP";
03461    case SIP_TRANSPORT_TLS:
03462       return "TLS";
03463    }
03464 
03465    return "UNKNOWN";
03466 }

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

Return configuration of transports for a device.

Definition at line 3433 of file chan_sip.c.

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

03433                                                                       {
03434    switch (transports) {
03435       case SIP_TRANSPORT_UDP:
03436          return "UDP";
03437       case SIP_TRANSPORT_TCP:
03438          return "TCP";
03439       case SIP_TRANSPORT_TLS:
03440          return "TLS";
03441       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP:
03442          return "TCP,UDP";
03443       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS:
03444          return "TLS,UDP";
03445       case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS:
03446          return "TLS,TCP";
03447       default:
03448          return transports ?
03449             "TLS,TCP,UDP" : "UNKNOWN"; 
03450    }
03451 }

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 3501 of file chan_sip.c.

References get_transport(), and set_socket_transport().

Referenced by __sip_xmit(), and build_via().

03502 {
03503    if (p->outboundproxy && p->outboundproxy->transport) {
03504       set_socket_transport(&p->socket, p->outboundproxy->transport);
03505    }
03506 
03507    return get_transport(p->socket.type);
03508 }

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 3411 of file chan_sip.c.

References ast_strlen_zero().

Referenced by __set_address_from_contact(), and parse_register_contact().

03412 {
03413    int res = 0;
03414 
03415    if (ast_strlen_zero(transport)) {
03416       return res;
03417    }
03418 
03419    if (!strcasecmp(transport, "udp")) {
03420       res |= SIP_TRANSPORT_UDP;
03421    }
03422    if (!strcasecmp(transport, "tcp")) {
03423       res |= SIP_TRANSPORT_TCP;
03424    }
03425    if (!strcasecmp(transport, "tls")) {
03426       res |= SIP_TRANSPORT_TLS;
03427    }
03428 
03429    return res;
03430 }

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 22439 of file chan_sip.c.

References ast_copy_string(), and get_header().

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

22440 {
22441    const char *thetag;
22442 
22443    if (!tagbuf)
22444       return NULL;
22445    tagbuf[0] = '\0';    /* reset the buffer */
22446    thetag = get_header(req, header);
22447    thetag = strcasestr(thetag, ";tag=");
22448    if (thetag) {
22449       thetag += 5;
22450       ast_copy_string(tagbuf, thetag, tagbufsize);
22451       return strsep(&tagbuf, ";");
22452    }
22453    return NULL;
22454 }

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

Definition at line 22456 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_header(), get_in_brackets(), status, transmit_publish(), and transmit_response().

Referenced by handle_request_notify().

22457 {
22458    struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
22459          find_sip_monitor_instance_by_subscription_pvt, pvt);
22460    const char *status = get_body(req, "cc-state", ':');
22461    struct cc_epa_entry *cc_entry;
22462    char *uri;
22463 
22464    if (!monitor_instance) {
22465       transmit_response(pvt, "400 Bad Request", req);
22466       return -1;
22467    }
22468 
22469    if (ast_strlen_zero(status)) {
22470       ao2_ref(monitor_instance, -1);
22471       transmit_response(pvt, "400 Bad Request", req);
22472       return -1;
22473    }
22474 
22475    if (!strcmp(status, "queued")) {
22476       /* We've been told that we're queued. This is the endpoint's way of telling
22477        * us that it has accepted our CC request. We need to alert the core of this
22478        * development
22479        */
22480       ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name);
22481       transmit_response(pvt, "200 OK", req);
22482       ao2_ref(monitor_instance, -1);
22483       return 0;
22484    }
22485 
22486    /* It's open! Yay! */
22487    uri = get_body(req, "cc-URI", ':');
22488    if (ast_strlen_zero(uri)) {
22489       uri = get_in_brackets((char *)get_header(req, "From"));
22490    }
22491 
22492    ast_string_field_set(monitor_instance, notify_uri, uri);
22493    if (monitor_instance->suspension_entry) {
22494       cc_entry = monitor_instance->suspension_entry->instance_data;
22495       if (cc_entry->current_state == CC_CLOSED) {
22496          /* If we've created a suspension entry and the current state is closed, then that means
22497           * we got a notice from the CC core earlier to suspend monitoring, but because this particular
22498           * call leg had not yet notified us that it was ready for recall, it meant that we
22499           * could not yet send a PUBLISH. Now, however, we can.
22500           */
22501          construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body,
22502                sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
22503          transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri);
22504       } else {
22505          ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
22506       }
22507    } else {
22508       ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
22509    }
22510    ao2_ref(monitor_instance, -1);
22511    transmit_response(pvt, "200 OK", req);
22512 
22513    return 0;
22514 }

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

Definition at line 25309 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(), get_header(), LOG_WARNING, ast_cc_agent::private_data, and transmit_response().

Referenced by handle_request_subscribe().

25310 {
25311    const char *uri = REQ_OFFSET_TO_STR(req, rlPart2);
25312    char *param_separator;
25313    struct ast_cc_agent *agent;
25314    struct sip_cc_agent_pvt *agent_pvt;
25315    const char *expires_str = get_header(req, "Expires");
25316    int expires = -1; /* Just need it to be non-zero */
25317 
25318    if (!ast_strlen_zero(expires_str)) {
25319       sscanf(expires_str, "%d", &expires);
25320    }
25321 
25322    if ((param_separator = strchr(uri, ';'))) {
25323       *param_separator = '\0';
25324    }
25325 
25326    p->subscribed = CALL_COMPLETION;
25327 
25328    if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) {
25329       if (!expires) {
25330          /* Typically, if a 0 Expires reaches us and we can't find
25331           * the corresponding agent, it means that the CC transaction
25332           * has completed and so the calling side is just trying to
25333           * clean up its subscription. We'll just respond with a
25334           * 200 OK and be done with it
25335           */
25336          transmit_response(p, "200 OK", req);
25337          return 0;
25338       }
25339       ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri);
25340       transmit_response(p, "404 Not Found", req);
25341       return -1;
25342    }
25343 
25344    agent_pvt = agent->private_data;
25345 
25346    if (!expires) {
25347       /* We got sent a SUBSCRIBE and found an agent. This means that CC
25348        * is being canceled.
25349        */
25350       ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name);
25351       transmit_response(p, "200 OK", req);
25352       ao2_ref(agent, -1);
25353       return 0;
25354    }
25355 
25356    agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog");
25357    ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE",
25358          agent->device_name);
25359 
25360    /* We don't send a response here. That is done in the agent's ack callback or in the
25361     * agent destructor, should a failure occur before we have responded
25362     */
25363    ao2_ref(agent, -1);
25364    return 0;
25365 }

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 two struct ast_flags
mask array of two 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 27584 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(), ast_variable::value, and word.

Referenced by build_peer(), and reload_config().

27585 {
27586    int res = 1;
27587 
27588    if (!strcasecmp(v->name, "trustrpid")) {
27589       ast_set_flag(&mask[0], SIP_TRUSTRPID);
27590       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
27591    } else if (!strcasecmp(v->name, "sendrpid")) {
27592       ast_set_flag(&mask[0], SIP_SENDRPID);
27593       if (!strcasecmp(v->value, "pai")) {
27594          ast_set_flag(&flags[0], SIP_SENDRPID_PAI);
27595       } else if (!strcasecmp(v->value, "rpid")) {
27596          ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
27597       } else if (ast_true(v->value)) {
27598          ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
27599       }
27600    } else if (!strcasecmp(v->name, "rpid_update")) {
27601       ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE);
27602       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE);
27603    } else if (!strcasecmp(v->name, "rpid_immediate")) {
27604       ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE);
27605       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE);
27606    } else if (!strcasecmp(v->name, "trust_id_outbound")) {
27607       ast_set_flag(&mask[1], SIP_PAGE2_TRUST_ID_OUTBOUND);
27608       ast_clear_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND);
27609       if (!strcasecmp(v->value, "legacy")) {
27610          ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY);
27611       } else if (ast_true(v->value)) {
27612          ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_YES);
27613       } else if (ast_false(v->value)) {
27614          ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_NO);
27615       } else {
27616          ast_log(LOG_WARNING, "Unknown trust_id_outbound mode '%s' on line %d, using legacy\n", v->value, v->lineno);
27617          ast_set_flag(&flags[1], SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY);
27618       }
27619    } else if (!strcasecmp(v->name, "g726nonstandard")) {
27620       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
27621       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
27622    } else if (!strcasecmp(v->name, "useclientcode")) {
27623       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
27624       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
27625    } else if (!strcasecmp(v->name, "dtmfmode")) {
27626       ast_set_flag(&mask[0], SIP_DTMF);
27627       ast_clear_flag(&flags[0], SIP_DTMF);
27628       if (!strcasecmp(v->value, "inband"))
27629          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
27630       else if (!strcasecmp(v->value, "rfc2833"))
27631          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
27632       else if (!strcasecmp(v->value, "info"))
27633          ast_set_flag(&flags[0], SIP_DTMF_INFO);
27634       else if (!strcasecmp(v->value, "shortinfo"))
27635          ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO);
27636       else if (!strcasecmp(v->value, "auto"))
27637          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
27638       else {
27639          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
27640          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
27641       }
27642    } else if (!strcasecmp(v->name, "nat")) {
27643       ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT);
27644       ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP);
27645       if (!strcasecmp(v->value, "yes")) {
27646          ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT);
27647          ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP);
27648       } else if (!strcasecmp(v->value, "force_rport")) {
27649          ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT);
27650       } else if (!strcasecmp(v->value, "comedia")) {
27651          ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP);
27652       }
27653    } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
27654       ast_set_flag(&mask[0], SIP_REINVITE);
27655       ast_clear_flag(&flags[0], SIP_REINVITE);
27656       if (ast_true(v->value)) {
27657          ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT);
27658       } else if (!ast_false(v->value)) {
27659          char buf[64];
27660          char *word, *next = buf;
27661 
27662          ast_copy_string(buf, v->value, sizeof(buf));
27663          while ((word = strsep(&next, ","))) {
27664             if (!strcasecmp(word, "update")) {
27665                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA);
27666             } else if (!strcasecmp(word, "nonat")) {
27667                ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
27668                ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT);
27669             } else if (!strcasecmp(word, "outgoing")) {
27670                ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
27671                ast_set_flag(&mask[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING);
27672                ast_set_flag(&flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING);
27673             } else {
27674                ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno);
27675             }
27676          }
27677       }
27678    } else if (!strcasecmp(v->name, "insecure")) {
27679       ast_set_flag(&mask[0], SIP_INSECURE);
27680       ast_clear_flag(&flags[0], SIP_INSECURE);
27681       set_insecure_flags(&flags[0], v->value, v->lineno);   
27682    } else if (!strcasecmp(v->name, "progressinband")) {
27683       ast_set_flag(&mask[0], SIP_PROG_INBAND);
27684       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
27685       if (ast_true(v->value))
27686          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
27687       else if (strcasecmp(v->value, "never"))
27688          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
27689    } else if (!strcasecmp(v->name, "promiscredir")) {
27690       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
27691       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
27692    } else if (!strcasecmp(v->name, "videosupport")) {
27693       if (!strcasecmp(v->value, "always")) {
27694          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
27695          ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
27696       } else {
27697          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
27698          ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
27699       }
27700    } else if (!strcasecmp(v->name, "textsupport")) {
27701       ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT);
27702       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT);
27703       res = 1;
27704    } else if (!strcasecmp(v->name, "allowoverlap")) {
27705       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
27706       ast_clear_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP);
27707       if (ast_true(v->value)) {
27708          ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_YES);
27709       } else if (!strcasecmp(v->value, "dtmf")){
27710          ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_DTMF);
27711       }
27712    } else if (!strcasecmp(v->name, "allowsubscribe")) {
27713       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
27714       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
27715    } else if (!strcasecmp(v->name, "ignoresdpversion")) {
27716       ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION);
27717       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION);
27718    } else if (!strcasecmp(v->name, "faxdetect")) {
27719       ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT);
27720       if (ast_true(v->value)) {
27721          ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH);
27722       } else if (ast_false(v->value)) {
27723          ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH);
27724       } else {
27725          char *buf = ast_strdupa(v->value);
27726          char *word, *next = buf;
27727 
27728          while ((word = strsep(&next, ","))) {
27729             if (!strcasecmp(word, "cng")) {
27730                ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG);
27731             } else if (!strcasecmp(word, "t38")) {
27732                ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38);
27733             } else {
27734                ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
27735             }
27736          }
27737       }
27738    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
27739       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
27740       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
27741    } else if (!strcasecmp(v->name, "buggymwi")) {
27742       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
27743       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
27744    } else
27745       res = 0;
27746 
27747    return res;
27748 }

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 25821 of file chan_sip.c.

References __get_header(), __sip_ack(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, AST_CONTROL_SRCCHANGE, ast_debug, ast_log(), ast_queue_control(), ast_random(), ast_skip_blanks(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_pendings(), extract_uri(), find_sdp(), get_header(), 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_methods, sip_pvt_lock, sip_pvt_unlock, 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().

25822 {
25823    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
25824       relatively static */
25825    const char *cmd;
25826    const char *cseq;
25827    const char *useragent;
25828    const char *via;
25829    const char *callid;
25830    int via_pos = 0;
25831    uint32_t seqno;
25832    int len;
25833    int respid;
25834    int res = 0;
25835    int debug = sip_debug_test_pvt(p);
25836    const char *e;
25837    int error = 0;
25838    int oldmethod = p->method;
25839    int acked = 0;
25840 
25841    /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via.
25842     * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request,
25843     * so we can check to make sure these fields exist for all requests and responses */
25844    cseq = get_header(req, "Cseq");
25845    cmd = REQ_OFFSET_TO_STR(req, header[0]);
25846    /* Save the via_pos so we can check later that responses only have 1 Via header */
25847    via = __get_header(req, "Via", &via_pos);
25848    /* This must exist already because we've called find_call by now */
25849    callid = get_header(req, "Call-ID");
25850 
25851    /* Must have Cseq */
25852    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) {
25853       ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid);
25854       error = 1;
25855    }
25856    if (!error && sscanf(cseq, "%30u%n", &seqno, &len) != 1) {
25857       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
25858       error = 1;
25859    }
25860    if (error) {
25861       if (!p->initreq.headers) { /* New call */
25862          pvt_set_needdestroy(p, "no headers");
25863       }
25864       return -1;
25865    }
25866    /* Get the command XXX */
25867 
25868    cmd = REQ_OFFSET_TO_STR(req, rlPart1);
25869    e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2));
25870 
25871    /* Save useragent of the client */
25872    useragent = get_header(req, "User-Agent");
25873    if (!ast_strlen_zero(useragent))
25874       ast_string_field_set(p, useragent, useragent);
25875 
25876    /* Find out SIP method for incoming request */
25877    if (req->method == SIP_RESPONSE) {  /* Response to our request */
25878       /* ignore means "don't do anything with it" but still have to
25879        * respond appropriately.
25880        * But in this case this is a response already, so we really
25881        * have nothing to do with this message, and even setting the
25882        * ignore flag is pointless.
25883        */
25884       if (ast_strlen_zero(e)) {
25885          return 0;
25886       }
25887       if (sscanf(e, "%30d %n", &respid, &len) != 1) {
25888          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
25889          return 0;
25890       }
25891       if (respid <= 0) {
25892          ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
25893          return 0;
25894       }
25895       /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse
25896        * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple
25897        * headers joined with a comma. Fixing that would pretty much involve writing a new parser */
25898       if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) {
25899          ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid);
25900          return 0;
25901       }
25902       if (p->ocseq && (p->ocseq < seqno)) {
25903          ast_debug(1, "Ignoring out of order response %u (expecting %u)\n", seqno, p->ocseq);
25904          return -1;
25905       } else {
25906          char causevar[256], causeval[256];
25907 
25908          if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
25909             extract_uri(p, req);
25910          }
25911 
25912          handle_response(p, respid, e + len, req, seqno);
25913 
25914          if (global_store_sip_cause && p->owner) {
25915             struct ast_channel *owner = p->owner;
25916 
25917             snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
25918             snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
25919 
25920             ast_channel_ref(owner);
25921             sip_pvt_unlock(p);
25922             ast_channel_unlock(owner);
25923             *nounlock = 1;
25924             pbx_builtin_setvar_helper(owner, causevar, causeval);
25925             ast_channel_unref(owner);
25926             sip_pvt_lock(p);
25927          }
25928       }
25929       return 0;
25930    }
25931 
25932    /* New SIP request coming in
25933       (could be new request in existing SIP dialog as well...)
25934     */         
25935    
25936    p->method = req->method;   /* Find out which SIP method they are using */
25937    ast_debug(4, "**** Received %s (%u) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd);
25938 
25939    if (p->icseq && (p->icseq > seqno) ) {
25940       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
25941          ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n");
25942       } else {
25943          ast_debug(1, "Ignoring too old SIP packet packet %u (expecting >= %u)\n", seqno, p->icseq);
25944          if (req->method == SIP_INVITE) {
25945             unsigned int ran = (ast_random() % 10) + 1;
25946             char seconds[4];
25947             snprintf(seconds, sizeof(seconds), "%u", ran);
25948             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 */
25949          } else if (req->method != SIP_ACK) {
25950             transmit_response(p, "500 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
25951          }
25952          return -1;
25953       }
25954    } else if (p->icseq &&
25955          p->icseq == seqno &&
25956          req->method != SIP_ACK &&
25957          (p->method != SIP_CANCEL || p->alreadygone)) {
25958       /* ignore means "don't do anything with it" but still have to
25959          respond appropriately.  We do this if we receive a repeat of
25960          the last sequence number  */
25961       req->ignore = 1;
25962       ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %u, ours %u)\n", sip_methods[p->method].text, p->icseq, seqno);
25963    }
25964 
25965    /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has
25966     * already given a final response." */
25967    if (!p->pendinginvite && (req->method == SIP_CANCEL)) {
25968       transmit_response(p, "481 Call/Transaction Does Not Exist", req);
25969       return res;
25970    }
25971 
25972    if (seqno >= p->icseq)
25973       /* Next should follow monotonically (but not necessarily
25974          incrementally -- thanks again to the genius authors of SIP --
25975          increasing */
25976       p->icseq = seqno;
25977 
25978    /* Find their tag if we haven't got it */
25979    if (ast_strlen_zero(p->theirtag)) {
25980       char tag[128];
25981 
25982       gettag(req, "From", tag, sizeof(tag));
25983       ast_string_field_set(p, theirtag, tag);
25984    }
25985    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
25986 
25987    if (sip_cfg.pedanticsipchecking) {
25988       /* If this is a request packet without a from tag, it's not
25989          correct according to RFC 3261  */
25990       /* Check if this a new request in a new dialog with a totag already attached to it,
25991          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
25992       if (!p->initreq.headers && req->has_to_tag) {
25993          /* If this is a first request and it got a to-tag, it is not for us */
25994          if (!req->ignore && req->method == SIP_INVITE) {
25995             /* Just because we think this is a dialog-starting INVITE with a to-tag
25996              * doesn't mean it actually is. It could be a reinvite for an established, but
25997              * unknown dialog. In such a case, we need to change our tag to the
25998              * incoming INVITE's to-tag so that they will recognize the 481 we send and
25999              * so that we will properly match their incoming ACK.
26000              */
26001             char totag[128];
26002             gettag(req, "To", totag, sizeof(totag));
26003             ast_string_field_set(p, tag, totag);
26004             p->pendinginvite = p->icseq;
26005             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
26006             /* Will cease to exist after ACK */
26007             return res;
26008          } else if (req->method != SIP_ACK) {
26009             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
26010             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
26011             return res;
26012          }
26013          /* Otherwise, this is an ACK. It will always have a to-tag */
26014       }
26015    }
26016 
26017    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) {
26018       transmit_response(p, "400 Bad request", req);
26019       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
26020       return -1;
26021    }
26022 
26023    /* Handle various incoming SIP methods in requests */
26024    switch (p->method) {
26025    case SIP_OPTIONS:
26026       res = handle_request_options(p, req, addr, e);
26027       break;
26028    case SIP_INVITE:
26029       res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock);
26030       break;
26031    case SIP_REFER:
26032       res = handle_request_refer(p, req, debug, seqno, nounlock);
26033       break;
26034    case SIP_CANCEL:
26035       res = handle_request_cancel(p, req);
26036       break;
26037    case SIP_BYE:
26038       res = handle_request_bye(p, req);
26039       break;
26040    case SIP_MESSAGE:
26041       res = handle_request_message(p, req);
26042       break;
26043    case SIP_PUBLISH:
26044       res = handle_request_publish(p, req, addr, seqno, e);
26045       break;
26046    case SIP_SUBSCRIBE:
26047       res = handle_request_subscribe(p, req, addr, seqno, e);
26048       break;
26049    case SIP_REGISTER:
26050       res = handle_request_register(p, req, addr, e);
26051       break;
26052    case SIP_INFO:
26053       if (req->debug)
26054          ast_verbose("Receiving INFO!\n");
26055       if (!req->ignore)
26056          handle_request_info(p, req);
26057       else  /* if ignoring, transmit response */
26058          transmit_response(p, "200 OK", req);
26059       break;
26060    case SIP_NOTIFY:
26061       res = handle_request_notify(p, req, addr, seqno, e);
26062       break;
26063    case SIP_UPDATE:
26064       res = handle_request_update(p, req);
26065       break;
26066    case SIP_ACK:
26067       /* Make sure we don't ignore this */
26068       if (seqno == p->pendinginvite) {
26069          p->invitestate = INV_TERMINATED;
26070          p->pendinginvite = 0;
26071          acked = __sip_ack(p, seqno, 1 /* response */, 0);
26072          if (p->owner && find_sdp(req)) {
26073             if (process_sdp(p, req, SDP_T38_NONE)) {
26074                return -1;
26075             }
26076             if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
26077                ast_queue_control(p->owner, AST_CONTROL_SRCCHANGE);
26078             }
26079          }
26080          check_pendings(p);
26081       } else if (p->glareinvite == seqno) {
26082          /* handle ack for the 491 pending sent for glareinvite */
26083          p->glareinvite = 0;
26084          acked = __sip_ack(p, seqno, 1, 0);
26085       }
26086       if (!acked) {
26087          /* Got an ACK that did not match anything. Ignore
26088           * silently and restore previous method */
26089          p->method = oldmethod;
26090       }
26091       if (!p->lastinvite && ast_strlen_zero(p->randdata)) {
26092          pvt_set_needdestroy(p, "unmatched ACK");
26093       }
26094       break;
26095    default:
26096       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
26097       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n",
26098          cmd, ast_sockaddr_stringify(&p->sa));
26099       /* If this is some new method, and we don't have a call, destroy it now */
26100       if (!p->initreq.headers) {
26101          pvt_set_needdestroy(p, "unimplemented method");
26102       }
26103       break;
26104    }
26105    return res;
26106 }

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 22769 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, AST_CEL_ANSWER, AST_CEL_PICKUP, ast_cel_report_event(), ast_channel_lock, ast_channel_masquerade(), 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_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().

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

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

Handle incoming BYE request.

Definition at line 24620 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_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_SCHED_DEL_UNREF, ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), ast_channel::context, context, copy_request(), get_also_info(), get_header(), LOG_NOTICE, LOG_WARNING, parse_sip_options(), pbx_builtin_setvar_helper(), quality, sip_alreadygone(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_queue_hangup_cause(), 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().

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

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

Handle incoming CANCEL request.

Definition at line 24552 of file chan_sip.c.

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

Referenced by handle_incoming().

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

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 26158 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_buffer(), ast_str_reset(), ast_str_strlen(), ast_update_use_count(), ast_verbose, copy_socket_data(), find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), lws2sws(), parse_request(), sip_cfg, sip_debug_test_addr(), sip_pvt_lock_full(), and sip_pvt_unlock.

Referenced by _sip_tcp_helper_thread(), and sipsock_read().

26159 {
26160    struct sip_pvt *p;
26161    struct ast_channel *owner_chan_ref = NULL;
26162    int recount = 0;
26163    int nounlock = 0;
26164 
26165    if (sip_debug_test_addr(addr))   /* Set the debug flag early on packet level */
26166       req->debug = 1;
26167    if (sip_cfg.pedanticsipchecking)
26168       lws2sws(req->data);  /* Fix multiline headers */
26169    if (req->debug) {
26170       ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n",
26171          get_transport(req->socket.type), ast_sockaddr_stringify(addr), ast_str_buffer(req->data));
26172    }
26173 
26174    if (parse_request(req) == -1) { /* Bad packet, can't parse */
26175       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
26176       return 1;
26177    }
26178    req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1));
26179 
26180    if (req->debug)
26181       ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : "");
26182 
26183    if (req->headers < 2) { /* Must have at least two headers */
26184       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
26185       return 1;
26186    }
26187 
26188    /* Process request, with netlock held, and with usual deadlock avoidance */
26189    ast_mutex_lock(&netlock);
26190 
26191    /* Find the active SIP dialog or create a new one */
26192    p = find_call(req, addr, req->method); /* returns p with a reference only. _NOT_ locked*/
26193    if (p == NULL) {
26194       ast_debug(1, "Invalid SIP message - rejected , no callid, len %zu\n", ast_str_strlen(req->data));
26195       ast_mutex_unlock(&netlock);
26196       return 1;
26197    }
26198 
26199    /* Lock both the pvt and the owner if owner is present.  This will
26200     * not fail. */
26201    owner_chan_ref = sip_pvt_lock_full(p);
26202 
26203    copy_socket_data(&p->socket, &req->socket);
26204 
26205    ast_sockaddr_copy(&p->recv, addr);
26206 
26207    /* if we have an owner, then this request has been authenticated */
26208    if (p->owner) {
26209       req->authenticated = 1;
26210    }
26211 
26212    if (p->do_history) /* This is a request or response, note what it was for */
26213       append_history(p, "Rx", "%s / %s / %s", ast_str_buffer(req->data), get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2));
26214 
26215    if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) {
26216       /* Request failed */
26217       ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
26218    }
26219 
26220    if (recount) {
26221       ast_update_use_count();
26222    }
26223 
26224    if (p->owner && !nounlock) {
26225       ast_channel_unlock(p->owner);
26226    }
26227    if (owner_chan_ref) {
26228       ast_channel_unref(owner_chan_ref);
26229    }
26230    sip_pvt_unlock(p);
26231    ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
26232    ast_mutex_unlock(&netlock);
26233 
26234    return 1;
26235 }

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

Receive SIP INFO Message.

Definition at line 19439 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_header(), get_msg_text(), ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, sip_scheddestroy(), ast_frame::subclass, and transmit_response().

Referenced by handle_incoming().

19440 {
19441    char buf[1024] = "";
19442    unsigned int event;
19443    const char *c = get_header(req, "Content-Type");
19444 
19445    /* Need to check the media/type */
19446    if (!strcasecmp(c, "application/dtmf-relay") ||
19447        !strcasecmp(c, "application/vnd.nortelnetworks.digits") ||
19448        !strcasecmp(c, "application/dtmf")) {
19449       unsigned int duration = 0;
19450 
19451       if (!p->owner) {  /* not a PBX call */
19452          transmit_response(p, "481 Call leg/transaction does not exist", req);
19453          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19454          return;
19455       }
19456 
19457       /* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration;
19458        * otherwise use the body as the signal */
19459       if (strcasecmp(c, "application/dtmf")) {
19460          const char *msg_body;
19461 
19462          if (   ast_strlen_zero(msg_body = get_body(req, "Signal", '='))
19463             && ast_strlen_zero(msg_body = get_body(req, "d", '='))) {
19464             ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on "
19465                   "call %s\n", p->callid);
19466             transmit_response(p, "200 OK", req);
19467             return;
19468          }
19469          ast_copy_string(buf, msg_body, sizeof(buf));
19470 
19471          if (!ast_strlen_zero((msg_body = get_body(req, "Duration", '=')))) {
19472             sscanf(msg_body, "%30u", &duration);
19473          }
19474       } else {
19475          /* Type is application/dtmf, simply use what's in the message body */
19476          get_msg_text(buf, sizeof(buf), req);
19477       }
19478 
19479       /* An empty message body requires us to send a 200 OK */
19480       if (ast_strlen_zero(buf)) {
19481          transmit_response(p, "200 OK", req);
19482          return;
19483       }
19484 
19485       if (!duration) {
19486          duration = 100; /* 100 ms */
19487       }
19488 
19489       if (buf[0] == '*') {
19490          event = 10;
19491       } else if (buf[0] == '#') {
19492          event = 11;
19493       } else if (buf[0] == '!') {
19494          event = 16;
19495       } else if ('A' <= buf[0] && buf[0] <= 'D') {
19496          event = 12 + buf[0] - 'A';
19497       } else if ('a' <= buf[0] && buf[0] <= 'd') {
19498          event = 12 + buf[0] - 'a';
19499       } else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) {
19500          ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid "
19501                "value for INFO message on call %s\n", p->callid);
19502          transmit_response(p, "200 OK", req);
19503          return;
19504       }
19505 
19506       if (event == 16) {
19507          /* send a FLASH event */
19508          struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
19509          ast_queue_frame(p->owner, &f);
19510          if (sipdebug) {
19511             ast_verbose("* DTMF-relay event received: FLASH\n");
19512          }
19513       } else {
19514          /* send a DTMF event */
19515          struct ast_frame f = { AST_FRAME_DTMF, };
19516          if (event < 10) {
19517             f.subclass.integer = '0' + event;
19518          } else if (event == 10) {
19519             f.subclass.integer = '*';
19520          } else if (event == 11) {
19521             f.subclass.integer = '#';
19522          } else {
19523             f.subclass.integer = 'A' + (event - 12);
19524          }
19525          f.len = duration;
19526          ast_queue_frame(p->owner, &f);
19527          if (sipdebug) {
19528             ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
19529          }
19530       }
19531       transmit_response(p, "200 OK", req);
19532       return;
19533    } else if (!strcasecmp(c, "application/media_control+xml")) {
19534       /* Eh, we'll just assume it's a fast picture update for now */
19535       if (p->owner)
19536          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
19537       transmit_response(p, "200 OK", req);
19538       return;
19539    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
19540       /* Client code (from SNOM phone) */
19541       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
19542          if (p->owner && p->owner->cdr)
19543             ast_cdr_setuserfield(p->owner, c);
19544          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
19545             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
19546          transmit_response(p, "200 OK", req);
19547       } else {
19548          transmit_response(p, "403 Forbidden", req);
19549       }
19550       return;
19551    } else if (!ast_strlen_zero(c = get_header(req, "Record"))) {
19552       /* INFO messages generated by some phones to start/stop recording
19553          on phone calls.
19554          OEJ: I think this should be something that is enabled/disabled
19555          per device. I don't want incoming callers to record calls in my
19556          pbx.
19557       */
19558       
19559       struct ast_call_feature *feat;
19560       int j;
19561       struct ast_frame f = { AST_FRAME_DTMF, };
19562 
19563       if (!p->owner) {        /* not a PBX call */
19564          transmit_response(p, "481 Call leg/transaction does not exist", req);
19565          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19566          return;
19567       }
19568 
19569       /* first, get the feature string, if it exists */
19570       ast_rdlock_call_features();
19571       feat = ast_find_call_feature("automon");
19572       if (!feat || ast_strlen_zero(feat->exten)) {
19573          ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
19574          /* 403 means that we don't support this feature, so don't request it again */
19575          transmit_response(p, "403 Forbidden", req);
19576          ast_unlock_call_features();
19577          return;
19578       }
19579       /* Send the feature code to the PBX as DTMF, just like the handset had sent it */
19580       f.len = 100;
19581       for (j=0; j < strlen(feat->exten); j++) {
19582          f.subclass.integer = feat->exten[j];
19583          ast_queue_frame(p->owner, &f);
19584          if (sipdebug)
19585             ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer);
19586       }
19587       ast_unlock_call_features();
19588 
19589       ast_debug(1, "Got a Request to Record the channel, state %s\n", c);
19590       transmit_response(p, "200 OK", req);
19591       return;
19592    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
19593       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
19594       transmit_response(p, "200 OK", req);
19595       return;
19596    }
19597 
19598    /* Other type of INFO message, not really understood by Asterisk */
19599    /* if (get_msg_text(buf, sizeof(buf), req)) { */
19600 
19601    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
19602    transmit_response(p, "415 Unsupported media type", req);
19603    return;
19604 }

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 23135 of file chan_sip.c.

References __get_header(), __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_FAILURE, ast_cc_agent_set_interfaces_chanvar(), 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_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_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_header(), get_ip_and_port_from_sdp(), get_rpid(), get_sip_pvt_byid_locked(), handle_invite_replaces(), handle_request_invite_st(), ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, 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_ok_contact(), parse_sip_options(), ast_party_name::presentation, ast_party_number::presentation, process_sdp(), ref_peer(), restart_session_timer(), S_OR, set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_new(), sip_pickup(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_t38_abort(), sip_uri_cmp(), ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, cfsip_methods::text, transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, unref_peer(), update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_incoming().

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

static int handle_request_invite_st ( struct sip_pvt *  p,
struct sip_request *  req,
const char *  required,
int  reinvite 
) [static]

Definition at line 22995 of file chan_sip.c.

References ast_debug, ast_log(), ast_strlen_zero(), FALSE, get_header(), LOG_ERROR, LOG_WARNING, MAX, parse_minse(), parse_session_expires(), sip_st_alloc(), st_get_mode(), st_get_refresher(), st_get_se(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_unsupported(), and TRUE.

Referenced by handle_request_invite().

22997 {
22998    const char *p_uac_se_hdr;       /* UAC's Session-Expires header string                      */
22999    const char *p_uac_min_se;       /* UAC's requested Min-SE interval (char string)            */
23000    int uac_max_se = -1;            /* UAC's Session-Expires in integer format                  */
23001    int uac_min_se = -1;            /* UAC's Min-SE in integer format                           */
23002    int st_active = FALSE;          /* Session-Timer on/off boolean                             */
23003    int st_interval = 0;            /* Session-Timer negotiated refresh interval                */
23004    enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; /* Session-Timer refresher     */
23005    int dlg_min_se = -1;
23006    int dlg_max_se = global_max_se;
23007    int rtn;
23008 
23009    /* Session-Timers */
23010    if ((p->sipoptions & SIP_OPT_TIMER)) {
23011       enum st_refresher_param st_ref_param = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN;
23012 
23013       /* The UAC has requested session-timers for this session. Negotiate
23014       the session refresh interval and who will be the refresher */
23015       ast_debug(2, "Incoming INVITE with 'timer' option supported\n");
23016 
23017       /* Allocate Session-Timers struct w/in the dialog */
23018       if (!p->stimer) {
23019          sip_st_alloc(p);
23020       }
23021 
23022       /* Parse the Session-Expires header */
23023       p_uac_se_hdr = get_header(req, "Session-Expires");
23024       if (!ast_strlen_zero(p_uac_se_hdr)) {
23025          ast_debug(2, "INVITE also has \"Session-Expires\" header.\n");
23026          rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref_param);
23027          tmp_st_ref = (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
23028          if (rtn != 0) {
23029             transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
23030             return -1;
23031          }
23032       }
23033 
23034       /* Parse the Min-SE header */
23035       p_uac_min_se = get_header(req, "Min-SE");
23036       if (!ast_strlen_zero(p_uac_min_se)) {
23037          ast_debug(2, "INVITE also has \"Min-SE\" header.\n");
23038          rtn = parse_minse(p_uac_min_se, &uac_min_se);
23039          if (rtn != 0) {
23040             transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req);
23041             return -1;
23042          }
23043       }
23044 
23045       dlg_min_se = st_get_se(p, FALSE);
23046       switch (st_get_mode(p, 1)) {
23047       case SESSION_TIMER_MODE_ACCEPT:
23048       case SESSION_TIMER_MODE_ORIGINATE:
23049          if (uac_max_se > 0 && uac_max_se < dlg_min_se) {
23050             transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se);
23051             return -1;
23052          }
23053 
23054          p->stimer->st_active_peer_ua = TRUE;
23055          st_active = TRUE;
23056          if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UNKNOWN) {
23057             tmp_st_ref = st_get_refresher(p);
23058          }
23059 
23060          dlg_max_se = st_get_se(p, TRUE);
23061          if (uac_max_se > 0) {
23062             if (dlg_max_se >= uac_min_se) {
23063                st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se;
23064             } else {
23065                st_interval = uac_max_se;
23066             }
23067          } else if (uac_min_se > 0) {
23068             st_interval = MAX(dlg_max_se, uac_min_se);
23069          } else {
23070             st_interval = dlg_max_se;
23071          }
23072          break;
23073 
23074       case SESSION_TIMER_MODE_REFUSE:
23075          if (p->reqsipoptions & SIP_OPT_TIMER) {
23076             transmit_response_with_unsupported(p, "420 Option Disabled", req, required);
23077             ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required);
23078             return -1;
23079          }
23080          break;
23081 
23082       default:
23083          ast_log(LOG_ERROR, "Internal Error %u at %s:%d\n", st_get_mode(p, 1), __FILE__, __LINE__);
23084          break;
23085       }
23086    } else {
23087       /* The UAC did not request session-timers.  Asterisk (UAS), will now decide
23088       (based on session-timer-mode in sip.conf) whether to run session-timers for
23089       this session or not. */
23090       switch (st_get_mode(p, 1)) {
23091       case SESSION_TIMER_MODE_ORIGINATE:
23092          st_active = TRUE;
23093          st_interval = st_get_se(p, TRUE);
23094          tmp_st_ref = SESSION_TIMER_REFRESHER_US;
23095          p->stimer->st_active_peer_ua = (p->sipoptions & SIP_OPT_TIMER) ? TRUE : FALSE;
23096          break;
23097 
23098       default:
23099          break;
23100       }
23101    }
23102 
23103    if (reinvite == 0) {
23104       /* Session-Timers: Start session refresh timer based on negotiation/config */
23105       if (st_active == TRUE) {
23106          p->stimer->st_active = TRUE;
23107          p->stimer->st_interval = st_interval;
23108          p->stimer->st_ref = tmp_st_ref;
23109       }
23110    } else {
23111       if (p->stimer->st_active == TRUE) {
23112          /* Session-Timers:  A re-invite request sent within a dialog will serve as
23113          a refresh request, no matter whether the re-invite was sent for refreshing
23114          the session or modifying it.*/
23115          ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid);
23116 
23117          /* The UAC may be adjusting the session-timers mid-session */
23118          if (st_interval > 0) {
23119             p->stimer->st_interval = st_interval;
23120             p->stimer->st_ref      = tmp_st_ref;
23121          }
23122       }
23123    }
23124 
23125    return 0;
23126 }

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

Handle incoming MESSAGE request.

Definition at line 24774 of file chan_sip.c.

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

Referenced by handle_incoming().

24775 {
24776    if (!req->ignore) {
24777       if (req->debug)
24778          ast_verbose("Receiving message!\n");
24779       receive_message(p, req);
24780    } else
24781       transmit_response(p, "202 Accepted", req);
24782    return 1;
24783 }

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 22517 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, find_peer(), get_body(), get_header(), get_msg_text(), handle_cc_notify(), LOG_NOTICE, LOG_WARNING, mailbox, sip_scheddestroy(), transmit_response(), TRUE, and unref_peer().

Referenced by handle_incoming().

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

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 22694 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(), get_header(), LOG_NOTICE, set_pvt_allowed_methods(), sip_cfg, sip_scheddestroy(), transmit_response(), and transmit_response_with_allow().

Referenced by handle_incoming().

22695 {
22696    const char *msg;
22697    enum sip_get_dest_result gotdest;
22698    int res;
22699 
22700    if (p->lastinvite) {
22701       /* if this is a request in an active dialog, just confirm that the dialog exists. */
22702       transmit_response_with_allow(p, "200 OK", req, 0);
22703       return 0;
22704    }
22705 
22706    if (sip_cfg.auth_options_requests) {
22707       /* Do authentication if this OPTIONS request began the dialog */
22708       copy_request(&p->initreq, req);
22709       set_pvt_allowed_methods(p, req);
22710       res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr);
22711       if (res == AUTH_CHALLENGE_SENT) {
22712          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22713          return 0;
22714       }
22715       if (res < 0) { /* Something failed in authentication */
22716          ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
22717          transmit_response(p, "403 Forbidden", req);
22718          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22719          return 0;
22720       }
22721    }
22722 
22723    /* must go through authentication before getting here */
22724    gotdest = get_destination(p, req, NULL);
22725    build_contact(p);
22726 
22727    if (ast_strlen_zero(p->context))
22728       ast_string_field_set(p, context, sip_cfg.default_context);
22729 
22730    if (ast_shutting_down()) {
22731       msg = "503 Unavailable";
22732    } else {
22733       msg = "404 Not Found";
22734       switch (gotdest) {
22735       case SIP_GET_DEST_INVALID_URI:
22736          msg = "416 Unsupported URI scheme";
22737          break;
22738       case SIP_GET_DEST_EXTEN_MATCHMORE:
22739       case SIP_GET_DEST_REFUSED:
22740       case SIP_GET_DEST_EXTEN_NOT_FOUND:
22741          //msg = "404 Not Found";
22742          break;
22743       case SIP_GET_DEST_EXTEN_FOUND:
22744          msg = "200 OK";
22745          break;
22746       }
22747    }
22748    transmit_response_with_allow(p, msg, req, 0);
22749 
22750    /* Destroy if this OPTIONS was the opening request, but not if
22751       it's in the middle of a normal call flow. */
22752    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22753 
22754    return 0;
22755 }

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 25206 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(), get_header(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), LOG_NOTICE, pvt_set_needdestroy(), sip_scheddestroy(), transmit_response(), and transmit_response_with_minexpires().

Referenced by handle_incoming().

25207 {
25208    const char *etag = get_header(req, "SIP-If-Match");
25209    const char *event = get_header(req, "Event");
25210    struct event_state_compositor *esc;
25211    enum sip_publish_type publish_type;
25212    const char *expires_str = get_header(req, "Expires");
25213    int expires_int;
25214    int auth_result;
25215    int handler_result = -1;
25216 
25217    if (ast_strlen_zero(event)) {
25218       transmit_response(p, "489 Bad Event", req);
25219       pvt_set_needdestroy(p, "missing Event: header");
25220       return -1;
25221    }
25222 
25223    if (!(esc = get_esc(event))) {
25224       transmit_response(p, "489 Bad Event", req);
25225       pvt_set_needdestroy(p, "unknown event package in publish");
25226       return -1;
25227    }
25228 
25229    auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_UNRELIABLE, addr);
25230    if (auth_result == AUTH_CHALLENGE_SENT) {
25231       p->lastinvite = seqno;
25232       return 0;
25233    } else if (auth_result < 0) {
25234       ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
25235       transmit_response(p, "403 Forbidden", req);
25236       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
25237       ast_string_field_set(p, theirtag, NULL);
25238       return 0;
25239    } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) {
25240       /* We need to stop retransmitting the 401 */
25241       __sip_ack(p, p->lastinvite, 1, 0);
25242    }
25243 
25244    publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int);
25245 
25246    if (expires_int > max_expiry) {
25247       expires_int = max_expiry;
25248    } else if (expires_int < min_expiry && expires_int > 0) {
25249       transmit_response_with_minexpires(p, "423 Interval too small", req);
25250       pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
25251       return 0;
25252    }
25253    p->expiry = expires_int;
25254 
25255    /* It is the responsibility of these handlers to formulate any response
25256     * sent for a PUBLISH
25257     */
25258    switch (publish_type) {
25259    case SIP_PUBLISH_UNKNOWN:
25260       transmit_response(p, "400 Bad Request", req);
25261       break;
25262    case SIP_PUBLISH_INITIAL:
25263       handler_result = handle_sip_publish_initial(p, req, esc, expires_int);
25264       break;
25265    case SIP_PUBLISH_REFRESH:
25266       handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int);
25267       break;
25268    case SIP_PUBLISH_MODIFY:
25269       handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int);
25270       break;
25271    case SIP_PUBLISH_REMOVE:
25272       handler_result = handle_sip_publish_remove(p, req, esc, etag);
25273       break;
25274    default:
25275       transmit_response(p, "400 Impossible Condition", req);
25276       break;
25277    }
25278    if (!handler_result && p->expiry > 0) {
25279       sip_scheddestroy(p, (p->expiry + 10) * 1000);
25280    } else {
25281       pvt_set_needdestroy(p, "forcing expiration");
25282    }
25283 
25284    return handler_result;
25285 }

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 24158 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_ref, 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().

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

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 25752 of file chan_sip.c.

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

Referenced by handle_incoming().

25753 {
25754    enum check_auth_result res;
25755 
25756    /* If this is not the intial request, and the initial request isn't
25757     * a register, something screwy happened, so bail */
25758    if (p->initreq.headers && p->initreq.method != SIP_REGISTER) {
25759       ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid);
25760       return -1;
25761    }
25762 
25763    /* Use this as the basis */
25764    copy_request(&p->initreq, req);
25765    if (sipdebug)
25766       ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
25767    check_via(p, req);
25768    if ((res = register_verify(p, addr, req, e)) < 0) {
25769       const char *reason;
25770 
25771       switch (res) {
25772       case AUTH_SECRET_FAILED:
25773          reason = "Wrong password";
25774          break;
25775       case AUTH_USERNAME_MISMATCH:
25776          reason = "Username/auth name mismatch";
25777          break;
25778       case AUTH_NOT_FOUND:
25779          reason = "No matching peer found";
25780          break;
25781       case AUTH_UNKNOWN_DOMAIN:
25782          reason = "Not a local domain";
25783          break;
25784       case AUTH_PEER_NOT_DYNAMIC:
25785          reason = "Peer is not supposed to register";
25786          break;
25787       case AUTH_ACL_FAILED:
25788          reason = "Device does not match ACL";
25789          break;
25790       case AUTH_BAD_TRANSPORT:
25791          reason = "Device not configured to use this transport type";
25792          break;
25793       default:
25794          reason = "Unknown failure";
25795          break;
25796       }
25797       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
25798          get_header(req, "To"), ast_sockaddr_stringify(addr),
25799          reason);
25800       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
25801    } else {
25802       req->authenticated = 1;
25803       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
25804    }
25805 
25806    if (res < 1) {
25807       /* Destroy the session, but keep us around for just a bit in case they don't
25808          get our 200 OK */
25809       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
25810    }
25811    return res;
25812 }

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 25368 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_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(), get_header(), gettag(), handle_cc_subscribe(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), MAX, NONE, option_debug, parse_ok_contact(), pvt_set_needdestroy(), ref_peer(), S_OR, set_pvt_allowed_methods(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_send_mwi_to_peer(), cfsip_methods::text, transmit_response(), transmit_response_with_minexpires(), transmit_state_notify(), and unref_peer().

Referenced by handle_incoming().

25369 {
25370    int gotdest = 0;
25371    int res = 0;
25372    int firststate;
25373    struct sip_peer *authpeer = NULL;
25374    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
25375    int resubscribe = (p->subscribed != NONE) && !req->ignore;
25376    char *event_end;
25377    ptrdiff_t event_len = 0;
25378 
25379    if (p->initreq.headers) {  
25380       /* We already have a dialog */
25381       if (p->initreq.method != SIP_SUBSCRIBE) {
25382          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
25383          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
25384          transmit_response(p, "403 Forbidden (within dialog)", req);
25385          /* Do not destroy session, since we will break the call if we do */
25386          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);
25387          return 0;
25388       } else if (req->debug) {
25389          if (resubscribe)
25390             ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid);
25391          else
25392             ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid);
25393       }
25394    }
25395 
25396    /* Check if we have a global disallow setting on subscriptions.
25397       if so, we don't have to check peer settings after auth, which saves a lot of processing
25398    */
25399    if (!sip_cfg.allowsubscribe) {
25400       transmit_response(p, "403 Forbidden (policy)", req);
25401       pvt_set_needdestroy(p, "forbidden");
25402       return 0;
25403    }
25404 
25405    if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */
25406       const char *to = get_header(req, "To");
25407       char totag[128];
25408       set_pvt_allowed_methods(p, req);
25409 
25410       /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
25411       if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
25412          if (req->debug)
25413             ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
25414          transmit_response(p, "481 Subscription does not exist", req);
25415          pvt_set_needdestroy(p, "subscription does not exist");
25416          return 0;
25417       }
25418 
25419       /* Use this as the basis */
25420       if (req->debug)
25421          ast_verbose("Creating new subscription\n");
25422 
25423       copy_request(&p->initreq, req);
25424       if (sipdebug)
25425          ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
25426       check_via(p, req);
25427       build_route(p, req, 0, 0);
25428    } else if (req->debug && req->ignore)
25429       ast_verbose("Ignoring this SUBSCRIBE request\n");
25430 
25431    /* Find parameters to Event: header value and remove them for now */
25432    if (ast_strlen_zero(eventheader)) {
25433       transmit_response(p, "489 Bad Event", req);
25434       ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n");
25435       pvt_set_needdestroy(p, "unknown event package in subscribe");
25436       return 0;
25437    }
25438 
25439    event_end = strchr(eventheader, ';');
25440    if (event_end) {
25441       event_len = event_end - eventheader;
25442    }
25443 
25444    /* Handle authentication if we're new and not a retransmission. We can't just
25445     * use if !req->ignore, because then we'll end up sending
25446     * a 200 OK if someone retransmits without sending auth */
25447    if (p->subscribed == NONE || resubscribe) {
25448       res = check_user_full(p, req, SIP_SUBSCRIBE, e, XMIT_UNRELIABLE, addr, &authpeer);
25449 
25450       /* if an authentication response was sent, we are done here */
25451       if (res == AUTH_CHALLENGE_SENT)  /* authpeer = NULL here */
25452          return 0;
25453       if (res != AUTH_SUCCESSFUL) {
25454          ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
25455          transmit_response(p, "403 Forbidden", req);
25456 
25457          pvt_set_needdestroy(p, "authentication failed");
25458          return 0;
25459       }
25460    }
25461 
25462    /* At this point, we hold a reference to authpeer (if not NULL).  It
25463     * must be released when done.
25464     */
25465 
25466    /* Check if this device  is allowed to subscribe at all */
25467    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
25468       transmit_response(p, "403 Forbidden (policy)", req);
25469       pvt_set_needdestroy(p, "subscription not allowed");
25470       if (authpeer) {
25471          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)");
25472       }
25473       return 0;
25474    }
25475 
25476    if (strncmp(eventheader, "message-summary", MAX(event_len, 15)) && strncmp(eventheader, "call-completion", MAX(event_len, 15))) {
25477       /* Get destination right away */
25478       gotdest = get_destination(p, NULL, NULL);
25479    }
25480 
25481    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
25482    parse_ok_contact(p, req);
25483 
25484    build_contact(p);
25485    if (gotdest != SIP_GET_DEST_EXTEN_FOUND) {
25486       if (gotdest == SIP_GET_DEST_INVALID_URI) {
25487          transmit_response(p, "416 Unsupported URI scheme", req);
25488       } else {
25489          transmit_response(p, "404 Not Found", req);
25490       }
25491       pvt_set_needdestroy(p, "subscription target not found");
25492       if (authpeer) {
25493          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
25494       }
25495       return 0;
25496    }
25497 
25498    /* Initialize tag for new subscriptions */   
25499    if (ast_strlen_zero(p->tag))
25500       make_our_tag(p);
25501 
25502    if (!strncmp(eventheader, "presence", MAX(event_len, 8)) || !strncmp(eventheader, "dialog", MAX(event_len, 6))) { /* Presence, RFC 3842 */
25503       unsigned int pidf_xml;
25504       const char *accept;
25505       int start = 0;
25506       enum subscriptiontype subscribed = NONE;
25507       const char *unknown_acceptheader = NULL;
25508 
25509       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
25510       accept = __get_header(req, "Accept", &start);
25511       while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
25512          pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0;
25513 
25514          /* Older versions of Polycom firmware will claim pidf+xml, but really
25515           * they only support xpidf+xml. */
25516          if (pidf_xml && strstr(p->useragent, "Polycom")) {
25517             subscribed = XPIDF_XML;
25518          } else if (pidf_xml) {
25519             subscribed = PIDF_XML;         /* RFC 3863 format */
25520          } else if (strstr(accept, "application/dialog-info+xml")) {
25521             subscribed = DIALOG_INFO_XML;
25522             /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
25523          } else if (strstr(accept, "application/cpim-pidf+xml")) {
25524             subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
25525          } else if (strstr(accept, "application/xpidf+xml")) {
25526             subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
25527          } else {
25528             unknown_acceptheader = accept;
25529          }
25530          /* check to see if there is another Accept header present */
25531          accept = __get_header(req, "Accept", &start);
25532       }
25533 
25534       if (!start) {
25535          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
25536             transmit_response(p, "489 Bad Event", req);
25537             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: "
25538                "stateid: %d, laststate: %d, dialogver: %u, subscribecont: "
25539                "'%s', subscribeuri: '%s'\n",
25540                p->stateid,
25541                p->laststate,
25542                p->dialogver,
25543                p->subscribecontext,
25544                p->subscribeuri);
25545             pvt_set_needdestroy(p, "no Accept header");
25546             if (authpeer) {
25547                unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
25548             }
25549             return 0;
25550          }
25551          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
25552             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
25553       } else if (subscribed == NONE) {
25554          /* Can't find a format for events that we know about */
25555          char mybuf[200];
25556          if (!ast_strlen_zero(unknown_acceptheader)) {
25557             snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader);
25558          } else {
25559             snprintf(mybuf, sizeof(mybuf), "489 Bad Event");
25560          }
25561          transmit_response(p, mybuf, req);
25562          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:"
25563             "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d,"
25564             "dialogver: %u, subscribecont: '%s', subscribeuri: '%s'\n",
25565             unknown_acceptheader,
25566             (int)p->subscribed,
25567             p->stateid,
25568             p->laststate,
25569             p->dialogver,
25570             p->subscribecontext,
25571             p->subscribeuri);
25572          pvt_set_needdestroy(p, "unrecognized format");
25573          if (authpeer) {
25574             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
25575          }
25576          return 0;
25577       } else {
25578          p->subscribed = subscribed;
25579       }
25580    } else if (!strncmp(eventheader, "message-summary", MAX(event_len, 15))) {
25581       int start = 0;
25582       int found_supported = 0;
25583       const char *acceptheader;
25584 
25585       acceptheader = __get_header(req, "Accept", &start);
25586       while (!found_supported && !ast_strlen_zero(acceptheader)) {
25587          found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1;
25588          if (!found_supported && (option_debug > 2)) {
25589             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
25590          }
25591          acceptheader = __get_header(req, "Accept", &start);
25592       }
25593       if (start && !found_supported) {
25594          /* Format requested that we do not support */
25595          transmit_response(p, "406 Not Acceptable", req);
25596          ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
25597          pvt_set_needdestroy(p, "unknown format");
25598          if (authpeer) {
25599             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
25600          }
25601          return 0;
25602       }
25603       /* Looks like they actually want a mailbox status
25604         This version of Asterisk supports mailbox subscriptions
25605         The subscribed URI needs to exist in the dial plan
25606         In most devices, this is configurable to the voicemailmain extension you use
25607       */
25608       if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) {
25609          if (!authpeer) {
25610             transmit_response(p, "404 Not found", req);
25611          } else {
25612             transmit_response(p, "404 Not found (no mailbox)", req);
25613             ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, ""));
25614          }
25615          pvt_set_needdestroy(p, "received 404 response");
25616          if (authpeer) {
25617             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
25618          }
25619          return 0;
25620       }
25621 
25622       p->subscribed = MWI_NOTIFICATION;
25623       if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) {
25624          ao2_unlock(p);
25625          add_peer_mwi_subs(authpeer);
25626          ao2_lock(p);
25627       }
25628       if (authpeer->mwipvt != p) {  /* Destroy old PVT if this is a new one */
25629          /* We only allow one subscription per peer */
25630          if (authpeer->mwipvt) {
25631             dialog_unlink_all(authpeer->mwipvt);
25632             authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
25633          }
25634          authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");
25635       }
25636       if (p->relatedpeer != authpeer) {
25637          if (p->relatedpeer) {
25638             unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
25639          }
25640          p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");
25641       }
25642       /* Do not release authpeer here */
25643    } else if (!strncmp(eventheader, "call-completion", MAX(event_len, 15))) {
25644       handle_cc_subscribe(p, req);
25645    } else { /* At this point, Asterisk does not understand the specified event */
25646       transmit_response(p, "489 Bad Event", req);
25647       ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", eventheader);
25648       pvt_set_needdestroy(p, "unknown event package");
25649       if (authpeer) {
25650          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)");
25651       }
25652       return 0;
25653    }
25654 
25655    /* Add subscription for extension state from the PBX core */
25656    if (p->subscribed != MWI_NOTIFICATION  && p->subscribed != CALL_COMPLETION && !resubscribe) {
25657       if (p->stateid != -1) {
25658          ast_extension_state_del(p->stateid, cb_extensionstate);
25659       }
25660       dialog_ref(p, "copying dialog ptr into extension state struct");
25661       p->stateid = ast_extension_state_add_destroy(p->context, p->exten,
25662          cb_extensionstate, cb_extensionstate_destroy, p);
25663       if (p->stateid == -1) {
25664          dialog_unref(p, "copying dialog ptr into extension state struct failed");
25665       }
25666    }
25667 
25668    if (!req->ignore) {
25669       p->lastinvite = seqno;
25670    }
25671    if (!p->needdestroy) {
25672       p->expiry = atoi(get_header(req, "Expires"));
25673 
25674       /* check if the requested expiry-time is within the approved limits from sip.conf */
25675       if (p->expiry > max_expiry) {
25676          p->expiry = max_expiry;
25677       } else if (p->expiry < min_expiry && p->expiry > 0) {
25678          transmit_response_with_minexpires(p, "423 Interval too small", req);
25679          ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" "
25680             "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n",
25681             p->exten, p->context, p->expiry, min_expiry);
25682          pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
25683          if (authpeer) {
25684             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)");
25685          }
25686          return 0;
25687       }
25688 
25689       if (sipdebug) {
25690          const char *action = p->expiry > 0 ? "Adding" : "Removing";
25691          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) {
25692             ast_debug(2, "%s subscription for mailbox notification - peer %s\n",
25693                   action, p->relatedpeer->name);
25694          } else if (p->subscribed == CALL_COMPLETION) {
25695             ast_debug(2, "%s CC subscription for peer %s\n", action, p->username);
25696          } else {
25697             ast_debug(2, "%s subscription for extension %s context %s for peer %s\n",
25698                   action, p->exten, p->context, p->username);
25699          }
25700       }
25701       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
25702          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
25703       if (p->expiry > 0)
25704          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
25705 
25706       if (p->subscribed == MWI_NOTIFICATION) {
25707          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
25708          transmit_response(p, "200 OK", req);
25709          if (p->relatedpeer) {   /* Send first notification */
25710             struct sip_peer *peer = p->relatedpeer;
25711             ref_peer(peer, "ensure a peer ref is held during MWI sending");
25712             ao2_unlock(p);
25713             sip_send_mwi_to_peer(peer, 0);
25714             ao2_lock(p);
25715             unref_peer(peer, "release a peer ref now that MWI is sent");
25716          }
25717       } else if (p->subscribed != CALL_COMPLETION) {
25718          sip_pvt_unlock(p);
25719          firststate = ast_extension_state(NULL, p->context, p->exten);
25720          sip_pvt_lock(p);
25721 
25722          if (firststate < 0) {
25723             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));
25724             transmit_response(p, "404 Not found", req);
25725             pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
25726             if (authpeer) {
25727                unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)");
25728             }
25729             return 0;
25730          }
25731          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
25732          transmit_response(p, "200 OK", req);
25733          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
25734          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
25735          /* hide the 'complete' exten/context in the refer_to field for later display */
25736          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
25737          /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */
25738 
25739       }
25740       if (!p->expiry) {
25741          pvt_set_needdestroy(p, "forcing expiration");
25742       }
25743    }
25744 
25745    if (authpeer) {
25746       unref_peer(authpeer, "unref pointer into (*authpeer)");
25747    }
25748    return 1;
25749 }

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 22954 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_header(), 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, 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().

22955 {
22956    if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) {
22957       transmit_response(p, "501 Method Not Implemented", req);
22958       return 0;
22959    }
22960    if (!p->owner) {
22961       transmit_response(p, "481 Call/Transaction Does Not Exist", req);
22962       return 0;
22963    }
22964    if (get_rpid(p, req)) {
22965       struct ast_party_connected_line connected;
22966       struct ast_set_party_connected_line update_connected;
22967 
22968       ast_party_connected_line_init(&connected);
22969       memset(&update_connected, 0, sizeof(update_connected));
22970 
22971       update_connected.id.number = 1;
22972       connected.id.number.valid = 1;
22973       connected.id.number.str = (char *) p->cid_num;
22974       connected.id.number.presentation = p->callingpres;
22975 
22976       update_connected.id.name = 1;
22977       connected.id.name.valid = 1;
22978       connected.id.name.str = (char *) p->cid_name;
22979       connected.id.name.presentation = p->callingpres;
22980 
22981       connected.id.tag = (char *) p->cid_tag;
22982       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
22983       ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
22984    }
22985    transmit_response(p, "200 OK", req);
22986    return 0;
22987 }

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 21717 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), append_history, AST_CC_CCBS, 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(), get_header(), 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_handle_cc(), sip_methods, stop_media_flows(), text, transmit_request(), TRUE, and update_redirecting().

Referenced by handle_incoming().

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

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 21631 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().

21632 {
21633    int sipmethod = SIP_INFO;
21634 
21635    switch (resp) {
21636    case 401: /* Not www-authorized on SIP method */
21637    case 407: /* Proxy auth required */
21638       ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n",
21639          ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text);
21640       break;
21641    case 405: /* Method not allowed */
21642    case 501: /* Not Implemented */
21643       mark_method_unallowed(&p->allowed_methods, sipmethod);
21644       if (p->relatedpeer) {
21645          mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod);
21646       }
21647       ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n",
21648          ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text);
21649       break;
21650    default:
21651       if (300 <= resp && resp < 700) {
21652          ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n",
21653             sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa));
21654       }
21655       break;
21656    }
21657 }

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 20692 of file chan_sip.c.

References append_history, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), 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_rtp_instance_get_remote_address(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), ast_sockaddr_isnull(), 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_header(), get_rpid(), hangup_sip2cause(), 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_handle_cc(), sip_queue_hangup_cause(), sip_reinvite_retry(), sip_scheddestroy(), ast_party_connected_line::source, st_get_mode(), st_get_se(), 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().

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

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 21667 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().

21668 {
21669    int sipmethod = SIP_MESSAGE;
21670    /* Out-of-dialog MESSAGE currently not supported. */
21671    //int in_dialog = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21672 
21673    switch (resp) {
21674    case 401: /* Not www-authorized on SIP method */
21675    case 407: /* Proxy auth required */
21676       ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n",
21677          ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text);
21678       break;
21679    case 405: /* Method not allowed */
21680    case 501: /* Not Implemented */
21681       mark_method_unallowed(&p->allowed_methods, sipmethod);
21682       if (p->relatedpeer) {
21683          mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod);
21684       }
21685       ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n",
21686          ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text);
21687       break;
21688    default:
21689       if (100 <= resp && resp < 200) {
21690          /* Must allow provisional responses for out-of-dialog requests. */
21691       } else if (200 <= resp && resp < 300) {
21692          p->authtries = 0; /* Reset authentication counter */
21693       } else if (300 <= resp && resp < 700) {
21694          ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n",
21695             sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa));
21696       }
21697       break;
21698    }
21699 }

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 21174 of file chan_sip.c.

References 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(), get_header(), LOG_NOTICE, LOG_WARNING, NONE, and pvt_set_needdestroy().

Referenced by handle_response().

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

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

Handle qualification responses (OPTIONS).

Definition at line 21564 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, 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(), ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().

Referenced by handle_response().

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

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 20606 of file chan_sip.c.

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

Referenced by handle_response().

20607 {
20608    struct sip_epa_entry *epa_entry = p->epa_entry;
20609    const char *etag = get_header(req, "Sip-ETag");
20610 
20611    ast_assert(epa_entry != NULL);
20612 
20613    if (resp == 401 || resp == 407) {
20614       ast_string_field_set(p, theirtag, NULL);
20615       if (p->options) {
20616          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
20617       }
20618       if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) {
20619          ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From"));
20620          pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH");
20621          sip_alreadygone(p);
20622       }
20623       return;
20624    }
20625 
20626    if (resp == 501 || resp == 405) {
20627       mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH);
20628    }
20629 
20630    if (resp == 200) {
20631       p->authtries = 0;
20632       /* If I've read section 6, item 6 of RFC 3903 correctly,
20633        * an ESC will only generate a new etag when it sends a 200 OK
20634        */
20635       if (!ast_strlen_zero(etag)) {
20636          ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag));
20637       }
20638       /* The nominal case. Everything went well. Everybody is happy.
20639        * Each EPA will have a specific action to take as a result of this
20640        * development, so ... callbacks!
20641        */
20642       if (epa_entry->static_data->handle_ok) {
20643          epa_entry->static_data->handle_ok(p, req, epa_entry);
20644       }
20645    } else {
20646       /* Rather than try to make individual callbacks for each error
20647        * type, there is just a single error callback. The callback
20648        * can distinguish between error messages and do what it needs to
20649        */
20650       if (epa_entry->static_data->handle_error) {
20651          epa_entry->static_data->handle_error(p, resp, req, epa_entry);
20652       }
20653    }
20654 }

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 21309 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(), get_header(), LOG_NOTICE, LOG_WARNING, and pvt_set_needdestroy().

Referenced by handle_response().

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

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 21409 of file chan_sip.c.

References __get_header(), ast_debug, ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), do_register_auth(), EVENT_FLAG_SYSTEM, get_header(), 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_reregister(), and transmit_register().

Referenced by handle_response().

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

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 21219 of file chan_sip.c.

References ao2_callback, ao2_ref, 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(), get_header(), LOG_NOTICE, LOG_WARNING, pvt_set_needdestroy(), set_pvt_allowed_methods(), sip_alreadygone(), sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and transmit_response_with_date().

Referenced by handle_response().

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

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 20546 of file chan_sip.c.

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

Referenced by handle_response().

20547 {
20548    if (p->options) {
20549       p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
20550    }
20551    if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) {
20552       ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From"));
20553    }
20554 }

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 25100 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().

25101 {
25102    struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires);
25103    int res = 0;
25104 
25105    if (!esc_entry) {
25106       transmit_response(p, "503 Internal Server Failure", req);
25107       return -1;
25108    }
25109 
25110    if (esc->callbacks->initial_handler) {
25111       res = esc->callbacks->initial_handler(p, req, esc, esc_entry);
25112    }
25113 
25114    if (!res) {
25115       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0);
25116    }
25117 
25118    ao2_ref(esc_entry, -1);
25119    return res;
25120 }

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 25150 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().

25151 {
25152    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
25153    int expires_ms = expires * 1000;
25154    int res = 0;
25155 
25156    if (!esc_entry) {
25157       transmit_response(p, "412 Conditional Request Failed", req);
25158       return -1;
25159    }
25160 
25161    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
25162          ao2_ref(_data, -1),
25163          ao2_ref(esc_entry, -1),
25164          ao2_ref(esc_entry, +1));
25165 
25166    if (esc->callbacks->modify_handler) {
25167       res = esc->callbacks->modify_handler(p, req, esc, esc_entry);
25168    }
25169 
25170    if (!res) {
25171       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
25172    }
25173 
25174    ao2_ref(esc_entry, -1);
25175    return res;
25176 }

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 25122 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().

25123 {
25124    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
25125    int expires_ms = expires * 1000;
25126    int res = 0;
25127 
25128    if (!esc_entry) {
25129       transmit_response(p, "412 Conditional Request Failed", req);
25130       return -1;
25131    }
25132 
25133    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
25134          ao2_ref(_data, -1),
25135          ao2_ref(esc_entry, -1),
25136          ao2_ref(esc_entry, +1));
25137 
25138    if (esc->callbacks->refresh_handler) {
25139       res = esc->callbacks->refresh_handler(p, req, esc, esc_entry);
25140    }
25141 
25142    if (!res) {
25143       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
25144    }
25145 
25146    ao2_ref(esc_entry, -1);
25147    return res;
25148 }

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 25178 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().

25179 {
25180    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
25181    int res = 0;
25182 
25183    if (!esc_entry) {
25184       transmit_response(p, "412 Conditional Request Failed", req);
25185       return -1;
25186    }
25187 
25188    AST_SCHED_DEL(sched, esc_entry->sched_id);
25189    /* Scheduler's ref of the esc_entry */
25190    ao2_ref(esc_entry, -1);
25191 
25192    if (esc->callbacks->remove_handler) {
25193       res = esc->callbacks->remove_handler(p, req, esc, esc_entry);
25194    }
25195 
25196    if (!res) {
25197       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
25198    }
25199 
25200    /* Ref from finding the esc_entry earlier in function */
25201    ao2_unlink(esc->compositor, esc_entry);
25202    ao2_ref(esc_entry, -1);
25203    return res;
25204 }

static int handle_t38_options ( struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v,
unsigned 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 27539 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, ast_variable::value, and word.

Referenced by build_peer(), and reload_config().

27541 {
27542    int res = 1;
27543 
27544    if (!strcasecmp(v->name, "t38pt_udptl")) {
27545       char *buf = ast_strdupa(v->value);
27546       char *word, *next = buf;
27547 
27548       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT);
27549 
27550       while ((word = strsep(&next, ","))) {
27551          if (ast_true(word) || !strcasecmp(word, "fec")) {
27552             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27553             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC);
27554          } else if (!strcasecmp(word, "redundancy")) {
27555             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27556             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY);
27557          } else if (!strcasecmp(word, "none")) {
27558             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27559             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL);
27560          } else if (!strncasecmp(word, "maxdatagram=", 12)) {
27561             if (sscanf(&word[12], "%30u", maxdatagram) != 1) {
27562                ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config);
27563                *maxdatagram = global_t38_maxdatagram;
27564             }
27565          }
27566       }
27567    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
27568       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
27569       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
27570    } else {
27571       res = 0;
27572    }
27573 
27574    return res;
27575 }

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 6426 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_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().

06427 {
06428    switch (cause) {
06429       case AST_CAUSE_UNALLOCATED:      /* 1 */
06430       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
06431       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
06432          return "404 Not Found";
06433       case AST_CAUSE_CONGESTION:    /* 34 */
06434       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
06435          return "503 Service Unavailable";
06436       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
06437          return "408 Request Timeout";
06438       case AST_CAUSE_NO_ANSWER:     /* 19 */
06439       case AST_CAUSE_UNREGISTERED:        /* 20 */
06440          return "480 Temporarily unavailable";
06441       case AST_CAUSE_CALL_REJECTED:    /* 21 */
06442          return "403 Forbidden";
06443       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
06444          return "410 Gone";
06445       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
06446          return "480 Temporarily unavailable";
06447       case AST_CAUSE_INVALID_NUMBER_FORMAT:
06448          return "484 Address incomplete";
06449       case AST_CAUSE_USER_BUSY:
06450          return "486 Busy here";
06451       case AST_CAUSE_FAILURE:
06452          return "500 Server internal failure";
06453       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
06454          return "501 Not Implemented";
06455       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
06456          return "503 Service Unavailable";
06457       /* Used in chan_iax2 */
06458       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
06459          return "502 Bad Gateway";
06460       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
06461          return "488 Not Acceptable Here";
06462          
06463       case AST_CAUSE_NOTDEFINED:
06464       default:
06465          ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause);
06466          return NULL;
06467    }
06468 
06469    /* Never reached */
06470    return 0;
06471 }

int hangup_sip2cause ( int  cause  ) 

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 6304 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(), handle_response(), and handle_response_invite().

06305 {
06306    /* Possible values taken from causes.h */
06307 
06308    switch(cause) {
06309       case 401:   /* Unauthorized */
06310          return AST_CAUSE_CALL_REJECTED;
06311       case 403:   /* Not found */
06312          return AST_CAUSE_CALL_REJECTED;
06313       case 404:   /* Not found */
06314          return AST_CAUSE_UNALLOCATED;
06315       case 405:   /* Method not allowed */
06316          return AST_CAUSE_INTERWORKING;
06317       case 407:   /* Proxy authentication required */
06318          return AST_CAUSE_CALL_REJECTED;
06319       case 408:   /* No reaction */
06320          return AST_CAUSE_NO_USER_RESPONSE;
06321       case 409:   /* Conflict */
06322          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
06323       case 410:   /* Gone */
06324          return AST_CAUSE_NUMBER_CHANGED;
06325       case 411:   /* Length required */
06326          return AST_CAUSE_INTERWORKING;
06327       case 413:   /* Request entity too large */
06328          return AST_CAUSE_INTERWORKING;
06329       case 414:   /* Request URI too large */
06330          return AST_CAUSE_INTERWORKING;
06331       case 415:   /* Unsupported media type */
06332          return AST_CAUSE_INTERWORKING;
06333       case 420:   /* Bad extension */
06334          return AST_CAUSE_NO_ROUTE_DESTINATION;
06335       case 480:   /* No answer */
06336          return AST_CAUSE_NO_ANSWER;
06337       case 481:   /* No answer */
06338          return AST_CAUSE_INTERWORKING;
06339       case 482:   /* Loop detected */
06340          return AST_CAUSE_INTERWORKING;
06341       case 483:   /* Too many hops */
06342          return AST_CAUSE_NO_ANSWER;
06343       case 484:   /* Address incomplete */
06344          return AST_CAUSE_INVALID_NUMBER_FORMAT;
06345       case 485:   /* Ambiguous */
06346          return AST_CAUSE_UNALLOCATED;
06347       case 486:   /* Busy everywhere */
06348          return AST_CAUSE_BUSY;
06349       case 487:   /* Request terminated */
06350          return AST_CAUSE_INTERWORKING;
06351       case 488:   /* No codecs approved */
06352          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
06353       case 491:   /* Request pending */
06354          return AST_CAUSE_INTERWORKING;
06355       case 493:   /* Undecipherable */
06356          return AST_CAUSE_INTERWORKING;
06357       case 500:   /* Server internal failure */
06358          return AST_CAUSE_FAILURE;
06359       case 501:   /* Call rejected */
06360          return AST_CAUSE_FACILITY_REJECTED;
06361       case 502:
06362          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
06363       case 503:   /* Service unavailable */
06364          return AST_CAUSE_CONGESTION;
06365       case 504:   /* Gateway timeout */
06366          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
06367       case 505:   /* SIP version not supported */
06368          return AST_CAUSE_INTERWORKING;
06369       case 600:   /* Busy everywhere */
06370          return AST_CAUSE_USER_BUSY;
06371       case 603:   /* Decline */
06372          return AST_CAUSE_CALL_REJECTED;
06373       case 604:   /* Does not exist anywhere */
06374          return AST_CAUSE_UNALLOCATED;
06375       case 606:   /* Not acceptable */
06376          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
06377       default:
06378          if (cause < 500 && cause >= 400) {
06379             /* 4xx class error that is unknown - someting wrong with our request */
06380             return AST_CAUSE_INTERWORKING;
06381          } else if (cause < 600 && cause >= 500) {
06382             /* 5xx class error - problem in the remote end */
06383             return AST_CAUSE_CONGESTION;
06384          } else if (cause < 700 && cause >= 600) {
06385             /* 6xx - global errors in the 4xx class */
06386             return AST_CAUSE_INTERWORKING;
06387          }
06388          return AST_CAUSE_NORMAL;
06389    }
06390    /* Never reached */
06391    return 0;
06392 }

static int init_req ( struct sip_request *  req,
int  sipmethod,
const char *  recip 
) [static]

Initialize SIP request.

Definition at line 10518 of file chan_sip.c.

References ast_free, ast_str_create(), ast_str_set(), sip_methods, and cfsip_methods::text.

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

10519 {
10520    /* Initialize a request */
10521    memset(req, 0, sizeof(*req));
10522    if (!(req->data = ast_str_create(SIP_MIN_PACKET)))
10523       goto e_return;
10524    if (!(req->content = ast_str_create(SIP_MIN_PACKET)))
10525       goto e_free_data;
10526    req->method = sipmethod;
10527    req->header[0] = 0;
10528    ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
10529    req->headers++;
10530    return 0;
10531 
10532 e_free_data:
10533    ast_free(req->data);
10534    req->data = NULL;
10535 e_return:
10536    return -1;
10537 }

static int init_resp ( struct sip_request *  resp,
const char *  msg 
) [static]

Initialize SIP response, based on SIP request.

Definition at line 10496 of file chan_sip.c.

References ast_free, ast_str_create(), and ast_str_set().

Referenced by respprep().

10497 {
10498    /* Initialize a response */
10499    memset(resp, 0, sizeof(*resp));
10500    resp->method = SIP_RESPONSE;
10501    if (!(resp->data = ast_str_create(SIP_MIN_PACKET)))
10502       goto e_return;
10503    if (!(resp->content = ast_str_create(SIP_MIN_PACKET)))
10504       goto e_free_data;
10505    resp->header[0] = 0;
10506    ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg);
10507    resp->headers++;
10508    return 0;
10509 
10510 e_free_data:
10511    ast_free(resp->data);
10512    resp->data = NULL;
10513 e_return:
10514    return -1;
10515 }

static int initialize_escs ( void   )  [static]

Definition at line 1056 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().

01057 {
01058    int i, res = 0;
01059    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01060       if (!((event_state_compositors[i].compositor) =
01061                ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) {
01062          res = -1;
01063       }
01064    }
01065    return res;
01066 }

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 3197 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_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and update_connectedline().

03198 {
03199    if (p->initreq.headers) {
03200       ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
03201    } else {
03202       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
03203    }
03204    /* Use this as the basis */
03205    copy_request(&p->initreq, req);
03206    parse_request(&p->initreq);
03207    if (req->debug) {
03208       ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
03209    }
03210 }

static int initialize_udptl ( struct sip_pvt *  p  )  [static]

Definition at line 7091 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().

07092 {
07093    int natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
07094 
07095    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
07096       return 1;
07097    }
07098 
07099    /* If we've already initialized T38, don't take any further action */
07100    if (p->udptl) {
07101       return 0;
07102    }
07103 
07104    /* T38 can be supported by this dialog, create it and set the derived properties */
07105    if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) {
07106       if (p->owner) {
07107          ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl));
07108       }
07109 
07110       ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio);
07111       p->t38_maxdatagram = p->relatedpeer ? p->relatedpeer->t38_maxdatagram : global_t38_maxdatagram;
07112       set_t38_capabilities(p);
07113 
07114       ast_debug(1, "Setting NAT on UDPTL to %s\n", natflags ? "On" : "Off");
07115       ast_udptl_setnat(p->udptl, natflags);
07116    } else {
07117       ast_log(AST_LOG_WARNING, "UDPTL creation failed - disabling T38 for this dialog\n");
07118       ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT);
07119       return 1;
07120    }
07121 
07122    return 0;
07123 }

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 12345 of file chan_sip.c.

References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), 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_buffer(), ast_str_set(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), exten, init_req(), ourport, sip_cfg, sip_methods, sip_standard_port(), and cfsip_methods::text.

Referenced by transmit_invite(), and transmit_notify_with_mwi().

12346 {
12347    struct ast_str *invite = ast_str_alloca(256);
12348    char from[256];
12349    char to[256];
12350    char tmp_n[SIPBUFSIZE/2];  /* build a local copy of 'n' if needed */
12351    char tmp_l[SIPBUFSIZE/2];  /* build a local copy of 'l' if needed */
12352    const char *l = NULL;   /* XXX what is this, exactly ? */
12353    const char *n = NULL;   /* XXX what is this, exactly ? */
12354    const char *d = NULL;   /* domain in from header */
12355    const char *urioptions = "";
12356    int ourport;
12357 
12358    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
12359       const char *s = p->username;  /* being a string field, cannot be NULL */
12360 
12361       /* Test p->username against allowed characters in AST_DIGIT_ANY
12362          If it matches the allowed characters list, then sipuser = ";user=phone"
12363          If not, then sipuser = ""
12364       */
12365       /* + is allowed in first position in a tel: uri */
12366       if (*s == '+')
12367          s++;
12368       for (; *s; s++) {
12369          if (!strchr(AST_DIGIT_ANYNUM, *s) )
12370             break;
12371       }
12372       /* If we have only digits, add ;user=phone to the uri */
12373       if (!*s)
12374          urioptions = ";user=phone";
12375    }
12376 
12377 
12378    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
12379 
12380    if (ast_strlen_zero(p->fromdomain)) {
12381       d = ast_sockaddr_stringify_host_remote(&p->ourip);
12382    }
12383    if (p->owner) {
12384       if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
12385          l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL;
12386          n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL;
12387       } else {
12388          /* Even if we are using RPID, we shouldn't leak information in the From if the user wants
12389           * their callerid restricted */
12390          l = "anonymous";
12391          n = CALLERID_UNKNOWN;
12392          d = FROMDOMAIN_INVALID;
12393       }
12394    }
12395 
12396    /* Hey, it's a NOTIFY! See if they've configured a mwi_from.
12397     * XXX Right now, this logic works because the only place that mwi_from
12398     * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then
12399     * we might end up putting the mwi_from setting into other types of NOTIFY
12400     * messages as well.
12401     */
12402    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) {
12403       l = p->mwi_from;
12404    }
12405 
12406    if (ast_strlen_zero(l))
12407       l = default_callerid;
12408    if (ast_strlen_zero(n))
12409       n = l;
12410    /* Allow user to be overridden */
12411    if (!ast_strlen_zero(p->fromuser))
12412       l = p->fromuser;
12413    else /* Save for any further attempts */
12414       ast_string_field_set(p, fromuser, l);
12415 
12416    /* Allow user to be overridden */
12417    if (!ast_strlen_zero(p->fromname))
12418       n = p->fromname;
12419    else /* Save for any further attempts */
12420       ast_string_field_set(p, fromname, n);
12421 
12422    /* Allow domain to be overridden */
12423    if (!ast_strlen_zero(p->fromdomain))
12424       d = p->fromdomain;
12425    else /* Save for any further attempts */
12426       ast_string_field_set(p, fromdomain, d);
12427 
12428    ast_copy_string(tmp_l, l, sizeof(tmp_l));
12429    if (sip_cfg.pedanticsipchecking) {
12430       ast_escape_quoted(n, tmp_n, sizeof(tmp_n));
12431       n = tmp_n;
12432       ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0);
12433    }
12434 
12435    ourport = (p->fromdomainport && (p->fromdomainport != STANDARD_SIP_PORT)) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
12436    if (!sip_standard_port(p->socket.type, ourport)) {
12437       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, tmp_l, d, ourport, p->tag);
12438    } else {
12439       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, tmp_l, d, p->tag);
12440    }
12441 
12442    if (!ast_strlen_zero(explicit_uri)) {
12443       ast_str_set(&invite, 0, "%s", explicit_uri);
12444    } else {
12445       /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
12446       if (!ast_strlen_zero(p->fullcontact)) {
12447          /* If we have full contact, trust it */
12448          ast_str_append(&invite, 0, "%s", p->fullcontact);
12449       } else {
12450          /* Otherwise, use the username while waiting for registration */
12451          ast_str_append(&invite, 0, "sip:");
12452          if (!ast_strlen_zero(p->username)) {
12453             n = p->username;
12454             if (sip_cfg.pedanticsipchecking) {
12455                ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0);
12456                n = tmp_n;
12457             }
12458             ast_str_append(&invite, 0, "%s@", n);
12459          }
12460          ast_str_append(&invite, 0, "%s", p->tohost);
12461          if (p->portinuri) {
12462             ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa));
12463          }
12464          ast_str_append(&invite, 0, "%s", urioptions);
12465       }
12466    }
12467 
12468    /* If custom URI options have been provided, append them */
12469    if (p->options && !ast_strlen_zero(p->options->uri_options))
12470       ast_str_append(&invite, 0, ";%s", p->options->uri_options);
12471    
12472    /* This is the request URI, which is the next hop of the call
12473       which may or may not be the destination of the call
12474    */
12475    ast_string_field_set(p, uri, ast_str_buffer(invite));
12476 
12477    if (!ast_strlen_zero(p->todnid)) {
12478       /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
12479       if (!strchr(p->todnid, '@')) {
12480          /* We have no domain in the dnid */
12481          snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
12482       } else {
12483          snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
12484       }
12485    } else {
12486       if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
12487          /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
12488          snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag);
12489       } else if (p->options && p->options->vxml_url) {
12490          /* If there is a VXML URL append it to the SIP URL */
12491          snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
12492       } else {
12493          snprintf(to, sizeof(to), "<%s>", p->uri);
12494       }
12495    }
12496 
12497    init_req(req, sipmethod, p->uri);
12498    /* now tmp_n is available so reuse it to build the CSeq */
12499    snprintf(tmp_n, sizeof(tmp_n), "%u %s", ++p->ocseq, sip_methods[sipmethod].text);
12500 
12501    add_header(req, "Via", p->via);
12502    add_header_max_forwards(p, req);
12503    /* This will be a no-op most of the time. However, under certain circumstances,
12504     * NOTIFY messages will use this function for preparing the request and should
12505     * have Route headers present.
12506     */
12507    add_route(req, p->route);
12508 
12509    add_header(req, "From", from);
12510    add_header(req, "To", to);
12511    ast_string_field_set(p, exten, l);
12512    build_contact(p);
12513    add_header(req, "Contact", p->our_contact);
12514    add_header(req, "Call-ID", p->callid);
12515    add_header(req, "CSeq", tmp_n);
12516    if (!ast_strlen_zero(global_useragent)) {
12517       add_header(req, "User-Agent", global_useragent);
12518    }
12519 }

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

Convert Insecure setting to printable string.

Definition at line 17590 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer().

17591 {
17592    return map_x_s(insecurestr, mode, "<error>");
17593 }

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 6997 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().

06998 {
06999    int res = 0;
07000 
07001    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) {
07002       return -1;
07003    }
07004    switch (parameters->request_response) {
07005    case AST_T38_NEGOTIATED:
07006    case AST_T38_REQUEST_NEGOTIATE:         /* Request T38 */
07007       /* Negotiation can not take place without a valid max_ifp value. */
07008       if (!parameters->max_ifp) {
07009          change_t38_state(p, T38_DISABLED);
07010          if (p->t38.state == T38_PEER_REINVITE) {
07011             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"));
07012             transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
07013          }
07014          break;
07015       } else if (p->t38.state == T38_PEER_REINVITE) {
07016          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"));
07017          p->t38.our_parms = *parameters;
07018          /* modify our parameters to conform to the peer's parameters,
07019           * based on the rules in the ITU T.38 recommendation
07020           */
07021          if (!p->t38.their_parms.fill_bit_removal) {
07022             p->t38.our_parms.fill_bit_removal = FALSE;
07023          }
07024          if (!p->t38.their_parms.transcoding_mmr) {
07025             p->t38.our_parms.transcoding_mmr = FALSE;
07026          }
07027          if (!p->t38.their_parms.transcoding_jbig) {
07028             p->t38.our_parms.transcoding_jbig = FALSE;
07029          }
07030          p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version);
07031          p->t38.our_parms.rate_management = p->t38.their_parms.rate_management;
07032          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
07033          change_t38_state(p, T38_ENABLED);
07034          transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
07035       } else if (p->t38.state != T38_ENABLED) {
07036          p->t38.our_parms = *parameters;
07037          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
07038          change_t38_state(p, T38_LOCAL_REINVITE);
07039          if (!p->pendinginvite) {
07040             transmit_reinvite_with_sdp(p, TRUE, FALSE);
07041          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
07042             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
07043          }
07044       }
07045       break;
07046    case AST_T38_TERMINATED:
07047    case AST_T38_REFUSED:
07048    case AST_T38_REQUEST_TERMINATE:         /* Shutdown T38 */
07049       if (p->t38.state == T38_PEER_REINVITE) {
07050          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"));
07051          change_t38_state(p, T38_DISABLED);
07052          transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
07053       } else if (p->t38.state == T38_ENABLED)
07054          transmit_reinvite_with_sdp(p, FALSE, FALSE);
07055       break;
07056    case AST_T38_REQUEST_PARMS: {    /* Application wants remote's parameters re-sent */
07057       struct ast_control_t38_parameters parameters = p->t38.their_parms;
07058 
07059       if (p->t38.state == T38_PEER_REINVITE) {
07060          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"));
07061          parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
07062          parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
07063          if (p->owner) {
07064             ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
07065          }
07066          /* we need to return a positive value here, so that applications that
07067           * send this request can determine conclusively whether it was accepted or not...
07068           * older versions of chan_sip would just silently accept it and return zero.
07069           */
07070          res = AST_T38_REQUEST_PARMS;
07071       }
07072       break;
07073    }
07074    default:
07075       res = -1;
07076       break;
07077    }
07078 
07079    return res;
07080 }

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 8658 of file chan_sip.c.

Referenced by sip_sendtext(), and update_connectedline().

08659 {
08660    return ((*allowed_methods) >> method) & 1;
08661 }

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

List all routes - mostly for debugging.

Definition at line 14687 of file chan_sip.c.

References ast_verbose.

Referenced by build_route().

14688 {
14689    if (!route) {
14690       ast_verbose("list_route: no route\n");
14691    } else {
14692       for (;route; route = route->next)
14693          ast_verbose("list_route: hop: <%s>\n", route->hop);
14694    }
14695 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 31814 of file chan_sip.c.

References ao2_container_alloc, ao2_t_container_alloc, ao2_t_ref, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_check_realtime(), ast_clear_flag, ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_realtime_require_field(), ast_register_application_xml, ast_rtp_glue_register, ast_string_field_set, AST_TEST_REGISTER, ast_udptl_proto_register(), ast_verbose, ASTOBJ_CONTAINER_INIT, BOGUS_PEER_MD5SECRET, 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, sched_context_create(), sched_context_destroy(), ast_channel_tech::send_digit_begin, SENTINEL, sip_addheader(), 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, temp_peer(), threadt_cmp_cb(), and threadt_hash_cb().

31815 {
31816    ast_verbose("SIP channel loading...\n");
31817 
31818    /* the fact that ao2_containers can't resize automatically is a major worry! */
31819    /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
31820    peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers");
31821    peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip");
31822    dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs");
31823    dialogs_to_destroy = ao2_t_container_alloc(1, NULL, NULL, "allocate dialogs_to_destroy");
31824    threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
31825    if (!peers || !peers_by_ip || !dialogs || !dialogs_to_destroy || !threadt) {
31826       ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n");
31827       return AST_MODULE_LOAD_FAILURE;
31828    }
31829 
31830    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
31831    ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
31832 
31833    if (!(sched = sched_context_create())) {
31834       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
31835       return AST_MODULE_LOAD_FAILURE;
31836    }
31837 
31838    if (!(io = io_context_create())) {
31839       ast_log(LOG_ERROR, "Unable to create I/O context\n");
31840       sched_context_destroy(sched);
31841       return AST_MODULE_LOAD_FAILURE;
31842    }
31843 
31844    sip_reloadreason = CHANNEL_MODULE_LOAD;
31845 
31846    can_parse_xml = sip_is_xml_parsable();
31847    if (reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */
31848       return AST_MODULE_LOAD_DECLINE;
31849    }
31850 
31851    /* Initialize bogus peer. Can be done first after reload_config() */
31852    if (!(bogus_peer = temp_peer("(bogus_peer)"))) {
31853       ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n");
31854       io_context_destroy(io);
31855       sched_context_destroy(sched);
31856       return AST_MODULE_LOAD_FAILURE;
31857    }
31858    /* Make sure the auth will always fail. */
31859    ast_string_field_set(bogus_peer, md5secret, BOGUS_PEER_MD5SECRET);
31860    ast_clear_flag(&bogus_peer->flags[0], SIP_INSECURE);
31861 
31862    /* Prepare the version that does not require DTMF BEGIN frames.
31863     * We need to use tricks such as memcpy and casts because the variable
31864     * has const fields.
31865     */
31866    memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
31867    memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
31868 
31869    /* Make sure we can register our sip channel type */
31870    if (ast_channel_register(&sip_tech)) {
31871       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
31872       ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
31873       io_context_destroy(io);
31874       sched_context_destroy(sched);
31875       return AST_MODULE_LOAD_FAILURE;
31876    }
31877 
31878 #ifdef TEST_FRAMEWORK
31879    AST_TEST_REGISTER(test_sip_peers_get);
31880    AST_TEST_REGISTER(test_sip_mwi_subscribe_parse);
31881    AST_TEST_REGISTER(test_tcp_message_fragmentation);
31882    AST_TEST_REGISTER(get_in_brackets_const_test);
31883 #endif
31884 
31885    /* Register AstData providers */
31886    ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers));
31887 
31888    /* Register all CLI functions for SIP */
31889    ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip));
31890 
31891    /* Tell the UDPTL subdriver that we're here */
31892    ast_udptl_proto_register(&sip_udptl);
31893 
31894    /* Tell the RTP engine about our RTP glue */
31895    ast_rtp_glue_register(&sip_rtp_glue);
31896 
31897    /* Register dialplan applications */
31898    ast_register_application_xml(app_dtmfmode, sip_dtmfmode);
31899    ast_register_application_xml(app_sipaddheader, sip_addheader);
31900    ast_register_application_xml(app_sipremoveheader, sip_removeheader);
31901 
31902    /* Register dialplan functions */
31903    ast_custom_function_register(&sip_header_function);
31904    ast_custom_function_register(&sippeer_function);
31905    ast_custom_function_register(&sipchaninfo_function);
31906    ast_custom_function_register(&checksipdomain_function);
31907 
31908    /* Register manager commands */
31909    ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers);
31910    ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer);
31911    ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer);
31912    ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry);
31913    ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify);
31914    sip_poke_all_peers();   
31915    sip_send_all_registers();
31916    sip_send_all_mwi_subscriptions();
31917    initialize_escs();
31918 
31919    if (sip_epa_register(&cc_epa_static_data)) {
31920       return AST_MODULE_LOAD_DECLINE;
31921    }
31922 
31923    if (sip_reqresp_parser_init() == -1) {
31924       ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n");
31925       return AST_MODULE_LOAD_DECLINE;
31926    }
31927 
31928    if (can_parse_xml) {
31929       /* SIP CC agents require the ability to parse XML PIDF bodies
31930        * in incoming PUBLISH requests
31931        */
31932       if (ast_cc_agent_register(&sip_cc_agent_callbacks)) {
31933          return AST_MODULE_LOAD_DECLINE;
31934       }
31935    }
31936    if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) {
31937       return AST_MODULE_LOAD_DECLINE;
31938    }
31939    if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) {
31940       return AST_MODULE_LOAD_DECLINE;
31941    }
31942 
31943    /* And start the monitor for the first time */
31944    restart_monitor();
31945 
31946    ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
31947       "name", RQ_CHAR, 10,
31948       "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1,
31949       "port", RQ_UINTEGER2, 5,
31950       "regseconds", RQ_INTEGER4, 11,
31951       "defaultuser", RQ_CHAR, 10,
31952       "fullcontact", RQ_CHAR, 35,
31953       "regserver", RQ_CHAR, 20,
31954       "useragent", RQ_CHAR, 20,
31955       "lastms", RQ_INTEGER4, 11,
31956       SENTINEL);
31957 
31958 
31959    sip_register_tests();
31960    network_change_event_subscribe();
31961 
31962    return AST_MODULE_LOAD_SUCCESS;
31963 }

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 23898 of file chan_sip.c.

References ao2_t_ref, append_history, ast_alloca, ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, ast_cel_report_event(), ast_channel_queue_connected_line_update(), ast_channel_ref, 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().

23899 {
23900    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
23901                /* Chan 2: Call from Asterisk to target */
23902    int res = 0;
23903    struct sip_pvt *targetcall_pvt;
23904    struct ast_party_connected_line connected_to_transferee;
23905    struct ast_party_connected_line connected_to_target;
23906    char transferer_linkedid[32];
23907    struct ast_channel *chans[2];
23908 
23909    /* Check if the call ID of the replaces header does exist locally */
23910    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag,
23911       transferer->refer->replaces_callid_fromtag))) {
23912       if (transferer->refer->localtransfer) {
23913          /* We did not find the refered call. Sorry, can't accept then */
23914          /* Let's fake a response from someone else in order
23915             to follow the standard */
23916          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
23917          append_history(transferer, "Xfer", "Refer failed");
23918          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
23919          transferer->refer->status = REFER_FAILED;
23920          return -1;
23921       }
23922       /* Fall through for remote transfers that we did not find locally */
23923       ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
23924       return 0;
23925    }
23926 
23927    /* Ok, we can accept this transfer */
23928    append_history(transferer, "Xfer", "Refer accepted");
23929    if (!targetcall_pvt->owner) { /* No active channel */
23930       ast_debug(4, "SIP attended transfer: Error: No owner of target call\n");
23931       /* Cancel transfer */
23932       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
23933       append_history(transferer, "Xfer", "Refer failed");
23934       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
23935       transferer->refer->status = REFER_FAILED;
23936       sip_pvt_unlock(targetcall_pvt);
23937       if (targetcall_pvt)
23938          ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer");
23939       return -1;
23940    }
23941 
23942    /* We have a channel, find the bridge */
23943    target.chan1 = ast_channel_ref(targetcall_pvt->owner);            /* Transferer to Asterisk */
23944    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
23945    if (target.chan2) {
23946       ast_channel_ref(target.chan2);
23947    }
23948 
23949    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
23950       /* Wrong state of new channel */
23951       if (target.chan2)
23952          ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
23953       else if (target.chan1->_state != AST_STATE_RING)
23954          ast_debug(4, "SIP attended transfer: Error: No target channel\n");
23955       else
23956          ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n");
23957    }
23958 
23959    /* Transfer */
23960    if (sipdebug) {
23961       if (current->chan2)  /* We have two bridges */
23962          ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
23963       else        /* One bridge, propably transfer of IVR/voicemail etc */
23964          ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
23965    }
23966 
23967    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
23968 
23969    ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid));
23970 
23971    /* Perform the transfer */
23972    chans[0] = transferer->owner;
23973    chans[1] = target.chan1;
23974    ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans,
23975       "TransferMethod: SIP\r\n"
23976       "TransferType: Attended\r\n"
23977       "Channel: %s\r\n"
23978       "Uniqueid: %s\r\n"
23979       "SIP-Callid: %s\r\n"
23980       "TargetChannel: %s\r\n"
23981       "TargetUniqueid: %s\r\n",
23982       transferer->owner->name,
23983       transferer->owner->uniqueid,
23984       transferer->callid,
23985       target.chan1->name,
23986       target.chan1->uniqueid);
23987    ast_party_connected_line_init(&connected_to_transferee);
23988    ast_party_connected_line_init(&connected_to_target);
23989    /* No need to lock current->chan1 here since it was locked in sipsock_read */
23990    ast_party_connected_line_copy(&connected_to_transferee, &current->chan1->connected);
23991    /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */
23992    ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected);
23993    connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
23994    res = attempt_transfer(current, &target);
23995    if (res) {
23996       /* Failed transfer */
23997       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
23998       append_history(transferer, "Xfer", "Refer failed");
23999       ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
24000       /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */
24001       sip_pvt_unlock(targetcall_pvt);
24002       ast_channel_unlock(target.chan1);
24003    } else {
24004       /* Transfer succeeded! */
24005       const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND");
24006 
24007       /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */
24008       ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2);
24009 
24010       /* Tell transferer that we're done. */
24011       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
24012       append_history(transferer, "Xfer", "Refer succeeded");
24013       transferer->refer->status = REFER_200OK;
24014       if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, target.chan2->language) >= 0) {
24015          ast_waitstream(target.chan2, "");
24016       }
24017 
24018       /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then
24019        * can queue connected line updates where they need to go.
24020        *
24021        * before a masquerade, all channel and pvt locks must be unlocked.  Any recursive
24022        * channel locks held before this function invalidates channel container locking order.
24023        * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1)
24024        * it is possible for current.chan1 to be destroyed in the pbx thread.  To prevent this
24025        * we must give c a reference before any unlocking takes place.
24026        */
24027 
24028       ast_channel_ref(current->chan1);
24029       ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/
24030       ast_channel_unlock(target.chan1);
24031       *nounlock = 1;  /* we just unlocked the dialog's channel and have no plans of locking it again. */
24032       sip_pvt_unlock(targetcall_pvt);
24033       sip_pvt_unlock(transferer);
24034 
24035       ast_do_masquerade(target.chan1);
24036 
24037       if (target.chan2) {
24038          ast_indicate(target.chan2, AST_CONTROL_UNHOLD);
24039       }
24040 
24041       if (current->chan2 && current->chan2->_state == AST_STATE_RING) {
24042          ast_indicate(target.chan1, AST_CONTROL_RINGING);
24043       }
24044 
24045       if (target.chan2) {
24046          ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
24047          ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL);
24048       } else {
24049          /* Since target.chan1 isn't actually connected to another channel, there is no way for us
24050           * to queue a frame so that its connected line status will be updated.
24051           *
24052           * Instead, we use the somewhat hackish approach of using a special control frame type that
24053           * instructs ast_read to perform a specific action. In this case, the frame we queue tells
24054           * ast_read to call the connected line interception macro configured for target.chan1.
24055           */
24056          struct ast_control_read_action_payload *frame_payload;
24057          int payload_size;
24058          int frame_size;
24059          unsigned char connected_line_data[1024];
24060          payload_size = ast_connected_line_build_data(connected_line_data,
24061             sizeof(connected_line_data), &connected_to_target, NULL);
24062          frame_size = payload_size + sizeof(*frame_payload);
24063          if (payload_size != -1) {
24064             frame_payload = ast_alloca(frame_size);
24065             frame_payload->payload_size = payload_size;
24066             memcpy(frame_payload->payload, connected_line_data, payload_size);
24067             frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
24068             ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size);
24069          }
24070          /* In addition to queueing the read action frame so that target.chan1's connected line info
24071           * will be updated, we also are going to queue a plain old connected line update on target.chan1. This
24072           * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel.
24073           */
24074          ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
24075 
24076       }
24077       sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */
24078 
24079       ast_channel_unref(current->chan1);
24080    }
24081 
24082    /* at this point if the transfer is successful only the transferer pvt should be locked. */
24083    ast_party_connected_line_free(&connected_to_target);
24084    ast_party_connected_line_free(&connected_to_transferee);
24085    ast_channel_unref(target.chan1);
24086    if (target.chan2) {
24087       ast_channel_unref(target.chan2);
24088    }
24089    if (targetcall_pvt)
24090       ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt");
24091    return 1;
24092 }

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 8746 of file chan_sip.c.

References ast_str_strlen(), and len().

Referenced by handle_request_do(), and read_raw_content_length().

08747 {
08748    char *msgbuf = data->str;
08749    int len = ast_str_strlen(data);
08750    int h = 0, t = 0;
08751    int lws = 0;
08752 
08753    for (; h < len;) {
08754       /* Eliminate all CRs */
08755       if (msgbuf[h] == '\r') {
08756          h++;
08757          continue;
08758       }
08759       /* Check for end-of-line */
08760       if (msgbuf[h] == '\n') {
08761          /* Check for end-of-message */
08762          if (h + 1 == len)
08763             break;
08764          /* Check for a continuation line */
08765          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') {
08766             /* Merge continuation line */
08767             h++;
08768             continue;
08769          }
08770          /* Propagate LF and start new line */
08771          msgbuf[t++] = msgbuf[h++];
08772          lws = 0;
08773          continue;
08774       }
08775       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') {
08776          if (lws) {
08777             h++;
08778             continue;
08779          }
08780          msgbuf[t++] = msgbuf[h++];
08781          lws = 1;
08782          continue;
08783       }
08784       msgbuf[t++] = msgbuf[h++];
08785       if (lws)
08786          lws = 0;
08787    }
08788    msgbuf[t] = '\0';
08789    data->used = t;
08790 }

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

Make our SIP dialog tag.

Definition at line 7938 of file chan_sip.c.

References ast_random(), and ast_string_field_build.

Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), and transmit_response_using_temp().

07939 {
07940    ast_string_field_build(pvt, tag, "as%08lx", (unsigned long)ast_random());
07941 }

static int manager_show_registry ( struct mansession s,
const struct message m 
) [static]

Show SIP registrations in the manager API.

Definition at line 17187 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().

17188 {
17189    const char *id = astman_get_header(m, "ActionID");
17190    char idtext[256] = "";
17191    int total = 0;
17192 
17193    if (!ast_strlen_zero(id))
17194       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
17195 
17196    astman_send_listack(s, m, "Registrations will follow", "start");
17197 
17198    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17199       ASTOBJ_RDLOCK(iterator);
17200       astman_append(s,
17201          "Event: RegistryEntry\r\n"
17202          "%s"
17203          "Host: %s\r\n"
17204          "Port: %d\r\n"
17205          "Username: %s\r\n"
17206          "Domain: %s\r\n"
17207          "DomainPort: %d\r\n"
17208          "Refresh: %d\r\n"
17209          "State: %s\r\n"
17210          "RegistrationTime: %ld\r\n"
17211          "\r\n",
17212          idtext,
17213          iterator->hostname,
17214          iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
17215          iterator->username,
17216          S_OR(iterator->regdomain,iterator->hostname),
17217          iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT,
17218          iterator->refresh,
17219          regstate2str(iterator->regstate),
17220          (long) iterator->regtime.tv_sec);
17221       ASTOBJ_UNLOCK(iterator);
17222       total++;
17223    } while(0));
17224 
17225    astman_append(s,
17226       "Event: RegistrationsComplete\r\n"
17227       "EventList: Complete\r\n"
17228       "ListItems: %d\r\n"
17229       "%s"
17230       "\r\n", total, idtext);
17231    
17232    return 0;
17233 }

static int manager_sip_qualify_peer ( struct mansession s,
const struct message m 
) [static]

Qualify SIP peers in the manager API.

Definition at line 17997 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().

17998 {
17999    const char *a[4];
18000    const char *peer;
18001 
18002    peer = astman_get_header(m, "Peer");
18003    if (ast_strlen_zero(peer)) {
18004       astman_send_error(s, m, "Peer: <name> missing.");
18005       return 0;
18006    }
18007    a[0] = "sip";
18008    a[1] = "qualify";
18009    a[2] = "peer";
18010    a[3] = peer;
18011 
18012    _sip_qualify_peer(1, -1, s, m, 4, a);
18013    astman_append(s, "\r\n\r\n" );
18014    return 0;
18015 }

static int manager_sip_show_peer ( struct mansession s,
const struct message m 
) [static]

Show SIP peers in the manager API.

Definition at line 17938 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().

17939 {
17940    const char *a[4];
17941    const char *peer;
17942 
17943    peer = astman_get_header(m, "Peer");
17944    if (ast_strlen_zero(peer)) {
17945       astman_send_error(s, m, "Peer: <name> missing.");
17946       return 0;
17947    }
17948    a[0] = "sip";
17949    a[1] = "show";
17950    a[2] = "peer";
17951    a[3] = peer;
17952 
17953    _sip_show_peer(1, -1, s, m, 4, a);
17954    astman_append(s, "\r\n" );
17955    return 0;
17956 }

static int manager_sip_show_peers ( struct mansession s,
const struct message m 
) [static]

Show SIP peers in the manager API.

Definition at line 17237 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().

17238 {
17239    const char *id = astman_get_header(m, "ActionID");
17240    const char *a[] = {"sip", "show", "peers"};
17241    char idtext[256] = "";
17242    int total = 0;
17243 
17244    if (!ast_strlen_zero(id))
17245       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
17246 
17247    astman_send_listack(s, m, "Peer status list will follow", "start");
17248    /* List the peers in separate manager events */
17249    _sip_show_peers(-1, &total, s, m, 3, a);
17250    /* Send final confirmation */
17251    astman_append(s,
17252    "Event: PeerlistComplete\r\n"
17253    "EventList: Complete\r\n"
17254    "ListItems: %d\r\n"
17255    "%s"
17256    "\r\n", total, idtext);
17257    return 0;
17258 }

static int manager_sipnotify ( struct mansession s,
const struct message m 
) [static]

Definition at line 13406 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_order(), astman_send_ack(), astman_send_error(), create_addr(), dialog_unlink_all(), LOG_WARNING, ast_variable::name, ast_variable::next, ORDER_NATURAL, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), ast_variable::value, and var.

Referenced by load_module().

13407 {
13408    const char *channame = astman_get_header(m, "Channel");
13409    struct ast_variable *vars = astman_get_variables_order(m, ORDER_NATURAL);
13410    struct sip_pvt *p;
13411    struct ast_variable *header, *var;
13412 
13413    if (ast_strlen_zero(channame)) {
13414       astman_send_error(s, m, "SIPNotify requires a channel name");
13415       return 0;
13416    }
13417 
13418    if (!strncasecmp(channame, "sip/", 4)) {
13419       channame += 4;
13420    }
13421 
13422    if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
13423       astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
13424       return 0;
13425    }
13426 
13427    if (create_addr(p, channame, NULL, 0)) {
13428       /* Maybe they're not registered, etc. */
13429       dialog_unlink_all(p);
13430       dialog_unref(p, "unref dialog inside for loop" );
13431       /* sip_destroy(p); */
13432       astman_send_error(s, m, "Could not create address");
13433       return 0;
13434    }
13435 
13436    /* Notify is outgoing call */
13437    ast_set_flag(&p->flags[0], SIP_OUTGOING);
13438    sip_notify_allocate(p);
13439 
13440    p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
13441 
13442    for (var = vars; var; var = var->next) {
13443       if (!strcasecmp(var->name, "Content")) {
13444          if (ast_str_strlen(p->notify->content))
13445             ast_str_append(&p->notify->content, 0, "\r\n");
13446          ast_str_append(&p->notify->content, 0, "%s", var->value);
13447       } else if (!strcasecmp(var->name, "Content-Length")) {
13448          ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring\n");
13449       } else {
13450          header->next = ast_variable_new(var->name, var->value, "");
13451          header = header->next;
13452       }
13453    }
13454 
13455    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
13456    transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
13457    dialog_unref(p, "bump down the count of p since we're done with it.");
13458 
13459    astman_send_ack(s, m, "Notify Sent");
13460    ast_variables_destroy(vars);
13461    return 0;
13462 }

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 2261 of file chan_sip.c.

Referenced by str2dtmfmode(), str2stmode(), and str2strefresherparam().

02262 {
02263    const struct _map_x_s *cur;
02264 
02265    for (cur = table; cur->s; cur++)
02266       if (!strcasecmp(cur->s, s))
02267          return cur->x;
02268    return errorvalue;
02269 }

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 2248 of file chan_sip.c.

Referenced by allowoverlap2str(), dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), strefresher2str(), strefresherparam2str(), and trust_id_outbound2str().

02249 {
02250    const struct _map_x_s *cur;
02251 
02252    for (cur = table; cur->s; cur++)
02253       if (cur->x == x)
02254          return cur->s;
02255    return errorstring;
02256 }

static void mark_method_allowed ( unsigned int *  allowed_methods,
enum sipmethod  method 
) [static]

Definition at line 8647 of file chan_sip.c.

Referenced by handle_response(), handle_response_info(), handle_response_message(), mark_parsed_methods(), and set_pvt_allowed_methods().

08648 {
08649    (*allowed_methods) |= (1 << method);
08650 }

static void mark_method_unallowed ( unsigned int *  allowed_methods,
enum sipmethod  method 
) [static]

Definition at line 8652 of file chan_sip.c.

Referenced by handle_response(), handle_response_info(), handle_response_message(), and handle_response_publish().

08653 {
08654    (*allowed_methods) &= ~(1 << method);
08655 }

static void mark_parsed_methods ( unsigned int *  methods,
char *  methods_str 
) [static]

Definition at line 8663 of file chan_sip.c.

References ast_skip_blanks(), ast_strlen_zero(), find_sip_method(), and mark_method_allowed().

Referenced by build_peer(), parse_allowed_methods(), and reload_config().

08664 {
08665    char *method;
08666    for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) {
08667       int id = find_sip_method(ast_skip_blanks(method));
08668       if (id == SIP_UNKNOWN) {
08669          continue;
08670       }
08671       mark_method_allowed(methods, id);
08672    }
08673 }

static int match_and_cleanup_peer_sched ( void *  peerobj,
void *  arg,
int  flags 
) [static]

Definition at line 3011 of file chan_sip.c.

References ast_dnsmgr_release(), CMP_MATCH, peer_sched_cleanup(), SIP_PEERS_ALL, and unref_peer().

Referenced by unlink_peers_from_tables().

03012 {
03013    struct sip_peer *peer = peerobj;
03014    peer_unlink_flag_t which = *(peer_unlink_flag_t *)arg;
03015 
03016    if (which == SIP_PEERS_ALL || peer->the_mark) {
03017       peer_sched_cleanup(peer);
03018       if (peer->dnsmgr) {
03019          ast_dnsmgr_release(peer->dnsmgr);
03020          peer->dnsmgr = NULL;
03021          unref_peer(peer, "Release peer from dnsmgr");
03022       }
03023       return CMP_MATCH;
03024    }
03025    return 0;
03026 }

static enum match_req_res match_req_to_dialog ( struct sip_pvt *  sip_pvt_ptr,
struct match_req_args arg 
) [static]

Definition at line 8184 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::ruri, match_req_args::seqno, 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().

08185 {
08186    const char *init_ruri = NULL;
08187    if (sip_pvt_ptr->initreq.headers) {
08188       init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2);
08189    }
08190 
08191    /*
08192     * Match Tags and call-id to Dialog
08193     */
08194    if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) {
08195       /* call-id does not match. */
08196       return SIP_REQ_NOT_MATCH;
08197    }
08198    if (arg->method == SIP_RESPONSE) {
08199       /* Verify totag if we have one stored for this dialog, but never be strict about this for
08200        * a response until the dialog is established */
08201       if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
08202          if (ast_strlen_zero(arg->totag)) {
08203             /* missing totag when they already gave us one earlier */
08204             return SIP_REQ_NOT_MATCH;
08205          }
08206          if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) {
08207             /* The totag of the response does not match the one we have stored */
08208             return SIP_REQ_NOT_MATCH;
08209          }
08210       }
08211       /* Verify fromtag of response matches the tag we gave them. */
08212       if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) {
08213          /* fromtag from response does not match our tag */
08214          return SIP_REQ_NOT_MATCH;
08215       }
08216    } else {
08217       /* Verify the fromtag of Request matches the tag they provided earlier.
08218        * If this is a Request with authentication credentials, forget their old
08219        * tag as it is not valid after the 401 or 407 response. */
08220       if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) {
08221          /* their tag does not match the one was have stored for them */
08222          return SIP_REQ_NOT_MATCH;
08223       }
08224       /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */
08225       if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) {
08226          /* totag from Request does not match our tag */
08227          return SIP_REQ_NOT_MATCH;
08228       }
08229    }
08230 
08231    /*
08232     * Compare incoming request against initial transaction.
08233     * 
08234     * This is a best effort attempt at distinguishing forked requests from
08235     * our initial transaction.  If all the elements are NOT in place to evaluate
08236     * this, this block is ignored and the dialog match is made regardless.
08237     * Once the totag is established after the dialog is confirmed, this is not necessary.
08238     *
08239     * CRITERIA required for initial transaction matching.
08240     * 
08241     * 1. Is a Request
08242     * 2. Callid and theirtag match (this is done in the dialog matching block)
08243     * 3. totag is NOT present
08244     * 4. CSeq matchs our initial transaction's cseq number
08245     * 5. pvt has init via branch parameter stored
08246     */
08247    if ((arg->method != SIP_RESPONSE) &&                 /* must be a Request */
08248       ast_strlen_zero(arg->totag) &&                   /* must not have a totag */
08249       (sip_pvt_ptr->init_icseq == arg->seqno) &&       /* the cseq must be the same as this dialogs initial cseq */
08250       !ast_strlen_zero(sip_pvt_ptr->initviabranch) &&  /* The dialog must have started with a RFC3261 compliant branch tag */
08251       init_ruri) {                                     /* the dialog must have an initial request uri associated with it */
08252       /* This Request matches all the criteria required for Loop/Merge detection.
08253        * Now we must go down the path of comparing VIA's and RURIs. */
08254       if (ast_strlen_zero(arg->viabranch) ||
08255          strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) ||
08256          ast_strlen_zero(arg->viasentby) ||
08257          strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) {
08258          /* At this point, this request does not match this Dialog.*/
08259 
08260          /* if methods are different this is just a mismatch */
08261          if ((sip_pvt_ptr->method != arg->method)) {
08262             return SIP_REQ_NOT_MATCH;
08263          }
08264 
08265          /* If RUIs are different, this is a forked request to a separate URI.
08266           * Returning a mismatch allows this Request to be processed separately. */
08267          if (sip_uri_cmp(init_ruri, arg->ruri)) {
08268             /* not a match, request uris are different */
08269             return SIP_REQ_NOT_MATCH;
08270          }
08271 
08272          /* Loop/Merge Detected
08273           *
08274           * ---Current Matches to Initial Request---
08275           * request uri
08276           * Call-id
08277           * their-tag
08278           * no totag present
08279           * method
08280           * cseq
08281           *
08282           * --- Does not Match Initial Request ---
08283           * Top Via
08284           *
08285           * Without the same Via, this can not match our initial transaction for this dialog,
08286           * but given that this Request matches everything else associated with that initial
08287           * Request this is most certainly a Forked request in which we have already received
08288           * part of the fork.
08289           */
08290          return SIP_REQ_LOOP_DETECTED;
08291       }
08292    } /* end of Request Via check */
08293 
08294    /* Match Authentication Request.
08295     *
08296     * A Request with an Authentication header must come back with the
08297     * same Request URI.  Otherwise it is not a match.
08298     */
08299    if ((arg->method != SIP_RESPONSE) &&      /* Must be a Request type to even begin checking this */
08300       ast_strlen_zero(arg->totag) &&        /* no totag is present to match */
08301       arg->authentication_present &&        /* Authentication header is present in Request */
08302       sip_uri_cmp(init_ruri, arg->ruri)) {  /* Compare the Request URI of both the last Request and this new one */
08303 
08304       /* Authentication was provided, but the Request URI did not match the last one on this dialog. */
08305       return SIP_REQ_NOT_MATCH;
08306    }
08307 
08308    return SIP_REQ_MATCH;
08309 }

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 3337 of file chan_sip.c.

References len(), sip_methods, and text.

Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().

03338 {
03339    int len = strlen(sip_methods[id].text);
03340    int l_name = name ? strlen(name) : 0;
03341    /* true if the string is long enough, and ends with whitespace, and matches */
03342    return (l_name >= len && name && name[len] < 33 &&
03343       !strncasecmp(sip_methods[id].text, name, len));
03344 }

static void mwi_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Receive MWI events that we have subscribed to.

Definition at line 15049 of file chan_sip.c.

References sip_send_mwi_to_peer().

Referenced by add_peer_mwi_subs().

15050 {
15051    struct sip_peer *peer = userdata;
15052 
15053    sip_send_mwi_to_peer(peer, 0);
15054 }

static void network_change_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Definition at line 15079 of file chan_sip.c.

References ast_debug, ast_sched_add(), and network_change_event_sched_cb().

Referenced by network_change_event_subscribe().

15080 {
15081    ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n");
15082    if (network_change_event_sched_id == -1) {
15083       network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
15084    }
15085 }

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

Definition at line 15071 of file chan_sip.c.

References sip_send_all_mwi_subscriptions(), and sip_send_all_registers().

Referenced by network_change_event_cb().

15072 {
15073    network_change_event_sched_id = -1;
15074    sip_send_all_registers();
15075    sip_send_all_mwi_subscriptions();
15076    return 0;
15077 }

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 3302 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(), sip_poke_peer(), and transmit_register().

03303 {
03304    if (dialog && dialog->options && dialog->options->outboundproxy) {
03305       if (sipdebug) {
03306          ast_debug(1, "OBPROXY: Applying dialplan set OBproxy to this call\n");
03307       }
03308       append_history(dialog, "OBproxy", "Using dialplan obproxy %s", dialog->options->outboundproxy->name);
03309       return dialog->options->outboundproxy;
03310    }
03311    if (peer && peer->outboundproxy) {
03312       if (sipdebug) {
03313          ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n");
03314       }
03315       append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name);
03316       return peer->outboundproxy;
03317    }
03318    if (sip_cfg.outboundproxy.name[0]) {
03319       if (sipdebug) {
03320          ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n");
03321       }
03322       append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name);
03323       return &sip_cfg.outboundproxy;
03324    }
03325    if (sipdebug) {
03326       ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n");
03327    }
03328    return NULL;
03329 }

static void on_dns_update_mwi ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
) [static]

Definition at line 12845 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().

12846 {
12847    struct sip_subscription_mwi *mwi = data;
12848    const char *old_str;
12849 
12850    /* This shouldn't happen, but just in case */
12851    if (ast_sockaddr_isnull(new)) {
12852       ast_debug(1, "Empty sockaddr change...ignoring!\n");
12853       return;
12854    }
12855 
12856    old_str = ast_strdupa(ast_sockaddr_stringify(old));
12857    ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, old_str, ast_sockaddr_stringify(new));
12858    ast_sockaddr_copy(&mwi->us, new);
12859 }

static void on_dns_update_peer ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
) [static]

Definition at line 12816 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().

12817 {
12818    struct sip_peer *peer = data;
12819    const char *old_str;
12820 
12821    /* This shouldn't happen, but just in case */
12822    if (ast_sockaddr_isnull(new)) {
12823       ast_debug(1, "Empty sockaddr change...ignoring!\n");
12824       return;
12825    }
12826 
12827    if (!ast_sockaddr_isnull(&peer->addr)) {
12828       ao2_unlink(peers_by_ip, peer);
12829    }
12830 
12831    if (!ast_sockaddr_port(new)) {
12832       ast_sockaddr_set_port(new, default_sip_port(peer->socket.type));
12833    }
12834 
12835    old_str = ast_strdupa(ast_sockaddr_stringify(old));
12836    ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, old_str, ast_sockaddr_stringify(new));
12837 
12838    ao2_lock(peer);
12839    ast_sockaddr_copy(&peer->addr, new);
12840    ao2_unlock(peer);
12841 
12842    ao2_link(peers_by_ip, peer);
12843 }

static void on_dns_update_registry ( struct ast_sockaddr old,
struct ast_sockaddr new,
void *  data 
) [static]

Definition at line 12795 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().

12796 {
12797    struct sip_registry *reg = data;
12798    const char *old_str;
12799 
12800    /* This shouldn't happen, but just in case */
12801    if (ast_sockaddr_isnull(new)) {
12802       ast_debug(1, "Empty sockaddr change...ignoring!\n");
12803       return;
12804    }
12805 
12806    if (!ast_sockaddr_port(new)) {
12807       ast_sockaddr_set_port(new, reg->portno);
12808    }
12809 
12810    old_str = ast_strdupa(ast_sockaddr_stringify(old));
12811 
12812    ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), old_str, ast_sockaddr_stringify(new));
12813    ast_sockaddr_copy(&reg->us, new);
12814 }

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 8690 of file chan_sip.c.

References ast_strdupa, ast_strip_quoted(), ast_strlen_zero(), get_header(), and mark_parsed_methods().

Referenced by set_pvt_allowed_methods().

08691 {
08692    char *allow = ast_strdupa(get_header(req, "Allow"));
08693    unsigned int allowed_methods = SIP_UNKNOWN;
08694 
08695    if (ast_strlen_zero(allow)) {
08696       /* I have witnessed that REGISTER requests from Polycom phones do not
08697        * place the phone's allowed methods in an Allow header. Instead, they place the
08698        * allowed methods in a methods= parameter in the Contact header.
08699        */
08700       char *contact = ast_strdupa(get_header(req, "Contact"));
08701       char *methods = strstr(contact, ";methods=");
08702 
08703       if (ast_strlen_zero(methods)) {
08704          /* RFC 3261 states:
08705           *
08706           * "The absence of an Allow header field MUST NOT be
08707           * interpreted to mean that the UA sending the message supports no
08708           * methods.   Rather, it implies that the UA is not providing any
08709           * information on what methods it supports."
08710           *
08711           * For simplicity, we'll assume that the peer allows all known
08712           * SIP methods if they have no Allow header. We can then clear out the necessary
08713           * bits if the peer lets us know that we have sent an unsupported method.
08714           */
08715          return UINT_MAX;
08716       }
08717       allow = ast_strip_quoted(methods + 9, "\"", "\"");
08718    }
08719    mark_parsed_methods(&allowed_methods, allow);
08720    return allowed_methods;
08721 }

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

Copy SIP request, parse it.

Definition at line 4262 of file chan_sip.c.

References copy_request(), and parse_request().

Referenced by send_request(), and send_response().

04263 {
04264    copy_request(dst, src);
04265    parse_request(dst);
04266 }

int parse_minse ( const char *  p_hdrval,
int *const   p_interval 
) [static]

Session-Timers: Function for parsing Min-SE header.

Definition at line 26881 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), ast_strlen_zero(), and LOG_WARNING.

Referenced by handle_request_invite_st(), and proc_422_rsp().

26882 {
26883    if (ast_strlen_zero(p_hdrval)) {
26884       ast_log(LOG_WARNING, "Null Min-SE header\n");
26885       return -1;
26886    }
26887 
26888    *p_interval = 0;
26889    p_hdrval = ast_skip_blanks(p_hdrval);
26890    if (!sscanf(p_hdrval, "%30d", p_interval)) {
26891       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
26892       return -1;
26893    }
26894 
26895    ast_debug(2, "Received Min-SE: %d\n", *p_interval);
26896    return 0;
26897 }

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 20359 of file chan_sip.c.

References ao2_ref, ast_copy_string(), ast_debug, ast_log(), ast_strdup, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), find_closing_quote(), get_header(), get_in_brackets(), get_transport(), LOG_NOTICE, pbx_builtin_setvar_helper(), remove_uri_parameters(), and set_socket_transport().

Referenced by change_redirecting_information().

20360 {
20361    char contact[SIPBUFSIZE];
20362    char *contact_name = NULL;
20363    char *contact_number = NULL;
20364    char *separator, *trans;
20365    char *domain;
20366    enum sip_transport transport = SIP_TRANSPORT_UDP;
20367 
20368    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
20369    if ((separator = strchr(contact, ',')))
20370       *separator = '\0';
20371 
20372    contact_number = get_in_brackets(contact);
20373    if ((trans = strcasestr(contact_number, ";transport="))) {
20374       trans += 11;
20375 
20376       if ((separator = strchr(trans, ';')))
20377          *separator = '\0';
20378 
20379       if (!strncasecmp(trans, "tcp", 3))
20380          transport = SIP_TRANSPORT_TCP;
20381       else if (!strncasecmp(trans, "tls", 3))
20382          transport = SIP_TRANSPORT_TLS;
20383       else {
20384          if (strncasecmp(trans, "udp", 3))
20385             ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number);
20386          /* This will assume UDP for all unknown transports */
20387          transport = SIP_TRANSPORT_UDP;
20388       }
20389    }
20390    contact_number = remove_uri_parameters(contact_number);
20391 
20392    if (p->socket.tcptls_session) {
20393       ao2_ref(p->socket.tcptls_session, -1);
20394       p->socket.tcptls_session = NULL;
20395    }
20396 
20397    set_socket_transport(&p->socket, transport);
20398 
20399    if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
20400       char *host = NULL;
20401       if (!strncasecmp(contact_number, "sip:", 4))
20402          contact_number += 4;
20403       else if (!strncasecmp(contact_number, "sips:", 5))
20404          contact_number += 5;
20405       separator = strchr(contact_number, '/');
20406       if (separator)
20407          *separator = '\0';
20408       if ((host = strchr(contact_number, '@'))) {
20409          *host++ = '\0';
20410          ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, get_transport(transport), host);
20411          if (p->owner)
20412             ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", contact_number, get_transport(transport), host);
20413       } else {
20414          ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), contact_number);
20415          if (p->owner)
20416             ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), contact_number);
20417       }
20418    } else {
20419       separator = strchr(contact, '@');
20420       if (separator) {
20421          *separator++ = '\0';
20422          domain = separator;
20423       } else {
20424          /* No username part */
20425          domain = contact;
20426       }
20427       separator = strchr(contact, '/');   /* WHEN do we hae a forward slash in the URI? */
20428       if (separator)
20429          *separator = '\0';
20430 
20431       if (!strncasecmp(contact_number, "sip:", 4))
20432          contact_number += 4;
20433       else if (!strncasecmp(contact_number, "sips:", 5))
20434          contact_number += 5;
20435       separator = strchr(contact_number, ';');  /* And username ; parameters? */
20436       if (separator)
20437          *separator = '\0';
20438       ast_uri_decode(contact_number);
20439       if (set_call_forward) {
20440          ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain);
20441          if (p->owner) {
20442             pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
20443             ast_string_field_set(p->owner, call_forward, contact_number);
20444          }
20445       }
20446    }
20447 
20448    /* We've gotten the number for the contact, now get the name */
20449 
20450    if (*contact == '\"') {
20451       contact_name = contact + 1;
20452       if (!(separator = (char *)find_closing_quote(contact_name, NULL))) {
20453          ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact);
20454       }
20455       *separator = '\0';
20456    }
20457 
20458    if (name && !ast_strlen_zero(contact_name)) {
20459       *name = ast_strdup(contact_name);
20460    }
20461    if (number) {
20462       *number = ast_strdup(contact_number);
20463    }
20464 }

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 14356 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, get_header(), get_in_brackets(), and TRUE.

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

14357 {
14358    char contact[SIPBUFSIZE];
14359    char *c;
14360 
14361    /* Look for brackets */
14362    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
14363    c = get_in_brackets(contact);
14364 
14365    /* Save full contact to call pvt for later bye or re-invite */
14366    ast_string_field_set(pvt, fullcontact, c);
14367 
14368    /* Save URI for later ACKs, BYE or RE-invites */
14369    ast_string_field_set(pvt, okcontacturi, c);
14370 
14371    /* We should return false for URI:s we can't handle,
14372       like tel:, mailto:,ldap: etc */
14373    return TRUE;      
14374 }

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 14463 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_transport(), 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, ast_verbose, copy_socket_data(), default_sip_port(), EVENT_FLAG_SYSTEM, expire_register(), FALSE, get_header(), get_in_brackets(), get_transport_str2enum(), LOG_NOTICE, LOG_WARNING, manager_event, parse_uri_legacy_check(), ref_peer(), register_peer_exten(), set_socket_transport(), sip_cfg, sip_poke_peer(), sip_pvt_lock, sip_pvt_unlock, TRUE, unref_peer(), VERBOSE_PREFIX_3, and VERBOSITY_ATLEAST.

Referenced by register_verify().

14464 {
14465    char contact[SIPBUFSIZE];
14466    char data[SIPBUFSIZE];
14467    const char *expires = get_header(req, "Expires");
14468    int expire = atoi(expires);
14469    char *curi = NULL, *hostport = NULL, *transport = NULL;
14470    int transport_type;
14471    const char *useragent;
14472    struct ast_sockaddr oldsin, testsa;
14473    char *firstcuri = NULL;
14474    int start = 0;
14475    int wildcard_found = 0;
14476    int single_binding_found = 0;
14477 
14478    ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
14479 
14480    if (ast_strlen_zero(expires)) {  /* No expires header, try look in Contact: */
14481       char *s = strcasestr(contact, ";expires=");
14482       if (s) {
14483          expires = strsep(&s, ";"); /* trim ; and beyond */
14484          if (sscanf(expires + 9, "%30d", &expire) != 1) {
14485             expire = default_expiry;
14486          }
14487       } else {
14488          /* Nothing has been specified */
14489          expire = default_expiry;
14490       }
14491    }
14492 
14493    if (expire > max_expiry) {
14494       expire = max_expiry;
14495    }
14496    if (expire < min_expiry && expire != 0) {
14497       expire = min_expiry;
14498    }
14499    pvt->expiry = expire;
14500 
14501    copy_socket_data(&pvt->socket, &req->socket);
14502 
14503    do {
14504       /* Look for brackets */
14505       curi = contact;
14506       if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
14507          strsep(&curi, ";");  /* This is Header options, not URI options */
14508       curi = get_in_brackets(contact);
14509       if (!firstcuri) {
14510          firstcuri = ast_strdupa(curi);
14511       }
14512 
14513       if (!strcasecmp(curi, "*")) {
14514          wildcard_found = 1;
14515       } else {
14516          single_binding_found = 1;
14517       }
14518 
14519       if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) {
14520          /* Contact header parameter "*" detected, so punt if: Expires header is missing,
14521           * Expires value is not zero, or another Contact header is present. */
14522          return PARSE_REGISTER_FAILED;
14523       }
14524 
14525       ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
14526    } while (!ast_strlen_zero(contact));
14527    curi = firstcuri;
14528 
14529    /* if they did not specify Contact: or Expires:, they are querying
14530       what we currently have stored as their contact address, so return
14531       it
14532    */
14533    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
14534       /* If we have an active registration, tell them when the registration is going to expire */
14535       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) {
14536          pvt->expiry = ast_sched_when(sched, peer->expire);
14537       }
14538       return PARSE_REGISTER_QUERY;
14539    } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */
14540       /* This means remove all registrations and return OK */
14541       AST_SCHED_DEL_UNREF(sched, peer->expire,
14542             unref_peer(peer, "remove register expire ref"));
14543       ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
14544       expire_register(ref_peer(peer,"add ref for explicit expire_register"));
14545       return PARSE_REGISTER_UPDATE;
14546    }
14547 
14548    /* Store whatever we got as a contact from the client */
14549    ast_string_field_set(peer, fullcontact, curi);
14550 
14551    /* For the 200 OK, we should use the received contact */
14552    ast_string_field_build(pvt, our_contact, "<%s>", curi);
14553 
14554    /* Make sure it's a SIP URL */
14555    if (ast_strlen_zero(curi) || parse_uri_legacy_check(curi, "sip:,sips:", &curi, NULL, &hostport, &transport)) {
14556       ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n");
14557    }
14558 
14559    /* handle the transport type specified in Contact header. */
14560    if (!(transport_type = get_transport_str2enum(transport))) {
14561       transport_type = pvt->socket.type;
14562    }
14563 
14564    /* if the peer's socket type is different than the Registration
14565     * transport type, change it.  If it got this far, it is a
14566     * supported type, but check just in case */
14567    if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) {
14568       set_socket_transport(&peer->socket, transport_type);
14569    }
14570 
14571    oldsin = peer->addr;
14572 
14573    /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */
14574    if (!ast_sockaddr_isnull(&peer->addr) && (!peer->is_realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))) {
14575       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
14576    }
14577 
14578    if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) {
14579        /* use the data provided in the Contact header for call routing */
14580       ast_debug(1, "Store REGISTER's Contact header for call routing.\n");
14581       /* XXX This could block for a long time XXX */
14582       /*! \todo Check NAPTR/SRV if we have not got a port in the URI */
14583       if (ast_sockaddr_resolve_first_transport(&testsa, hostport, 0, peer->socket.type)) {
14584          ast_log(LOG_WARNING, "Invalid hostport '%s'\n", hostport);
14585          ast_string_field_set(peer, fullcontact, "");
14586          ast_string_field_set(pvt, our_contact, "");
14587          return PARSE_REGISTER_FAILED;
14588       }
14589 
14590       /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records.
14591          The hostport part is actually a host. */
14592       peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE;
14593 
14594       if (!ast_sockaddr_port(&testsa)) {
14595          ast_sockaddr_set_port(&testsa, default_sip_port(transport_type));
14596       }
14597 
14598       ast_sockaddr_copy(&peer->addr, &testsa);
14599    } else {
14600       /* Don't trust the contact field.  Just use what they came to us
14601          with */
14602       ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n");
14603       peer->addr = pvt->recv;
14604    }
14605 
14606    /* Check that they're allowed to register at this IP */
14607    if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW ||
14608          ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) {
14609       ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", hostport,
14610             ast_sockaddr_stringify_addr(&peer->addr));
14611       ast_string_field_set(peer, fullcontact, "");
14612       ast_string_field_set(pvt, our_contact, "");
14613       return PARSE_REGISTER_DENIED;
14614    }
14615 
14616    /* if the Contact header information copied into peer->addr matches the
14617     * received address, and the transport types are the same, then copy socket
14618     * data into the peer struct */
14619    if ((peer->socket.type == pvt->socket.type) &&
14620       !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) {
14621       copy_socket_data(&peer->socket, &pvt->socket);
14622    }
14623 
14624    /* Now that our address has been updated put ourselves back into the container for lookups */
14625    if (!peer->is_realtime || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
14626       ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table");
14627    }
14628 
14629    /* Save SIP options profile */
14630    peer->sipoptions = pvt->sipoptions;
14631 
14632    if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) {
14633       ast_string_field_set(peer, username, curi);
14634    }
14635 
14636    AST_SCHED_DEL_UNREF(sched, peer->expire,
14637          unref_peer(peer, "remove register expire ref"));
14638 
14639    if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
14640       peer->expire = -1;
14641    } else {
14642       peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register,
14643             ref_peer(peer, "add registration ref"));
14644       if (peer->expire == -1) {
14645          unref_peer(peer, "remote registration ref");
14646       }
14647    }
14648    snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr),
14649        expire, peer->username, peer->fullcontact);
14650    /* We might not immediately be able to reconnect via TCP, but try caching it anyhow */
14651    if (!peer->rt_fromcontact || !sip_cfg.peer_rtupdate)
14652       ast_db_put("SIP/Registry", peer->name, data);
14653    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));
14654 
14655    /* Is this a new IP address for us? */
14656    if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) {
14657       ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name,
14658             ast_sockaddr_stringify(&peer->addr));
14659    }
14660    sip_pvt_unlock(pvt);
14661    sip_poke_peer(peer, 0);
14662    sip_pvt_lock(pvt);
14663    register_peer_exten(peer, 1);
14664    
14665    /* Save User agent */
14666    useragent = get_header(req, "User-Agent");
14667    if (strcasecmp(useragent, peer->useragent)) {
14668       ast_string_field_set(peer, useragent, useragent);
14669       ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);
14670    }
14671    return PARSE_REGISTER_UPDATE;
14672 }

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 8795 of file chan_sip.c.

References ast_debug, ast_log(), ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), determine_firstline_parts(), and LOG_WARNING.

Referenced by handle_request_do(), initialize_initreq(), and parse_copy().

08796 {
08797    char *c = req->data->str;
08798    ptrdiff_t *dst = req->header;
08799    int i = 0, lim = SIP_MAX_HEADERS - 1;
08800    unsigned int skipping_headers = 0;
08801    ptrdiff_t current_header_offset = 0;
08802    char *previous_header = "";
08803 
08804    req->header[0] = 0;
08805    req->headers = -1;   /* mark that we are working on the header */
08806    for (; *c; c++) {
08807       if (*c == '\r') {    /* remove \r */
08808          *c = '\0';
08809       } else if (*c == '\n') {   /* end of this line */
08810          *c = '\0';
08811          current_header_offset = (c + 1) - ast_str_buffer(req->data);
08812          previous_header = ast_str_buffer(req->data) + dst[i];
08813          if (skipping_headers) {
08814             /* check to see if this line is blank; if so, turn off
08815                the skipping flag, so the next line will be processed
08816                as a body line */
08817             if (ast_strlen_zero(previous_header)) {
08818                skipping_headers = 0;
08819             }
08820             dst[i] = current_header_offset; /* record start of next line */
08821             continue;
08822          }
08823          if (sipdebug) {
08824             ast_debug(4, "%7s %2d [%3d]: %s\n",
08825                  req->headers < 0 ? "Header" : "Body",
08826                  i, (int) strlen(previous_header), previous_header);
08827          }
08828          if (ast_strlen_zero(previous_header) && req->headers < 0) {
08829             req->headers = i; /* record number of header lines */
08830             dst = req->line;  /* start working on the body */
08831             i = 0;
08832             lim = SIP_MAX_LINES - 1;
08833          } else { /* move to next line, check for overflows */
08834             if (i++ == lim) {
08835                /* if we're processing headers, then skip any remaining
08836                   headers and move on to processing the body, otherwise
08837                   we're done */
08838                if (req->headers != -1) {
08839                   break;
08840                } else {
08841                   req->headers = i;
08842                   dst = req->line;
08843                   i = 0;
08844                   lim = SIP_MAX_LINES - 1;
08845                   skipping_headers = 1;
08846                }
08847             }
08848          }
08849          dst[i] = current_header_offset; /* record start of next line */
08850       }
08851    }
08852 
08853    /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF,
08854       but since some devices send without, we'll be generous in what we accept. However,
08855       if we've already reached the maximum number of lines for portion of the message
08856       we were parsing, we can't accept any more, so just ignore it.
08857    */
08858    previous_header = ast_str_buffer(req->data) + dst[i];
08859    if ((i < lim) && !ast_strlen_zero(previous_header)) {
08860       if (sipdebug) {
08861          ast_debug(4, "%7s %2d [%3d]: %s\n",
08862               req->headers < 0 ? "Header" : "Body",
08863               i, (int) strlen(previous_header), previous_header );
08864       }
08865       i++;
08866    }
08867 
08868    /* update count of header or body lines */
08869    if (req->headers >= 0) {   /* we are in the body */
08870       req->lines = i;
08871    } else {       /* no body */
08872       req->headers = i;
08873       req->lines = 0;
08874       /* req->data->used will be a NULL byte */
08875       req->line[0] = ast_str_strlen(req->data);
08876    }
08877 
08878    if (*c) {
08879       ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c);
08880    }
08881 
08882    /* Split up the first line parts */
08883    return determine_firstline_parts(req);
08884 }

int parse_session_expires ( const char *  p_hdrval,
int *const   p_interval,
enum st_refresher_param *const   p_ref 
) [static]

Session-Timers: Function for parsing Session-Expires header.

Definition at line 26901 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), and LOG_WARNING.

Referenced by handle_request_invite_st(), and handle_response_invite().

26902 {
26903    char *p_token;
26904    int  ref_idx;
26905    char *p_se_hdr;
26906 
26907    if (ast_strlen_zero(p_hdrval)) {
26908       ast_log(LOG_WARNING, "Null Session-Expires header\n");
26909       return -1;
26910    }
26911 
26912    *p_ref = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN;
26913    *p_interval = 0;
26914 
26915    p_se_hdr = ast_strdupa(p_hdrval);
26916    p_se_hdr = ast_skip_blanks(p_se_hdr);
26917 
26918    while ((p_token = strsep(&p_se_hdr, ";"))) {
26919       p_token = ast_skip_blanks(p_token);
26920       if (!sscanf(p_token, "%30d", p_interval)) {
26921          ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n");
26922          return -1;
26923       }
26924 
26925       ast_debug(2, "Session-Expires: %d\n", *p_interval);
26926 
26927       if (!p_se_hdr)
26928          continue;
26929 
26930       p_se_hdr = ast_skip_blanks(p_se_hdr);
26931       ref_idx = strlen("refresher=");
26932       if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
26933          p_se_hdr += ref_idx;
26934          p_se_hdr = ast_skip_blanks(p_se_hdr);
26935 
26936          if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) {
26937             *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAC;
26938             ast_debug(2, "Refresher: UAC\n");
26939          } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) {
26940             *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAS;
26941             ast_debug(2, "Refresher: UAS\n");
26942          } else {
26943             ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr);
26944             return -1;
26945          }
26946          break;
26947       }
26948    }
26949    return 0;
26950 }

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 14382 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().

14383 {
14384    int ret = parse_uri(uri, scheme, user, pass, hostport, transport);
14385    if (sip_cfg.legacy_useroption_parsing) { /* if legacy mode is active, strip semis from the user field */
14386       char *p;
14387       if ((p = strchr(uri, (int)';'))) {
14388          *p = '\0';
14389       }
14390    }
14391    return ret;
14392 }

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 30736 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

30737 {
30738    struct sip_peer *peer = obj, *peer2 = arg;
30739 
30740    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
30741 }

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

Definition at line 17501 of file chan_sip.c.

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

Referenced by sip_show_objects().

17502 {
17503    struct sip_peer *peer = userobj;
17504    int refc = ao2_t_ref(userobj, 0, "");
17505    struct ast_cli_args *a = (struct ast_cli_args *) arg;
17506    
17507    ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n",
17508       peer->name, 0, refc);
17509    return 0;
17510 }

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 30726 of file chan_sip.c.

References ast_str_case_hash().

Referenced by load_module().

30727 {
30728    const struct sip_peer *peer = obj;
30729 
30730    return ast_str_case_hash(peer->name);
30731 }

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

Match Peers by IP and Port number.

This function has two modes.

  • If the peer arg does not have INSECURE_PORT set, then we will only return a match for a peer that matches both the IP and port.
  • If the peer arg does have the INSECURE_PORT flag set, then we will only return a match for a peer that matches the IP and has insecure=port in its configuration.

This callback will be used twice when doing peer matching. There is a first pass for full IP+port matching, and a second pass in case there is a match that meets the insecure=port criteria.

Note:
Connections coming in over TCP or TLS should never be matched by port.
the peer's addr struct provides to fields combined to make a key: the sin_addr.s_addr and sin_port fields.

Definition at line 30784 of file chan_sip.c.

References ast_sockaddr_cmp_addr(), ast_sockaddr_port, ast_test_flag, CMP_MATCH, and CMP_STOP.

Referenced by load_module().

30785 {
30786    struct sip_peer *peer = obj, *peer2 = arg;
30787 
30788    if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) {
30789       /* IP doesn't match */
30790       return 0;
30791    }
30792 
30793    /* We matched the IP, check to see if we need to match by port as well. */
30794    if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) {
30795       /* peer matching on port is not possible with TCP/TLS */
30796       return CMP_MATCH | CMP_STOP;
30797    } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
30798       /* We are allowing match without port for peers configured that
30799        * way in this pass through the peers. */
30800       return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ?
30801             (CMP_MATCH | CMP_STOP) : 0;
30802    }
30803 
30804    /* Now only return a match if the port matches, as well. */
30805    return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ?
30806          (CMP_MATCH | CMP_STOP) : 0;
30807 }

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

Hash function based on the the peer's ip address. For IPv6, we use the end of the address.

Todo:
Find a better hashing function

Definition at line 30748 of file chan_sip.c.

References ast_log(), ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.

Referenced by load_module().

30749 {
30750    const struct sip_peer *peer = obj;
30751    int ret = 0;
30752 
30753    if (ast_sockaddr_isnull(&peer->addr)) {
30754       ast_log(LOG_ERROR, "Empty address\n");
30755    }
30756 
30757    ret = ast_sockaddr_hash(&peer->addr);
30758 
30759    if (ret < 0) {
30760       ret = -ret;
30761    }
30762 
30763    return ret;
30764 }

static void peer_mailboxes_to_str ( struct ast_str **  mailbox_str,
struct sip_peer *  peer 
) [static]

list peer mailboxes to CLI

Definition at line 18035 of file chan_sip.c.

References AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_str_append(), ast_strlen_zero(), mailbox, and S_OR.

Referenced by _sip_show_peer(), function_sippeer(), show_channels_cb(), and sip_send_mwi_to_peer().

18036 {
18037    struct sip_mailbox *mailbox;
18038 
18039    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
18040       ast_str_append(mailbox_str, 0, "%s%s%s%s",
18041          mailbox->mailbox,
18042          ast_strlen_zero(mailbox->context) ? "" : "@",
18043          S_OR(mailbox->context, ""),
18044          AST_LIST_NEXT(mailbox, entry) ? "," : "");
18045    }
18046 }

static int peer_markall_func ( void *  device,
void *  arg,
int  flags 
) [static]

Definition at line 28749 of file chan_sip.c.

Referenced by reload_config().

28750 {
28751    struct sip_peer *peer = device;
28752    peer->the_mark = 1;
28753    return 0;
28754 }

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

Definition at line 2992 of file chan_sip.c.

References AST_SCHED_DEL_UNREF, and unref_peer().

Referenced by match_and_cleanup_peer_sched().

02993 {
02994    if (peer->pokeexpire != -1) {
02995       AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
02996             unref_peer(peer, "removing poke peer ref"));
02997    }
02998    if (peer->expire != -1) {
02999       AST_SCHED_DEL_UNREF(sched, peer->expire,
03000             unref_peer(peer, "remove register expire ref"));
03001    }
03002 }

static int peer_status ( struct sip_peer *  peer,
char *  status,
int  statuslen 
) [static]

Definition at line 17052 of file chan_sip.c.

References ast_copy_string().

Referenced by _sip_show_peer(), _sip_show_peers_one(), and function_sippeer().

17053 {
17054    int res = 0;
17055    if (peer->maxms) {
17056       if (peer->lastms < 0) {
17057          ast_copy_string(status, "UNREACHABLE", statuslen);
17058       } else if (peer->lastms > peer->maxms) {
17059          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
17060          res = 1;
17061       } else if (peer->lastms) {
17062          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
17063          res = 1;
17064       } else {
17065          ast_copy_string(status, "UNKNOWN", statuslen);
17066       }
17067    } else {
17068       ast_copy_string(status, "Unmonitored", statuslen);
17069       /* Checking if port is 0 */
17070       res = -1;
17071    }
17072    return res;
17073 }

int peercomparefunc ( const void *  a,
const void *  b 
)

Definition at line 17280 of file chan_sip.c.

Referenced by _sip_show_peers().

17281 {
17282    struct sip_peer **ap = (struct sip_peer **)a;
17283    struct sip_peer **bp = (struct sip_peer **)b;
17284    return strcmp((*ap)->name, (*bp)->name);
17285 }

static int peers_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
) [static]

Definition at line 31694 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ARRAY_LEN, ast_cdr_flags2str(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_describe_caller_presentation(), AST_LIST_TRAVERSE, get_transport_list(), mailbox, text, and transfermode2str().

31696 {
31697    struct sip_peer *peer;
31698    struct ao2_iterator i;
31699    struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node;
31700    struct ast_data *data_sip_options;
31701    int total_mailboxes, x;
31702    struct sip_mailbox *mailbox;
31703 
31704    i = ao2_iterator_init(peers, 0);
31705    while ((peer = ao2_iterator_next(&i))) {
31706       ao2_lock(peer);
31707 
31708       data_peer = ast_data_add_node(data_root, "peer");
31709       if (!data_peer) {
31710          ao2_unlock(peer);
31711          ao2_ref(peer, -1);
31712          continue;
31713       }
31714 
31715       ast_data_add_structure(sip_peer, data_peer, peer);
31716 
31717       /* transfer mode */
31718       enum_node = ast_data_add_node(data_peer, "allowtransfer");
31719       if (!enum_node) {
31720          ao2_unlock(peer);
31721          ao2_ref(peer, -1);
31722          continue;
31723       }
31724       ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer));
31725       ast_data_add_int(enum_node, "value", peer->allowtransfer);
31726 
31727       /* transports */
31728       ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports));
31729 
31730       /* peer type */
31731       if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) {
31732          ast_data_add_str(data_peer, "type", "friend");
31733       } else if (peer->type & SIP_TYPE_PEER) {
31734          ast_data_add_str(data_peer, "type", "peer");
31735       } else if (peer->type & SIP_TYPE_USER) {
31736          ast_data_add_str(data_peer, "type", "user");
31737       }
31738 
31739       /* mailboxes */
31740       total_mailboxes = 0;
31741       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
31742          if (!total_mailboxes) {
31743             data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes");
31744             if (!data_peer_mailboxes) {
31745                break;
31746             }
31747             total_mailboxes++;
31748          }
31749 
31750          data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox");
31751          if (!data_peer_mailbox) {
31752             continue;
31753          }
31754          ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox);
31755          ast_data_add_str(data_peer_mailbox, "context", mailbox->context);
31756       }
31757 
31758       /* amaflags */
31759       enum_node = ast_data_add_node(data_peer, "amaflags");
31760       if (!enum_node) {
31761          ao2_unlock(peer);
31762          ao2_ref(peer, -1);
31763          continue;
31764       }
31765       ast_data_add_int(enum_node, "value", peer->amaflags);
31766       ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags));
31767 
31768       /* sip options */
31769       data_sip_options = ast_data_add_node(data_peer, "sipoptions");
31770       if (!data_sip_options) {
31771          ao2_unlock(peer);
31772          ao2_ref(peer, -1);
31773          continue;
31774       }
31775       for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
31776          ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id);
31777       }
31778 
31779       /* callingpres */
31780       enum_node = ast_data_add_node(data_peer, "callingpres");
31781       if (!enum_node) {
31782          ao2_unlock(peer);
31783          ao2_ref(peer, -1);
31784          continue;
31785       }
31786       ast_data_add_int(enum_node, "value", peer->callingpres);
31787       ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres));
31788 
31789       /* codecs */
31790       ast_data_add_codecs(data_peer, "codecs", peer->capability);
31791 
31792       if (!ast_data_search_match(search, data_peer)) {
31793          ast_data_remove_node(data_root, data_peer);
31794       }
31795 
31796       ao2_unlock(peer);
31797       ao2_ref(peer, -1);
31798    }
31799    ao2_iterator_destroy(&i);
31800 
31801    return 0;
31802 }

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.

Definition at line 3291 of file chan_sip.c.

References ast_strlen_zero().

Referenced by build_peer(), reload_config(), and sip_parse_register_line().

03292 {
03293    int port = standard;
03294    if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) {
03295       port = standard;
03296    }
03297 
03298    return port;
03299 }

static void print_codec_to_cli ( int  fd,
struct ast_codec_pref pref 
) [static]

Print codec list from preference to CLI/manager.

Definition at line 17872 of file chan_sip.c.

References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.

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

17873 {
17874    int x;
17875    format_t codec;
17876 
17877    for(x = 0; x < 64 ; x++) {
17878       codec = ast_codec_pref_index(pref, x);
17879       if (!codec)
17880          break;
17881       ast_cli(fd, "%s", ast_getformatname(codec));
17882       ast_cli(fd, ":%d", pref->framing[x]);
17883       if (x < 31 && ast_codec_pref_index(pref, x + 1))
17884          ast_cli(fd, ",");
17885    }
17886    if (!x)
17887       ast_cli(fd, "none");
17888 }

static void print_group ( int  fd,
ast_group_t  group,
int  crlf 
) [static]

Print call group and pickup group.

Definition at line 17553 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

17554 {
17555    char buf[256];
17556    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
17557 }

static void proc_422_rsp ( struct sip_pvt *  p,
struct sip_request *  rsp 
) [static]

Handle 422 response to INVITE with session-timer requested.

Session-Timers: An INVITE originated by Asterisk that asks for session-timers support from the UAS can result into a 422 response. This is how a UAS or an intermediary proxy server tells Asterisk that the session refresh interval offered by Asterisk is too low for them. The proc_422_rsp() function handles a 422 response. It extracts the Min-SE header that comes back in 422 and sends a new INVITE accordingly.

Definition at line 26960 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), get_header(), LOG_WARNING, parse_minse(), and transmit_invite().

Referenced by handle_response_invite().

26961 {
26962    int rtn;
26963    const char *p_hdrval;
26964    int minse;
26965 
26966    p_hdrval = get_header(rsp, "Min-SE");
26967    if (ast_strlen_zero(p_hdrval)) {
26968       ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval);
26969       return;
26970    }
26971    rtn = parse_minse(p_hdrval, &minse);
26972    if (rtn != 0) {
26973       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
26974       return;
26975    }
26976    p->stimer->st_cached_min_se = minse;
26977    if (p->stimer->st_interval < minse) {
26978       p->stimer->st_interval = minse;
26979    }
26980    transmit_invite(p, SIP_INVITE, 1, 2, NULL);
26981 }

static int proc_session_timer ( const void *  vp  )  [static]

Session-Timers: Process session refresh timeout event.

Definition at line 26811 of file chan_sip.c.

References ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, FALSE, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, stop_session_timer(), transmit_reinvite_with_sdp(), and TRUE.

Referenced by start_session_timer().

26812 {
26813    struct sip_pvt *p = (struct sip_pvt *) vp;
26814    int res = 0;
26815 
26816    if (!p->stimer) {
26817       ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid);
26818       goto return_unref;
26819    }
26820 
26821    ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid);
26822 
26823    if (!p->owner) {
26824       goto return_unref;
26825    }
26826 
26827    if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) {
26828       goto return_unref;
26829    }
26830 
26831    if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) {
26832       res = 1;
26833       if (T38_ENABLED == p->t38.state) {
26834          transmit_reinvite_with_sdp(p, TRUE, TRUE);
26835       } else {
26836          transmit_reinvite_with_sdp(p, FALSE, TRUE);
26837       }
26838    } else {
26839       if (p->stimer->quit_flag) {
26840          goto return_unref;
26841       }
26842       ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
26843       sip_pvt_lock(p);
26844       while (p->owner && ast_channel_trylock(p->owner)) {
26845          sip_pvt_unlock(p);
26846          usleep(1);
26847          if (p->stimer && p->stimer->quit_flag) {
26848             goto return_unref;
26849          }
26850          sip_pvt_lock(p);
26851       }
26852 
26853       ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
26854       ast_channel_unlock(p->owner);
26855       sip_pvt_unlock(p);
26856    }
26857 
26858 return_unref:
26859    if (!res) {
26860       /* An error occurred.  Stop session timer processing */
26861       if (p->stimer) {
26862          ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
26863          /* Don't pass go, don't collect $200.. we are the scheduled
26864           * callback. We can rip ourself out here. */
26865          p->stimer->st_schedid = -1;
26866          /* Calling stop_session_timer is nice for consistent debug
26867           * logs. */
26868          stop_session_timer(p);
26869       }
26870 
26871       /* If we are not asking to be rescheduled, then we need to release our
26872        * reference to the dialog. */
26873       dialog_unref(p, "removing session timer ref");
26874    }
26875 
26876    return res;
26877 }

static int process_crypto ( struct sip_pvt *  p,
struct ast_rtp_instance rtp,
struct sip_srtp **  srtp,
const char *  a 
) [static]

Definition at line 30564 of file chan_sip.c.

References ast_debug, ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_WARNING, sdp_crypto_process(), sdp_crypto_setup(), setup_srtp(), and TRUE.

Referenced by process_sdp().

30565 {
30566    /* If no RTP instance exists for this media stream don't bother processing the crypto line */
30567    if (!rtp) {
30568       ast_debug(3, "Received offer with crypto line for media stream that is not enabled\n");
30569       return FALSE;
30570    }
30571 
30572    if (strncasecmp(a, "crypto:", 7)) {
30573       return FALSE;
30574    }
30575    if (!*srtp) {
30576       if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
30577          ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
30578          return FALSE;
30579       }
30580 
30581       if (setup_srtp(srtp) < 0) {
30582          return FALSE;
30583       }
30584    }
30585 
30586    if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) {
30587       return FALSE;
30588    }
30589 
30590    if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) {
30591       return FALSE;
30592    }
30593 
30594    ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK);
30595 
30596    return TRUE;
30597 }

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

Process SIP SDP offer, select formats and activate media 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().

< RTP audio destination IP address

< RTP video destination IP address

< RTP text destination IP address

< UDPTL image destination IP address

< RTP audio destination port number

< RTP video destination port number

< RTP text destination port number

< UDPTL image destination port number

Definition at line 9092 of file chan_sip.c.

References ast_async_goto(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_T140RED, ast_getformatname_multiple(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_clear(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_set_m_type(), AST_RTP_DTMF, ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_remote_address(), ast_rtp_instance_stop(), ast_rtp_lookup_mime_multiple2(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_rtp_red_init(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, ast_udptl_get_far_max_datagram(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose, change_hold_state(), change_t38_state(), FALSE, get_sdp_iterate(), get_sdp_line(), initialize_udptl(), len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_crypto(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), S_COR, S_OR, sip_debug_test_pvt(), sockaddr_is_null_or_any(), text, TRUE, type, UDPTL_ERROR_CORRECTION_NONE, value, and VERBOSE_PREFIX_2.

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

09093 {
09094    /* Iterators for SDP parsing */
09095    int start = req->sdp_start;
09096    int next = start;
09097    int iterator = start;
09098 
09099    /* Temporary vars for SDP parsing */
09100    char type = '\0';
09101    const char *value = NULL;
09102    const char *m = NULL;           /* SDP media offer */
09103    const char *nextm = NULL;
09104    int len = -1;
09105 
09106    /* Host information */
09107    struct ast_sockaddr sessionsa;
09108    struct ast_sockaddr audiosa;
09109    struct ast_sockaddr videosa;
09110    struct ast_sockaddr textsa;
09111    struct ast_sockaddr imagesa;
09112    struct ast_sockaddr *sa = NULL;     /*!< RTP audio destination IP address */
09113    struct ast_sockaddr *vsa = NULL; /*!< RTP video destination IP address */
09114    struct ast_sockaddr *tsa = NULL; /*!< RTP text destination IP address */
09115    struct ast_sockaddr *isa = NULL; /*!< UDPTL image destination IP address */
09116    int portno = -1;        /*!< RTP audio destination port number */
09117    int vportno = -1;       /*!< RTP video destination port number */
09118    int tportno = -1;       /*!< RTP text destination port number */
09119    int udptlportno = -1;         /*!< UDPTL image destination port number */
09120 
09121    /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */
09122    format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0;
09123    int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0;
09124 
09125    struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp;
09126    format_t newjointcapability;           /* Negotiated capability */
09127    format_t newpeercapability;
09128    int newnoncodeccapability;
09129 
09130    const char *codecs;
09131    unsigned int codec;
09132 
09133    /* SRTP */
09134    int secure_audio = FALSE;
09135    int secure_video = FALSE;
09136 
09137    /* Others */
09138    int sendonly = -1;
09139    unsigned int numberofports;
09140    int numberofmediastreams = 0;
09141    int last_rtpmap_codec = 0;
09142    int red_data_pt[10];    /* For T.140 RED */
09143    int red_num_gen = 0;    /* For T.140 RED */
09144    char red_fmtp[100] = "empty"; /* For T.140 RED */
09145    int debug = sip_debug_test_pvt(p);
09146 
09147    /* START UNKNOWN */
09148    char buf[SIPBUFSIZE];
09149    /* END UNKNOWN */
09150 
09151    /* Initial check */
09152    if (!p->rtp) {
09153       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
09154       return -1;
09155    }
09156 
09157    /* Make sure that the codec structures are all cleared out */
09158    ast_rtp_codecs_payloads_clear(&newaudiortp, NULL);
09159    ast_rtp_codecs_payloads_clear(&newvideortp, NULL);
09160    ast_rtp_codecs_payloads_clear(&newtextrtp, NULL);
09161 
09162    /* Update our last rtprx when we receive an SDP, too */
09163    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
09164 
09165    memset(p->offered_media, 0, sizeof(p->offered_media));
09166 
09167    /* default: novideo and notext set */
09168    p->novideo = TRUE;
09169    p->notext = TRUE;
09170 
09171    /* Scan for the first media stream (m=) line to limit scanning of globals */
09172    nextm = get_sdp_iterate(&next, req, "m");
09173    if (ast_strlen_zero(nextm)) {
09174       ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n");
09175       return -1;
09176    }
09177 
09178    /* Scan session level SDP parameters (lines before first media stream) */
09179    while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
09180       int processed = FALSE;
09181       switch (type) {
09182       case 'o':
09183          /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal
09184           * error. We just want to ignore the SDP and let the rest of the packet be handled as normal.
09185           */
09186          if (!process_sdp_o(value, p)) {
09187             return (p->session_modify == FALSE) ? 0 : -1;
09188          }
09189          processed = TRUE;
09190          break;
09191       case 'c':
09192          if (process_sdp_c(value, &sessionsa)) {
09193             processed = TRUE;
09194             sa = &sessionsa;
09195             vsa = sa;
09196             tsa = sa;
09197             isa = sa;
09198          }
09199          break;
09200       case 'a':
09201          if (process_sdp_a_sendonly(value, &sendonly)) {
09202             processed = TRUE;
09203          }
09204          else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
09205             processed = TRUE;
09206          else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
09207             processed = TRUE;
09208          else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
09209             processed = TRUE;
09210          else if (process_sdp_a_image(value, p))
09211             processed = TRUE;
09212          break;
09213       }
09214 
09215       ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED.");
09216    }
09217 
09218    /* Scan media stream (m=) specific parameters loop */
09219    while (!ast_strlen_zero(nextm)) {
09220       int audio = FALSE;
09221       int video = FALSE;
09222       int image = FALSE;
09223       int text = FALSE;
09224       int processed_crypto = FALSE;
09225       char protocol[18] = {0,};
09226       unsigned int x;
09227 
09228       numberofports = 0;
09229       len = -1;
09230       start = next;
09231       m = nextm;
09232       iterator = next;
09233       nextm = get_sdp_iterate(&next, req, "m");
09234 
09235       /* Check for 'audio' media offer */
09236       if (strncmp(m, "audio ", 6) == 0) {
09237          if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
09238              (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) {
09239             if (x == 0) {
09240                ast_log(LOG_WARNING, "Ignoring audio media offer because port number is zero\n");
09241                continue;
09242             }
09243 
09244             /* Check number of ports offered for stream */
09245             if (numberofports > 1) {
09246                ast_log(LOG_WARNING, "%u ports offered for audio media, not supported by Asterisk. Will try anyway...\n", numberofports);
09247             }
09248 
09249             if (!strcmp(protocol, "SAVP")) {
09250                secure_audio = 1;
09251             } else if (strcmp(protocol, "AVP")) {
09252                ast_log(LOG_WARNING, "Unknown RTP profile in audio offer: %s\n", m);
09253                continue;
09254             }
09255 
09256             if (p->offered_media[SDP_AUDIO].order_offered) {
09257                ast_log(LOG_WARNING, "Rejecting non-primary audio stream: %s\n", m);
09258                return -1;
09259             }
09260 
09261             audio = TRUE;
09262             p->offered_media[SDP_AUDIO].order_offered = ++numberofmediastreams;
09263             portno = x;
09264 
09265             /* Scan through the RTP payload types specified in a "m=" line: */
09266             codecs = m + len;
09267             ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs));
09268             for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
09269                if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
09270                   ast_log(LOG_WARNING, "Invalid syntax in RTP audio format list: %s\n", codecs);
09271                   return -1;
09272                }
09273                if (debug) {
09274                   ast_verbose("Found RTP audio format %u\n", codec);
09275                }
09276 
09277                ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec);
09278             }
09279          } else {
09280             ast_log(LOG_WARNING, "Rejecting audio media offer due to invalid or unsupported syntax: %s\n", m);
09281             return -1;
09282          }
09283       }
09284       /* Check for 'video' media offer */
09285       else if (strncmp(m, "video ", 6) == 0) {
09286          if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
09287              (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) {
09288             if (x == 0) {
09289                ast_log(LOG_WARNING, "Ignoring video media offer because port number is zero\n");
09290                continue;
09291             }
09292 
09293             /* Check number of ports offered for stream */
09294             if (numberofports > 1) {
09295                ast_log(LOG_WARNING, "%u ports offered for video media, not supported by Asterisk. Will try anyway...\n", numberofports);
09296             }
09297 
09298             if (!strcmp(protocol, "SAVP")) {
09299                secure_video = 1;
09300             } else if (strcmp(protocol, "AVP")) {
09301                ast_log(LOG_WARNING, "Unknown RTP profile in video offer: %s\n", m);
09302                continue;
09303             }
09304 
09305             if (p->offered_media[SDP_VIDEO].order_offered) {
09306                ast_log(LOG_WARNING, "Rejecting non-primary video stream: %s\n", m);
09307                return -1;
09308             }
09309 
09310             video = TRUE;
09311             p->novideo = FALSE;
09312             p->offered_media[SDP_VIDEO].order_offered = ++numberofmediastreams;
09313             vportno = x;
09314 
09315             /* Scan through the RTP payload types specified in a "m=" line: */
09316             codecs = m + len;
09317             ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs));
09318             for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
09319                if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
09320                   ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs);
09321                   return -1;
09322                }
09323                if (debug) {
09324                   ast_verbose("Found RTP video format %u\n", codec);
09325                }
09326                ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec);
09327             }
09328          } else {
09329             ast_log(LOG_WARNING, "Rejecting video media offer due to invalid or unsupported syntax: %s\n", m);
09330             return -1;
09331          }
09332       }
09333       /* Check for 'text' media offer */
09334       else if (strncmp(m, "text ", 5) == 0) {
09335          if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
09336              (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) {
09337             if (x == 0) {
09338                ast_log(LOG_WARNING, "Ignoring text media offer because port number is zero\n");
09339                continue;
09340             }
09341 
09342             /* Check number of ports offered for stream */
09343             if (numberofports > 1) {
09344                ast_log(LOG_WARNING, "%u ports offered for text media, not supported by Asterisk. Will try anyway...\n", numberofports);
09345             }
09346 
09347             if (p->offered_media[SDP_TEXT].order_offered) {
09348                ast_log(LOG_WARNING, "Rejecting non-primary text stream: %s\n", m);
09349                return -1;
09350             }
09351 
09352             text = TRUE;
09353             p->notext = FALSE;
09354             p->offered_media[SDP_TEXT].order_offered = ++numberofmediastreams;
09355             tportno = x;
09356 
09357             /* Scan through the RTP payload types specified in a "m=" line: */
09358             codecs = m + len;
09359             ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs));
09360             for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
09361                if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
09362                   ast_log(LOG_WARNING, "Invalid syntax in RTP video format list: %s\n", codecs);
09363                   return -1;
09364                }
09365                if (debug) {
09366                   ast_verbose("Found RTP text format %u\n", codec);
09367                }
09368                ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec);
09369             }
09370          } else {
09371             ast_log(LOG_WARNING, "Rejecting text media offer due to invalid or unsupported syntax: %s\n", m);
09372             return -1;
09373          }
09374       }
09375       /* Check for 'image' media offer */
09376       else if (strncmp(m, "image ", 6) == 0) {
09377          if (((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) ||
09378               (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0))) {
09379             if (x == 0) {
09380                ast_log(LOG_WARNING, "Ignoring image media offer because port number is zero\n");
09381                continue;
09382             }
09383 
09384             if (initialize_udptl(p)) {
09385                ast_log(LOG_WARNING, "Rejecting offer with image stream due to UDPTL initialization failure\n");
09386                return -1;
09387             }
09388 
09389             if (p->offered_media[SDP_IMAGE].order_offered) {
09390                ast_log(LOG_WARNING, "Rejecting non-primary image stream: %s\n", m);
09391                return -1;
09392             }
09393 
09394             image = TRUE;
09395             if (debug) {
09396                ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
09397             }
09398 
09399             p->offered_media[SDP_IMAGE].order_offered = ++numberofmediastreams;
09400             udptlportno = x;
09401 
09402             if (p->t38.state != T38_ENABLED) {
09403                memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms));
09404 
09405                /* default EC to none, the remote end should
09406                 * respond with the EC they want to use */
09407                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
09408             }
09409          } else if (sscanf(m, "image %30u %17s t38%n", &x, protocol, &len) == 2 && len > 0) {
09410             ast_log(LOG_WARNING, "Declining image stream due to unsupported transport: %s\n", m);
09411             continue;
09412          } else {
09413             ast_log(LOG_WARNING, "Rejecting image media offer due to invalid or unsupported syntax: %s\n", m);
09414             return -1;
09415          }
09416       } else {
09417          ast_log(LOG_WARNING, "Unsupported top-level media type in offer: %s\n", m);
09418          continue;
09419       }
09420 
09421       /* Media stream specific parameters */
09422       while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
09423          int processed = FALSE;
09424 
09425          switch (type) {
09426          case 'c':
09427             if (audio) {
09428                if (process_sdp_c(value, &audiosa)) {
09429                   processed = TRUE;
09430                   sa = &audiosa;
09431                }
09432             } else if (video) {
09433                if (process_sdp_c(value, &videosa)) {
09434                   processed = TRUE;
09435                   vsa = &videosa;
09436                }
09437             } else if (text) {
09438                if (process_sdp_c(value, &textsa)) {
09439                   processed = TRUE;
09440                   tsa = &textsa;
09441                }
09442             } else if (image) {
09443                if (process_sdp_c(value, &imagesa)) {
09444                   processed = TRUE;
09445                   isa = &imagesa;
09446                }
09447             }
09448             break;
09449          case 'a':
09450             /* Audio specific scanning */
09451             if (audio) {
09452                if (process_sdp_a_sendonly(value, &sendonly)) {
09453                   processed = TRUE;
09454                } else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) {
09455                   processed_crypto = TRUE;
09456                   processed = TRUE;
09457                } else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) {
09458                   processed = TRUE;
09459                }
09460             }
09461             /* Video specific scanning */
09462             else if (video) {
09463                if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) {
09464                   processed_crypto = TRUE;
09465                   processed = TRUE;
09466                } else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) {
09467                   processed = TRUE;
09468                }
09469             }
09470             /* Text (T.140) specific scanning */
09471             else if (text) {
09472                if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) {
09473                   processed = TRUE;
09474                } else if (!processed_crypto && process_crypto(p, p->trtp, &p->tsrtp, value)) {
09475                   processed_crypto = TRUE;
09476                   processed = TRUE;
09477                }
09478             }
09479             /* Image (T.38 FAX) specific scanning */
09480             else if (image) {
09481                if (process_sdp_a_image(value, p))
09482                   processed = TRUE;
09483             }
09484             break;
09485          }
09486 
09487          ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n",
09488               (audio == TRUE)? "audio" : (video == TRUE)? "video" : (text == TRUE)? "text" : "image",
09489               type, value,
09490               (processed == TRUE)? "OK." : "UNSUPPORTED OR FAILED.");
09491       }
09492 
09493       /* Ensure crypto lines are provided where necessary */
09494       if (audio && secure_audio && !processed_crypto) {
09495          ast_log(LOG_WARNING, "Rejecting secure audio stream without encryption details: %s\n", m);
09496          return -1;
09497       } else if (video && secure_video && !processed_crypto) {
09498          ast_log(LOG_WARNING, "Rejecting secure video stream without encryption details: %s\n", m);
09499          return -1;
09500       }
09501    }
09502 
09503    /* Sanity checks */
09504    if (!sa && !vsa && !tsa && !isa) {
09505       ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
09506       return -1;
09507    }
09508 
09509    if ((portno == -1) &&
09510        (vportno == -1) &&
09511        (tportno == -1) &&
09512        (udptlportno == -1)) {
09513       ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n");
09514       return -1;
09515    }
09516 
09517    if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) {
09518       ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
09519       return -1;
09520    }
09521 
09522    if (!secure_audio && p->srtp) {
09523       ast_log(LOG_WARNING, "We are requesting SRTP for audio, but they responded without it!\n");
09524       return -1;
09525    }
09526 
09527    if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) {
09528       ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
09529       return -1;
09530    }
09531 
09532    if (!p->novideo && !secure_video && p->vsrtp) {
09533       ast_log(LOG_WARNING, "We are requesting SRTP for video, but they responded without it!\n");
09534       return -1;
09535    }
09536 
09537    if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
09538       ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n");
09539       return -1;
09540    }
09541 
09542    if (udptlportno == -1) {
09543       change_t38_state(p, T38_DISABLED);
09544    }
09545 
09546    /* Now gather all of the codecs that we are asked for: */
09547    ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability);
09548    ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability);
09549    ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability);
09550 
09551    newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability);
09552    newpeercapability = (peercapability | vpeercapability | tpeercapability);
09553    newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
09554 
09555    if (debug) {
09556       /* shame on whoever coded this.... */
09557       char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE];
09558 
09559       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n",
09560              ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability),
09561              ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability),
09562              ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
09563              ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability),
09564              ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability));
09565    }
09566    if (debug) {
09567       struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE);
09568       struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE);
09569       struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE);
09570 
09571       ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
09572              ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0),
09573              ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0),
09574              ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0));
09575    }
09576    if (!newjointcapability && udptlportno == -1) {
09577       ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
09578       /* Do NOT Change current setting */
09579       return -1;
09580    }
09581 
09582    if (portno != -1 || vportno != -1 || tportno != -1) {
09583       /* We are now ready to change the sip session and RTP structures with the offered codecs, since
09584          they are acceptable */
09585       p->jointcapability = newjointcapability;                /* Our joint codec profile for this call */
09586       p->peercapability = newpeercapability;                  /* The other side's capability in latest offer */
09587       p->jointnoncodeccapability = newnoncodeccapability;     /* DTMF capabilities */
09588 
09589       /* respond with single most preferred joint codec, limiting the other side's choice */
09590       if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) {
09591          p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1);
09592       }
09593    }
09594 
09595    /* Setup audio address and port */
09596    if (p->rtp) {
09597       if (sa && portno > 0) {
09598          ast_sockaddr_set_port(sa, portno);
09599          ast_rtp_instance_set_remote_address(p->rtp, sa);
09600          if (debug) {
09601             ast_verbose("Peer audio RTP is at port %s\n",
09602                    ast_sockaddr_stringify(sa));
09603          }
09604 
09605          ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp);
09606          /* Ensure RTCP is enabled since it may be inactive
09607             if we're coming back from a T.38 session */
09608          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1);
09609          /* Ensure audio RTCP reads are enabled */
09610          if (p->owner) {
09611             ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1));
09612          }
09613 
09614          if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
09615             ast_clear_flag(&p->flags[0], SIP_DTMF);
09616             if (newnoncodeccapability & AST_RTP_DTMF) {
09617                /* XXX Would it be reasonable to drop the DSP at this point? XXX */
09618                ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
09619                /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
09620                ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
09621                ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
09622             } else {
09623                ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
09624             }
09625          }
09626       } else if (udptlportno > 0) {
09627          if (debug)
09628             ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
09629          /* Prevent audio RTCP reads */
09630          if (p->owner) {
09631             ast_channel_set_fd(p->owner, 1, -1);
09632          }
09633          /* Silence RTCP while audio RTP is inactive */
09634          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0);
09635       } else {
09636          ast_rtp_instance_stop(p->rtp);
09637          if (debug)
09638             ast_verbose("Peer doesn't provide audio\n");
09639       }
09640    }
09641 
09642    /* Setup video address and port */
09643    if (p->vrtp) {
09644       if (vsa && vportno > 0) {
09645          ast_sockaddr_set_port(vsa, vportno);
09646          ast_rtp_instance_set_remote_address(p->vrtp, vsa);
09647          if (debug) {
09648             ast_verbose("Peer video RTP is at port %s\n",
09649                    ast_sockaddr_stringify(vsa));
09650          }
09651          ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp);
09652       } else {
09653          ast_rtp_instance_stop(p->vrtp);
09654          if (debug)
09655             ast_verbose("Peer doesn't provide video\n");
09656       }
09657    }
09658 
09659    /* Setup text address and port */
09660    if (p->trtp) {
09661       if (tsa && tportno > 0) {
09662          ast_sockaddr_set_port(tsa, tportno);
09663          ast_rtp_instance_set_remote_address(p->trtp, tsa);
09664          if (debug) {
09665             ast_verbose("Peer T.140 RTP is at port %s\n",
09666                    ast_sockaddr_stringify(tsa));
09667          }
09668          if ((p->jointcapability & AST_FORMAT_T140RED)) {
09669             p->red = 1;
09670             ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
09671          } else {
09672             p->red = 0;
09673          }
09674          ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp);
09675       } else {
09676          ast_rtp_instance_stop(p->trtp);
09677          if (debug)
09678             ast_verbose("Peer doesn't provide T.140\n");
09679       }
09680    }
09681 
09682    /* Setup image address and port */
09683    if (p->udptl) {
09684       if (isa && udptlportno > 0) {
09685          if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
09686             ast_rtp_instance_get_remote_address(p->rtp, isa);
09687             if (!ast_sockaddr_isnull(isa) && debug) {
09688                ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa));
09689             }
09690          }
09691          ast_sockaddr_set_port(isa, udptlportno);
09692          ast_udptl_set_peer(p->udptl, isa);
09693          if (debug)
09694             ast_debug(1,"Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa));
09695 
09696          /* verify the far max ifp can be calculated. this requires far max datagram to be set. */
09697          if (!ast_udptl_get_far_max_datagram(p->udptl)) {
09698             /* setting to zero will force a default if none was provided by the SDP */
09699             ast_udptl_set_far_max_datagram(p->udptl, 0);
09700          }
09701 
09702          /* Remote party offers T38, we need to update state */
09703          if ((t38action == SDP_T38_ACCEPT) &&
09704              (p->t38.state == T38_LOCAL_REINVITE)) {
09705             change_t38_state(p, T38_ENABLED);
09706          } else if ((t38action == SDP_T38_INITIATE) &&
09707                p->owner && p->lastinvite) {
09708             change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */
09709             /* If fax detection is enabled then send us off to the fax extension */
09710             if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) {
09711                ast_channel_lock(p->owner);
09712                if (strcmp(p->owner->exten, "fax")) {
09713                   const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
09714                   ast_channel_unlock(p->owner);
09715                   if (ast_exists_extension(p->owner, target_context, "fax", 1,
09716                      S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) {
09717                      ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name);
09718                      pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);
09719                      if (ast_async_goto(p->owner, target_context, "fax", 1)) {
09720                         ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context);
09721                      }
09722                   } else {
09723                      ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n");
09724                   }
09725                } else {
09726                   ast_channel_unlock(p->owner);
09727                }
09728             }
09729          }
09730       } else {
09731          change_t38_state(p, T38_DISABLED);
09732          ast_udptl_stop(p->udptl);
09733          if (debug)
09734             ast_debug(1, "Peer doesn't provide T.38 UDPTL\n");
09735       }
09736    }
09737 
09738    if ((portno == -1) && (p->t38.state != T38_DISABLED)) {
09739       ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n");
09740       return 0;
09741         }
09742 
09743    /* Ok, we're going with this offer */
09744    ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability));
09745 
09746    if (!p->owner)    /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
09747       return 0;
09748 
09749    ast_debug(4, "We have an owner, now see if we need to change this call\n");
09750 
09751    if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
09752       if (debug) {
09753          char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
09754          ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n",
09755             ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability),
09756             ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats));
09757       }
09758       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability);
09759       ast_set_read_format(p->owner, p->owner->readformat);
09760       ast_set_write_format(p->owner, p->owner->writeformat);
09761    }
09762 
09763    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (!ast_sockaddr_isnull(sa) || !ast_sockaddr_isnull(vsa) || !ast_sockaddr_isnull(tsa) || !ast_sockaddr_isnull(isa)) && (!sendonly || sendonly == -1)) {
09764       ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
09765       /* Activate a re-invite */
09766       ast_queue_frame(p->owner, &ast_null_frame);
09767       change_hold_state(p, req, FALSE, sendonly);
09768    } else if ((sockaddr_is_null_or_any(sa) && sockaddr_is_null_or_any(vsa) && sockaddr_is_null_or_any(tsa) && sockaddr_is_null_or_any(isa)) || (sendonly && sendonly != -1)) {
09769       ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
09770                    S_OR(p->mohsuggest, NULL),
09771                    !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
09772       if (sendonly)
09773          ast_rtp_instance_stop(p->rtp);
09774       /* RTCP needs to go ahead, even if we're on hold!!! */
09775       /* Activate a re-invite */
09776       ast_queue_frame(p->owner, &ast_null_frame);
09777       change_hold_state(p, req, TRUE, sendonly);
09778    }
09779 
09780    return 0;
09781 }

static int process_sdp_a_audio ( const char *  a,
struct sip_pvt *  p,
struct ast_rtp_codecs newaudiortp,
int *  last_rtpmap_codec 
) [static]

Definition at line 9909 of file chan_sip.c.

References ast_codec_pref_setsize(), ast_debug, AST_FORMAT_G719, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_codecs_payload_lookup(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_rtp_instance_get_codecs(), AST_RTP_MAX_PT, AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, FALSE, format, LOG_WARNING, ast_rtp_codecs::pref, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

09910 {
09911    int found = FALSE;
09912    unsigned int codec;
09913    char mimeSubtype[128];
09914    char fmtp_string[64];
09915    unsigned int sample_rate;
09916    int debug = sip_debug_test_pvt(p);
09917 
09918    if (!strncasecmp(a, "ptime", 5)) {
09919       char *tmp = strrchr(a, ':');
09920       long int framing = 0;
09921       if (tmp) {
09922          tmp++;
09923          framing = strtol(tmp, NULL, 10);
09924          if (framing == LONG_MIN || framing == LONG_MAX) {
09925             framing = 0;
09926             ast_debug(1, "Can't read framing from SDP: %s\n", a);
09927          }
09928       }
09929       if (framing && p->autoframing) {
09930          struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
09931          int codec_n;
09932          for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) {
09933             struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n);
09934             if (!format.asterisk_format || !format.code) /* non-codec or not found */
09935                continue;
09936             ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing);
09937             ast_codec_pref_setsize(pref, format.code, framing);
09938          }
09939          ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref);
09940       }
09941       found = TRUE;
09942    } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
09943       /* We have a rtpmap to handle */
09944       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
09945          if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype,
09946              ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate))) {
09947             if (debug)
09948                ast_verbose("Found audio description format %s for ID %u\n", mimeSubtype, codec);
09949             //found_rtpmap_codecs[last_rtpmap_codec] = codec;
09950             (*last_rtpmap_codec)++;
09951             found = TRUE;
09952          } else {
09953             ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
09954             if (debug)
09955                ast_verbose("Found unknown media description format %s for ID %u\n", mimeSubtype, codec);
09956          }
09957       } else {
09958          if (debug)
09959             ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec);
09960       }
09961    } else if (sscanf(a, "fmtp: %30u %63[^\t\n]", &codec, fmtp_string) == 2) {
09962       struct ast_rtp_payload_type payload;
09963 
09964       payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec);
09965       if (payload.code && payload.asterisk_format) {
09966          unsigned int bit_rate;
09967 
09968          switch (payload.code) {
09969          case AST_FORMAT_SIREN7:
09970             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
09971                if (bit_rate != 32000) {
09972                   ast_log(LOG_WARNING, "Got Siren7 offer at %u bps, but only 32000 bps supported; ignoring.\n", bit_rate);
09973                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
09974                } else {
09975                   found = TRUE;
09976                }
09977             }
09978             break;
09979          case AST_FORMAT_SIREN14:
09980             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
09981                if (bit_rate != 48000) {
09982                   ast_log(LOG_WARNING, "Got Siren14 offer at %u bps, but only 48000 bps supported; ignoring.\n", bit_rate);
09983                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
09984                } else {
09985                   found = TRUE;
09986                }
09987             }
09988             break;
09989          case AST_FORMAT_G719:
09990             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
09991                if (bit_rate != 64000) {
09992                   ast_log(LOG_WARNING, "Got G.719 offer at %u bps, but only 64000 bps supported; ignoring.\n", bit_rate);
09993                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
09994                } else {
09995                   found = TRUE;
09996                }
09997             }
09998          }
09999       }
10000    }
10001 
10002    return found;
10003 }

static int process_sdp_a_image ( const char *  a,
struct sip_pvt *  p 
) [static]

Definition at line 10088 of file chan_sip.c.

References ast_debug, ast_strdupa, AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, AST_T38_RATE_9600, AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), FALSE, initialize_udptl(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by process_sdp().

10089 {
10090    int found = FALSE;
10091    char s[256];
10092    unsigned int x;
10093    char *attrib = ast_strdupa(a);
10094    char *pos;
10095 
10096    if (initialize_udptl(p)) {
10097       return found;
10098    }
10099 
10100    /* Due to a typo in an IANA registration of one of the T.38 attributes,
10101     * RFC5347 section 2.5.2 recommends that all T.38 attributes be parsed in
10102     * a case insensitive manner. Hence, the importance of proof reading (and
10103     * code reviews).
10104     */
10105    for (pos = attrib; *pos; ++pos) {
10106       *pos = tolower(*pos);
10107    }
10108 
10109    if ((sscanf(attrib, "t38faxmaxbuffer:%30u", &x) == 1)) {
10110       ast_debug(3, "MaxBufferSize:%u\n", x);
10111       found = TRUE;
10112    } else if ((sscanf(attrib, "t38maxbitrate:%30u", &x) == 1) || (sscanf(attrib, "t38faxmaxrate:%30u", &x) == 1)) {
10113       ast_debug(3, "T38MaxBitRate: %u\n", x);
10114       switch (x) {
10115       case 14400:
10116          p->t38.their_parms.rate = AST_T38_RATE_14400;
10117          break;
10118       case 12000:
10119          p->t38.their_parms.rate = AST_T38_RATE_12000;
10120          break;
10121       case 9600:
10122          p->t38.their_parms.rate = AST_T38_RATE_9600;
10123          break;
10124       case 7200:
10125          p->t38.their_parms.rate = AST_T38_RATE_7200;
10126          break;
10127       case 4800:
10128          p->t38.their_parms.rate = AST_T38_RATE_4800;
10129          break;
10130       case 2400:
10131          p->t38.their_parms.rate = AST_T38_RATE_2400;
10132          break;
10133       }
10134       found = TRUE;
10135    } else if ((sscanf(attrib, "t38faxversion:%30u", &x) == 1)) {
10136       ast_debug(3, "FaxVersion: %u\n", x);
10137       p->t38.their_parms.version = x;
10138       found = TRUE;
10139    } else if ((sscanf(attrib, "t38faxmaxdatagram:%30u", &x) == 1) || (sscanf(attrib, "t38maxdatagram:%30u", &x) == 1)) {
10140       /* override the supplied value if the configuration requests it */
10141       if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) {
10142          ast_debug(1, "Overriding T38FaxMaxDatagram '%u' with '%u'\n", x, p->t38_maxdatagram);
10143          x = p->t38_maxdatagram;
10144       }
10145       ast_debug(3, "FaxMaxDatagram: %u\n", x);
10146       ast_udptl_set_far_max_datagram(p->udptl, x);
10147       found = TRUE;
10148    } else if ((strncmp(attrib, "t38faxfillbitremoval", 20) == 0)) {
10149       if (sscanf(attrib, "t38faxfillbitremoval:%30u", &x) == 1) {
10150          ast_debug(3, "FillBitRemoval: %u\n", x);
10151          if (x == 1) {
10152             p->t38.their_parms.fill_bit_removal = TRUE;
10153          }
10154       } else {
10155          ast_debug(3, "FillBitRemoval\n");
10156          p->t38.their_parms.fill_bit_removal = TRUE;
10157       }
10158       found = TRUE;
10159    } else if ((strncmp(attrib, "t38faxtranscodingmmr", 20) == 0)) {
10160       if (sscanf(attrib, "t38faxtranscodingmmr:%30u", &x) == 1) {
10161          ast_debug(3, "Transcoding MMR: %u\n", x);
10162          if (x == 1) {
10163             p->t38.their_parms.transcoding_mmr = TRUE;
10164          }
10165       } else {
10166          ast_debug(3, "Transcoding MMR\n");
10167          p->t38.their_parms.transcoding_mmr = TRUE;
10168       }
10169       found = TRUE;
10170    } else if ((strncmp(attrib, "t38faxtranscodingjbig", 21) == 0)) {
10171       if (sscanf(attrib, "t38faxtranscodingjbig:%30u", &x) == 1) {
10172          ast_debug(3, "Transcoding JBIG: %u\n", x);
10173          if (x == 1) {
10174             p->t38.their_parms.transcoding_jbig = TRUE;
10175          }
10176       } else {
10177          ast_debug(3, "Transcoding JBIG\n");
10178          p->t38.their_parms.transcoding_jbig = TRUE;
10179       }
10180       found = TRUE;
10181    } else if ((sscanf(attrib, "t38faxratemanagement:%255s", s) == 1)) {
10182       ast_debug(3, "RateManagement: %s\n", s);
10183       if (!strcasecmp(s, "localTCF"))
10184          p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF;
10185       else if (!strcasecmp(s, "transferredTCF"))
10186          p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF;
10187       found = TRUE;
10188    } else if ((sscanf(attrib, "t38faxudpec:%255s", s) == 1)) {
10189       ast_debug(3, "UDP EC: %s\n", s);
10190       if (!strcasecmp(s, "t38UDPRedundancy")) {
10191          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
10192       } else if (!strcasecmp(s, "t38UDPFEC")) {
10193          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
10194       } else {
10195          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
10196       }
10197       found = TRUE;
10198    }
10199 
10200    return found;
10201 }

static int process_sdp_a_sendonly ( const char *  a,
int *  sendonly 
) [static]

Definition at line 9889 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by process_sdp().

09890 {
09891    int found = FALSE;
09892 
09893    if (!strcasecmp(a, "sendonly")) {
09894       if (*sendonly == -1)
09895          *sendonly = 1;
09896       found = TRUE;
09897    } else if (!strcasecmp(a, "inactive")) {
09898       if (*sendonly == -1)
09899          *sendonly = 2;
09900       found = TRUE;
09901    }  else if (!strcasecmp(a, "sendrecv")) {
09902       if (*sendonly == -1)
09903          *sendonly = 0;
09904       found = TRUE;
09905    }
09906    return found;
09907 }

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]

Definition at line 10039 of file chan_sip.c.

References AST_RED_MAX_GENERATION, ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_verbose, FALSE, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

10040 {
10041    int found = FALSE;
10042    unsigned int codec;
10043    char mimeSubtype[128];
10044    unsigned int sample_rate;
10045    char *red_cp;
10046    int debug = sip_debug_test_pvt(p);
10047 
10048    if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
10049       /* We have a rtpmap to handle */
10050       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
10051          if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */
10052             if (p->trtp) {
10053                /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
10054                ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
10055                found = TRUE;
10056             }
10057          } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */
10058             if (p->trtp) {
10059                ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
10060                sprintf(red_fmtp, "fmtp:%u ", codec);
10061                if (debug)
10062                   ast_verbose("RED submimetype has payload type: %u\n", codec);
10063                found = TRUE;
10064             }
10065          }
10066       } else {
10067          if (debug)
10068             ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec);
10069       }
10070    } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) {
10071       /* count numbers of generations in fmtp */
10072       red_cp = &red_fmtp[strlen(red_fmtp)];
10073       strncpy(red_fmtp, a, 100);
10074 
10075       sscanf(red_cp, "%30u", (unsigned *)&red_data_pt[*red_num_gen]);
10076       red_cp = strtok(red_cp, "/");
10077       while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) {
10078          sscanf(red_cp, "%30u", (unsigned *)&red_data_pt[*red_num_gen]);
10079          red_cp = strtok(NULL, "/");
10080       }
10081       red_cp = red_fmtp;
10082       found = TRUE;
10083    }
10084 
10085    return found;
10086 }

static int process_sdp_a_video ( const char *  a,
struct sip_pvt *  p,
struct ast_rtp_codecs newvideortp,
int *  last_rtpmap_codec 
) [static]

Definition at line 10005 of file chan_sip.c.

References ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_verbose, FALSE, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

10006 {
10007    int found = FALSE;
10008    unsigned int codec;
10009    char mimeSubtype[128];
10010    unsigned int sample_rate;
10011    int debug = sip_debug_test_pvt(p);
10012 
10013    if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
10014       /* We have a rtpmap to handle */
10015       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
10016          /* Note: should really look at the '#chans' params too */
10017          if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) {
10018             if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate))) {
10019                if (debug)
10020                   ast_verbose("Found video description format %s for ID %u\n", mimeSubtype, codec);
10021                //found_rtpmap_codecs[last_rtpmap_codec] = codec;
10022                (*last_rtpmap_codec)++;
10023                found = TRUE;
10024             } else {
10025                ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec);
10026                if (debug)
10027                   ast_verbose("Found unknown media description format %s for ID %u\n", mimeSubtype, codec);
10028             }
10029          }
10030       } else {
10031          if (debug)
10032             ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec);
10033       }
10034    }
10035 
10036    return found;
10037 }

static int process_sdp_c ( const char *  c,
struct ast_sockaddr addr 
) [static]

Definition at line 9862 of file chan_sip.c.

References ast_log(), ast_sockaddr_resolve_first_af(), FALSE, LOG_WARNING, and TRUE.

Referenced by process_sdp().

09863 {
09864    char proto[4], host[258];
09865    int af;
09866 
09867    /* Check for Media-description-level-address */
09868    if (sscanf(c, "IN %3s %255s", proto, host) == 2) {
09869       if (!strcmp("IP4", proto)) {
09870          af = AF_INET;
09871       } else if (!strcmp("IP6", proto)) {
09872          af = AF_INET6;
09873       } else {
09874          ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
09875          return FALSE;
09876       }
09877       if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
09878          ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c);
09879          return FALSE;
09880       }
09881       return TRUE;
09882    } else {
09883       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
09884       return FALSE;
09885    }
09886    return FALSE;
09887 }

static int process_sdp_o ( const char *  o,
struct sip_pvt *  p 
) [static]

Definition at line 9783 of file chan_sip.c.

References ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, FALSE, LOG_WARNING, and TRUE.

Referenced by process_sdp().

09784 {
09785    char *o_copy;
09786    char *token;
09787    int64_t rua_version;
09788 
09789    /* Store the SDP version number of remote UA. This will allow us to
09790    distinguish between session modifications and session refreshes. If
09791    the remote UA does not send an incremented SDP version number in a
09792    subsequent RE-INVITE then that means its not changing media session.
09793    The RE-INVITE may have been sent to update connected party, remote
09794    target or to refresh the session (Session-Timers).  Asterisk must not
09795    change media session and increment its own version number in answer
09796    SDP in this case. */
09797 
09798    p->session_modify = TRUE;
09799 
09800    if (ast_strlen_zero(o)) {
09801       ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n");
09802       return FALSE;
09803    }
09804 
09805    o_copy = ast_strdupa(o);
09806    token = strsep(&o_copy, " ");  /* Skip username   */
09807    if (!o_copy) {
09808       ast_log(LOG_WARNING, "SDP syntax error in o= line username\n");
09809       return FALSE;
09810    }
09811    token = strsep(&o_copy, " ");  /* Skip session-id */
09812    if (!o_copy) {
09813       ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n");
09814       return FALSE;
09815    }
09816    token = strsep(&o_copy, " ");  /* Version         */
09817    if (!o_copy) {
09818       ast_log(LOG_WARNING, "SDP syntax error in o= line\n");
09819       return FALSE;
09820    }
09821    if (!sscanf(token, "%30" SCNd64, &rua_version)) {
09822       ast_log(LOG_WARNING, "SDP syntax error in o= line version\n");
09823       return FALSE;
09824    }
09825 
09826    /* we need to check the SDP version number the other end sent us;
09827     * our rules for deciding what to accept are a bit complex.
09828     *
09829     * 1) if 'ignoresdpversion' has been set for this dialog, then
09830     *    we will just accept whatever they sent and assume it is
09831     *    a modification of the session, even if it is not
09832     * 2) otherwise, if this is the first SDP we've seen from them
09833     *    we accept it
09834     * 3) otherwise, if the new SDP version number is higher than the
09835     *    old one, we accept it
09836     * 4) otherwise, if this SDP is in response to us requesting a switch
09837     *    to T.38, we accept the SDP, but also generate a warning message
09838     *    that this peer should have the 'ignoresdpversion' option set,
09839     *    because it is not following the SDP offer/answer RFC; if we did
09840     *    not request a switch to T.38, then we stop parsing the SDP, as it
09841     *    has not changed from the previous version
09842     */
09843 
09844    if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) ||
09845        (p->sessionversion_remote < 0) ||
09846        (p->sessionversion_remote < rua_version)) {
09847       p->sessionversion_remote = rua_version;
09848    } else {
09849       if (p->t38.state == T38_LOCAL_REINVITE) {
09850          p->sessionversion_remote = rua_version;
09851          ast_log(LOG_WARNING, "Call %s responded to our T.38 reinvite without changing SDP version; 'ignoresdpversion' should be set for this peer.\n", p->callid);
09852       } else {
09853          p->session_modify = FALSE;
09854          ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid);
09855          return FALSE;
09856       }
09857    }
09858 
09859    return TRUE;
09860 }

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

Process the Via header according to RFC 3261 section 18.2.2.

Parameters:
p a sip_pvt structure that will be modified according to the received header
req a sip request with a Via header to process

This function will update the destination of the response according to the Via header in the request and RFC 3261 section 18.2.2. We do not have a transport layer so we ignore certain values like the 'received' param (we set the destination address to the addres the request came from in the respprep() function).

Return values:
-1 error
0 success

Definition at line 8128 of file chan_sip.c.

References addr_is_multicast(), ast_log(), ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, free_via(), get_header(), LOG_ERROR, LOG_WARNING, PARSE_PORT_FORBID, and parse_via().

Referenced by respprep().

08129 {
08130    struct sip_via *via = parse_via(get_header(req, "Via"));
08131 
08132    if (!via) {
08133       ast_log(LOG_ERROR, "error processing via header\n");
08134       return -1;
08135    }
08136 
08137    if (via->maddr) {
08138       if (ast_sockaddr_resolve_first_transport(&p->sa, via->maddr, PARSE_PORT_FORBID, p->socket.type)) {
08139          ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr);
08140          ast_log(LOG_ERROR, "error processing via header\n");
08141          free_via(via);
08142          return -1;
08143       }
08144 
08145       if (addr_is_multicast(&p->sa)) {
08146          setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl));
08147       }
08148    }
08149 
08150    ast_sockaddr_set_port(&p->sa, via->port ? via->port : STANDARD_SIP_PORT);
08151 
08152    free_via(via);
08153    return 0;
08154 }

static struct sip_proxy* proxy_from_config ( const char *  proxy,
int  sipconf_lineno,
struct sip_proxy *  dest 
) [static, read]

Parse proxy string and return an ao2_alloc'd proxy. If dest is non-NULL, no allocation is performed and dest is used instead. On error NULL is returned.

Definition at line 3244 of file chan_sip.c.

References ao2_alloc, ao2_ref, ast_copy_string(), ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_WARNING, name, proxy_update(), and sip_parse_host().

Referenced by build_peer(), reload_config(), and sip_request_call().

03245 {
03246    char *mutable_proxy, *sep, *name;
03247    int allocated = 0;
03248 
03249    if (!dest) {
03250       dest = ao2_alloc(sizeof(struct sip_proxy), NULL);
03251       if (!dest) {
03252          ast_log(LOG_WARNING, "Unable to allocate config storage for proxy\n");
03253          return NULL;
03254       }
03255       allocated = 1;
03256    }
03257 
03258    /* Format is: [transport://]name[:port][,force] */
03259    mutable_proxy = ast_skip_blanks(ast_strdupa(proxy));
03260    sep = strchr(mutable_proxy, ',');
03261    if (sep) {
03262       *sep++ = '\0';
03263       dest->force = !strncasecmp(ast_skip_blanks(sep), "force", 5);
03264    } else {
03265       dest->force = FALSE;
03266    }
03267 
03268    sip_parse_host(mutable_proxy, sipconf_lineno, &name, &dest->port, &dest->transport);
03269 
03270    /* Check that there is a name at all */
03271    if (ast_strlen_zero(name)) {
03272       if (allocated) {
03273          ao2_ref(dest, -1);
03274       } else {
03275          dest->name[0] = '\0';
03276       }
03277       return NULL;
03278    }
03279    ast_copy_string(dest->name, name, sizeof(dest->name));
03280 
03281    /* Resolve host immediately */
03282    proxy_update(dest);
03283 
03284    return dest;
03285 }

static int proxy_update ( struct sip_proxy *  proxy  )  [static]

Resolve DNS srv name or host name in a sip_proxy structure

Definition at line 3220 of file chan_sip.c.

References ast_get_ip_or_srv(), ast_log(), ast_sockaddr_parse(), ast_sockaddr_set_port, FALSE, get_address_family_filter(), LOG_WARNING, sip_cfg, and TRUE.

Referenced by proxy_from_config().

03221 {
03222    /* if it's actually an IP address and not a name,
03223            there's no need for a managed lookup */
03224    if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) {
03225       /* Ok, not an IP address, then let's check if it's a domain or host */
03226       /* XXX Todo - if we have proxy port, don't do SRV */
03227       proxy->ip.ss.ss_family = get_address_family_filter(SIP_TRANSPORT_UDP); /* Filter address family */
03228       if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) {
03229             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
03230             return FALSE;
03231       }
03232 
03233    }
03234 
03235    ast_sockaddr_set_port(&proxy->ip, proxy->port);
03236 
03237    proxy->last_dnsupdate = time(NULL);
03238    return TRUE;
03239 }

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

Definition at line 1009 of file chan_sip.c.

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

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

01010 {
01011    struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data;
01012    struct event_state_compositor *esc = get_esc(esc_entry->event);
01013 
01014    ast_assert(esc != NULL);
01015 
01016    ao2_unlink(esc->compositor, esc_entry);
01017    ao2_ref(esc_entry, -1);
01018    return 0;
01019 }

static void pvt_set_needdestroy ( struct sip_pvt *  pvt,
const char *  reason 
) [inline, static]

Definition at line 3185 of file chan_sip.c.

References append_history.

Referenced by __sip_autodestruct(), handle_incoming(), handle_request_publish(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), retrans_pkt(), sip_hangup(), and sip_reg_timeout().

03186 {
03187    if (pvt->final_destruction_scheduled) {
03188       return; /* This is already scheduled for final destruction, let the scheduler take care of it. */
03189    }
03190    append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason);
03191    pvt->needdestroy = 1;
03192 }

static int read_raw_content_length ( const char *  message  )  [static]

Get the content length from an unparsed SIP message.

Parameters:
message The unparsed SIP message headers
Returns:
The value of the Content-Length header or -1 if message is invalid

Definition at line 2532 of file chan_sip.c.

References ast_free, ast_str_buffer(), ast_str_create(), ast_str_set(), lws2sws(), and sip_cfg.

Referenced by check_message_integrity().

02533 {
02534    char *content_length_str;
02535    int content_length = -1;
02536 
02537    struct ast_str *msg_copy;
02538    char *msg;
02539 
02540    /* Using a ast_str because lws2sws takes one of those */
02541    if (!(msg_copy = ast_str_create(strlen(message) + 1))) {
02542       return -1;
02543    }
02544    ast_str_set(&msg_copy, 0, "%s", message);
02545 
02546    if (sip_cfg.pedanticsipchecking) {
02547       lws2sws(msg_copy);
02548    }
02549 
02550    msg = ast_str_buffer(msg_copy);
02551 
02552    /* Let's find a Content-Length header */
02553    if ((content_length_str = strcasestr(msg, "\nContent-Length:"))) {
02554       content_length_str += sizeof("\nContent-Length:") - 1;
02555    } else if ((content_length_str = strcasestr(msg, "\nl:"))) {
02556       content_length_str += sizeof("\nl:") - 1;
02557    } else {
02558       /* RFC 3261 18.3
02559        * "In the case of stream-oriented transports such as TCP, the Content-
02560        *  Length header field indicates the size of the body.  The Content-
02561        *  Length header field MUST be used with stream oriented transports."
02562        */
02563       goto done;
02564    }
02565 
02566    /* Double-check that this is a complete header */
02567    if (!strchr(content_length_str, '\n')) {
02568       goto done;
02569    }
02570 
02571    if (sscanf(content_length_str, "%30d", &content_length) != 1) {
02572       content_length = -1;
02573    }
02574 
02575 done:
02576    ast_free(msg_copy);
02577    return content_length;
02578 }

static struct sip_peer * realtime_peer ( const char *  newpeername,
struct ast_sockaddr addr,
int  devstate_only,
int  which_objects 
) [static, read]

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.

Note:
This is never called with both newpeername and addr at the same time. If you do, be prepared to get a peer with a different name than newpeername.

Definition at line 5145 of file chan_sip.c.

References ao2_t_link, ast_check_realtime(), ast_copy_flags, ast_copy_string(), ast_debug, AST_SCHED_REPLACE_UNREF, ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), ast_test_flag, ast_variables_destroy(), build_peer(), cleanup(), expire_register(), ipaddr, ast_variable::name, ast_variable::next, realtime_peer_by_addr(), realtime_peer_by_name(), ref_peer(), sip_cfg, TRUE, unref_peer(), ast_variable::value, and var.

Referenced by find_peer().

05146 {
05147    struct sip_peer *peer = NULL;
05148    struct ast_variable *var = NULL;
05149    struct ast_variable *varregs = NULL;
05150    char ipaddr[INET6_ADDRSTRLEN];
05151    int realtimeregs = ast_check_realtime("sipregs");
05152 
05153    if (addr) {
05154       ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
05155    } else {
05156       ipaddr[0] = '\0';
05157    }
05158 
05159    if (newpeername && realtime_peer_by_name(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) {
05160       ;
05161    } else if (addr && realtime_peer_by_addr(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) {
05162       ;
05163    } else {
05164       return NULL;
05165    }
05166 
05167    /* If we're looking for users, don't return peers (although this check
05168     * should probably be done in realtime_peer_by_* instead...) */
05169    if (which_objects == FINDUSERS) {
05170       struct ast_variable *tmp;
05171       for (tmp = var; tmp; tmp = tmp->next) {
05172          if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer"))) {
05173             goto cleanup;
05174          }
05175       }
05176    }
05177 
05178    /* Peer found in realtime, now build it in memory */
05179    peer = build_peer(newpeername, var, varregs, TRUE, devstate_only);
05180    if (!peer) {
05181       goto cleanup;
05182    }
05183 
05184    /* Previous versions of Asterisk did not require the type field to be
05185     * set for real time peers.  This statement preserves that behavior. */
05186    if  (peer->type == 0) {
05187       if (which_objects == FINDUSERS) {
05188          peer->type = SIP_TYPE_USER;
05189       } else if (which_objects == FINDPEERS) {
05190          peer->type = SIP_TYPE_PEER;
05191       } else {
05192          peer->type = SIP_TYPE_PEER | SIP_TYPE_USER;
05193       }
05194    }
05195 
05196    ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
05197 
05198    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) {
05199       /* Cache peer */
05200       ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
05201       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
05202          AST_SCHED_REPLACE_UNREF(peer->expire, sched, sip_cfg.rtautoclear * 1000, expire_register, peer,
05203                unref_peer(_data, "remove registration ref"),
05204                unref_peer(peer, "remove registration ref"),
05205                ref_peer(peer, "add registration ref"));
05206       }
05207       ao2_t_link(peers, peer, "link peer into peers table");
05208       if (!ast_sockaddr_isnull(&peer->addr)) {
05209          ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
05210       }
05211    }
05212    peer->is_realtime = 1;
05213 
05214 cleanup:
05215    ast_variables_destroy(var);
05216    ast_variables_destroy(varregs);
05217    return peer;
05218 }

static int realtime_peer_by_addr ( const char **  name,
struct ast_sockaddr addr,
const char *  ipaddr,
struct ast_variable **  var,
struct ast_variable **  varregs 
) [static]

Definition at line 5076 of file chan_sip.c.

References ast_copy_string(), ast_load_realtime(), ast_log(), ast_sockaddr_stringify_port(), ast_variables_destroy(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), get_name_from_variable(), LOG_WARNING, realtime_peer_get_sippeer_helper(), and SENTINEL.

Referenced by realtime_peer().

05077 {
05078    char portstring[6]; /* up to 5 digits plus null terminator */
05079    ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring));
05080 
05081    /* We're not finding this peer by this name anymore. Reset it. */
05082    *name = NULL;
05083 
05084    /* First check for fixed IP hosts */
05085    if ((*var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL))) {
05086       ;
05087    /* Check for registered hosts (in sipregs) */
05088    } else if (varregs && (*varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL)) &&
05089          (*var = realtime_peer_get_sippeer_helper(name, varregs))) {
05090       ;
05091    /* Check for registered hosts (in sippeers) */
05092    } else if (!varregs && (*var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL))) {
05093       ;
05094    /* We couldn't match on ipaddress and port, so we need to check if port is insecure */
05095    } else if ((*var = get_insecure_variable_from_sippeers("host", ipaddr))) {
05096       ;
05097    /* Same as above, but try the IP address field (in sipregs)
05098     * Observe that it fetches the name/var at the same time, without the
05099     * realtime_peer_get_sippeer_helper. Also note that it is quite inefficient.
05100     * Avoid sipregs if possible. */
05101    } else if (varregs && (*varregs = get_insecure_variable_from_sipregs("ipaddr", ipaddr, var))) {
05102       ;
05103    /* Same as above, but try the IP address field (in sippeers) */
05104    } else if (!varregs && (*var = get_insecure_variable_from_sippeers("ipaddr", ipaddr))) {
05105       ;
05106    }
05107 
05108    /* Nothing found? */
05109    if (!*var) {
05110       return 0;
05111    }
05112 
05113    /* Check peer name. It must not be empty. There may exist a
05114     * different match that does have a name, but it's too late for
05115     * that now. */
05116    if (!*name && !(*name = get_name_from_variable(*var))) {
05117       ast_log(LOG_WARNING, "Found peer for IP %s but it has no name\n", ipaddr);
05118       ast_variables_destroy(*var);
05119       *var = NULL;
05120       if (varregs && *varregs) {
05121          ast_variables_destroy(*varregs);
05122          *varregs = NULL;
05123       }
05124       return 0;
05125    }
05126 
05127    /* Make sure varregs is populated if var is. The inverse,
05128     * ensuring that var is set when varregs is, is taken
05129     * care of by realtime_peer_get_sippeer_helper(). */
05130    if (varregs && !*varregs) {
05131       *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL);
05132    }
05133    return 1;
05134 }

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]

Note:
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 5004 of file chan_sip.c.

References ast_free, ast_load_realtime(), ast_sockaddr_cmp(), ast_sockaddr_resolve(), ast_variables_destroy(), get_address_family_filter(), ast_variable::name, ast_variable::next, PARSE_PORT_FORBID, SENTINEL, and ast_variable::value.

Referenced by realtime_peer().

05005 {
05006    /* Peer by name and host=dynamic */
05007    if ((*var = ast_load_realtime("sippeers", "name", *name, "host", "dynamic", SENTINEL))) {
05008       ;
05009    /* Peer by name and host=IP */
05010    } else if (addr && !(*var = ast_load_realtime("sippeers", "name", *name, "host", ipaddr, SENTINEL))) {
05011       ;
05012    /* Peer by name and host=HOSTNAME */
05013    } else if ((*var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) {
05014       /*!\note
05015        * If this one loaded something, then we need to ensure that the host
05016        * field matched.  The only reason why we can't have this as a criteria
05017        * is because we only have the IP address and the host field might be
05018        * set as a name (and the reverse PTR might not match).
05019        */
05020       if (addr) {
05021          struct ast_variable *tmp;
05022          for (tmp = *var; tmp; tmp = tmp->next) {
05023             if (!strcasecmp(tmp->name, "host")) {
05024                struct ast_sockaddr *addrs = NULL;
05025 
05026                if (ast_sockaddr_resolve(&addrs,
05027                          tmp->value,
05028                          PARSE_PORT_FORBID,
05029                          get_address_family_filter(SIP_TRANSPORT_UDP)) <= 0 ||
05030                          ast_sockaddr_cmp(&addrs[0], addr)) {
05031                   /* No match */
05032                   ast_variables_destroy(*var);
05033                   *var = NULL;
05034                }
05035                ast_free(addrs);
05036                break;
05037             }
05038          }
05039       }
05040    }
05041 
05042    /* Did we find anything? */
05043    if (*var) {
05044       if (varregs) {
05045          *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL);
05046       }
05047       return 1;
05048    }
05049    return 0;
05050 }

static struct ast_variable* realtime_peer_get_sippeer_helper ( const char **  name,
struct ast_variable **  varregs 
) [static, read]

Definition at line 5058 of file chan_sip.c.

References ast_load_realtime(), ast_log(), ast_variables_destroy(), get_name_from_variable(), LOG_WARNING, SENTINEL, and var.

Referenced by realtime_peer_by_addr().

05058                                                                                                                {
05059    struct ast_variable *var = NULL;
05060    const char *old_name = *name;
05061    *name = get_name_from_variable(*varregs);
05062    if (!*name || !(var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) {
05063       if (!*name) {
05064          ast_log(LOG_WARNING, "Found sipreg but it has no name\n");
05065       }
05066       ast_variables_destroy(*varregs);
05067       *varregs = NULL;
05068       *name = old_name;
05069    }
05070    return var;
05071 }

static void realtime_update_peer ( const char *  peername,
struct ast_sockaddr addr,
const char *  username,
const char *  fullcontact,
const char *  useragent,
int  expirey,
unsigned short  deprecated_username,
int  lastms 
) [static]

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.

Definition at line 4714 of file chan_sip.c.

References ast_check_realtime(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strlen_zero(), ast_update_realtime(), ipaddr, SENTINEL, and sip_cfg.

Referenced by update_peer().

04715 {
04716    char port[10];
04717    char ipaddr[INET6_ADDRSTRLEN];
04718    char regseconds[20];
04719    char *tablename = NULL;
04720    char str_lastms[20];
04721 
04722    const char *sysname = ast_config_AST_SYSTEM_NAME;
04723    char *syslabel = NULL;
04724 
04725    time_t nowtime = time(NULL) + expirey;
04726    const char *fc = fullcontact ? "fullcontact" : NULL;
04727 
04728    int realtimeregs = ast_check_realtime("sipregs");
04729 
04730    tablename = realtimeregs ? "sipregs" : "sippeers";
04731    
04732 
04733    snprintf(str_lastms, sizeof(str_lastms), "%d", lastms);
04734    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
04735    ast_copy_string(ipaddr, ast_sockaddr_isnull(addr) ? "" : ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
04736    ast_copy_string(port, ast_sockaddr_port(addr) ? ast_sockaddr_stringify_port(addr) : "", sizeof(port));
04737 
04738    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04739       sysname = NULL;
04740    else if (sip_cfg.rtsave_sysname)
04741       syslabel = "regserver";
04742 
04743    /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you
04744          *  must also add it to contrib/scripts/asterisk.ldap-schema,
04745          *  contrib/scripts/asterisk.ldif,
04746          *  and to configs/res_ldap.conf.sample as described in
04747          *  bugs 15156 and 15895 
04748          */
04749    if (fc) {
04750       ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
04751          "port", port, "regseconds", regseconds,
04752          deprecated_username ? "username" : "defaultuser", defaultuser,
04753          "useragent", useragent, "lastms", str_lastms,
04754          fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */
04755    } else {
04756       ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
04757          "port", port, "regseconds", regseconds,
04758          "useragent", useragent, "lastms", str_lastms,
04759          deprecated_username ? "username" : "defaultuser", defaultuser,
04760          syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */
04761    }
04762 }

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

Receive SIP MESSAGE method messages.

Note:
We only handle messages within current calls currently Reference: RFC 3428

Definition at line 16886 of file chan_sip.c.

References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose, ast_frame::data, ast_frame::datalen, f, ast_frame::frametype, get_header(), get_msg_text(), ast_frame_subclass::integer, LOG_WARNING, ast_frame::offset, ast_frame::ptr, sip_debug_test_pvt(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().

Referenced by handle_request_message().

16887 {
16888    char buf[1400];   
16889    char *bufp;
16890    struct ast_frame f;
16891    const char *content_type = get_header(req, "Content-Type");
16892 
16893    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
16894       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
16895       if (!p->owner)
16896          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16897       return;
16898    }
16899 
16900    if (get_msg_text(buf, sizeof(buf), req)) {
16901       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
16902       transmit_response(p, "500 Internal Server Error", req);
16903       if (!p->owner) {
16904          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16905       }
16906       return;
16907    }
16908 
16909    /* Strip trailing line feeds from message body. (get_msg_text may add
16910     * a trailing linefeed and we don't need any at the end) */
16911    bufp = buf + strlen(buf);
16912    while (--bufp >= buf && *bufp == '\n') {
16913       *bufp = '\0';
16914    }
16915 
16916    if (p->owner) {
16917       if (sip_debug_test_pvt(p))
16918          ast_verbose("SIP Text message received: '%s'\n", buf);
16919       memset(&f, 0, sizeof(f));
16920       f.frametype = AST_FRAME_TEXT;
16921       f.subclass.integer = 0;
16922       f.offset = 0;
16923       f.data.ptr = buf;
16924       f.datalen = strlen(buf) + 1;
16925       ast_queue_frame(p->owner, &f);
16926       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
16927       return;
16928    }
16929 
16930    /* Message outside of a call, we do not support that */
16931    ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n  Content-Type:%s\n  Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf);
16932    transmit_response(p, "405 Method Not Allowed", req);
16933    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16934    return;
16935 }

static struct sip_peer* ref_peer ( struct sip_peer *  peer,
char *  tag 
) [static, read]
static void ref_proxy ( struct sip_pvt *  pvt,
struct sip_proxy *  proxy 
) [static]

maintain proper refcounts for a sip_pvt's outboundproxy

This function sets pvt's outboundproxy pointer to the one referenced by the proxy parameter. Because proxy may be a refcounted object, and because pvt's old outboundproxy may also be a refcounted object, we need to maintain the proper refcounts.

Parameters:
pvt The sip_pvt for which we wish to set the outboundproxy
proxy The sip_proxy which we will point pvt towards.
Returns:
Returns void

Definition at line 3058 of file chan_sip.c.

References ao2_ref, and sip_cfg.

Referenced by __sip_ack(), __sip_destroy(), __sip_subscribe_mwi_do(), create_addr(), create_addr_from_peer(), and sip_poke_peer().

03059 {
03060    struct sip_proxy *old_obproxy = pvt->outboundproxy;
03061    /* The sip_cfg.outboundproxy is statically allocated, and so
03062     * we don't ever need to adjust refcounts for it
03063     */
03064    if (proxy && proxy != &sip_cfg.outboundproxy) {
03065       ao2_ref(proxy, +1);
03066    }
03067    pvt->outboundproxy = proxy;
03068    if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) {
03069       ao2_ref(old_obproxy, -1);
03070    }
03071 }

static const char * referstatus2str ( enum referstatus  rstatus  )  [static]

Convert transfer status to string.

Definition at line 3180 of file chan_sip.c.

References map_x_s().

Referenced by show_channels_cb().

03181 {
03182    return map_x_s(referstatusstrings, rstatus, "");
03183 }

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

Get registration details from Asterisk DB.

Definition at line 14292 of file chan_sip.c.

References args, AST_APP_ARG, ast_db_get(), ast_debug, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_RAW_ARGS, ast_random(), AST_SCHED_REPLACE_UNREF, ast_sockaddr_copy(), ast_sockaddr_parse(), ast_sockaddr_stringify_host(), ast_string_field_set, expire_register(), ref_peer(), register_peer_exten(), sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().

Referenced by build_peer(), and temp_peer().

14293 {
14294    char data[256];
14295    struct ast_sockaddr sa;
14296    int expire;
14297    char full_addr[128];
14298    AST_DECLARE_APP_ARGS(args,
14299       AST_APP_ARG(addr);
14300       AST_APP_ARG(port);
14301       AST_APP_ARG(expiry_str);
14302       AST_APP_ARG(username);
14303       AST_APP_ARG(contact);
14304    );
14305 
14306    /* If read-only RT backend, then refresh from local DB cache */
14307    if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
14308       return;
14309    }
14310    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) {
14311       return;
14312    }
14313 
14314    AST_NONSTANDARD_RAW_ARGS(args, data, ':');
14315 
14316    snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port);
14317 
14318    if (!ast_sockaddr_parse(&sa, full_addr, 0)) {
14319       return;
14320    }
14321 
14322    if (args.expiry_str) {
14323       expire = atoi(args.expiry_str);
14324    } else {
14325       return;
14326    }
14327 
14328    if (args.username) {
14329       ast_string_field_set(peer, username, args.username);
14330    }
14331    if (args.contact) {
14332       ast_string_field_set(peer, fullcontact, args.contact);
14333    }
14334 
14335    ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n",
14336        peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire);
14337 
14338    ast_sockaddr_copy(&peer->addr, &sa);
14339    if (peer->maxms) {
14340       /* Don't poke peer immediately, just schedule it within qualifyfreq */
14341       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
14342             ast_random() % ((peer->qualifyfreq) ? peer->qualifyfreq : global_qualifyfreq) + 1,
14343             sip_poke_peer_s, peer,
14344             unref_peer(_data, "removing poke peer ref"),
14345             unref_peer(peer, "removing poke peer ref"),
14346             ref_peer(peer, "adding poke peer ref"));
14347    }
14348    AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer,
14349          unref_peer(_data, "remove registration ref"),
14350          unref_peer(peer, "remove registration ref"),
14351          ref_peer(peer, "add registration ref"));
14352    register_peer_exten(peer, TRUE);
14353 }

static void register_peer_exten ( struct sip_peer *  peer,
int  onoff 
) [static]

Automatically add peer extension to dial plan.

Definition at line 4765 of file chan_sip.c.

References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr(), ast_log(), ast_strdup, ast_strlen_zero(), context, E_MATCH, ext, LOG_WARNING, pbx_find_extension(), S_OR, and sip_cfg.

Referenced by expire_register(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and sip_poke_noanswer().

04766 {
04767    char multi[256];
04768    char *stringp, *ext, *context;
04769    struct pbx_find_info q = { .stacklen = 0 };
04770 
04771    /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and
04772     * the name of the global regexten context, if not specified
04773     * individually.
04774     */
04775    if (ast_strlen_zero(sip_cfg.regcontext))
04776       return;
04777 
04778    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
04779    stringp = multi;
04780    while ((ext = strsep(&stringp, "&"))) {
04781       if ((context = strchr(ext, '@'))) {
04782          *context++ = '\0';   /* split ext@context */
04783          if (!ast_context_find(context)) {
04784             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
04785             continue;
04786          }
04787       } else {
04788          context = sip_cfg.regcontext;
04789       }
04790       if (onoff) {
04791          if (!ast_exists_extension(NULL, context, ext, 1, NULL)) {
04792             ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
04793                 ast_strdup(peer->name), ast_free_ptr, "SIP");
04794          }
04795       } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) {
04796          ast_context_remove_extension(context, ext, 1, NULL);
04797       }
04798    }
04799 }

static enum check_auth_result register_verify ( struct sip_pvt *  p,
struct ast_sockaddr addr,
struct sip_request *  req,
const char *  uri 
) [static]

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".

Definition at line 15277 of file chan_sip.c.

References ao2_lock, ao2_t_link, ao2_unlock, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), build_contact(), check_auth(), check_request_transport, check_sip_domain(), EVENT_FLAG_SYSTEM, exten, extract_host_from_hostport(), FALSE, find_peer(), get_header(), get_in_brackets(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, name, parse_register_contact(), parse_uri_legacy_check(), ref_peer(), remove_uri_parameters(), sip_cancel_destroy(), sip_cfg, SIP_PEDANTIC_DECODE, sip_pvt_lock, sip_pvt_unlock, sip_send_mwi_to_peer(), temp_peer(), terminate_uri(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), TRUE, unref_peer(), update_peer(), and update_peer_lastmsgssent().

Referenced by handle_request_register().

15279 {
15280    enum check_auth_result res = AUTH_NOT_FOUND;
15281    struct sip_peer *peer;
15282    char tmp[256];
15283    char *c, *name, *unused_password, *domain;
15284    char *uri2 = ast_strdupa(uri);
15285    int send_mwi = 0;
15286 
15287    terminate_uri(uri2);
15288 
15289    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
15290 
15291    c = get_in_brackets(tmp);
15292    c = remove_uri_parameters(c);
15293 
15294    if (parse_uri_legacy_check(c, "sip:,sips:", &name, &unused_password, &domain, NULL)) {
15295       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr));
15296       return -1;
15297    }
15298 
15299    SIP_PEDANTIC_DECODE(name);
15300    SIP_PEDANTIC_DECODE(domain);
15301 
15302    extract_host_from_hostport(&domain);
15303 
15304    if (ast_strlen_zero(domain)) {
15305       /* <sip:name@[EMPTY]>, never good */
15306       transmit_response(p, "404 Not found", &p->initreq);
15307       return AUTH_UNKNOWN_DOMAIN;
15308    }
15309 
15310    if (ast_strlen_zero(name)) {
15311       /* <sip:[EMPTY][@]hostport>, unsure whether valid for
15312        * registration. RFC 3261, 10.2 states:
15313        * "The To header field and the Request-URI field typically
15314        * differ, as the former contains a user name."
15315        * But, Asterisk has always treated the domain-only uri as a
15316        * username: we allow admins to create accounts described by
15317        * domain name. */
15318       name = domain;
15319    }
15320 
15321    /* This here differs from 1.4 and 1.6: the domain matching ACLs were
15322     * skipped if it was a domain-only URI (used as username). Here we treat
15323     * <sip:hostport> as <sip:host@hostport> and won't forget to test the
15324     * domain ACLs against host. */
15325    if (!AST_LIST_EMPTY(&domain_list)) {
15326       if (!check_sip_domain(domain, NULL, 0)) {
15327          if (sip_cfg.alwaysauthreject) {
15328             transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
15329          } else {
15330             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
15331          }
15332          return AUTH_UNKNOWN_DOMAIN;
15333       }
15334    }
15335 
15336    ast_string_field_set(p, exten, name);
15337    build_contact(p);
15338    if (req->ignore) {
15339       /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
15340       const char *expires = get_header(req, "Expires");
15341       int expire = atoi(expires);
15342 
15343       if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */
15344          if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) {
15345             expire = atoi(expires + 9);
15346          }
15347       }
15348       if (!ast_strlen_zero(expires) && expire == 0) {
15349          transmit_response_with_date(p, "200 OK", req);
15350          return 0;
15351       }
15352    }
15353    peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
15354 
15355    /* If we don't want username disclosure, use the bogus_peer when a user
15356     * is not found. */
15357    if (!peer && sip_cfg.alwaysauthreject && !sip_cfg.autocreatepeer) {
15358       peer = bogus_peer;
15359       ref_peer(peer, "register_verify: ref the bogus_peer");
15360    }
15361 
15362    if (!(peer && ast_apply_ha(peer->ha, addr))) {
15363       /* Peer fails ACL check */
15364       if (peer) {
15365          unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
15366          peer = NULL;
15367          res = AUTH_ACL_FAILED;
15368       } else {
15369          res = AUTH_NOT_FOUND;
15370       }
15371    }
15372 
15373    if (peer) {
15374       ao2_lock(peer);
15375       if (!peer->host_dynamic) {
15376          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
15377          res = AUTH_PEER_NOT_DYNAMIC;
15378       } else {
15379          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT);
15380          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) {
15381             if (sip_cancel_destroy(p))
15382                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
15383 
15384             if (check_request_transport(peer, req)) {
15385                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
15386                transmit_response_with_date(p, "403 Forbidden", req);
15387                res = AUTH_BAD_TRANSPORT;
15388             } else {
15389 
15390                /* We have a successful registration attempt with proper authentication,
15391                   now, update the peer */
15392                switch (parse_register_contact(p, peer, req)) {
15393                case PARSE_REGISTER_DENIED:
15394                   ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
15395                   transmit_response_with_date(p, "603 Denied", req);
15396                   res = 0;
15397                   break;
15398                case PARSE_REGISTER_FAILED:
15399                   ast_log(LOG_WARNING, "Failed to parse contact info\n");
15400                   transmit_response_with_date(p, "400 Bad Request", req);
15401                   res = 0;
15402                   break;
15403                case PARSE_REGISTER_QUERY:
15404                   ast_string_field_set(p, fullcontact, peer->fullcontact);
15405                   transmit_response_with_date(p, "200 OK", req);
15406                   res = 0;
15407                   break;
15408                case PARSE_REGISTER_UPDATE:
15409                   ast_string_field_set(p, fullcontact, peer->fullcontact);
15410                   /* If expiry is 0, peer has been unregistered already */
15411                   if (p->expiry != 0) {
15412                      update_peer(peer, p->expiry);
15413                   }
15414                   /* Say OK and ask subsystem to retransmit msg counter */
15415                   transmit_response_with_date(p, "200 OK", req);
15416                   send_mwi = 1;
15417                   res = 0;
15418                   break;
15419                }
15420             }
15421 
15422          }
15423       }
15424       ao2_unlock(peer);
15425    }
15426    if (!peer && sip_cfg.autocreatepeer) {
15427       /* Create peer if we have autocreate mode enabled */
15428       peer = temp_peer(name);
15429       if (peer) {
15430          ao2_t_link(peers, peer, "link peer into peer table");
15431          if (!ast_sockaddr_isnull(&peer->addr)) {
15432             ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
15433          }
15434          ao2_lock(peer);
15435          if (sip_cancel_destroy(p))
15436             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
15437          switch (parse_register_contact(p, peer, req)) {
15438          case PARSE_REGISTER_DENIED:
15439             ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
15440             transmit_response_with_date(p, "403 Forbidden", req);
15441             res = 0;
15442             break;
15443          case PARSE_REGISTER_FAILED:
15444             ast_log(LOG_WARNING, "Failed to parse contact info\n");
15445             transmit_response_with_date(p, "400 Bad Request", req);
15446             res = 0;
15447             break;
15448          case PARSE_REGISTER_QUERY:
15449             ast_string_field_set(p, fullcontact, peer->fullcontact);
15450             transmit_response_with_date(p, "200 OK", req);
15451             send_mwi = 1;
15452             res = 0;
15453             break;
15454          case PARSE_REGISTER_UPDATE:
15455             ast_string_field_set(p, fullcontact, peer->fullcontact);
15456             /* Say OK and ask subsystem to retransmit msg counter */
15457             transmit_response_with_date(p, "200 OK", req);
15458             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(addr));
15459             send_mwi = 1;
15460             res = 0;
15461             break;
15462          }
15463          ao2_unlock(peer);
15464       }
15465    }
15466    if (!res) {
15467       if (send_mwi) {
15468          sip_pvt_unlock(p);
15469          sip_send_mwi_to_peer(peer, 0);
15470          sip_pvt_lock(p);
15471       } else {
15472          update_peer_lastmsgssent(peer, -1, 0);
15473       }
15474       ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
15475    }
15476    if (res < 0) {
15477       switch (res) {
15478       case AUTH_SECRET_FAILED:
15479          /* Wrong password in authentication. Go away, don't try again until you fixed it */
15480          transmit_response(p, "403 Forbidden", &p->initreq);
15481          if (global_authfailureevents) {
15482             const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
15483             const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
15484             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
15485                      "ChannelType: SIP\r\n"
15486                      "Peer: SIP/%s\r\n"
15487                      "PeerStatus: Rejected\r\n"
15488                      "Cause: AUTH_SECRET_FAILED\r\n"
15489                      "Address: %s\r\n"
15490                      "Port: %s\r\n",
15491                      name, peer_addr, peer_port);
15492          }
15493          break;
15494       case AUTH_USERNAME_MISMATCH:
15495          /* Username and digest username does not match.
15496             Asterisk uses the From: username for authentication. We need the
15497             devices to use the same authentication user name until we support
15498             proper authentication by digest auth name */
15499       case AUTH_NOT_FOUND:
15500       case AUTH_PEER_NOT_DYNAMIC:
15501       case AUTH_ACL_FAILED:
15502          if (sip_cfg.alwaysauthreject) {
15503             transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
15504             if (global_authfailureevents) {
15505                const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
15506                const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
15507                manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
15508                         "ChannelType: SIP\r\n"
15509                         "Peer: SIP/%s\r\n"
15510                         "PeerStatus: Rejected\r\n"
15511                         "Cause: %s\r\n"
15512                         "Address: %s\r\n"
15513                         "Port: %s\r\n",
15514                         name,
15515                         res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND",
15516                         peer_addr, peer_port);
15517             }
15518          } else {
15519             /* URI not found */
15520             if (res == AUTH_PEER_NOT_DYNAMIC) {
15521                transmit_response(p, "403 Forbidden", &p->initreq);
15522                if (global_authfailureevents) {
15523                   const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
15524                   const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
15525                   manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
15526                      "ChannelType: SIP\r\n"
15527                      "Peer: SIP/%s\r\n"
15528                      "PeerStatus: Rejected\r\n"
15529                      "Cause: AUTH_PEER_NOT_DYNAMIC\r\n"
15530                      "Address: %s\r\n"
15531                      "Port: %s\r\n",
15532                      name, peer_addr, peer_port);
15533                }
15534             } else {
15535                transmit_response(p, "404 Not found", &p->initreq);
15536                if (global_authfailureevents) {
15537                   const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
15538                   const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
15539                   manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
15540                      "ChannelType: SIP\r\n"
15541                      "Peer: SIP/%s\r\n"
15542                      "PeerStatus: Rejected\r\n"
15543                      "Cause: %s\r\n"
15544                      "Address: %s\r\n"
15545                      "Port: %s\r\n",
15546                      name,
15547                      (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND",
15548                      peer_addr, peer_port);
15549                }
15550             }
15551          }
15552          break;
15553       case AUTH_BAD_TRANSPORT:
15554       default:
15555          break;
15556       }
15557    }
15558    if (peer) {
15559       unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func");
15560    }
15561 
15562    return res;
15563 }

static struct sip_registry* registry_addref ( struct sip_registry *  reg,
char *  tag 
) [static, read]

Add object reference to SIP registry.

Definition at line 3162 of file chan_sip.c.

References ast_debug, and ASTOBJ_REF.

Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().

03163 {
03164    ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount + 1);
03165    return ASTOBJ_REF(reg); /* Add pointer to registry in packet */
03166 }

void * registry_unref ( struct sip_registry *  reg,
char *  tag 
) [static]

Definition at line 3154 of file chan_sip.c.

References ast_debug, ASTOBJ_UNREF, and sip_registry_destroy().

Referenced by __sip_destroy(), cleanup_all_regs(), dialog_unlink_all(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_registry_destroy(), sip_reregister(), sip_send_all_registers(), and transmit_register().

03155 {
03156    ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount - 1);
03157    ASTOBJ_UNREF(reg, sip_registry_destroy);
03158    return NULL;
03159 }

static const char * regstate2str ( enum sipregistrystate  regstate  )  [static]

Convert registration state status to string.

Definition at line 13558 of file chan_sip.c.

References map_x_s().

Referenced by handle_response_register(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().

13559 {
13560    return map_x_s(regstatestrings, regstate, "Unknown");
13561 }

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

Definition at line 6473 of file chan_sip.c.

References ao2_unlock, ast_channel_unlock, ast_channel_unref, check_pendings(), and sip_pvt_lock_full().

Referenced by sip_hangup().

06474 {
06475    struct sip_pvt *dialog = (struct sip_pvt *) data;
06476    struct ast_channel *owner = sip_pvt_lock_full(dialog);
06477    dialog->reinviteid = -1;
06478    check_pendings(dialog);
06479    if (owner) {
06480       ast_channel_unlock(owner);
06481       ast_channel_unref(owner);
06482    }
06483    ao2_unlock(dialog);
06484    dialog_unref(dialog, "unref for reinvite timeout");
06485    return 0;
06486 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 30672 of file chan_sip.c.

References sip_reload().

30673 {
30674    if (sip_reload(0, 0, NULL))
30675       return 0;
30676    return 1;
30677 }

static int reload_config ( enum channelreloadreason  reason  )  [static]

Re-read SIP.conf config file.

Note:
This function reloads all config data, except for active peers (with registrations). They will only change configuration data at restart, not at reload. SIP debug and recordhistory state will not change

< Don't force proxy usage, use route: headers

< Keep track of hold status for a peer

< Match auth username if available instead of From: Default off.

< Default DTMF setting: RFC2833

< Allow re-invites

< Default to nat=force_rport

Definition at line 28801 of file chan_sip.c.

References ast_tcptls_session_args::accept_fd, add_realm_authentication(), add_sip_domain(), ao2_t_callback, ao2_t_link, ao2_t_ref, ast_append_ha(), ast_bind(), ast_category_browse(), AST_CERTFILE, ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_flags, ast_copy_string(), ast_debug, ast_enable_packet_fragmentation(), ast_false(), ast_find_ourip(), AST_FLAGS_ALL, ast_free, ast_free_ha(), ast_get_version(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock, ast_mutex_unlock, ast_parse_allow_disallow(), ast_parse_arg(), ast_set2_flag, ast_set_flag, ast_set_qos(), ast_skip_blanks(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_ssl_setup(), ast_str2cos(), ast_str2tos(), ast_strdup, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_tcptls_server_start(), ast_test_flag, ast_tls_read_conf(), ast_true(), ast_unload_realtime(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, ASTOBJ_CONTAINER_DESTROYALL, bindaddr, build_peer(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, CHANNEL_MODULE_LOAD, channelreloadreason2txt(), ast_tls_config::cipher, cleanup_all_regs(), cleanup_stale_contexts(), clear_sip_domains(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, context, DEFAULT_AUTHLIMIT, DEFAULT_AUTHTIMEOUT, DEFAULT_CONTEXT, DEFAULT_MAXMS, DEFAULT_PARKINGLOT, default_prefs, DEFAULT_REALM, display_nat_warning(), ast_tls_config::enabled, errno, EVENT_FLAG_SYSTEM, externaddr, FALSE, gen, global_jbconf, handle_common_options(), handle_t38_options(), internip, ast_variable::lineno, ast_tcptls_session_args::local_address, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, mark_parsed_methods(), MAXHOSTNAMELEN, media_address, ast_variable::name, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, OBJ_NODATA, PARSE_ADDR, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_INT32, peer_markall_func(), port_str2int(), proxy_from_config(), ast_tls_config::pvtfile, regl, S_OR, secret, sip_cfg, sip_register(), sip_registry_destroy(), sip_subscribe_mwi(), str2stmode(), str2strefresherparam(), ast_tcptls_session_args::tls_cfg, TRUE, unref_peer(), and ast_variable::value.

Referenced by load_module(), and sip_do_reload().

28802 {
28803    struct ast_config *cfg, *ucfg;
28804    struct ast_variable *v;
28805    struct sip_peer *peer;
28806    char *cat, *stringp, *context, *oldregcontext;
28807    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
28808    struct ast_flags mask[3] = {{0}};
28809    struct ast_flags setflags[3] = {{0}};
28810    struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED };
28811    int auto_sip_domains = FALSE;
28812    struct ast_sockaddr old_bindaddr = bindaddr;
28813    int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0;
28814    int subscribe_network_change = 1;
28815    time_t run_start, run_end;
28816    int bindport = 0;
28817 
28818    run_start = time(0);
28819    ast_unload_realtime("sipregs");
28820    ast_unload_realtime("sippeers");
28821    cfg = ast_config_load(config, config_flags);
28822 
28823    /* We *must* have a config file otherwise stop immediately */
28824    if (!cfg) {
28825       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
28826       return -1;
28827    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
28828       ucfg = ast_config_load("users.conf", config_flags);
28829       if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
28830          return 1;
28831       } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
28832          ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n");
28833          return 1;
28834       }
28835       /* Must reread both files, because one changed */
28836       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
28837       if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
28838          ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config);
28839          ast_config_destroy(ucfg);
28840          return 1;
28841       }
28842       if (!cfg) {
28843          /* should have been able to reload here */
28844          ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
28845          return -1;
28846       }
28847    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
28848       ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config);
28849       return 1;
28850    } else {
28851       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
28852       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
28853          ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n");
28854          ast_config_destroy(cfg);
28855          return 1;
28856       }
28857    }
28858 
28859    ast_free_ha(sip_cfg.contact_ha);
28860    sip_cfg.contact_ha = NULL;
28861 
28862    default_tls_cfg.enabled = FALSE;    /* Default: Disable TLS */
28863 
28864    if (reason != CHANNEL_MODULE_LOAD) {
28865       ast_debug(4, "--------------- SIP reload started\n");
28866 
28867       clear_sip_domains();
28868       ast_mutex_lock(&authl_lock);
28869       if (authl) {
28870          ao2_t_ref(authl, -1, "Removing old global authentication");
28871          authl = NULL;
28872       }
28873       ast_mutex_unlock(&authl_lock);
28874 
28875 
28876       cleanup_all_regs();
28877       /* Then, actually destroy users and registry */
28878       ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
28879       ast_debug(4, "--------------- Done destroying registry list\n");
28880       ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers");
28881    }
28882 
28883    /* Reset certificate handling for TLS sessions */
28884    if (reason != CHANNEL_MODULE_LOAD) {
28885       ast_free(default_tls_cfg.certfile);
28886       ast_free(default_tls_cfg.pvtfile);
28887       ast_free(default_tls_cfg.cipher);
28888       ast_free(default_tls_cfg.cafile);
28889       ast_free(default_tls_cfg.capath);
28890    }
28891    default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */
28892    default_tls_cfg.pvtfile = ast_strdup("");
28893    default_tls_cfg.cipher = ast_strdup("");
28894    default_tls_cfg.cafile = ast_strdup("");
28895    default_tls_cfg.capath = ast_strdup("");
28896 
28897    /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */
28898    ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts));
28899    oldregcontext = oldcontexts;
28900 
28901    /* Clear all flags before setting default values */
28902    /* Preserve debugging settings for console */
28903    sipdebug &= sip_debug_console;
28904    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
28905    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
28906    ast_clear_flag(&global_flags[2], AST_FLAGS_ALL);
28907 
28908    /* Reset IP addresses  */
28909    ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
28910    memset(&internip, 0, sizeof(internip));
28911 
28912    /* Free memory for local network address mask */
28913    ast_free_ha(localaddr);
28914    memset(&localaddr, 0, sizeof(localaddr));
28915    memset(&externaddr, 0, sizeof(externaddr));
28916    memset(&media_address, 0, sizeof(media_address));
28917    memset(&default_prefs, 0 , sizeof(default_prefs));
28918    memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy));
28919    sip_cfg.outboundproxy.force = FALSE;      /*!< Don't force proxy usage, use route: headers */
28920    default_transports = SIP_TRANSPORT_UDP;
28921    default_primary_transport = SIP_TRANSPORT_UDP;
28922    ourport_tcp = STANDARD_SIP_PORT;
28923    ourport_tls = STANDARD_TLS_PORT;
28924    externtcpport = STANDARD_SIP_PORT;
28925    externtlsport = STANDARD_TLS_PORT;
28926    sip_cfg.srvlookup = DEFAULT_SRVLOOKUP;
28927    global_tos_sip = DEFAULT_TOS_SIP;
28928    global_tos_audio = DEFAULT_TOS_AUDIO;
28929    global_tos_video = DEFAULT_TOS_VIDEO;
28930    global_tos_text = DEFAULT_TOS_TEXT;
28931    global_cos_sip = DEFAULT_COS_SIP;
28932    global_cos_audio = DEFAULT_COS_AUDIO;
28933    global_cos_video = DEFAULT_COS_VIDEO;
28934    global_cos_text = DEFAULT_COS_TEXT;
28935 
28936    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
28937    externexpire = 0;       /* Expiration for DNS re-issuing */
28938    externrefresh = 10;
28939 
28940    /* Reset channel settings to default before re-configuring */
28941    sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM;           /* Allow external invites */
28942    sip_cfg.regcontext[0] = '\0';
28943    sip_cfg.capability = DEFAULT_CAPABILITY;
28944    sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY;
28945    sip_cfg.legacy_useroption_parsing = DEFAULT_LEGACY_USEROPTION_PARSING;
28946    sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING;
28947    sip_cfg.notifycid = DEFAULT_NOTIFYCID;
28948    sip_cfg.notifyhold = FALSE;      /*!< Keep track of hold status for a peer */
28949    sip_cfg.directrtpsetup = FALSE;     /* Experimental feature, disabled by default */
28950    sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT;
28951    sip_cfg.auth_options_requests = DEFAULT_AUTH_OPTIONS;
28952    sip_cfg.allowsubscribe = FALSE;
28953    sip_cfg.disallowed_methods = SIP_UNKNOWN;
28954    sip_cfg.contact_ha = NULL;    /* Reset the contact ACL */
28955    snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version());
28956    snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version());
28957    snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER);
28958    global_prematuremediafilter = TRUE;
28959    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
28960    ast_copy_string(sip_cfg.realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(sip_cfg.realm));
28961    sip_cfg.domainsasrealm = DEFAULT_DOMAINSASREALM;
28962    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
28963    ast_copy_string(default_mwi_from, DEFAULT_MWI_FROM, sizeof(default_mwi_from));
28964    sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS;
28965    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
28966    global_regattempts_max = 0;
28967    global_reg_retry_403 = 0;
28968    sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC;
28969    sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER;
28970    global_autoframing = 0;
28971    sip_cfg.allowguest = DEFAULT_ALLOWGUEST;
28972    global_callcounter = DEFAULT_CALLCOUNTER;
28973    global_match_auth_username = FALSE;    /*!< Match auth username if available instead of From: Default off. */
28974    global_rtptimeout = 0;
28975    global_rtpholdtimeout = 0;
28976    global_rtpkeepalive = DEFAULT_RTPKEEPALIVE;
28977    sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */
28978    sip_cfg.rtautoclear = 120;
28979    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for all devices: TRUE */
28980    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */
28981    sip_cfg.peer_rtupdate = TRUE;
28982    global_dynamic_exclude_static = 0;  /* Exclude static peers */
28983    sip_cfg.tcp_enabled = FALSE;
28984 
28985    /* Session-Timers */
28986    global_st_mode = SESSION_TIMER_MODE_ACCEPT;
28987    global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS;
28988    global_min_se  = DEFAULT_MIN_SE;
28989    global_max_se  = DEFAULT_MAX_SE;
28990 
28991    /* Peer poking settings */
28992    global_qualify_gap = DEFAULT_QUALIFY_GAP;
28993    global_qualify_peers = DEFAULT_QUALIFY_PEERS;
28994 
28995    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */
28996    ast_copy_string(sip_cfg.default_context, DEFAULT_CONTEXT, sizeof(sip_cfg.default_context));
28997    sip_cfg.default_subscribecontext[0] = '\0';
28998    sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS;
28999    default_language[0] = '\0';
29000    default_fromdomain[0] = '\0';
29001    default_fromdomainport = 0;
29002    default_qualify = DEFAULT_QUALIFY;
29003    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
29004    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
29005    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
29006    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
29007    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);    /*!< Default DTMF setting: RFC2833 */
29008    ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA);    /*!< Allow re-invites */
29009    ast_set_flag(&global_flags[0], SIP_NAT_FORCE_RPORT); /*!< Default to nat=force_rport */
29010    ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine));
29011    ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot));
29012 
29013    /* Debugging settings, always default to off */
29014    dumphistory = FALSE;
29015    recordhistory = FALSE;
29016    sipdebug &= ~sip_debug_config;
29017 
29018    /* Misc settings for the channel */
29019    global_relaxdtmf = FALSE;
29020    sip_cfg.callevents = DEFAULT_CALLEVENTS;
29021    global_authfailureevents = FALSE;
29022    global_t1 = DEFAULT_TIMER_T1;
29023    global_timer_b = 64 * DEFAULT_TIMER_T1;
29024    global_t1min = DEFAULT_T1MIN;
29025    global_qualifyfreq = DEFAULT_QUALIFYFREQ;
29026    global_t38_maxdatagram = -1;
29027    global_shrinkcallerid = 1;
29028    authlimit = DEFAULT_AUTHLIMIT;
29029    authtimeout = DEFAULT_AUTHTIMEOUT;
29030    global_store_sip_cause = DEFAULT_STORE_SIP_CAUSE;
29031 
29032    sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY;
29033 
29034    /* Copy the default jb config over global_jbconf */
29035    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
29036 
29037    ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT);
29038    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
29039    ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT);
29040    ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION);
29041 
29042 
29043    /* Read the [general] config section of sip.conf (or from realtime config) */
29044    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
29045       if (handle_common_options(&setflags[0], &mask[0], v)) {
29046          continue;
29047       }
29048       if (handle_t38_options(&setflags[0], &mask[0], v, &global_t38_maxdatagram)) {
29049          continue;
29050       }
29051       /* handle jb conf */
29052       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
29053          continue;
29054 
29055       /* handle tls conf, don't allow setting of tlsverifyclient as it isn't supported by chan_sip */
29056       if (!strcasecmp(v->name, "tlsverifyclient")) {
29057          ast_log(LOG_WARNING, "Ignoring unsupported option 'tlsverifyclient'\n");
29058          continue;
29059       } else if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) {
29060          continue;
29061       }
29062 
29063       if (!strcasecmp(v->name, "context")) {
29064          ast_copy_string(sip_cfg.default_context, v->value, sizeof(sip_cfg.default_context));
29065       } else if (!strcasecmp(v->name, "subscribecontext")) {
29066          ast_copy_string(sip_cfg.default_subscribecontext, v->value, sizeof(sip_cfg.default_subscribecontext));
29067       } else if (!strcasecmp(v->name, "callcounter")) {
29068          global_callcounter = ast_true(v->value) ? 1 : 0;
29069       } else if (!strcasecmp(v->name, "allowguest")) {
29070          sip_cfg.allowguest = ast_true(v->value) ? 1 : 0;
29071       } else if (!strcasecmp(v->name, "realm")) {
29072          ast_copy_string(sip_cfg.realm, v->value, sizeof(sip_cfg.realm));
29073       } else if (!strcasecmp(v->name, "domainsasrealm")) {
29074          sip_cfg.domainsasrealm = ast_true(v->value);
29075       } else if (!strcasecmp(v->name, "useragent")) {
29076          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
29077          ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
29078       } else if (!strcasecmp(v->name, "sdpsession")) {
29079          ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession));
29080       } else if (!strcasecmp(v->name, "sdpowner")) {
29081          /* Field cannot contain spaces */
29082          if (!strstr(v->value, " ")) {
29083             ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner));
29084          } else {
29085             ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d.  Using default.\n", v->value, v->lineno);
29086          }
29087       } else if (!strcasecmp(v->name, "allowtransfer")) {
29088          sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
29089       } else if (!strcasecmp(v->name, "rtcachefriends")) {
29090          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);
29091       } else if (!strcasecmp(v->name, "rtsavesysname")) {
29092          sip_cfg.rtsave_sysname = ast_true(v->value);
29093       } else if (!strcasecmp(v->name, "rtupdate")) {
29094          sip_cfg.peer_rtupdate = ast_true(v->value);
29095       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
29096          sip_cfg.ignore_regexpire = ast_true(v->value);
29097       } else if (!strcasecmp(v->name, "timert1")) {
29098          /* Defaults to 500ms, but RFC 3261 states that it is recommended
29099           * for the value to be set higher, though a lower value is only
29100           * allowed on private networks unconnected to the Internet. */
29101          global_t1 = atoi(v->value);
29102       } else if (!strcasecmp(v->name, "timerb")) {
29103          int tmp = atoi(v->value);
29104          if (tmp < 500) {
29105             global_timer_b = global_t1 * 64;
29106             ast_log(LOG_WARNING, "Invalid value for timerb ('%s').  Setting to default ('%d').\n", v->value, global_timer_b);
29107          }
29108          timerb_set = 1;
29109       } else if (!strcasecmp(v->name, "t1min")) {
29110          global_t1min = atoi(v->value);
29111       } else if (!strcasecmp(v->name, "transport")) {
29112          char *val = ast_strdupa(v->value);
29113          char *trans;
29114 
29115          default_transports = default_primary_transport = 0;
29116          while ((trans = strsep(&val, ","))) {
29117             trans = ast_skip_blanks(trans);
29118 
29119             if (!strncasecmp(trans, "udp", 3)) {
29120                default_transports |= SIP_TRANSPORT_UDP;
29121             } else if (!strncasecmp(trans, "tcp", 3)) {
29122                default_transports |= SIP_TRANSPORT_TCP;
29123             } else if (!strncasecmp(trans, "tls", 3)) {
29124                default_transports |= SIP_TRANSPORT_TLS;
29125             } else {
29126                ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
29127             }
29128             if (default_primary_transport == 0) {
29129                default_primary_transport = default_transports;
29130             }
29131          }
29132       } else if (!strcasecmp(v->name, "tcpenable")) {
29133          if (!ast_false(v->value)) {
29134             ast_debug(2, "Enabling TCP socket for listening\n");
29135             sip_cfg.tcp_enabled = TRUE;
29136          }
29137       } else if (!strcasecmp(v->name, "tcpbindaddr")) {
29138          if (ast_parse_arg(v->value, PARSE_ADDR,
29139                  &sip_tcp_desc.local_address)) {
29140             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
29141                v->name, v->value, v->lineno, config);
29142          }
29143          ast_debug(2, "Setting TCP socket address to %s\n",
29144               ast_sockaddr_stringify(&sip_tcp_desc.local_address));
29145       } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) {
29146          global_dynamic_exclude_static = ast_true(v->value);
29147       } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
29148          int ha_error = 0;
29149          sip_cfg.contact_ha = ast_append_ha(v->name + 7, v->value, sip_cfg.contact_ha, &ha_error);
29150          if (ha_error) {
29151             ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
29152          }
29153       } else if (!strcasecmp(v->name, "rtautoclear")) {
29154          int i = atoi(v->value);
29155          if (i > 0) {
29156             sip_cfg.rtautoclear = i;
29157          } else {
29158             i = 0;
29159          }
29160          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
29161       } else if (!strcasecmp(v->name, "usereqphone")) {
29162          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);
29163       } else if (!strcasecmp(v->name, "prematuremedia")) {
29164          global_prematuremediafilter = ast_true(v->value);
29165       } else if (!strcasecmp(v->name, "relaxdtmf")) {
29166          global_relaxdtmf = ast_true(v->value);
29167       } else if (!strcasecmp(v->name, "vmexten")) {
29168          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
29169       } else if (!strcasecmp(v->name, "rtptimeout")) {
29170          if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
29171             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
29172             global_rtptimeout = 0;
29173          }
29174       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
29175          if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
29176             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
29177             global_rtpholdtimeout = 0;
29178          }
29179       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
29180          if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
29181             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
29182             global_rtpkeepalive = DEFAULT_RTPKEEPALIVE;
29183          }
29184       } else if (!strcasecmp(v->name, "compactheaders")) {
29185          sip_cfg.compactheaders = ast_true(v->value);
29186       } else if (!strcasecmp(v->name, "notifymimetype")) {
29187          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
29188       } else if (!strcasecmp(v->name, "directrtpsetup")) {
29189          sip_cfg.directrtpsetup = ast_true(v->value);
29190       } else if (!strcasecmp(v->name, "notifyringing")) {
29191          sip_cfg.notifyringing = ast_true(v->value);
29192       } else if (!strcasecmp(v->name, "notifyhold")) {
29193          sip_cfg.notifyhold = ast_true(v->value);
29194       } else if (!strcasecmp(v->name, "notifycid")) {
29195          if (!strcasecmp(v->value, "ignore-context")) {
29196             sip_cfg.notifycid = IGNORE_CONTEXT;
29197          } else {
29198             sip_cfg.notifycid = ast_true(v->value) ? ENABLED : DISABLED;
29199          }
29200       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
29201          sip_cfg.alwaysauthreject = ast_true(v->value);
29202       } else if (!strcasecmp(v->name, "auth_options_requests")) {
29203          if (ast_true(v->value)) {
29204             sip_cfg.auth_options_requests = 1;
29205          }
29206       } else if (!strcasecmp(v->name, "mohinterpret")) {
29207          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
29208       } else if (!strcasecmp(v->name, "mohsuggest")) {
29209          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
29210       } else if (!strcasecmp(v->name, "language")) {
29211          ast_copy_string(default_language, v->value, sizeof(default_language));
29212       } else if (!strcasecmp(v->name, "regcontext")) {
29213          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
29214          stringp = newcontexts;
29215          /* Let's remove any contexts that are no longer defined in regcontext */
29216          cleanup_stale_contexts(stringp, oldregcontext);
29217          /* Create contexts if they don't exist already */
29218          while ((context = strsep(&stringp, "&"))) {
29219             ast_copy_string(used_context, context, sizeof(used_context));
29220             ast_context_find_or_create(NULL, NULL, context, "SIP");
29221          }
29222          ast_copy_string(sip_cfg.regcontext, v->value, sizeof(sip_cfg.regcontext));
29223       } else if (!strcasecmp(v->name, "regextenonqualify")) {
29224          sip_cfg.regextenonqualify = ast_true(v->value);
29225       } else if (!strcasecmp(v->name, "legacy_useroption_parsing")) {
29226          sip_cfg.legacy_useroption_parsing = ast_true(v->value);
29227       } else if (!strcasecmp(v->name, "callerid")) {
29228          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
29229       } else if (!strcasecmp(v->name, "mwi_from")) {
29230          ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from));
29231       } else if (!strcasecmp(v->name, "fromdomain")) {
29232          char *fromdomainport;
29233          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
29234          if ((fromdomainport = strchr(default_fromdomain, ':'))) {
29235             *fromdomainport++ = '\0';
29236             if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) {
29237                ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
29238             }
29239          } else {
29240             default_fromdomainport = STANDARD_SIP_PORT;
29241          }
29242       } else if (!strcasecmp(v->name, "outboundproxy")) {
29243          struct sip_proxy *proxy;
29244          if (ast_strlen_zero(v->value)) {
29245             ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno);
29246             continue;
29247          }
29248          proxy = proxy_from_config(v->value, v->lineno, &sip_cfg.outboundproxy);
29249          if (!proxy) {
29250             ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno);
29251             continue;
29252          }
29253       } else if (!strcasecmp(v->name, "autocreatepeer")) {
29254          sip_cfg.autocreatepeer = ast_true(v->value);
29255       } else if (!strcasecmp(v->name, "match_auth_username")) {
29256          global_match_auth_username = ast_true(v->value);
29257       } else if (!strcasecmp(v->name, "srvlookup")) {
29258          sip_cfg.srvlookup = ast_true(v->value);
29259       } else if (!strcasecmp(v->name, "pedantic")) {
29260          sip_cfg.pedanticsipchecking = ast_true(v->value);
29261       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
29262          max_expiry = atoi(v->value);
29263          if (max_expiry < 1) {
29264             max_expiry = DEFAULT_MAX_EXPIRY;
29265          }
29266       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
29267          min_expiry = atoi(v->value);
29268          if (min_expiry < 1) {
29269             min_expiry = DEFAULT_MIN_EXPIRY;
29270          }
29271       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
29272          default_expiry = atoi(v->value);
29273          if (default_expiry < 1) {
29274             default_expiry = DEFAULT_DEFAULT_EXPIRY;
29275          }
29276       } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) {
29277          mwi_expiry = atoi(v->value);
29278          if (mwi_expiry < 1) {
29279             mwi_expiry = DEFAULT_MWI_EXPIRY;
29280          }
29281       } else if (!strcasecmp(v->name, "tcpauthtimeout")) {
29282          if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
29283                  &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) {
29284             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
29285                v->name, v->value, v->lineno, config);
29286          }
29287       } else if (!strcasecmp(v->name, "tcpauthlimit")) {
29288          if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
29289                  &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) {
29290             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
29291                v->name, v->value, v->lineno, config);
29292          }
29293       } else if (!strcasecmp(v->name, "sipdebug")) {
29294          if (ast_true(v->value))
29295             sipdebug |= sip_debug_config;
29296       } else if (!strcasecmp(v->name, "dumphistory")) {
29297          dumphistory = ast_true(v->value);
29298       } else if (!strcasecmp(v->name, "recordhistory")) {
29299          recordhistory = ast_true(v->value);
29300       } else if (!strcasecmp(v->name, "registertimeout")) {
29301          global_reg_timeout = atoi(v->value);
29302          if (global_reg_timeout < 1) {
29303             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
29304          }
29305       } else if (!strcasecmp(v->name, "registerattempts")) {
29306          global_regattempts_max = atoi(v->value);
29307       } else if (!strcasecmp(v->name, "register_retry_403")) {
29308          global_reg_retry_403 = ast_true(v->value);
29309       } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) {
29310          if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
29311             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
29312          }
29313       } else if (!strcasecmp(v->name, "localnet")) {
29314          struct ast_ha *na;
29315          int ha_error = 0;
29316 
29317          if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) {
29318             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
29319          } else {
29320             localaddr = na;
29321          }
29322          if (ha_error) {
29323             ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value);
29324          }
29325       } else if (!strcasecmp(v->name, "media_address")) {
29326          if (ast_parse_arg(v->value, PARSE_ADDR, &media_address))
29327             ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value);
29328       } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) {
29329          if (ast_parse_arg(v->value, PARSE_ADDR, &externaddr)) {
29330             ast_log(LOG_WARNING,
29331                "Invalid address for externaddr keyword: %s\n",
29332                v->value);
29333          }
29334          externexpire = 0;
29335       } else if (!strcasecmp(v->name, "externhost")) {
29336          ast_copy_string(externhost, v->value, sizeof(externhost));
29337          if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
29338             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
29339          }
29340          externexpire = time(NULL);
29341       } else if (!strcasecmp(v->name, "externrefresh")) {
29342          if (sscanf(v->value, "%30d", &externrefresh) != 1) {
29343             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
29344             externrefresh = 10;
29345          }
29346       } else if (!strcasecmp(v->name, "externtcpport")) {
29347          if (!(externtcpport = port_str2int(v->value, 0))) {
29348             ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
29349             externtcpport = 0;
29350          }
29351       } else if (!strcasecmp(v->name, "externtlsport")) {
29352          if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) {
29353             ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
29354          }
29355       } else if (!strcasecmp(v->name, "allow")) {
29356          int error =  ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE);
29357          if (error) {
29358             ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
29359          }
29360       } else if (!strcasecmp(v->name, "disallow")) {
29361          int error =  ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE);
29362          if (error) {
29363             ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
29364          }
29365       } else if (!strcasecmp(v->name, "preferred_codec_only")) {
29366          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
29367       } else if (!strcasecmp(v->name, "autoframing")) {
29368          global_autoframing = ast_true(v->value);
29369       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
29370          sip_cfg.allow_external_domains = ast_true(v->value);
29371       } else if (!strcasecmp(v->name, "autodomain")) {
29372          auto_sip_domains = ast_true(v->value);
29373       } else if (!strcasecmp(v->name, "domain")) {
29374          char *domain = ast_strdupa(v->value);
29375          char *cntx = strchr(domain, ',');
29376 
29377          if (cntx) {
29378             *cntx++ = '\0';
29379          }
29380 
29381          if (ast_strlen_zero(cntx)) {
29382             ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
29383          }
29384          if (ast_strlen_zero(domain)) {
29385             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
29386          } else {
29387             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : "");
29388          }
29389       } else if (!strcasecmp(v->name, "register")) {
29390          if (sip_register(v->value, v->lineno) == 0) {
29391             registry_count++;
29392          }
29393       } else if (!strcasecmp(v->name, "mwi")) {
29394          sip_subscribe_mwi(v->value, v->lineno);
29395       } else if (!strcasecmp(v->name, "tos_sip")) {
29396          if (ast_str2tos(v->value, &global_tos_sip)) {
29397             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno);
29398          }
29399       } else if (!strcasecmp(v->name, "tos_audio")) {
29400          if (ast_str2tos(v->value, &global_tos_audio)) {
29401             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
29402          }
29403       } else if (!strcasecmp(v->name, "tos_video")) {
29404          if (ast_str2tos(v->value, &global_tos_video)) {
29405             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno);
29406          }
29407       } else if (!strcasecmp(v->name, "tos_text")) {
29408          if (ast_str2tos(v->value, &global_tos_text)) {
29409             ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno);
29410          }
29411       } else if (!strcasecmp(v->name, "cos_sip")) {
29412          if (ast_str2cos(v->value, &global_cos_sip)) {
29413             ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno);
29414          }
29415       } else if (!strcasecmp(v->name, "cos_audio")) {
29416          if (ast_str2cos(v->value, &global_cos_audio)) {
29417             ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
29418          }
29419       } else if (!strcasecmp(v->name, "cos_video")) {
29420          if (ast_str2cos(v->value, &global_cos_video)) {
29421             ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno);
29422          }
29423       } else if (!strcasecmp(v->name, "cos_text")) {
29424          if (ast_str2cos(v->value, &global_cos_text)) {
29425             ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno);
29426          }
29427       } else if (!strcasecmp(v->name, "bindport")) {
29428          if (sscanf(v->value, "%5d", &bindport) != 1) {
29429             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
29430          }
29431       } else if (!strcasecmp(v->name, "qualify")) {
29432          if (!strcasecmp(v->value, "no")) {
29433             default_qualify = 0;
29434          } else if (!strcasecmp(v->value, "yes")) {
29435             default_qualify = DEFAULT_MAXMS;
29436          } else if (sscanf(v->value, "%30d", &default_qualify) != 1) {
29437             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
29438             default_qualify = 0;
29439          }
29440       } else if (!strcasecmp(v->name, "qualifyfreq")) {
29441          int i;
29442          if (sscanf(v->value, "%30d", &i) == 1) {
29443             global_qualifyfreq = i * 1000;
29444          } else {
29445             ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
29446             global_qualifyfreq = DEFAULT_QUALIFYFREQ;
29447          }
29448       } else if (!strcasecmp(v->name, "callevents")) {
29449          sip_cfg.callevents = ast_true(v->value);
29450       } else if (!strcasecmp(v->name, "authfailureevents")) {
29451          global_authfailureevents = ast_true(v->value);
29452       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
29453          default_maxcallbitrate = atoi(v->value);
29454          if (default_maxcallbitrate < 0)
29455             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
29456       } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) {
29457          sip_cfg.matchexternaddrlocally = ast_true(v->value);
29458       } else if (!strcasecmp(v->name, "session-timers")) {
29459          int i = (int) str2stmode(v->value);
29460          if (i < 0) {
29461             ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
29462             global_st_mode = SESSION_TIMER_MODE_ACCEPT;
29463          } else {
29464             global_st_mode = i;
29465          }
29466       } else if (!strcasecmp(v->name, "session-expires")) {
29467          if (sscanf(v->value, "%30d", &global_max_se) != 1) {
29468             ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
29469             global_max_se = DEFAULT_MAX_SE;
29470          }
29471       } else if (!strcasecmp(v->name, "session-minse")) {
29472          if (sscanf(v->value, "%30d", &global_min_se) != 1) {
29473             ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
29474             global_min_se = DEFAULT_MIN_SE;
29475          }
29476          if (global_min_se < DEFAULT_MIN_SE) {
29477             ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < %d secs\n", v->value, v->lineno, config, DEFAULT_MIN_SE);
29478             global_min_se = DEFAULT_MIN_SE;
29479          }
29480       } else if (!strcasecmp(v->name, "session-refresher")) {
29481          int i = (int) str2strefresherparam(v->value);
29482          if (i < 0) {
29483             ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
29484             global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS;
29485          } else {
29486             global_st_refresher = i;
29487          }
29488       } else if (!strcasecmp(v->name, "storesipcause")) {
29489          global_store_sip_cause = ast_true(v->value);
29490       } else if (!strcasecmp(v->name, "qualifygap")) {
29491          if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) {
29492             ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config);
29493             global_qualify_gap = DEFAULT_QUALIFY_GAP;
29494          }
29495       } else if (!strcasecmp(v->name, "qualifypeers")) {
29496          if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) {
29497             ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config);
29498             global_qualify_peers = DEFAULT_QUALIFY_PEERS;
29499          }
29500       } else if (!strcasecmp(v->name, "disallowed_methods")) {
29501          char *disallow = ast_strdupa(v->value);
29502          mark_parsed_methods(&sip_cfg.disallowed_methods, disallow);
29503       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
29504          if (ast_true(v->value)) {
29505             global_shrinkcallerid = 1;
29506          } else if (ast_false(v->value)) {
29507             global_shrinkcallerid = 0;
29508          } else {
29509             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
29510          }
29511       } else if (!strcasecmp(v->name, "use_q850_reason")) {
29512          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
29513       } else if (!strcasecmp(v->name, "maxforwards")) {
29514          if (sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1
29515             || sip_cfg.default_max_forwards < 1 || 255 < sip_cfg.default_max_forwards) {
29516             ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d.  Using default.\n", v->value, v->lineno);
29517             sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS;
29518          }
29519       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
29520          if (ast_true(v->value)) {
29521             subscribe_network_change = 1;
29522          } else if (ast_false(v->value)) {
29523             subscribe_network_change = 0;
29524          } else {
29525             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
29526          }
29527       } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
29528          ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
29529       } else if (!strcasecmp(v->name, "parkinglot")) {
29530          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
29531       }
29532    }
29533 
29534    /* Override global defaults if setting found in general section */
29535    ast_copy_flags(&global_flags[0], &setflags[0], mask[0].flags);
29536    ast_copy_flags(&global_flags[1], &setflags[1], mask[1].flags);
29537    ast_copy_flags(&global_flags[2], &setflags[2], mask[2].flags);
29538 
29539    if (subscribe_network_change) {
29540       network_change_event_subscribe();
29541    } else {
29542       network_change_event_unsubscribe();
29543    }
29544 
29545    if (global_t1 < global_t1min) {
29546       ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d).  Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1);
29547       global_t1 = global_t1min;
29548    }
29549 
29550    if (global_timer_b < global_t1 * 64) {
29551       if (timerb_set && timert1_set) {
29552          ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1);
29553       } else if (timerb_set) {
29554          if ((global_t1 = global_timer_b / 64) < global_t1min) {
29555             ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1);
29556             global_t1 = global_t1min;
29557             global_timer_b = global_t1 * 64;
29558          }
29559       } else {
29560          global_timer_b = global_t1 * 64;
29561       }
29562    }
29563    if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
29564       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
29565       sip_cfg.allow_external_domains = 1;
29566    }
29567    /* If not or badly configured, set default transports */
29568    if (!sip_cfg.tcp_enabled && (default_transports & SIP_TRANSPORT_TCP)) {
29569       ast_log(LOG_WARNING, "Cannot use 'tcp' transport with tcpenable=no. Removing from available transports.\n");
29570       default_primary_transport &= ~SIP_TRANSPORT_TCP;
29571       default_transports &= ~SIP_TRANSPORT_TCP;
29572    }
29573    if (!default_tls_cfg.enabled && (default_transports & SIP_TRANSPORT_TLS)) {
29574       ast_log(LOG_WARNING, "Cannot use 'tls' transport with tlsenable=no. Removing from available transports.\n");
29575       default_primary_transport &= ~SIP_TRANSPORT_TLS;
29576       default_transports &= ~SIP_TRANSPORT_TLS;
29577    }
29578    if (!default_transports) {
29579       ast_log(LOG_WARNING, "No valid transports available, falling back to 'udp'.\n");
29580       default_transports = default_primary_transport = SIP_TRANSPORT_UDP;
29581    } else if (!default_primary_transport) {
29582       ast_log(LOG_WARNING, "No valid default transport. Selecting 'udp' as default.\n");
29583       default_primary_transport = SIP_TRANSPORT_UDP;
29584    }
29585 
29586    /* Build list of authentication to various SIP realms, i.e. service providers */
29587    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
29588       /* Format for authentication is auth = username:password@realm */
29589       if (!strcasecmp(v->name, "auth")) {
29590          add_realm_authentication(&authl, v->value, v->lineno);
29591       }
29592    }
29593 
29594    if (bindport) {
29595       if (ast_sockaddr_port(&bindaddr)) {
29596          ast_log(LOG_WARNING, "bindport is also specified in bindaddr. "
29597             "Using %d.\n", bindport);
29598       }
29599       ast_sockaddr_set_port(&bindaddr, bindport);
29600    }
29601 
29602    if (!ast_sockaddr_port(&bindaddr)) {
29603       ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT);
29604    }
29605 
29606    /* Set UDP address and open socket */
29607    ast_sockaddr_copy(&internip, &bindaddr);
29608    if (ast_find_ourip(&internip, &bindaddr, 0)) {
29609       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
29610       ast_config_destroy(cfg);
29611       return 0;
29612    }
29613 
29614    ast_mutex_lock(&netlock);
29615    if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) {
29616       close(sipsock);
29617       sipsock = -1;
29618    }
29619    if (sipsock < 0) {
29620       sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ?
29621              AF_INET6 : AF_INET, SOCK_DGRAM, 0);
29622       if (sipsock < 0) {
29623          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
29624          ast_config_destroy(cfg);
29625          ast_mutex_unlock(&netlock);
29626          return -1;
29627       } else {
29628          /* Allow SIP clients on the same host to access us: */
29629          const int reuseFlag = 1;
29630 
29631          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
29632                (const char*)&reuseFlag,
29633                sizeof reuseFlag);
29634 
29635          ast_enable_packet_fragmentation(sipsock);
29636 
29637          if (ast_bind(sipsock, &bindaddr) < 0) {
29638             ast_log(LOG_WARNING, "Failed to bind to %s: %s\n",
29639                ast_sockaddr_stringify(&bindaddr), strerror(errno));
29640             close(sipsock);
29641             sipsock = -1;
29642          } else {
29643             ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr));
29644             ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
29645          }
29646       }
29647    } else {
29648       ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
29649    }
29650    ast_mutex_unlock(&netlock);
29651 
29652    /* Start TCP server */
29653    if (sip_cfg.tcp_enabled) {
29654       if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) {
29655          ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr);
29656       }
29657       if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) {
29658          ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT);
29659       }
29660    } else {
29661       ast_sockaddr_setnull(&sip_tcp_desc.local_address);
29662    }
29663    ast_tcptls_server_start(&sip_tcp_desc);
29664    if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) {
29665       /* TCP server start failed. Tell the admin */
29666       ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n");
29667    } else {
29668       ast_debug(2, "SIP TCP server started\n");
29669    }
29670 
29671    /* Start TLS server if needed */
29672    memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg));
29673 
29674    if (ast_ssl_setup(sip_tls_desc.tls_cfg)) {
29675       if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) {
29676          ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr);
29677          ast_sockaddr_set_port(&sip_tls_desc.local_address,
29678                      STANDARD_TLS_PORT);
29679       }
29680       if (!ast_sockaddr_port(&sip_tls_desc.local_address)) {
29681          ast_sockaddr_set_port(&sip_tls_desc.local_address,
29682                      STANDARD_TLS_PORT);
29683       }
29684       ast_tcptls_server_start(&sip_tls_desc);
29685       if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) {
29686          ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n");
29687          sip_tls_desc.tls_cfg = NULL;
29688       }
29689    } else if (sip_tls_desc.tls_cfg->enabled) {
29690       sip_tls_desc.tls_cfg = NULL;
29691       ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n");
29692    }
29693 
29694    if (ucfg) {
29695       struct ast_variable *gen;
29696       int genhassip, genregistersip;
29697       const char *hassip, *registersip;
29698       
29699       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
29700       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
29701       gen = ast_variable_browse(ucfg, "general");
29702       cat = ast_category_browse(ucfg, NULL);
29703       while (cat) {
29704          if (strcasecmp(cat, "general")) {
29705             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
29706             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
29707             if (ast_true(hassip) || (!hassip && genhassip)) {
29708                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0);
29709                if (peer) {
29710                   /* user.conf entries are always of type friend */
29711                   peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
29712                   ao2_t_link(peers, peer, "link peer into peer table");
29713                   if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
29714                      ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
29715                   }
29716                   
29717                   unref_peer(peer, "unref_peer: from reload_config");
29718                   peer_count++;
29719                }
29720             }
29721             if (ast_true(registersip) || (!registersip && genregistersip)) {
29722                char tmp[256];
29723                const char *host = ast_variable_retrieve(ucfg, cat, "host");
29724                const char *username = ast_variable_retrieve(ucfg, cat, "username");
29725                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
29726                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
29727                const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser");
29728                if (!host) {
29729                   host = ast_variable_retrieve(ucfg, "general", "host");
29730                }
29731                if (!username) {
29732                   username = ast_variable_retrieve(ucfg, "general", "username");
29733                }
29734                if (!secret) {
29735                   secret = ast_variable_retrieve(ucfg, "general", "secret");
29736                }
29737                if (!contact) {
29738                   contact = "s";
29739                }
29740                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
29741                   if (!ast_strlen_zero(secret)) {
29742                      if (!ast_strlen_zero(authuser)) {
29743                         snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact);
29744                      } else {
29745                         snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact);
29746                      }
29747                   } else if (!ast_strlen_zero(authuser)) {
29748                      snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact);
29749                   } else {
29750                      snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact);
29751                   }
29752                   if (sip_register(tmp, 0) == 0) {
29753                      registry_count++;
29754                   }
29755                }
29756             }
29757          }
29758          cat = ast_category_browse(ucfg, cat);
29759       }
29760       ast_config_destroy(ucfg);
29761    }
29762 
29763    /* Load peers, users and friends */
29764    cat = NULL;
29765    while ( (cat = ast_category_browse(cfg, cat)) ) {
29766       const char *utype;
29767       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
29768          continue;
29769       utype = ast_variable_retrieve(cfg, cat, "type");
29770       if (!utype) {
29771          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
29772          continue;
29773       } else {
29774          if (!strcasecmp(utype, "user")) {
29775             ;
29776          } else if (!strcasecmp(utype, "friend")) {
29777             ;
29778          } else if (!strcasecmp(utype, "peer")) {
29779             ;
29780          } else {
29781             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
29782             continue;
29783          }
29784          peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
29785          if (peer) {
29786             display_nat_warning(cat, reason, &peer->flags[0]);
29787             ao2_t_link(peers, peer, "link peer into peers table");
29788             if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
29789                ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
29790             }
29791             unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
29792             peer_count++;
29793          }
29794       }
29795    }
29796 
29797    /* Add default domains - host name, IP address and IP:port
29798     * Only do this if user added any sip domain with "localdomains"
29799     * In order to *not* break backwards compatibility
29800     *    Some phones address us at IP only, some with additional port number
29801     */
29802    if (auto_sip_domains) {
29803       char temp[MAXHOSTNAMELEN];
29804 
29805       /* First our default IP address */
29806       if (!ast_sockaddr_isnull(&bindaddr) && !ast_sockaddr_is_any(&bindaddr)) {
29807          add_sip_domain(ast_sockaddr_stringify_addr(&bindaddr),
29808                    SIP_DOMAIN_AUTO, NULL);
29809       } else if (!ast_sockaddr_isnull(&internip) && !ast_sockaddr_is_any(&internip)) {
29810       /* Our internal IP address, if configured */
29811          add_sip_domain(ast_sockaddr_stringify_addr(&internip),
29812                    SIP_DOMAIN_AUTO, NULL);
29813       } else {
29814          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
29815       }
29816 
29817       /* If TCP is running on a different IP than UDP, then add it too */
29818       if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) &&
29819           !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) {
29820          add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address),
29821                    SIP_DOMAIN_AUTO, NULL);
29822       }
29823 
29824       /* If TLS is running on a different IP than UDP and TCP, then add that too */
29825       if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) &&
29826           !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) &&
29827           !ast_sockaddr_cmp(&sip_tcp_desc.local_address,
29828                   &sip_tls_desc.local_address)) {
29829          add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address),
29830                    SIP_DOMAIN_AUTO, NULL);
29831       }
29832 
29833       /* Our extern IP address, if configured */
29834       if (!ast_sockaddr_isnull(&externaddr)) {
29835          add_sip_domain(ast_sockaddr_stringify_addr(&externaddr),
29836                    SIP_DOMAIN_AUTO, NULL);
29837       }
29838 
29839       /* Extern host name (NAT traversal support) */
29840       if (!ast_strlen_zero(externhost)) {
29841          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
29842       }
29843       
29844       /* Our host name */
29845       if (!gethostname(temp, sizeof(temp))) {
29846          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
29847       }
29848    }
29849 
29850    /* Release configuration from memory */
29851    ast_config_destroy(cfg);
29852 
29853    /* Load the list of manual NOTIFY types to support */
29854    if (notify_types)
29855       ast_config_destroy(notify_types);
29856    if ((notify_types = ast_config_load(notify_config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
29857       ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config);
29858       notify_types = NULL;
29859    }
29860 
29861    /* Done, tell the manager */
29862    manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "ChannelType: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count);
29863    run_end = time(0);
29864    ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start));
29865 
29866    return 0;
29867 }

static char * remove_uri_parameters ( char *  uri  )  [static]

Definition at line 12299 of file chan_sip.c.

Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().

12300 {
12301    char *atsign;
12302    atsign = strchr(uri, '@'); /* First, locate the at sign */
12303    if (!atsign) {
12304       atsign = uri;  /* Ok hostname only, let's stick with the rest */
12305    }
12306    atsign = strchr(atsign, ';'); /* Locate semi colon */
12307    if (atsign)
12308       *atsign = '\0';   /* Kill at the semi colon */
12309    return uri;
12310 }

static int reply_digest ( struct sip_pvt *  p,
struct sip_request *  req,
char *  header,
int  sipmethod,
char *  digest,
int  digest_len 
) [static]

reply to authentication for outbound registrations

Returns:
Returns -1 if we have no auth
Note:
This is used for register= servers in sip.conf, SIP proxies we register with for receiving calls from.

Definition at line 19849 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), and LOG_WARNING.

Referenced by do_proxy_auth(), and do_register_auth().

19850 {
19851    char tmp[512];
19852    char *c;
19853    char oldnonce[256];
19854 
19855    /* table of recognised keywords, and places where they should be copied */
19856    const struct x {
19857       const char *key;
19858       const ast_string_field *field;
19859    } *i, keys[] = {
19860       { "realm=", &p->realm },
19861       { "nonce=", &p->nonce },
19862       { "opaque=", &p->opaque },
19863       { "qop=", &p->qop },
19864       { "domain=", &p->domain },
19865       { NULL, 0 },
19866    };
19867 
19868    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
19869    if (ast_strlen_zero(tmp))
19870       return -1;
19871    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
19872       ast_log(LOG_WARNING, "missing Digest.\n");
19873       return -1;
19874    }
19875    c = tmp + strlen("Digest ");
19876    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
19877    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
19878       for (i = keys; i->key != NULL; i++) {
19879          char *src, *separator;
19880          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
19881             continue;
19882          /* Found. Skip keyword, take text in quotes or up to the separator. */
19883          c += strlen(i->key);
19884          if (*c == '"') {
19885             src = ++c;
19886             separator = "\"";
19887          } else {
19888             src = c;
19889             separator = ",";
19890          }
19891          strsep(&c, separator); /* clear separator and move ptr */
19892          ast_string_field_ptr_set(p, i->field, src);
19893          break;
19894       }
19895       if (i->key == NULL) /* not found, try ',' */
19896          strsep(&c, ",");
19897    }
19898    /* Reset nonce count */
19899    if (strcmp(p->nonce, oldnonce))
19900       p->noncecount = 0;
19901 
19902    /* Save auth data for following registrations */
19903    if (p->registry) {
19904       struct sip_registry *r = p->registry;
19905 
19906       if (strcmp(r->nonce, p->nonce)) {
19907          ast_string_field_set(r, realm, p->realm);
19908          ast_string_field_set(r, nonce, p->nonce);
19909          ast_string_field_set(r, authdomain, p->domain);
19910          ast_string_field_set(r, opaque, p->opaque);
19911          ast_string_field_set(r, qop, p->qop);
19912          r->noncecount = 0;
19913       }
19914    }
19915    return build_reply_digest(p, sipmethod, digest, digest_len);
19916 }

static int reqprep ( struct sip_request *  req,
struct sip_pvt *  p,
int  sipmethod,
uint32_t  seqno,
int  newbranch 
) [static]

Initialize a SIP request message (not the initial one in a dialog).

< Strict routing flag

Definition at line 10706 of file chan_sip.c.

References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), copy_header(), FALSE, get_header(), get_in_brackets(), init_req(), remove_uri_parameters(), set_destination(), sip_methods, st_get_se(), text, cfsip_methods::text, TRUE, and url.

Referenced by transmit_cc_notify(), transmit_info_with_aoc(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_state_notify(), and update_connectedline().

10707 {
10708    struct sip_request *orig = &p->initreq;
10709    char stripped[80];
10710    char tmp[80];
10711    char newto[256];
10712    const char *c;
10713    const char *ot, *of;
10714    int is_strict = FALSE;     /*!< Strict routing flag */
10715    int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING);   /* Session direction */
10716 
10717    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
10718    
10719    if (!seqno) {
10720       p->ocseq++;
10721       seqno = p->ocseq;
10722    }
10723    
10724    /* A CANCEL must have the same branch as the INVITE that it is canceling. */
10725    if (sipmethod == SIP_CANCEL) {
10726       p->branch = p->invite_branch;
10727       build_via(p);
10728    } else if (newbranch && (sipmethod == SIP_INVITE)) {
10729       p->branch ^= ast_random();
10730       p->invite_branch = p->branch;
10731       build_via(p);
10732    } else if (newbranch) {
10733       p->branch ^= ast_random();
10734       build_via(p);
10735    }
10736 
10737    /* Check for strict or loose router */
10738    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) {
10739       is_strict = TRUE;
10740       if (sipdebug)
10741          ast_debug(1, "Strict routing enforced for session %s\n", p->callid);
10742    }
10743    
10744    if (sipmethod == SIP_CANCEL)
10745       c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); /* Use original URI */
10746    else if (sipmethod == SIP_ACK) {
10747       /* Use URI from Contact: in 200 OK (if INVITE)
10748       (we only have the contacturi on INVITEs) */
10749       if (!ast_strlen_zero(p->okcontacturi))
10750          c = is_strict ? p->route->hop : p->okcontacturi;
10751       else
10752          c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2);
10753    } else if (!ast_strlen_zero(p->okcontacturi))
10754       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
10755    else if (!ast_strlen_zero(p->uri))
10756       c = p->uri;
10757    else {
10758       char *n;
10759       /* We have no URI, use To: or From:  header as URI (depending on direction) */
10760       ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"),
10761             sizeof(stripped));
10762       n = get_in_brackets(stripped);
10763       c = remove_uri_parameters(n);
10764    }  
10765    init_req(req, sipmethod, c);
10766 
10767    snprintf(tmp, sizeof(tmp), "%u %s", seqno, sip_methods[sipmethod].text);
10768 
10769    add_header(req, "Via", p->via);
10770    /*
10771     * Use the learned route set unless this is a CANCEL on an ACK for a non-2xx
10772     * final response. For a CANCEL or ACK, we have to send to the same destination
10773     * as the original INVITE.
10774     */
10775    if (p->route &&
10776          !(sipmethod == SIP_CANCEL ||
10777             (sipmethod == SIP_ACK && (p->invitestate == INV_COMPLETED || p->invitestate == INV_CANCELLED)))) {
10778       set_destination(p, p->route->hop);
10779       add_route(req, is_strict ? p->route->next : p->route);
10780    }
10781    add_header_max_forwards(p, req);
10782 
10783    ot = get_header(orig, "To");
10784    of = get_header(orig, "From");
10785 
10786    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
10787       as our original request, including tag (or presumably lack thereof) */
10788    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
10789       /* Add the proper tag if we don't have it already.  If they have specified
10790          their tag, use it.  Otherwise, use our own tag */
10791       if (is_outbound && !ast_strlen_zero(p->theirtag))
10792          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
10793       else if (!is_outbound)
10794          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
10795       else
10796          snprintf(newto, sizeof(newto), "%s", ot);
10797       ot = newto;
10798    }
10799 
10800    if (is_outbound) {
10801       add_header(req, "From", of);
10802       add_header(req, "To", ot);
10803    } else {
10804       add_header(req, "From", ot);
10805       add_header(req, "To", of);
10806    }
10807    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
10808    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
10809       add_header(req, "Contact", p->our_contact);
10810 
10811    copy_header(req, orig, "Call-ID");
10812    add_header(req, "CSeq", tmp);
10813 
10814    if (!ast_strlen_zero(global_useragent))
10815       add_header(req, "User-Agent", global_useragent);
10816 
10817    if (!ast_strlen_zero(p->url)) {
10818       add_header(req, "Access-URL", p->url);
10819       ast_string_field_set(p, url, NULL);
10820    }
10821 
10822    /* Add Session-Timers related headers if the feature is active for this session.
10823       An exception to this behavior is the ACK request. Since Asterisk never requires
10824       session-timers support from a remote end-point (UAS) in an INVITE, it must
10825       not send 'Require: timer' header in the ACK request.
10826       This should only be added in the INVITE transactions, not MESSAGE or REFER or other
10827       in-dialog messages.
10828    */
10829    if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE
10830        && sipmethod == SIP_INVITE) {
10831       char se_hdr[256];
10832       snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
10833          p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uac" : "uas");
10834       add_header(req, "Session-Expires", se_hdr);
10835       snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE));
10836       add_header(req, "Min-SE", se_hdr);
10837    }
10838 
10839    return 0;
10840 }

static int resp_needs_contact ( const char *  msg,
enum sipmethod  method 
) [inline, static]

Test if this response needs a contact header.

Definition at line 10554 of file chan_sip.c.

Referenced by respprep().

10554                                                                              {
10555    /* Requirements for Contact header inclusion in responses generated
10556     * from the header tables found in the following RFCs.  Where the
10557     * Contact header was marked mandatory (m) or optional (o) this
10558     * function returns 1.
10559     *
10560     * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER)
10561     * - RFC 2976 (INFO)
10562     * - RFC 3262 (PRACK)
10563     * - RFC 3265 (SUBSCRIBE, NOTIFY)
10564     * - RFC 3311 (UPDATE)
10565     * - RFC 3428 (MESSAGE)
10566     * - RFC 3515 (REFER)
10567     * - RFC 3903 (PUBLISH)
10568     */
10569 
10570    switch (method) {
10571       /* 1xx, 2xx, 3xx, 485 */
10572       case SIP_INVITE:
10573       case SIP_UPDATE:
10574       case SIP_SUBSCRIBE:
10575       case SIP_NOTIFY:
10576          if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3))
10577             return 1;
10578          break;
10579 
10580       /* 2xx, 3xx, 485 */
10581       case SIP_REGISTER:
10582       case SIP_OPTIONS:
10583          if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3))
10584             return 1;
10585          break;
10586 
10587       /* 3xx, 485 */
10588       case SIP_BYE:
10589       case SIP_PRACK:
10590       case SIP_MESSAGE:
10591       case SIP_PUBLISH:
10592          if (msg[0] == '3' || !strncmp(msg, "485", 3))
10593             return 1;
10594          break;
10595 
10596       /* 2xx, 3xx, 4xx, 5xx, 6xx */
10597       case SIP_REFER:
10598          if (msg[0] >= '2' && msg[0] <= '6')
10599             return 1;
10600          break;
10601 
10602       /* contact will not be included for everything else */
10603       case SIP_ACK:
10604       case SIP_CANCEL:
10605       case SIP_INFO:
10606       case SIP_PING:
10607       default:
10608          return 0;
10609    }
10610    return 0;
10611 }

static int respprep ( struct sip_request *  resp,
struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

Prepare SIP response packet.

Definition at line 10614 of file chan_sip.c.

References add_header(), add_supported_header(), ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), get_header(), init_resp(), LOG_WARNING, process_via(), resp_needs_contact(), TRUE, and url.

Referenced by __transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sdp(), transmit_response_with_sip_etag(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), update_connectedline(), and update_redirecting().

10615 {
10616    char newto[256];
10617    const char *ot;
10618 
10619    init_resp(resp, msg);
10620    copy_via_headers(p, resp, req, "Via");
10621    if (msg[0] == '1' || msg[0] == '2')
10622       copy_all_header(resp, req, "Record-Route");
10623    copy_header(resp, req, "From");
10624    ot = get_header(req, "To");
10625    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
10626       /* Add the proper tag if we don't have it already.  If they have specified
10627          their tag, use it.  Otherwise, use our own tag */
10628       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
10629          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
10630       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
10631          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
10632       else
10633          ast_copy_string(newto, ot, sizeof(newto));
10634       ot = newto;
10635    }
10636    add_header(resp, "To", ot);
10637    copy_header(resp, req, "Call-ID");
10638    copy_header(resp, req, "CSeq");
10639    if (!ast_strlen_zero(global_useragent))
10640       add_header(resp, "Server", global_useragent);
10641    add_header(resp, "Allow", ALLOWED_METHODS);
10642    add_supported_header(p, resp);
10643 
10644    /* If this is an invite, add Session-Timers related headers if the feature is active for this session */
10645    if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE) {
10646       char se_hdr[256];
10647       snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
10648          p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uas" : "uac");
10649       add_header(resp, "Session-Expires", se_hdr);
10650       /* RFC 2048, Section 9
10651        * If the refresher parameter in the Session-Expires header field in the
10652        * 2xx response has a value of 'uac', the UAS MUST place a Require
10653        * header field into the response with the value 'timer'.
10654        * ...
10655        * If the refresher parameter in
10656        * the 2xx response has a value of 'uas' and the Supported header field
10657        * in the request contained the value 'timer', the UAS SHOULD place a
10658        * Require header field into the response with the value 'timer'
10659        */
10660       if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_THEM ||
10661             (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US &&
10662              p->stimer->st_active_peer_ua == TRUE)) {
10663          resp->reqsipoptions |= SIP_OPT_TIMER;
10664       }
10665    }
10666 
10667    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_PUBLISH)) {
10668       /* For registration responses, we also need expiry and
10669          contact info */
10670       char tmp[256];
10671 
10672       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
10673       add_header(resp, "Expires", tmp);
10674       if (p->expiry) {  /* Only add contact if we have an expiry time */
10675          char contact[SIPBUFSIZE];
10676          const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact;
10677          char *brackets = strchr(contact_uri, '<');
10678          snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry);
10679          add_header(resp, "Contact", contact);  /* Not when we unregister */
10680       }
10681    } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) {
10682       add_header(resp, "Contact", p->our_contact);
10683    }
10684 
10685    if (!ast_strlen_zero(p->url)) {
10686       add_header(resp, "Access-URL", p->url);
10687       ast_string_field_set(p, url, NULL);
10688    }
10689 
10690    /* default to routing the response to the address where the request
10691     * came from.  Since we don't have a transport layer, we do this here.
10692     * The process_via() function will update the port to either the port
10693     * specified in the via header or the default port later on (per RFC
10694     * 3261 section 18.2.2).
10695     */
10696    p->sa = p->recv;
10697 
10698    if (process_via(p, req)) {
10699       ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n");
10700    }
10701 
10702    return 0;
10703 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

Definition at line 26718 of file chan_sip.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.

Referenced by load_module(), sip_reload(), and sip_request_call().

26719 {
26720    /* If we're supposed to be stopped -- stay stopped */
26721    if (monitor_thread == AST_PTHREADT_STOP)
26722       return 0;
26723    ast_mutex_lock(&monlock);
26724    if (monitor_thread == pthread_self()) {
26725       ast_mutex_unlock(&monlock);
26726       ast_log(LOG_WARNING, "Cannot kill myself\n");
26727       return -1;
26728    }
26729    if (monitor_thread != AST_PTHREADT_NULL) {
26730       /* Wake up the thread */
26731       pthread_kill(monitor_thread, SIGURG);
26732    } else {
26733       /* Start a new monitor */
26734       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
26735          ast_mutex_unlock(&monlock);
26736          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
26737          return -1;
26738       }
26739    }
26740    ast_mutex_unlock(&monlock);
26741    return 0;
26742 }

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

Session-Timers: Restart session timer.

Definition at line 26746 of file chan_sip.c.

References ast_debug, AST_SCHED_DEL_UNREF, start_session_timer(), and TRUE.

Referenced by handle_request_invite().

26747 {
26748    if (p->stimer->st_active == TRUE) {
26749       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
26750       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
26751             dialog_unref(p, "Removing session timer ref"));
26752       start_session_timer(p);
26753    }
26754 }

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

Retransmit SIP message if no answer (Called from scheduler).

Definition at line 3730 of file chan_sip.c.

References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_free, ast_log(), ast_queue_hangup_with_cause(), ast_sockaddr_stringify(), ast_str_buffer(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_verbose, check_pendings(), DEFAULT_RETRANS, LOG_WARNING, pvt_set_needdestroy(), sip_alreadygone(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), cfsip_methods::text, and UNLINK.

Referenced by __sip_reliable_xmit(), and sip_show_sched().

03731 {
03732    struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
03733    int reschedule = DEFAULT_RETRANS;
03734    int xmitres = 0;
03735    /* how many ms until retrans timeout is reached */
03736    int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent);
03737 
03738    /* Do not retransmit if time out is reached. This will be negative if the time between
03739     * the first transmission and now is larger than our timeout period. This is a fail safe
03740     * check in case the scheduler gets behind or the clock is changed. */
03741    if ((diff <= 0) || (diff > pkt->retrans_stop_time)) {
03742       pkt->retrans_stop = 1;
03743    }
03744 
03745    /* Lock channel PVT */
03746    sip_pvt_lock(pkt->owner);
03747 
03748    if (!pkt->retrans_stop) {
03749       pkt->retrans++;
03750       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
03751          if (sipdebug) {
03752             ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n",
03753                pkt->retransid,
03754                sip_methods[pkt->method].text,
03755                pkt->method);
03756          }
03757       } else {
03758          int siptimer_a;
03759 
03760          if (sipdebug) {
03761             ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n",
03762                pkt->retransid,
03763                pkt->retrans,
03764                sip_methods[pkt->method].text,
03765                pkt->method);
03766          }
03767          if (!pkt->timer_a) {
03768             pkt->timer_a = 2 ;
03769          } else {
03770             pkt->timer_a = 2 * pkt->timer_a;
03771          }
03772 
03773          /* For non-invites, a maximum of 4 secs */
03774          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
03775          if (pkt->method != SIP_INVITE && siptimer_a > 4000) {
03776             siptimer_a = 4000;
03777          }
03778 
03779          /* Reschedule re-transmit */
03780          reschedule = siptimer_a;
03781          ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n",
03782             pkt->retrans + 1,
03783             siptimer_a,
03784             pkt->timer_t1,
03785             pkt->retransid);
03786       }
03787 
03788       if (sip_debug_test_pvt(pkt->owner)) {
03789          const struct ast_sockaddr *dst = sip_real_dst(pkt->owner);
03790          ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n",
03791             pkt->retrans, sip_nat_mode(pkt->owner),
03792             ast_sockaddr_stringify(dst),
03793             ast_str_buffer(pkt->data));
03794       }
03795 
03796       append_history(pkt->owner, "ReTx", "%d %s", reschedule, ast_str_buffer(pkt->data));
03797       xmitres = __sip_xmit(pkt->owner, pkt->data);
03798 
03799       /* If there was no error during the network transmission, schedule the next retransmission,
03800        * but if the next retransmission is going to be beyond our timeout period, mark the packet's
03801        * stop_retrans value and set the next retransmit to be the exact time of timeout.  This will
03802        * allow any responses to the packet to be processed before the packet is destroyed on the next
03803        * call to this function by the scheduler. */
03804       if (xmitres != XMIT_ERROR) {
03805          if (reschedule >= diff) {
03806             pkt->retrans_stop = 1;
03807             reschedule = diff;
03808          }
03809          sip_pvt_unlock(pkt->owner);
03810          return  reschedule;
03811       }
03812    }
03813 
03814    /* At this point, either the packet's retransmission timed out, or there was a
03815     * transmission error, either way destroy the scheduler item and this packet. */
03816 
03817    pkt->retransid = -1; /* Kill this scheduler item */
03818 
03819    if (pkt->method != SIP_OPTIONS && xmitres == 0) {
03820       if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */
03821          ast_log(LOG_WARNING, "Retransmission timeout reached on transmission %s for seqno %u (%s %s) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n"
03822             "Packet timed out after %dms with no response\n",
03823             pkt->owner->callid,
03824             pkt->seqno,
03825             pkt->is_fatal ? "Critical" : "Non-critical",
03826             pkt->is_resp ? "Response" : "Request",
03827             (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent));
03828       }
03829    } else if (pkt->method == SIP_OPTIONS && sipdebug) {
03830       ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s)  -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n", pkt->owner->callid);
03831    }
03832 
03833    if (xmitres == XMIT_ERROR) {
03834       ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid);
03835       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03836    } else {
03837       append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03838    }
03839 
03840    if (pkt->is_fatal) {
03841       while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
03842          sip_pvt_unlock(pkt->owner);   /* SIP_PVT, not channel */
03843          usleep(1);
03844          sip_pvt_lock(pkt->owner);
03845       }
03846       if (pkt->owner->owner && !pkt->owner->owner->hangupcause) {
03847          pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
03848       }
03849       if (pkt->owner->owner) {
03850          ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions).\n", pkt->owner->callid);
03851 
03852          if (pkt->is_resp &&
03853             (pkt->response_code >= 200) &&
03854             (pkt->response_code < 300) &&
03855             pkt->owner->pendinginvite &&
03856             ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
03857             /* This is a timeout of the 2XX response to a pending INVITE.  In this case terminate the INVITE
03858              * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup
03859              * will send the BYE as long as the dialog is not set as "alreadygone")
03860              * RFC 3261 section 13.3.1.4.
03861              * "If the server retransmits the 2xx response for 64*T1 seconds without receiving
03862              * an ACK, the dialog is confirmed, but the session SHOULD be terminated.  This is
03863              * accomplished with a BYE, as described in Section 15." */
03864             pkt->owner->invitestate = INV_TERMINATED;
03865             pkt->owner->pendinginvite = 0;
03866          } else {
03867             /* there is nothing left to do, mark the dialog as gone */
03868             sip_alreadygone(pkt->owner);
03869          }
03870          ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_NO_USER_RESPONSE);
03871          ast_channel_unlock(pkt->owner->owner);
03872       } else {
03873          /* If no channel owner, destroy now */
03874 
03875          /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
03876          if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) {
03877             pvt_set_needdestroy(pkt->owner, "no response to critical packet");
03878             sip_alreadygone(pkt->owner);
03879             append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
03880          }
03881       }
03882    } else if (pkt->owner->pendinginvite == pkt->seqno) {
03883           ast_log(LOG_WARNING, "Timeout on %s on non-critical invite transaction.\n", pkt->owner->callid);
03884           pkt->owner->invitestate = INV_TERMINATED;
03885           pkt->owner->pendinginvite = 0;
03886           check_pendings(pkt->owner);
03887    }
03888 
03889    if (pkt->method == SIP_BYE) {
03890       /* We're not getting answers on SIP BYE's.  Tear down the call anyway. */
03891       sip_alreadygone(pkt->owner);
03892       if (pkt->owner->owner) {
03893          ast_channel_unlock(pkt->owner->owner);
03894       }
03895       append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
03896       pvt_set_needdestroy(pkt->owner, "no response to BYE");
03897    }
03898 
03899    /* Remove the packet */
03900    for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
03901       if (cur == pkt) {
03902          UNLINK(cur, pkt->owner->packets, prev);
03903          sip_pvt_unlock(pkt->owner);
03904          if (pkt->owner) {
03905             pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03906          }
03907          if (pkt->data) {
03908             ast_free(pkt->data);
03909          }
03910          pkt->data = NULL;
03911          ast_free(pkt);
03912          return 0;
03913       }
03914    }
03915    /* error case */
03916    ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
03917    sip_pvt_unlock(pkt->owner);
03918    return 0;
03919 }

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

Definition at line 4327 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

04327                                                         {
04328    struct sip_pvt *pvt = (struct sip_pvt *) data;
04329 
04330    return send_provisional_keepalive_full(pvt, 0);
04331 }

static int send_provisional_keepalive_full ( struct sip_pvt *  pvt,
int  with_sdp 
) [static]

Definition at line 4277 of file chan_sip.c.

References ast_channel_unlock, ast_channel_unref, FALSE, S_OR, sip_pvt_lock_full(), sip_pvt_unlock, transmit_response(), and transmit_response_with_sdp().

Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

04278 {
04279    const char *msg = NULL;
04280    struct ast_channel *chan;
04281    int res = 0;
04282    int old_sched_id = pvt->provisional_keepalive_sched_id;
04283 
04284    chan = sip_pvt_lock_full(pvt);
04285    /* Check that nothing has changed while we were waiting for the lock */
04286    if (old_sched_id != pvt->provisional_keepalive_sched_id) {
04287       /* Keepalive has been cancelled or rescheduled, clean up and leave */
04288       if (chan) {
04289          ast_channel_unlock(chan);
04290          chan = ast_channel_unref(chan);
04291       }
04292       sip_pvt_unlock(pvt);
04293       dialog_unref(pvt, "dialog ref for provisional keepalive");
04294       return 0;
04295    }
04296 
04297    if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) {
04298       msg = "183 Session Progress";
04299    }
04300 
04301    if (pvt->invitestate < INV_COMPLETED) {
04302       if (with_sdp) {
04303          transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE);
04304       } else {
04305          transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq);
04306       }
04307       res = PROVIS_KEEPALIVE_TIMEOUT;
04308    }
04309 
04310    if (chan) {
04311       ast_channel_unlock(chan);
04312       chan = ast_channel_unref(chan);
04313    }
04314 
04315    if (!res) {
04316       pvt->provisional_keepalive_sched_id = -1;
04317    }
04318 
04319    sip_pvt_unlock(pvt);
04320 
04321    if (!res) {
04322       dialog_unref(pvt, "dialog ref for provisional keepalive");
04323    }
04324    return res;
04325 }

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

Definition at line 4333 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

04333                                                                  {
04334    struct sip_pvt *pvt = (void *)data;
04335 
04336    return send_provisional_keepalive_full(pvt, 1);
04337 }

static int send_request ( struct sip_pvt *  p,
struct sip_request *  req,
enum xmittype  reliable,
uint32_t  seqno 
) [static]

Definition at line 4418 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_sockaddr_stringify(), ast_str_buffer(), ast_test_flag, ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, and cfsip_methods::text.

Referenced by transmit_cc_notify(), transmit_info_with_aoc(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_state_notify(), and update_connectedline().

04419 {
04420    int res;
04421 
04422    /* If we have an outbound proxy, reset peer address
04423       Only do this once.
04424    */
04425    if (p->outboundproxy) {
04426       p->sa = p->outboundproxy->ip;
04427    }
04428 
04429    finalize_content(req);
04430    add_blank(req);
04431    if (sip_debug_test_pvt(p)) {
04432       if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) {
04433          ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), ast_str_buffer(req->data));
04434       } else {
04435          ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), ast_str_buffer(req->data));
04436       }
04437    }
04438    if (p->do_history) {
04439       struct sip_request tmp = { .rlPart1 = 0, };
04440       parse_copy(&tmp, req);
04441       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
04442       deinit_req(&tmp);
04443    }
04444    res = (reliable) ?
04445       __sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) :
04446       __sip_xmit(p, req->data);
04447    deinit_req(req);
04448    return res;
04449 }

static int send_response ( struct sip_pvt *  p,
struct sip_request *  req,
enum xmittype  reliable,
uint32_t  seqno 
) [static]

Transmit response on SIP request.

Definition at line 4376 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, AST_SCHED_DEL_UNREF, ast_sockaddr_stringify(), ast_str_buffer(), ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_real_dst(), and cfsip_methods::text.

Referenced by __transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_minexpires(), transmit_response_with_minse(), transmit_response_with_retry_after(), transmit_response_with_sdp(), transmit_response_with_sip_etag(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), update_connectedline(), and update_redirecting().

04377 {
04378    int res;
04379 
04380    finalize_content(req);
04381    add_blank(req);
04382    if (sip_debug_test_pvt(p)) {
04383       const struct ast_sockaddr *dst = sip_real_dst(p);
04384 
04385       ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n",
04386          reliable ? "Reliably " : "", sip_nat_mode(p),
04387          ast_sockaddr_stringify(dst),
04388          ast_str_buffer(req->data));
04389    }
04390    if (p->do_history) {
04391       struct sip_request tmp = { .rlPart1 = 0, };
04392       parse_copy(&tmp, req);
04393       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"),
04394          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text);
04395       deinit_req(&tmp);
04396    }
04397 
04398    /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */
04399    if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) {
04400       AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
04401    }
04402 
04403    res = (reliable) ?
04404        __sip_reliable_xmit(p, seqno, 1, req->data, (reliable == XMIT_CRITICAL), req->method) :
04405       __sip_xmit(p, req->data);
04406    deinit_req(req);
04407    if (res > 0) {
04408       return 0;
04409    }
04410    return res;
04411 }

static enum ast_cc_service_type service_string_to_service_type ( const char *const   service_string  )  [static]

Definition at line 830 of file chan_sip.c.

References AST_CC_CCBS, AST_CC_CCNL, AST_CC_NONE, service, and sip_cc_service_map.

Referenced by sip_get_cc_information().

00831 {
00832    enum ast_cc_service_type service;
00833    for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) {
00834       if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) {
00835          return service;
00836       }
00837    }
00838    return AST_CC_NONE;
00839 }

static int set_address_from_contact ( struct sip_pvt *  pvt  )  [static]

Change the other partys IP address based on given contact.

Todo:
We need to save the TRANSPORT here too

Definition at line 14449 of file chan_sip.c.

References __set_address_from_contact(), and ast_test_flag.

Referenced by handle_response_invite().

14450 {
14451    if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) {
14452       /* NAT: Don't trust the contact field.  Just use what they came to us
14453          with. */
14454       /*! \todo We need to save the TRANSPORT here too */
14455       pvt->sa = pvt->recv;
14456       return 0;
14457    }
14458 
14459    return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
14460 }

static void set_destination ( struct sip_pvt *  p,
char *  uri 
) [static]

Set destination from SIP URI.

Parse uri to h (host) and port - uri is already just the part inside the <> general form we are expecting is sip[s]:username[:password][;parameter][:port][;...] If there's a port given, turn NAPTR/SRV off. NAPTR might indicate SIPS preference even for SIP: uri's

If there's a sips: uri scheme, TLS will be required.

Todo:
XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, otherwise, just look for A records
Todo:
XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, otherwise, just look for A records

Definition at line 10423 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first_transport(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, FALSE, hostname, LOG_WARNING, PARSE_PORT_FORBID, sip_debug_test_pvt(), and TRUE.

Referenced by reqprep().

10424 {
10425    char *h, *maddr, hostname[256];
10426    int hn;
10427    int debug=sip_debug_test_pvt(p);
10428    int tls_on = FALSE;
10429 
10430    if (debug)
10431       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
10432 
10433    /* Find and parse hostname */
10434    h = strchr(uri, '@');
10435    if (h)
10436       ++h;
10437    else {
10438       h = uri;
10439       if (!strncasecmp(h, "sip:", 4)) {
10440          h += 4;
10441       } else if (!strncasecmp(h, "sips:", 5)) {
10442          h += 5;
10443          tls_on = TRUE;
10444       }
10445    }
10446    hn = strcspn(h, ";>") + 1;
10447    if (hn > sizeof(hostname))
10448       hn = sizeof(hostname);
10449    ast_copy_string(hostname, h, hn);
10450    /* XXX bug here if string has been trimmed to sizeof(hostname) */
10451    h += hn - 1;
10452 
10453    /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV,
10454     * otherwise, just look for A records */
10455    if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, 0, p->socket.type)) {
10456       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
10457       return;
10458    }
10459 
10460    /* Got the hostname - but maybe there's a "maddr=" to override address? */
10461    maddr = strstr(h, "maddr=");
10462    if (maddr) {
10463       int port;
10464 
10465       maddr += 6;
10466       hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
10467                     "0123456789-.:[]") + 1;
10468       if (hn > sizeof(hostname))
10469          hn = sizeof(hostname);
10470       ast_copy_string(hostname, maddr, hn);
10471 
10472       port = ast_sockaddr_port(&p->sa);
10473 
10474       /*! \todo XXX If we have sip_cfg.srvlookup on, then look for
10475        * NAPTR/SRV, otherwise, just look for A records */
10476       if (ast_sockaddr_resolve_first_transport(&p->sa, hostname, PARSE_PORT_FORBID, p->socket.type)) {
10477          ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
10478          return;
10479       }
10480 
10481       ast_sockaddr_set_port(&p->sa, port);
10482    }
10483 
10484    if (!ast_sockaddr_port(&p->sa)) {
10485       ast_sockaddr_set_port(&p->sa, tls_on ?
10486                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
10487    }
10488 
10489    if (debug) {
10490       ast_verbose("set_destination: set destination to %s\n",
10491              ast_sockaddr_stringify(&p->sa));
10492    }
10493 }

static void set_insecure_flags ( struct ast_flags flags,
const char *  value,
int  lineno 
) [static]

Parse insecure= setting in sip.conf and set flags according to setting.

Definition at line 27513 of file chan_sip.c.

References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), LOG_WARNING, and word.

Referenced by get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), and handle_common_options().

27514 {
27515    if (ast_strlen_zero(value))
27516       return;
27517 
27518    if (!ast_false(value)) {
27519       char buf[64];
27520       char *word, *next;
27521 
27522       ast_copy_string(buf, value, sizeof(buf));
27523       next = buf;
27524       while ((word = strsep(&next, ","))) {
27525          if (!strcasecmp(word, "port"))
27526             ast_set_flag(&flags[0], SIP_INSECURE_PORT);
27527          else if (!strcasecmp(word, "invite"))
27528             ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
27529          else
27530             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
27531       }
27532    }
27533 }

static void set_nonce_randdata ( struct sip_pvt *  p,
int  forceupdate 
) [static]

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.

Definition at line 14823 of file chan_sip.c.

References ast_random(), ast_string_field_build, and ast_strlen_zero().

Referenced by check_auth(), and transmit_fake_auth_response().

14824 {
14825    if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) {
14826       ast_string_field_build(p, randdata, "%08lx", (unsigned long)ast_random()); /* Create nonce for challenge */
14827       p->stalenonce = 0;
14828    }
14829 }

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

Set peer defaults before configuring specific configurations.

Definition at line 27947 of file chan_sip.c.

References ao2_ref, ast_copy_flags, ast_sockaddr_setnull(), ast_string_field_set, cid_name, cid_num, clear_peer_mailboxes(), context, default_prefs, language, mohinterpret, mohsuggest, secret, set_socket_transport(), and sip_cfg.

Referenced by build_peer(), and temp_peer().

27948 {
27949    if (peer->expire == 0) {
27950       /* Don't reset expire or port time during reload
27951          if we have an active registration
27952       */
27953       peer->expire = -1;
27954       peer->pokeexpire = -1;
27955       set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP);
27956    }
27957    peer->type = SIP_TYPE_PEER;
27958    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
27959    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
27960    ast_copy_flags(&peer->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY);
27961    ast_string_field_set(peer, context, sip_cfg.default_context);
27962    ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext);
27963    ast_string_field_set(peer, language, default_language);
27964    ast_string_field_set(peer, mohinterpret, default_mohinterpret);
27965    ast_string_field_set(peer, mohsuggest, default_mohsuggest);
27966    ast_string_field_set(peer, engine, default_engine);
27967    ast_sockaddr_setnull(&peer->addr);
27968    ast_sockaddr_setnull(&peer->defaddr);
27969    peer->capability = sip_cfg.capability;
27970    peer->maxcallbitrate = default_maxcallbitrate;
27971    peer->rtptimeout = global_rtptimeout;
27972    peer->rtpholdtimeout = global_rtpholdtimeout;
27973    peer->rtpkeepalive = global_rtpkeepalive;
27974    peer->allowtransfer = sip_cfg.allowtransfer;
27975    peer->autoframing = global_autoframing;
27976    peer->t38_maxdatagram = global_t38_maxdatagram;
27977    peer->qualifyfreq = global_qualifyfreq;
27978    if (global_callcounter)
27979       peer->call_limit=INT_MAX;
27980    ast_string_field_set(peer, vmexten, default_vmexten);
27981    ast_string_field_set(peer, secret, "");
27982    ast_string_field_set(peer, remotesecret, "");
27983    ast_string_field_set(peer, md5secret, "");
27984    ast_string_field_set(peer, cid_num, "");
27985    ast_string_field_set(peer, cid_name, "");
27986    ast_string_field_set(peer, cid_tag, "");
27987    ast_string_field_set(peer, fromdomain, "");
27988    ast_string_field_set(peer, fromuser, "");
27989    ast_string_field_set(peer, regexten, "");
27990    peer->callgroup = 0;
27991    peer->pickupgroup = 0;
27992    peer->maxms = default_qualify;
27993    peer->prefs = default_prefs;
27994    peer->stimer.st_mode_oper = global_st_mode;  /* Session-Timers */
27995    peer->stimer.st_ref = global_st_refresher;
27996    peer->stimer.st_min_se = global_min_se;
27997    peer->stimer.st_max_se = global_max_se;
27998    peer->timer_t1 = global_t1;
27999    peer->timer_b = global_timer_b;
28000    clear_peer_mailboxes(peer);
28001    peer->disallowed_methods = sip_cfg.disallowed_methods;
28002    peer->transports = default_transports;
28003    peer->default_outbound_transport = default_primary_transport;
28004    if (peer->outboundproxy) {
28005       ao2_ref(peer->outboundproxy, -1);
28006       peer->outboundproxy = NULL;
28007    }
28008 }

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

A wrapper for parse_allowed_methods geared toward sip_pvts

This function, in addition to setting the allowed methods for a sip_pvt also will take into account the setting of the SIP_PAGE2_RPID_UPDATE flag.

Parameters:
pvt The sip_pvt we are setting the allowed_methods for
req The request which we are parsing
Return values:
The methods alloweded by the sip_pvt

Definition at line 8732 of file chan_sip.c.

References ast_test_flag, mark_method_allowed(), and parse_allowed_methods().

Referenced by check_peer_ok(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response_invite(), and handle_response_subscribe().

08733 {
08734    pvt->allowed_methods = parse_allowed_methods(req);
08735    
08736    if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) {
08737       mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE);
08738    }
08739    pvt->allowed_methods &= ~(pvt->disallowed_methods);
08740 
08741    return pvt->allowed_methods;
08742 }

static void set_socket_transport ( struct sip_socket *  socket,
int  transport 
) [static]

Definition at line 14202 of file chan_sip.c.

References ao2_ref.

Referenced by __sip_subscribe_mwi_do(), _sip_tcp_helper_thread(), build_peer(), create_addr(), expire_register(), get_transport_pvt(), parse_moved_contact(), parse_register_contact(), set_peer_defaults(), sip_alloc(), sip_request_call(), sip_send_mwi_to_peer(), sipsock_read(), and transmit_register().

14203 {
14204    /* if the transport type changes, clear all socket data */
14205    if (socket->type != transport) {
14206       socket->fd = -1;
14207       socket->type = transport;
14208       if (socket->tcptls_session) {
14209          ao2_ref(socket->tcptls_session, -1);
14210          socket->tcptls_session = NULL;
14211       }
14212    }
14213 }

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

Set the global T38 capabilities on a SIP dialog structure.

Definition at line 5386 of file chan_sip.c.

References ast_test_flag, ast_udptl_set_error_correction_scheme(), UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by check_peer_ok(), and initialize_udptl().

05387 {
05388    if (p->udptl) {
05389       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY) {
05390                         ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
05391       } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_FEC) {
05392          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
05393       } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL) {
05394          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
05395       }
05396    }
05397 }

static int setup_srtp ( struct sip_srtp **  srtp  )  [static]

Definition at line 30550 of file chan_sip.c.

References ast_log(), ast_rtp_engine_srtp_is_registered(), LOG_ERROR, and sip_srtp_alloc().

Referenced by process_crypto(), and sip_call().

30551 {
30552    if (!ast_rtp_engine_srtp_is_registered()) {
30553       ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n");
30554       return -1;
30555    }
30556 
30557    if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */
30558       return -1;
30559    }
30560 
30561    return 0;
30562 }

static int show_channels_cb ( void *  __cur,
void *  __arg,
int  flags 
) [static]

callback for show channel|subscription

Definition at line 18983 of file chan_sip.c.

References ast_cli(), AST_CLI_YESNO, ast_extension_state2str(), ast_getformatname_multiple(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_test_flag, FORMAT, FORMAT4, NONE, peer_mailboxes_to_str(), referstatus2str(), S_OR, sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), and subscription_type2str().

Referenced by sip_show_channels().

18984 {
18985    struct sip_pvt *cur = __cur;
18986    struct __show_chan_arg *arg = __arg;
18987    const struct ast_sockaddr *dst;
18988 
18989    sip_pvt_lock(cur);
18990    dst = sip_real_dst(cur);
18991 
18992    /* XXX indentation preserved to reduce diff. Will be fixed later */
18993    if (cur->subscribed == NONE && !arg->subscriptions) {
18994       /* set if SIP transfer in progress */
18995       const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : "";
18996       char formatbuf[SIPBUFSIZE/2];
18997       
18998       ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst),
18999             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
19000             cur->callid,
19001             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
19002             AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)),
19003             cur->needdestroy ? "(d)" : "",
19004             cur->lastmsg ,
19005             referstatus,
19006             cur->relatedpeer ? cur->relatedpeer->name : "<guest>"
19007          );
19008       arg->numchans++;
19009    }
19010    if (cur->subscribed != NONE && arg->subscriptions) {
19011       struct ast_str *mailbox_str = ast_str_alloca(512);
19012       if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer)
19013          peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer);
19014       ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst),
19015             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
19016                cur->callid,
19017             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
19018             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
19019             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate),
19020             subscription_type2str(cur->subscribed),
19021             cur->subscribed == MWI_NOTIFICATION ? S_OR(ast_str_buffer(mailbox_str), "<none>") : "<none>",
19022             cur->expiry
19023          );
19024       arg->numchans++;
19025    }
19026    sip_pvt_unlock(cur);
19027    return 0;   /* don't care, we scan all channels */
19028 }

static int show_chanstats_cb ( void *  __cur,
void *  __arg,
int  flags 
) [static]

Callback for show_chanstats.

Definition at line 18585 of file chan_sip.c.

References ast_cli(), ast_log(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, ast_sockaddr_stringify_addr(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel::cdr, invstate2stringtable::desc, FORMAT, invitestate2string, LOG_WARNING, NONE, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, sip_pvt_lock, sip_pvt_unlock, ast_cdr::start, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, and ast_rtp_instance_stats::txploss.

Referenced by sip_show_channelstats().

18586 {
18587 #define FORMAT2 "%-15.15s  %-11.11s  %-8.8s %-10.10s  %-10.10s (     %%) %-6.6s %-10.10s  %-10.10s (     %%) %-6.6s\n"
18588 #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"
18589    struct sip_pvt *cur = __cur;
18590    struct ast_rtp_instance_stats stats;
18591    char durbuf[10];
18592    int duration;
18593    int durh, durm, durs;
18594    struct ast_channel *c;
18595    struct __show_chan_arg *arg = __arg;
18596    int fd = arg->fd;
18597 
18598    sip_pvt_lock(cur);
18599    c = cur->owner;
18600 
18601    if (cur->subscribed != NONE) {
18602       /* Subscriptions */
18603       sip_pvt_unlock(cur);
18604       return 0;   /* don't care, we scan all channels */
18605    }
18606 
18607    if (!cur->rtp) {
18608       if (sipdebug) {
18609          ast_cli(fd, "%-15.15s  %-11.11s (inv state: %s) -- %s\n",
18610             ast_sockaddr_stringify_addr(&cur->sa), cur->callid,
18611             invitestate2string[cur->invitestate].desc,
18612             "-- No RTP active");
18613       }
18614       sip_pvt_unlock(cur);
18615       return 0;   /* don't care, we scan all channels */
18616    }
18617 
18618    if (ast_rtp_instance_get_stats(cur->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) {
18619       sip_pvt_unlock(cur);
18620       ast_log(LOG_WARNING, "Could not get RTP stats.\n");
18621       return 0;
18622    }
18623 
18624    if (c && c->cdr && !ast_tvzero(c->cdr->start)) {
18625       duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
18626       durh = duration / 3600;
18627       durm = (duration % 3600) / 60;
18628       durs = duration % 60;
18629       snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
18630    } else {
18631       durbuf[0] = '\0';
18632    }
18633 
18634    ast_cli(fd, FORMAT,
18635       ast_sockaddr_stringify_addr(&cur->sa),
18636       cur->callid,
18637       durbuf,
18638       stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount,
18639       stats.rxcount > (unsigned int) 100000 ? "K":" ",
18640       stats.rxploss,
18641       (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0,
18642       stats.rxjitter,
18643       stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount,
18644       stats.txcount > (unsigned int) 100000 ? "K":" ",
18645       stats.txploss,
18646       stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0,
18647       stats.txjitter
18648    );
18649    arg->numchans++;
18650    sip_pvt_unlock(cur);
18651 
18652    return 0;   /* don't care, we scan all channels */
18653 }

static int sip_addheader ( struct ast_channel chan,
const char *  data 
) [static]

Add a SIP header to an outbound INVITE.

Definition at line 30337 of file chan_sip.c.

References ast_alloca, ast_channel_lock, ast_channel_unlock, ast_debug, ast_get_encoded_str(), ast_log(), ast_strlen_zero(), FALSE, inbuf(), len(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and TRUE.

Referenced by load_module().

30338 {
30339    int no = 0;
30340    int ok = FALSE;
30341    char varbuf[30];
30342    const char *inbuf = data;
30343    char *subbuf;
30344    
30345    if (ast_strlen_zero(inbuf)) {
30346       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
30347       return 0;
30348    }
30349    ast_channel_lock(chan);
30350 
30351    /* Check for headers */
30352    while (!ok && no <= 50) {
30353       no++;
30354       snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no);
30355 
30356       /* Compare without the leading underscores */
30357       if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) {
30358          ok = TRUE;
30359       }
30360    }
30361    if (ok) {
30362       size_t len = strlen(inbuf);
30363       subbuf = ast_alloca(len + 1);
30364       ast_get_encoded_str(inbuf, subbuf, len + 1);
30365       pbx_builtin_setvar_helper(chan, varbuf, subbuf);
30366       if (sipdebug) {
30367          ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf);
30368       }
30369    } else {
30370       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
30371    }
30372    ast_channel_unlock(chan);
30373    return 0;
30374 }

struct sip_pvt* sip_alloc ( ast_string_field  callid,
struct ast_sockaddr addr,
int  useglobal_nat,
const int  intended_method,
struct sip_request *  req 
) [read]

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.

Definition at line 7967 of file chan_sip.c.

References ao2_t_alloc, ao2_t_link, ao2_t_ref, ast_cc_config_params_init, ast_copy_flags, ast_debug, AST_LIST_HEAD_INIT_NOLOCK, ast_random(), AST_RTP_DTMF, ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), free_via(), get_header(), internip, make_our_tag(), mohinterpret, mohsuggest, NONE, parkinglot, parse_via(), set_socket_transport(), sip_cfg, sip_destroy_fn(), sip_methods, cfsip_methods::text, and TRUE.

Referenced by __sip_subscribe_mwi_do(), find_call(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), and transmit_register().

07969 {
07970    struct sip_pvt *p;
07971 
07972    if (!(p = ao2_t_alloc(sizeof(*p), sip_destroy_fn, "allocate a dialog(pvt) struct")))
07973       return NULL;
07974 
07975    if (ast_string_field_init(p, 512)) {
07976       ao2_t_ref(p, -1, "failed to string_field_init, drop p");
07977       return NULL;
07978    }
07979 
07980    if (!(p->cc_params = ast_cc_config_params_init())) {
07981       ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
07982       return NULL;
07983    }
07984 
07985    /* If this dialog is created as the result of an incoming Request. Lets store
07986     * some information about that request */
07987    if (req) {
07988       struct sip_via *via;
07989       const char *cseq = get_header(req, "Cseq");
07990       uint32_t seqno;
07991 
07992       /* get branch parameter from initial Request that started this dialog */
07993       via = parse_via(get_header(req, "Via"));
07994       if (via) {
07995          /* only store the branch if it begins with the magic prefix "z9hG4bK", otherwise
07996           * it is not useful to us to have it */
07997          if (!ast_strlen_zero(via->branch) && !strncasecmp(via->branch, "z9hG4bK", 7)) {
07998             ast_string_field_set(p, initviabranch, via->branch);
07999             ast_string_field_set(p, initviasentby, via->sent_by);
08000          }
08001          free_via(via);
08002       }
08003 
08004       /* Store initial incoming cseq. An error in sscanf here is ignored.  There is no approperiate
08005        * except not storing the number.  CSeq validation must take place before dialog creation in find_call */
08006       if (!ast_strlen_zero(cseq) && (sscanf(cseq, "%30u", &seqno) == 1)) {
08007          p->init_icseq = seqno;
08008       }
08009       /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */
08010       set_socket_transport(&p->socket, req->socket.type);
08011    } else {
08012       set_socket_transport(&p->socket, SIP_TRANSPORT_UDP);
08013    }
08014 
08015    p->socket.fd = -1;
08016    p->method = intended_method;
08017    p->initid = -1;
08018    p->waitid = -1;
08019    p->reinviteid = -1;
08020    p->autokillid = -1;
08021    p->request_queue_sched_id = -1;
08022    p->provisional_keepalive_sched_id = -1;
08023    p->t38id = -1;
08024    p->subscribed = NONE;
08025    p->stateid = -1;
08026    p->sessionversion_remote = -1;
08027    p->session_modify = TRUE;
08028    p->stimer = NULL;
08029    p->prefs = default_prefs;     /* Set default codecs for this call */
08030    p->maxforwards = sip_cfg.default_max_forwards;
08031 
08032    if (intended_method != SIP_OPTIONS) {  /* Peerpoke has it's own system */
08033       p->timer_t1 = global_t1;   /* Default SIP retransmission timer T1 (RFC 3261) */
08034       p->timer_b = global_timer_b;  /* Default SIP transaction timer B (RFC 3261) */
08035    }
08036 
08037    if (!addr) {
08038       p->ourip = internip;
08039    } else {
08040       ast_sockaddr_copy(&p->sa, addr);
08041       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
08042    }
08043 
08044    /* Copy global flags to this PVT at setup. */
08045    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
08046    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
08047    ast_copy_flags(&p->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY);
08048 
08049    p->do_history = recordhistory;
08050 
08051    p->branch = ast_random();  
08052    make_our_tag(p);
08053    p->ocseq = INITIAL_CSEQ;
08054    p->allowed_methods = UINT_MAX;
08055 
08056    if (sip_methods[intended_method].need_rtp) {
08057       p->maxcallbitrate = default_maxcallbitrate;
08058       p->autoframing = global_autoframing;
08059    }
08060 
08061    if (useglobal_nat && addr) {
08062       /* Setup NAT structure according to global settings if we have an address */
08063       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
08064       ast_sockaddr_copy(&p->recv, addr);
08065 
08066       do_setnat(p);
08067    }
08068 
08069    if (p->method != SIP_REGISTER) {
08070       ast_string_field_set(p, fromdomain, default_fromdomain);
08071       p->fromdomainport = default_fromdomainport;
08072    }
08073    build_via(p);
08074    if (!callid)
08075       build_callid_pvt(p);
08076    else
08077       ast_string_field_set(p, callid, callid);
08078    /* Assign default music on hold class */
08079    ast_string_field_set(p, mohinterpret, default_mohinterpret);
08080    ast_string_field_set(p, mohsuggest, default_mohsuggest);
08081    p->capability = sip_cfg.capability;
08082    p->allowtransfer = sip_cfg.allowtransfer;
08083    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
08084        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
08085       p->noncodeccapability |= AST_RTP_DTMF;
08086    }
08087    ast_string_field_set(p, context, sip_cfg.default_context);
08088    ast_string_field_set(p, parkinglot, default_parkinglot);
08089    ast_string_field_set(p, engine, default_engine);
08090 
08091    AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue);
08092 
08093    /* Add to active dialog list */
08094 
08095    ao2_t_link(dialogs, p, "link pvt into dialogs table");
08096    
08097    ast_debug(1, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : p->callid, sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP");
08098    return p;
08099 }

static void sip_alreadygone ( struct sip_pvt *  dialog  )  [static]

Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.

Definition at line 3213 of file chan_sip.c.

References ast_debug.

Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_publish(), handle_response_subscribe(), retrans_pkt(), sip_indicate(), and sip_sipredirect().

03214 {
03215    ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
03216    dialog->alreadygone = 1;
03217 }

static int sip_answer ( struct ast_channel ast  )  [static]

sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface

Definition at line 6729 of file chan_sip.c.

References ast_channel::_state, ast_debug, ast_rtp_instance_update_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, ast_test_flag, FALSE, sip_pvt_lock, sip_pvt_unlock, start_session_timer(), ast_channel::tech_pvt, transmit_response_with_sdp(), TRUE, and try_suggested_sip_codec().

06730 {
06731    int res = 0;
06732    struct sip_pvt *p = ast->tech_pvt;
06733    int oldsdp = FALSE;
06734 
06735    if (!p) {
06736       ast_debug(1, "Asked to answer channel %s without tech pvt; ignoring\n",
06737             ast->name);
06738       return res;
06739    }
06740    sip_pvt_lock(p);
06741    if (ast->_state != AST_STATE_UP) {
06742       try_suggested_sip_codec(p);   
06743 
06744       if (ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) {
06745          oldsdp = TRUE;
06746       }
06747 
06748       ast_setstate(ast, AST_STATE_UP);
06749       ast_debug(1, "SIP answering channel: %s\n", ast->name);
06750       ast_rtp_instance_update_source(p->rtp);
06751       res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, oldsdp, TRUE);
06752       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
06753       /* RFC says the session timer starts counting on 200,
06754        * not on INVITE. */
06755       if (p->stimer->st_active == TRUE) {
06756          start_session_timer(p);
06757       }
06758    }
06759    sip_pvt_unlock(p);
06760    return res;
06761 }

static int sip_call ( struct ast_channel ast,
char *  dest,
int  timeout 
) [static]

Initiate SIP call from PBX used from the dial() application.

Definition at line 5759 of file chan_sip.c.

References ast_channel::_state, ao2_t_ref, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_USER_BUSY, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_channel_queue_connected_line_update(), ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_party_connected_line_init(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_rtp_instance_available_formats(), AST_SCHED_REPLACE_UNREF, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), ast_channel::caller, cid_name, connected, ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, ast_party_caller::id, LOG_WARNING, 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, ast_cc_monitor::private_data, setup_srtp(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), ast_party_name::valid, ast_party_number::valid, and ast_channel::varshead.

05760 {
05761    int res;
05762    struct sip_pvt *p = ast->tech_pvt;  /* chan is locked, so the reference cannot go away */
05763    struct varshead *headp;
05764    struct ast_var_t *current;
05765    const char *referer = NULL;   /* SIP referrer */
05766    int cc_core_id;
05767    char uri[SIPBUFSIZE] = "";
05768 
05769    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
05770       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
05771       return -1;
05772    }
05773 
05774    if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) {
05775       char device_name[AST_CHANNEL_NAME];
05776       struct ast_cc_monitor *recall_monitor;
05777       struct sip_monitor_instance *monitor_instance;
05778       ast_channel_get_device_name(ast, device_name, sizeof(device_name));
05779       if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) {
05780          monitor_instance = recall_monitor->private_data;
05781          ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri));
05782          ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor");
05783       }
05784    }
05785 
05786    /* Check whether there is vxml_url, distinctive ring variables */
05787    headp=&ast->varshead;
05788    AST_LIST_TRAVERSE(headp, current, entries) {
05789       /* Check whether there is a VXML_URL variable */
05790       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
05791          p->options->vxml_url = ast_var_value(current);
05792       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
05793          p->options->uri_options = ast_var_value(current);
05794       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
05795          /* Check whether there is a variable with a name starting with SIPADDHEADER */
05796          p->options->addsipheaders = 1;
05797       } else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) {
05798          ast_string_field_set(p, fromdomain, ast_var_value(current));
05799       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
05800          /* This is a transferred call */
05801          p->options->transfer = 1;
05802       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
05803          /* This is the referrer */
05804          referer = ast_var_value(current);
05805       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
05806          /* We're replacing a call. */
05807          p->options->replaces = ast_var_value(current);
05808       } else if (!strcasecmp(ast_var_name(current), "SIP_MAX_FORWARDS")) {
05809          if (sscanf(ast_var_value(current), "%d", &(p->maxforwards)) != 1) {
05810             ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer.\n");
05811          }
05812       }
05813    }
05814 
05815    /* Check to see if we should try to force encryption */
05816    if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) {
05817       ast_log(LOG_WARNING, "Encrypted signaling is required\n");
05818       ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05819       return -1;
05820    }
05821 
05822    if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
05823       if (ast_test_flag(&p->flags[0], SIP_REINVITE)) {
05824          ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n");
05825          ast_clear_flag(&p->flags[0], SIP_REINVITE);
05826       }
05827 
05828       if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) {
05829          ast_log(LOG_WARNING, "SRTP audio setup failed\n");
05830          return -1;
05831       }
05832 
05833       if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) {
05834          ast_log(LOG_WARNING, "SRTP video setup failed\n");
05835          return -1;
05836       }
05837 
05838       if (p->trtp && !p->tsrtp && setup_srtp(&p->tsrtp) < 0) {
05839          ast_log(LOG_WARNING, "SRTP text setup failed\n");
05840          return -1;
05841       }
05842    }
05843 
05844    res = 0;
05845    ast_set_flag(&p->flags[0], SIP_OUTGOING);
05846 
05847    /* T.38 re-INVITE FAX detection should never be done for outgoing calls,
05848     * so ensure it is disabled.
05849     */
05850    ast_clear_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38);
05851 
05852    if (p->options->transfer) {
05853       char buf[SIPBUFSIZE/2];
05854 
05855       if (referer) {
05856          if (sipdebug)
05857             ast_debug(3, "Call for %s transferred by %s\n", p->username, referer);
05858          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
05859       } else
05860          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
05861       ast_string_field_set(p, cid_name, buf);
05862    }
05863    ast_debug(1, "Outgoing Call for %s\n", p->username);
05864 
05865    res = update_call_counter(p, INC_CALL_RINGING);
05866 
05867    if (res == -1) {
05868       ast->hangupcause = AST_CAUSE_USER_BUSY;
05869       return res;
05870    }
05871    p->callingpres = ast_party_id_presentation(&ast->caller.id);
05872    p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec);
05873    p->jointnoncodeccapability = p->noncodeccapability;
05874 
05875    /* If there are no audio formats left to offer, punt */
05876    if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
05877       ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
05878       res = -1;
05879    } else {
05880       int xmitres;
05881       struct ast_party_connected_line connected;
05882       struct ast_set_party_connected_line update_connected;
05883 
05884       sip_pvt_lock(p);
05885 
05886       /* Supply initial connected line information if available. */
05887       memset(&update_connected, 0, sizeof(update_connected));
05888       ast_party_connected_line_init(&connected);
05889       if (!ast_strlen_zero(p->cid_num)
05890          || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
05891          update_connected.id.number = 1;
05892          connected.id.number.valid = 1;
05893          connected.id.number.str = (char *) p->cid_num;
05894          connected.id.number.presentation = p->callingpres;
05895       }
05896       if (!ast_strlen_zero(p->cid_name)
05897          || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
05898          update_connected.id.name = 1;
05899          connected.id.name.valid = 1;
05900          connected.id.name.str = (char *) p->cid_name;
05901          connected.id.name.presentation = p->callingpres;
05902       }
05903       if (update_connected.id.number || update_connected.id.name) {
05904          connected.id.tag = (char *) p->cid_tag;
05905          connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
05906          ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
05907       }
05908 
05909       xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri);
05910       if (xmitres == XMIT_ERROR) {
05911          sip_pvt_unlock(p);
05912          return -1;
05913       }
05914       p->invitestate = INV_CALLING;
05915 
05916       /* Initialize auto-congest time */
05917       AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p,
05918                         dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"),
05919                         dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
05920                         dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
05921       sip_pvt_unlock(p);
05922    }
05923    return res;
05924 }

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.

Definition at line 4139 of file chan_sip.c.

References append_history, and AST_SCHED_DEL_UNREF.

Referenced by handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), sip_hangup(), and sip_scheddestroy().

04140 {
04141    if (p->final_destruction_scheduled) {
04142       return 0;
04143    }
04144 
04145    if (p->autokillid > -1) {
04146       append_history(p, "CancelDestroy", "");
04147       AST_SCHED_DEL_UNREF(sched, p->autokillid, dialog_unref(p, "remove ref for autokillid"));
04148    }
04149    return 0;
04150 }

static void sip_cc_agent_destructor ( struct ast_cc_agent agent  )  [static]

Definition at line 1812 of file chan_sip.c.

References ast_free, ast_test_flag, ast_cc_agent::private_data, sip_cc_agent_stop_offer_timer(), sip_pvt_lock, sip_pvt_unlock, and transmit_response().

01813 {
01814    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01815 
01816    if (!agent_pvt) {
01817       /* The agent constructor probably failed. */
01818       return;
01819    }
01820 
01821    sip_cc_agent_stop_offer_timer(agent);
01822    if (agent_pvt->subscribe_pvt) {
01823       sip_pvt_lock(agent_pvt->subscribe_pvt);
01824       if (!ast_test_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
01825          /* If we haven't sent a 200 OK for the SUBSCRIBE dialog yet, then we need to send a response letting
01826           * the subscriber know something went wrong
01827           */
01828          transmit_response(agent_pvt->subscribe_pvt, "500 Internal Server Error", &agent_pvt->subscribe_pvt->initreq);
01829       }
01830       sip_pvt_unlock(agent_pvt->subscribe_pvt);
01831       agent_pvt->subscribe_pvt = dialog_unref(agent_pvt->subscribe_pvt, "SIP CC agent destructor: Remove ref to subscription");
01832    }
01833    ast_free(agent_pvt);
01834 }

static int sip_cc_agent_init ( struct ast_cc_agent agent,
struct ast_channel chan 
) [static]

Definition at line 1699 of file chan_sip.c.

References ast_assert, ast_calloc, ast_copy_string(), ast_set_flag, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, ast_channel::tech_pvt, and ast_channel_tech::type.

01700 {
01701    struct sip_cc_agent_pvt *agent_pvt = ast_calloc(1, sizeof(*agent_pvt));
01702    struct sip_pvt *call_pvt = chan->tech_pvt;
01703 
01704    if (!agent_pvt) {
01705       return -1;
01706    }
01707 
01708    ast_assert(!strcmp(chan->tech->type, "SIP"));
01709 
01710    ast_copy_string(agent_pvt->original_callid, call_pvt->callid, sizeof(agent_pvt->original_callid));
01711    ast_copy_string(agent_pvt->original_exten, call_pvt->exten, sizeof(agent_pvt->original_exten));
01712    agent_pvt->offer_timer_id = -1;
01713    agent->private_data = agent_pvt;
01714    sip_pvt_lock(call_pvt);
01715    ast_set_flag(&call_pvt->flags[0], SIP_OFFER_CC);
01716    sip_pvt_unlock(call_pvt);
01717    return 0;
01718 }

static int sip_cc_agent_recall ( struct ast_cc_agent agent  )  [static]

Definition at line 1792 of file chan_sip.c.

References ast_cc_agent_caller_busy(), ast_cc_agent::core_id, ast_cc_agent::device_name, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, and transmit_cc_notify().

01793 {
01794    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01795    /* If we have received a PUBLISH beforehand stating that the caller in question
01796     * is not available, we can save ourself a bit of effort here and just report
01797     * the caller as busy
01798     */
01799    if (!agent_pvt->is_available) {
01800       return ast_cc_agent_caller_busy(agent->core_id, "Caller %s is busy, reporting to the core",
01801             agent->device_name);
01802    }
01803    /* Otherwise, we transmit a NOTIFY to the caller and await either
01804     * a PUBLISH or an INVITE
01805     */
01806    sip_pvt_lock(agent_pvt->subscribe_pvt);
01807    transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_READY);
01808    sip_pvt_unlock(agent_pvt->subscribe_pvt);
01809    return 0;
01810 }

static void sip_cc_agent_respond ( struct ast_cc_agent agent,
enum ast_cc_agent_response_reason  reason 
) [static]

Definition at line 1748 of file chan_sip.c.

References AST_CC_AGENT_RESPONSE_SUCCESS, ast_set_flag, ast_strlen_zero(), ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, transmit_cc_notify(), transmit_response(), and TRUE.

01749 {
01750    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01751 
01752    sip_pvt_lock(agent_pvt->subscribe_pvt);
01753    ast_set_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
01754    if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) {
01755       /* The second half of this if statement may be a bit hard to grasp,
01756        * so here's an explanation. When a subscription comes into
01757        * chan_sip, as long as it is not malformed, it will be passed
01758        * to the CC core. If the core senses an out-of-order state transition,
01759        * then the core will call this callback with the "reason" set to a
01760        * failure condition.
01761        * However, an out-of-order state transition will occur during a resubscription
01762        * for CC. In such a case, we can see that we have already generated a notify_uri
01763        * and so we can detect that this isn't a *real* failure. Rather, it is just
01764        * something the core doesn't recognize as a legitimate SIP state transition.
01765        * Thus we respond with happiness and flowers.
01766        */
01767       transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq);
01768       transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED);
01769    } else {
01770       transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq);
01771    }
01772    sip_pvt_unlock(agent_pvt->subscribe_pvt);
01773    agent_pvt->is_available = TRUE;
01774 }

static int sip_cc_agent_start_monitoring ( struct ast_cc_agent agent  )  [static]

Definition at line 1783 of file chan_sip.c.

01784 {
01785    /* To start monitoring just means to wait for an incoming PUBLISH
01786     * to tell us that the caller has become available again. No special
01787     * action is needed
01788     */
01789    return 0;
01790 }

static int sip_cc_agent_start_offer_timer ( struct ast_cc_agent agent  )  [static]

Definition at line 1730 of file chan_sip.c.

References ast_get_cc_offer_timer(), ast_sched_add(), ast_cc_agent::cc_params, ast_cc_agent::private_data, and sip_offer_timer_expire().

01731 {
01732    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01733    int when;
01734 
01735    when = ast_get_cc_offer_timer(agent->cc_params) * 1000;
01736    agent_pvt->offer_timer_id = ast_sched_add(sched, when, sip_offer_timer_expire, agent);
01737    return 0;
01738 }

static int sip_cc_agent_status_request ( struct ast_cc_agent agent  )  [static]

Definition at line 1776 of file chan_sip.c.

References ast_cc_agent_status_response(), AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_cc_agent::core_id, and ast_cc_agent::private_data.

01777 {
01778    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01779    enum ast_device_state state = agent_pvt->is_available ? AST_DEVICE_NOT_INUSE : AST_DEVICE_INUSE;
01780    return ast_cc_agent_status_response(agent->core_id, state);
01781 }

static int sip_cc_agent_stop_offer_timer ( struct ast_cc_agent agent  )  [static]

Definition at line 1740 of file chan_sip.c.

References AST_SCHED_DEL, and ast_cc_agent::private_data.

Referenced by sip_cc_agent_destructor().

01741 {
01742    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01743 
01744    AST_SCHED_DEL(sched, agent_pvt->offer_timer_id);
01745    return 0;
01746 }

static int sip_cc_monitor_cancel_available_timer ( struct ast_cc_monitor monitor,
int *  sched_id 
) [static]

Definition at line 2051 of file chan_sip.c.

References ao2_t_ref, and AST_SCHED_DEL.

02052 {
02053    if (*sched_id != -1) {
02054       AST_SCHED_DEL(sched, *sched_id);
02055       ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor");
02056    }
02057    return 0;
02058 }

static void sip_cc_monitor_destructor ( void *  private_data  )  [static]

Definition at line 2060 of file chan_sip.c.

References ao2_unlink, and ast_module_unref().

02061 {
02062    struct sip_monitor_instance *monitor_instance = private_data;
02063    ao2_unlink(sip_monitor_instances, monitor_instance);
02064    ast_module_unref(ast_module_info->self);
02065 }

static int sip_cc_monitor_request_cc ( struct ast_cc_monitor monitor,
int *  available_timer_id 
) [static]

Definition at line 1918 of file chan_sip.c.

References ao2_t_ref, ast_cc_available_timer_expire(), AST_CC_CCBS, ast_get_ccbs_available_timer(), ast_get_ccnr_available_timer(), ast_sched_add(), ast_set_flag, ast_sip_ouraddrfor(), ast_cc_interface::config_params, create_addr(), FALSE, ast_cc_monitor::interface, ast_cc_monitor::private_data, service, ast_cc_monitor::service_offered, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, and transmit_invite().

01919 {
01920    struct sip_monitor_instance *monitor_instance = monitor->private_data;
01921    enum ast_cc_service_type service = monitor->service_offered;
01922    int when;
01923 
01924    if (!monitor_instance) {
01925       return -1;
01926    }
01927 
01928    if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) {
01929       return -1;
01930    }
01931 
01932    when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) :
01933       ast_get_ccnr_available_timer(monitor->interface->config_params);
01934 
01935    sip_pvt_lock(monitor_instance->subscription_pvt);
01936    ast_set_flag(&monitor_instance->subscription_pvt->flags[0], SIP_OUTGOING);
01937    create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1);
01938    ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt);
01939    monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION;
01940    monitor_instance->subscription_pvt->expiry = when;
01941 
01942    transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri);
01943    sip_pvt_unlock(monitor_instance->subscription_pvt);
01944 
01945    ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler");
01946    *available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor);
01947    return 0;
01948 }

static int sip_cc_monitor_suspend ( struct ast_cc_monitor monitor  )  [static]

Definition at line 1976 of file chan_sip.c.

References ao2_ref, ast_calloc, ast_log(), ast_strlen_zero(), construct_pidf_body(), ast_cc_monitor::core_id, create_epa_entry(), LOG_WARNING, ast_cc_monitor::private_data, and transmit_publish().

01977 {
01978    struct sip_monitor_instance *monitor_instance = monitor->private_data;
01979    enum sip_publish_type publish_type;
01980    struct cc_epa_entry *cc_entry;
01981 
01982    if (!monitor_instance) {
01983       return -1;
01984    }
01985 
01986    if (!monitor_instance->suspension_entry) {
01987       /* We haven't yet allocated the suspension entry, so let's give it a shot */
01988       if (!(monitor_instance->suspension_entry = create_epa_entry("call-completion", monitor_instance->peername))) {
01989          ast_log(LOG_WARNING, "Unable to allocate sip EPA entry for call-completion\n");
01990          ao2_ref(monitor_instance, -1);
01991          return -1;
01992       }
01993       if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) {
01994          ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n");
01995          ao2_ref(monitor_instance, -1);
01996          return -1;
01997       }
01998       cc_entry->core_id = monitor->core_id;
01999       monitor_instance->suspension_entry->instance_data = cc_entry;
02000       publish_type = SIP_PUBLISH_INITIAL;
02001    } else {
02002       publish_type = SIP_PUBLISH_MODIFY;
02003       cc_entry = monitor_instance->suspension_entry->instance_data;
02004    }
02005 
02006    cc_entry->current_state = CC_CLOSED;
02007 
02008    if (ast_strlen_zero(monitor_instance->notify_uri)) {
02009       /* If we have no set notify_uri, then what this means is that we have
02010        * not received a NOTIFY from this destination stating that he is
02011        * currently available.
02012        *
02013        * This situation can arise when the core calls the suspend callbacks
02014        * of multiple destinations. If one of the other destinations aside
02015        * from this one notified Asterisk that he is available, then there
02016        * is no reason to take any suspension action on this device. Rather,
02017        * we should return now and if we receive a NOTIFY while monitoring
02018        * is still "suspended" then we can immediately respond with the
02019        * proper PUBLISH to let this endpoint know what is going on.
02020        */
02021       return 0;
02022    }
02023    construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
02024    return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri);
02025 }

static int sip_cc_monitor_unsuspend ( struct ast_cc_monitor monitor  )  [static]

Definition at line 2027 of file chan_sip.c.

References ast_assert, ast_strlen_zero(), construct_pidf_body(), ast_cc_monitor::private_data, and transmit_publish().

02028 {
02029    struct sip_monitor_instance *monitor_instance = monitor->private_data;
02030    struct cc_epa_entry *cc_entry;
02031 
02032    if (!monitor_instance) {
02033       return -1;
02034    }
02035 
02036    ast_assert(monitor_instance->suspension_entry != NULL);
02037 
02038    cc_entry = monitor_instance->suspension_entry->instance_data;
02039    cc_entry->current_state = CC_OPEN;
02040    if (ast_strlen_zero(monitor_instance->notify_uri)) {
02041       /* This means we are being asked to unsuspend a call leg we never
02042        * sent a PUBLISH on. As such, there is no reason to send another
02043        * PUBLISH at this point either. We can just return instead.
02044        */
02045       return 0;
02046    }
02047    construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
02048    return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri);
02049 }

static int sip_check_authtimeout ( time_t  start  )  [static]

Check if the authtimeout has expired.

Parameters:
start the time when the session started
Return values:
0 the timeout has expired
-1 error
Returns:
the number of milliseconds until the timeout will expire

Definition at line 2483 of file chan_sip.c.

References ast_log(), errno, and LOG_ERROR.

Referenced by _sip_tcp_helper_thread(), and sip_tcptls_read().

02484 {
02485    int timeout;
02486    time_t now;
02487    if(time(&now) == -1) {
02488       ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
02489       return -1;
02490    }
02491 
02492    timeout = (authtimeout - (now - start)) * 1000;
02493    if (timeout < 0) {
02494       /* we have timed out */
02495       return 0;
02496    }
02497 
02498    return timeout;
02499 }

static char * sip_cli_notify ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Cli command to send SIP notify to peer.

Definition at line 19681 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), ast_str_append(), ast_str_strlen(), ast_unescape_semicolon(), ast_variable_browse(), ast_variable_new(), build_via(), change_callid_pvt(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipnotify(), create_addr(), dialog_unlink_all(), ast_cli_args::fd, ast_cli_args::line, LOG_WARNING, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), ast_cli_entry::usage, ast_variable::value, var, and ast_cli_args::word.

19682 {
19683    struct ast_variable *varlist;
19684    int i;
19685 
19686    switch (cmd) {
19687    case CLI_INIT:
19688       e->command = "sip notify";
19689       e->usage =
19690          "Usage: sip notify <type> <peer> [<peer>...]\n"
19691          "       Send a NOTIFY message to a SIP peer or peers\n"
19692          "       Message types are defined in sip_notify.conf\n";
19693       return NULL;
19694    case CLI_GENERATE:
19695       return complete_sipnotify(a->line, a->word, a->pos, a->n);
19696    }
19697 
19698    if (a->argc < 4)
19699       return CLI_SHOWUSAGE;
19700 
19701    if (!notify_types) {
19702       ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config);
19703       return CLI_FAILURE;
19704    }
19705 
19706    varlist = ast_variable_browse(notify_types, a->argv[2]);
19707 
19708    if (!varlist) {
19709       ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]);
19710       return CLI_FAILURE;
19711    }
19712 
19713    for (i = 3; i < a->argc; i++) {
19714       struct sip_pvt *p;
19715       char buf[512];
19716       struct ast_variable *header, *var;
19717 
19718       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
19719          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
19720          return CLI_FAILURE;
19721       }
19722 
19723       if (create_addr(p, a->argv[i], NULL, 1)) {
19724          /* Maybe they're not registered, etc. */
19725          dialog_unlink_all(p);
19726          dialog_unref(p, "unref dialog inside for loop" );
19727          /* sip_destroy(p); */
19728          ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]);
19729          continue;
19730       }
19731 
19732       /* Notify is outgoing call */
19733       ast_set_flag(&p->flags[0], SIP_OUTGOING);
19734       sip_notify_allocate(p);
19735       p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
19736 
19737       for (var = varlist; var; var = var->next) {
19738          ast_copy_string(buf, var->value, sizeof(buf));
19739          ast_unescape_semicolon(buf);
19740 
19741          if (!strcasecmp(var->name, "Content")) {
19742             if (ast_str_strlen(p->notify->content))
19743                ast_str_append(&p->notify->content, 0, "\r\n");
19744             ast_str_append(&p->notify->content, 0, "%s", buf);
19745          } else if (!strcasecmp(var->name, "Content-Length")) {
19746             ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring\n");
19747          } else {
19748             header->next = ast_variable_new(var->name, buf, "");
19749             header = header->next;
19750          }
19751       }
19752 
19753       /* Now that we have the peer's address, set our ip and change callid */
19754       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
19755       build_via(p);
19756 
19757       change_callid_pvt(p, NULL);
19758 
19759       ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]);
19760       sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
19761       transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
19762       dialog_unref(p, "bump down the count of p since we're done with it.");
19763    }
19764 
19765    return CLI_SUCCESS;
19766 }

static int sip_debug_test_addr ( const struct ast_sockaddr addr  )  [inline, static]

See if we pass debug IP filter.

Definition at line 3363 of file chan_sip.c.

References ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_port, and debugaddr.

Referenced by check_peer_ok(), handle_request_do(), and sip_debug_test_pvt().

03364 {
03365    /* Can't debug if sipdebug is not enabled */
03366    if (!sipdebug) {
03367       return 0;
03368    }
03369 
03370    /* A null debug_addr means we'll debug any address */
03371    if (ast_sockaddr_isnull(&debugaddr)) {
03372       return 1;
03373    }
03374 
03375    /* If no port was specified for a debug address, just compare the
03376     * addresses, otherwise compare the address and port
03377     */
03378    if (ast_sockaddr_port(&debugaddr)) {
03379       return !ast_sockaddr_cmp(&debugaddr, addr);
03380    } else {
03381       return !ast_sockaddr_cmp_addr(&debugaddr, addr);
03382    }
03383 }

static int sip_debug_test_pvt ( struct sip_pvt *  p  )  [inline, static]
struct sip_pvt* sip_destroy ( struct sip_pvt *  p  )  [read]

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.

Definition at line 6296 of file chan_sip.c.

References __sip_destroy(), ast_debug, and TRUE.

Referenced by sip_destroy_fn().

06297 {
06298    ast_debug(3, "Destroying SIP dialog %s\n", p->callid);
06299    __sip_destroy(p, TRUE, TRUE);
06300    return NULL;
06301 }

static void sip_destroy_fn ( void *  p  )  [static]

Definition at line 6286 of file chan_sip.c.

References sip_destroy().

Referenced by sip_alloc().

06287 {
06288    sip_destroy(p);
06289 }

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

Destroy peer object from memory.

Definition at line 4824 of file chan_sip.c.

References ao2_ref, ao2_t_ref, ast_atomic_fetchadd_int(), ast_cc_config_params_destroy(), ast_debug, ast_free_ha(), ast_string_field_free_memory, ast_test_flag, ast_variables_destroy(), clear_peer_mailboxes(), dialog_unlink_all(), FALSE, and register_peer_exten().

Referenced by sip_destroy_peer_fn().

04825 {
04826    ast_debug(3, "Destroying SIP peer %s\n", peer->name);
04827 
04828    /*
04829     * Remove any mailbox event subscriptions for this peer before
04830     * we destroy anything.  An event subscription callback may be
04831     * happening right now.
04832     */
04833    clear_peer_mailboxes(peer);
04834 
04835    if (peer->outboundproxy) {
04836       ao2_ref(peer->outboundproxy, -1);
04837       peer->outboundproxy = NULL;
04838    }
04839 
04840    /* Delete it, it needs to disappear */
04841    if (peer->call) {
04842       dialog_unlink_all(peer->call);
04843       peer->call = dialog_unref(peer->call, "peer->call is being unset");
04844    }
04845 
04846    if (peer->mwipvt) {  /* We have an active subscription, delete it */
04847       dialog_unlink_all(peer->mwipvt);
04848       peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt");
04849    }
04850    
04851    if (peer->chanvars) {
04852       ast_variables_destroy(peer->chanvars);
04853       peer->chanvars = NULL;
04854    }
04855    
04856    register_peer_exten(peer, FALSE);
04857    ast_free_ha(peer->ha);
04858    ast_free_ha(peer->directmediaha);
04859    if (peer->selfdestruct)
04860       ast_atomic_fetchadd_int(&apeerobjs, -1);
04861    else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->is_realtime) {
04862       ast_atomic_fetchadd_int(&rpeerobjs, -1);
04863       ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs);
04864    } else
04865       ast_atomic_fetchadd_int(&speerobjs, -1);
04866    if (peer->auth) {
04867       ao2_t_ref(peer->auth, -1, "Removing peer authentication");
04868       peer->auth = NULL;
04869    }
04870 
04871    if (peer->socket.tcptls_session) {
04872       ao2_ref(peer->socket.tcptls_session, -1);
04873       peer->socket.tcptls_session = NULL;
04874    }
04875 
04876    ast_cc_config_params_destroy(peer->cc_params);
04877 
04878    ast_string_field_free_memory(peer);
04879 }

static void sip_destroy_peer_fn ( void *  peer  )  [static]

Definition at line 4818 of file chan_sip.c.

References sip_destroy_peer().

Referenced by build_peer(), and temp_peer().

04819 {
04820    sip_destroy_peer(peer);
04821 }

static int sip_devicestate ( void *  data  )  [static]

Part of PBX channel interface.

Note:
Return values:---

If we have qualify on and the device is not reachable, regardless of registration state we return AST_DEVICE_UNAVAILABLE

For peers with call limit:

  • not registered AST_DEVICE_UNAVAILABLE
  • registered, no call AST_DEVICE_NOT_INUSE
  • registered, active calls AST_DEVICE_INUSE
  • registered, call limit reached AST_DEVICE_BUSY
  • registered, onhold AST_DEVICE_ONHOLD
  • registered, ringing AST_DEVICE_RINGING

For peers without call limit:

  • not registered AST_DEVICE_UNAVAILABLE
  • registered AST_DEVICE_NOT_INUSE
  • fixed IP (!dynamic) AST_DEVICE_NOT_INUSE

Peers that does not have a known call and can't be reached by OPTIONS

  • unreachable AST_DEVICE_UNAVAILABLE

If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.

The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID

When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN

Definition at line 27237 of file chan_sip.c.

References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, ast_sockaddr_isnull(), ast_strdupa, FALSE, find_peer(), TRUE, and unref_peer().

27238 {
27239    char *host;
27240    char *tmp;
27241    struct sip_peer *p;
27242 
27243    int res = AST_DEVICE_INVALID;
27244 
27245    /* make sure data is not null. Maybe unnecessary, but better be safe */
27246    host = ast_strdupa(data ? data : "");
27247    if ((tmp = strchr(host, '@')))
27248       host = tmp + 1;
27249 
27250    ast_debug(3, "Checking device state for peer %s\n", host);
27251 
27252    /* If find_peer asks for a realtime peer, then this breaks rtautoclear.  This
27253     * is because when a peer tries to autoexpire, the last thing it does is to
27254     * queue up an event telling the system that the devicestate has changed
27255     * (presumably to unavailable).  If we ask for a realtime peer here, this would
27256     * load it BACK into memory, thus defeating the point of trying to clear dead
27257     * hosts out of memory.
27258     */
27259    if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) {
27260       if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) {
27261          /* we have an address for the peer */
27262       
27263          /* Check status in this order
27264             - Hold
27265             - Ringing
27266             - Busy (enforced only by call limit)
27267             - Inuse (we have a call)
27268             - Unreachable (qualify)
27269             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
27270             for registered devices */
27271 
27272          if (p->onHold)
27273             /* First check for hold or ring states */
27274             res = AST_DEVICE_ONHOLD;
27275          else if (p->inRinging) {
27276             if (p->inRinging == p->inUse)
27277                res = AST_DEVICE_RINGING;
27278             else
27279                res = AST_DEVICE_RINGINUSE;
27280          } else if (p->call_limit && (p->inUse == p->call_limit))
27281             /* check call limit */
27282             res = AST_DEVICE_BUSY;
27283          else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level)
27284             /* We're forcing busy before we've reached the call limit */
27285             res = AST_DEVICE_BUSY;
27286          else if (p->call_limit && p->inUse)
27287             /* Not busy, but we do have a call */
27288             res = AST_DEVICE_INUSE;
27289          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0)))
27290             /* We don't have a call. Are we reachable at all? Requires qualify= */
27291             res = AST_DEVICE_UNAVAILABLE;
27292          else  /* Default reply if we're registered and have no other data */
27293             res = AST_DEVICE_NOT_INUSE;
27294       } else {
27295          /* there is no address, it's unavailable */
27296          res = AST_DEVICE_UNAVAILABLE;
27297       }
27298       unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer");
27299    }
27300 
27301    return res;
27302 }

static char * sip_do_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Turn on SIP debugging (CLI command).

Note:
this can be a special debug command - "sip debug text" or something

Definition at line 19638 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), debugaddr, ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, sip_do_debug_ip(), sip_do_debug_peer(), ast_cli_entry::usage, and ast_cli_args::word.

19639 {
19640    int oldsipdebug = sipdebug & sip_debug_console;
19641    const char *what;
19642 
19643    if (cmd == CLI_INIT) {
19644       e->command = "sip set debug {on|off|ip|peer}";
19645       e->usage =
19646          "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n"
19647          "       Globally disables dumping of SIP packets,\n"
19648          "       or enables it either globally or for a (single)\n"
19649          "       IP address or registered peer.\n";
19650       return NULL;
19651    } else if (cmd == CLI_GENERATE) {
19652       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
19653          return complete_sip_peer(a->word, a->n, 0);
19654       return NULL;
19655         }
19656 
19657    what = a->argv[e->args-1];      /* guaranteed to exist */
19658    if (a->argc == e->args) {       /* on/off */
19659       if (!strcasecmp(what, "on")) {
19660          sipdebug |= sip_debug_console;
19661          sipdebug_text = 1;   /*! \note this can be a special debug command - "sip debug text" or something */
19662          memset(&debugaddr, 0, sizeof(debugaddr));
19663          ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
19664          return CLI_SUCCESS;
19665       } else if (!strcasecmp(what, "off")) {
19666          sipdebug &= ~sip_debug_console;
19667          sipdebug_text = 0;
19668          ast_cli(a->fd, "SIP Debugging Disabled\n");
19669          return CLI_SUCCESS;
19670       }
19671    } else if (a->argc == e->args +1) {/* ip/peer */
19672       if (!strcasecmp(what, "ip"))
19673          return sip_do_debug_ip(a->fd, a->argv[e->args]);
19674       else if (!strcasecmp(what, "peer"))
19675          return sip_do_debug_peer(a->fd, a->argv[e->args]);
19676    }
19677    return CLI_SHOWUSAGE;   /* default, failure */
19678 }

static char * sip_do_debug_ip ( int  fd,
const char *  arg 
) [static]

Enable SIP Debugging for a single IP.

Definition at line 19607 of file chan_sip.c.

References ast_cli(), ast_sockaddr_resolve_first_af(), ast_sockaddr_stringify_addr(), CLI_SHOWUSAGE, CLI_SUCCESS, and debugaddr.

Referenced by sip_do_debug().

19608 {
19609    if (ast_sockaddr_resolve_first_af(&debugaddr, arg, 0, 0)) {
19610       return CLI_SHOWUSAGE;
19611    }
19612 
19613    ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
19614    sipdebug |= sip_debug_console;
19615 
19616    return CLI_SUCCESS;
19617 }

static char * sip_do_debug_peer ( int  fd,
const char *  arg 
) [static]

Turn on SIP debugging for a given peer.

Definition at line 19620 of file chan_sip.c.

References ast_cli(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), CLI_SUCCESS, debugaddr, FALSE, find_peer(), TRUE, and unref_peer().

Referenced by sip_do_debug().

19621 {
19622    struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0);
19623    if (!peer)
19624       ast_cli(fd, "No such peer '%s'\n", arg);
19625    else if (ast_sockaddr_isnull(&peer->addr))
19626       ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg);
19627    else {
19628       ast_sockaddr_copy(&debugaddr, &peer->addr);
19629       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
19630       sipdebug |= sip_debug_console;
19631    }
19632    if (peer)
19633       unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call");
19634    return CLI_SUCCESS;
19635 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 30600 of file chan_sip.c.

References ast_debug, ast_sched_dump(), reload_config(), sip_poke_all_peers(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), and unlink_marked_peers_from_tables().

Referenced by do_monitor().

30601 {
30602    time_t start_poke, end_poke;
30603    
30604    reload_config(reason);
30605    ast_sched_dump(sched);
30606 
30607    start_poke = time(0);
30608    /* Prune peers who still are supposed to be deleted */
30609    unlink_marked_peers_from_tables();
30610 
30611    ast_debug(4, "--------------- Done destroying pruned peers\n");
30612 
30613    /* Send qualify (OPTIONS) to all peers */
30614    sip_poke_all_peers();
30615 
30616    /* Register with all services */
30617    sip_send_all_registers();
30618 
30619    sip_send_all_mwi_subscriptions();
30620 
30621    end_poke = time(0);
30622    
30623    ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke));
30624 
30625    ast_debug(4, "--------------- SIP reload done\n");
30626 
30627    return 0;
30628 }

static int sip_dtmfmode ( struct ast_channel chan,
const char *  data 
) [static]

Set the DTMFmode for an outbound SIP call (application).

Definition at line 30283 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_log(), AST_RTP_DTMF, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, ast_set_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, and ast_channel::tech_pvt.

Referenced by load_module().

30284 {
30285    struct sip_pvt *p;
30286    const char *mode = data;
30287 
30288    if (!data) {
30289       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
30290       return 0;
30291    }
30292    ast_channel_lock(chan);
30293    if (!IS_SIP_TECH(chan->tech)) {
30294       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
30295       ast_channel_unlock(chan);
30296       return 0;
30297    }
30298    p = chan->tech_pvt;
30299    if (!p) {
30300       ast_channel_unlock(chan);
30301       return 0;
30302    }
30303    sip_pvt_lock(p);
30304    if (!strcasecmp(mode, "info")) {
30305       ast_clear_flag(&p->flags[0], SIP_DTMF);
30306       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
30307       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
30308    } else if (!strcasecmp(mode, "shortinfo")) {
30309       ast_clear_flag(&p->flags[0], SIP_DTMF);
30310       ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO);
30311       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
30312    } else if (!strcasecmp(mode, "rfc2833")) {
30313       ast_clear_flag(&p->flags[0], SIP_DTMF);
30314       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
30315       p->jointnoncodeccapability |= AST_RTP_DTMF;
30316    } else if (!strcasecmp(mode, "inband")) {
30317       ast_clear_flag(&p->flags[0], SIP_DTMF);
30318       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
30319       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
30320    } else {
30321       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode);
30322    }
30323    if (p->rtp)
30324       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
30325    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
30326        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
30327       enable_dsp_detect(p);
30328    } else {
30329       disable_dsp_detect(p);
30330    }
30331    sip_pvt_unlock(p);
30332    ast_channel_unlock(chan);
30333    return 0;
30334 }

static void sip_dump_history ( struct sip_pvt *  dialog  )  [static]

Dump SIP history to debug log file at end of lifespan for SIP dialog.

Definition at line 19407 of file chan_sip.c.

References ast_debug, AST_LIST_TRAVERSE, ast_log(), LOG_NOTICE, and option_debug.

Referenced by __sip_destroy().

19408 {
19409    int x = 0;
19410    struct sip_history *hist;
19411    static int errmsg = 0;
19412 
19413    if (!dialog)
19414       return;
19415 
19416    if (!option_debug && !sipdebug) {
19417       if (!errmsg) {
19418          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
19419          errmsg = 1;
19420       }
19421       return;
19422    }
19423 
19424    ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
19425    if (dialog->subscribed)
19426       ast_debug(1, "  * Subscription\n");
19427    else
19428       ast_debug(1, "  * SIP Call\n");
19429    if (dialog->history)
19430       AST_LIST_TRAVERSE(dialog->history, hist, list)
19431          ast_debug(1, "  %-3.3d. %s\n", ++x, hist->event);
19432    if (!x)
19433       ast_debug(1, "Call '%s' has no history\n", dialog->callid);
19434    ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
19435 }

static int sip_epa_register ( const struct epa_static_data *  static_data  )  [static]

Definition at line 851 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, and AST_LIST_UNLOCK.

Referenced by load_module().

00852 {
00853    struct epa_backend *backend = ast_calloc(1, sizeof(*backend));
00854 
00855    if (!backend) {
00856       return -1;
00857    }
00858 
00859    backend->static_data = static_data;
00860 
00861    AST_LIST_LOCK(&epa_static_data_list);
00862    AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next);
00863    AST_LIST_UNLOCK(&epa_static_data_list);
00864    return 0;
00865 }

static void sip_epa_unregister_all ( void   )  [static]

Definition at line 867 of file chan_sip.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.

Referenced by unload_module().

00868 {
00869    struct epa_backend *backend;
00870 
00871    AST_LIST_LOCK(&epa_static_data_list);
00872    while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) {
00873       ast_free(backend);
00874    }
00875    AST_LIST_UNLOCK(&epa_static_data_list);
00876 }

static int sip_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links

Definition at line 6872 of file chan_sip.c.

References append_history, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, sip_set_rtp_peer(), and ast_channel::tech_pvt.

06873 {
06874    int ret = -1;
06875    struct sip_pvt *p;
06876 
06877    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE))
06878       ast_debug(1, "New channel is zombie\n");
06879    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE))
06880       ast_debug(1, "Old channel is zombie\n");
06881 
06882    if (!newchan || !newchan->tech_pvt) {
06883       if (!newchan)
06884          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
06885       else
06886          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
06887       return -1;
06888    }
06889    p = newchan->tech_pvt;
06890 
06891    sip_pvt_lock(p);
06892    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
06893    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
06894    if (p->owner != oldchan)
06895       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
06896    else {
06897       p->owner = newchan;
06898       /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
06899          RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
06900          able to do this if the masquerade happens before the bridge breaks (e.g., AMI
06901          redirect of both channels). Note that a channel can not be masqueraded *into*
06902          a native bridge. So there is no danger that this breaks a native bridge that
06903          should stay up. */
06904       sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0);
06905       ret = 0;
06906    }
06907    ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
06908 
06909    sip_pvt_unlock(p);
06910    return ret;
06911 }

static const char * sip_get_callid ( struct ast_channel chan  )  [static]

Deliver SIP call ID for the call.

Definition at line 4672 of file chan_sip.c.

References ast_channel::tech_pvt.

04673 {
04674    return chan->tech_pvt ? ((struct sip_pvt *) chan->tech_pvt)->callid : "";
04675 }

static int sip_get_cc_information ( struct sip_request *  req,
char *  subscribe_uri,
size_t  size,
enum ast_cc_service_type service 
) [static]

Definition at line 2067 of file chan_sip.c.

References AST_CC_NONE, ast_copy_string(), ast_strdupa, ast_strlen_zero(), get_header(), get_in_brackets(), and service_string_to_service_type().

Referenced by sip_handle_cc().

02068 {
02069    char *call_info = ast_strdupa(get_header(req, "Call-Info"));
02070    char *uri;
02071    char *purpose;
02072    char *service_str;
02073    static const char cc_purpose[] = "purpose=call-completion";
02074    static const int cc_purpose_len = sizeof(cc_purpose) - 1;
02075 
02076    if (ast_strlen_zero(call_info)) {
02077       /* No Call-Info present. Definitely no CC offer */
02078       return -1;
02079    }
02080 
02081    uri = strsep(&call_info, ";");
02082 
02083    while ((purpose = strsep(&call_info, ";"))) {
02084       if (!strncmp(purpose, cc_purpose, cc_purpose_len)) {
02085          break;
02086       }
02087    }
02088    if (!purpose) {
02089       /* We didn't find the appropriate purpose= parameter. Oh well */
02090       return -1;
02091    }
02092 
02093    /* Okay, call-completion has been offered. Let's figure out what type of service this is */
02094    while ((service_str = strsep(&call_info, ";"))) {
02095       if (!strncmp(service_str, "m=", 2)) {
02096          break;
02097       }
02098    }
02099    if (!service_str) {
02100       /* So they didn't offer a particular service, We'll just go with CCBS since it really
02101        * doesn't matter anyway
02102        */
02103       service_str = "BS";
02104    } else {
02105       /* We already determined that there is an "m=" so no need to check
02106        * the result of this strsep
02107        */
02108       strsep(&service_str, "=");
02109    }
02110 
02111    if ((*service = service_string_to_service_type(service_str)) == AST_CC_NONE) {
02112       /* Invalid service offered */
02113       return -1;
02114    }
02115 
02116    ast_copy_string(subscribe_uri, get_in_brackets(uri), size);
02117 
02118    return 0;
02119 }

static format_t sip_get_codec ( struct ast_channel chan  )  [static]

Definition at line 30263 of file chan_sip.c.

References ast_channel::tech_pvt.

30264 {
30265    struct sip_pvt *p = chan->tech_pvt;
30266    return p->peercapability ? p->peercapability : p->capability;
30267 }

static enum ast_rtp_glue_result sip_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 29974 of file chan_sip.c.

References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_JB_FORCED, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, global_jbconf, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.

29975 {
29976    struct sip_pvt *p = NULL;
29977    struct ast_channel *opp_chan;
29978    struct sip_pvt *opp = NULL;
29979    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
29980 
29981    if (!(p = chan->tech_pvt)) {
29982       return AST_RTP_GLUE_RESULT_FORBID;
29983    }
29984 
29985    if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
29986                          (!(opp = opp_chan->tech_pvt)))) {
29987       return AST_RTP_GLUE_RESULT_FORBID;
29988    }
29989 
29990    sip_pvt_lock(p);
29991    while (opp && sip_pvt_trylock(opp)) {
29992       sip_pvt_unlock(p);
29993       usleep(1);
29994       sip_pvt_lock(p);
29995    }
29996 
29997    if (!(p->rtp)) {
29998       if (opp) {
29999          sip_pvt_unlock(opp);
30000       }
30001       sip_pvt_unlock(p);
30002       return AST_RTP_GLUE_RESULT_FORBID;
30003    }
30004 
30005    ao2_ref(p->rtp, +1);
30006    *instance = p->rtp;
30007 
30008    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
30009       res = AST_RTP_GLUE_RESULT_REMOTE;
30010       if (opp && !apply_directmedia_ha(p, opp, "audio")) {
30011          res = AST_RTP_GLUE_RESULT_FORBID;
30012       }
30013    } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
30014       res = AST_RTP_GLUE_RESULT_REMOTE;
30015    } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) {
30016       res = AST_RTP_GLUE_RESULT_FORBID;
30017    }
30018 
30019    if (opp) {
30020       sip_pvt_unlock(opp);
30021    }
30022 
30023    if (p->srtp) {
30024       res = AST_RTP_GLUE_RESULT_FORBID;
30025    }
30026 
30027    sip_pvt_unlock(p);
30028 
30029    return res;
30030 }

static enum ast_rtp_glue_result sip_get_trtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 30081 of file chan_sip.c.

References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.

30082 {
30083    struct sip_pvt *p = NULL;
30084    struct ast_channel *opp_chan;
30085    struct sip_pvt *opp = NULL;
30086    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
30087 
30088    if (!(p = chan->tech_pvt)) {
30089       return AST_RTP_GLUE_RESULT_FORBID;
30090    }
30091 
30092    if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
30093                          (!(opp = opp_chan->tech_pvt)))) {
30094       return AST_RTP_GLUE_RESULT_FORBID;
30095    }
30096 
30097    sip_pvt_lock(p);
30098    while (opp && sip_pvt_trylock(opp)) {
30099       sip_pvt_unlock(p);
30100       usleep(1);
30101       sip_pvt_lock(p);
30102    }
30103 
30104    if (!(p->trtp)) {
30105       if (opp) {
30106          sip_pvt_unlock(opp);
30107       }
30108       sip_pvt_unlock(p);
30109       return AST_RTP_GLUE_RESULT_FORBID;
30110    }
30111 
30112    ao2_ref(p->trtp, +1);
30113    *instance = p->trtp;
30114 
30115    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
30116       res = AST_RTP_GLUE_RESULT_REMOTE;
30117       if (opp && !apply_directmedia_ha(p, opp, "text")) {
30118          res = AST_RTP_GLUE_RESULT_FORBID;
30119       }
30120    }
30121 
30122    if (opp) {
30123       sip_pvt_unlock(opp);
30124    }
30125    sip_pvt_unlock(p);
30126 
30127    return res;
30128 }

static struct ast_udptl * sip_get_udptl_peer ( struct ast_channel chan  )  [static, read]

Definition at line 29894 of file chan_sip.c.

References apply_directmedia_ha(), ast_bridged_channel(), ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.

29895 {
29896    struct sip_pvt *p;
29897    struct ast_channel *opp_chan;
29898    struct sip_pvt *opp;
29899    struct ast_udptl *udptl = NULL;
29900 
29901    p = chan->tech_pvt;
29902    if (!p) {
29903       return NULL;
29904    }
29905 
29906    if (!(opp_chan = ast_bridged_channel(chan))) {
29907       return NULL;
29908    } else if (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
29909          (!(opp = opp_chan->tech_pvt))) {
29910       return NULL;
29911    }
29912 
29913    sip_pvt_lock(p);
29914    while (sip_pvt_trylock(opp)) {
29915       sip_pvt_unlock(p);
29916       usleep(1);
29917       sip_pvt_lock(p);
29918    }
29919 
29920    if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
29921       if (apply_directmedia_ha(p, opp, "UDPTL T.38 data")) {
29922          udptl = p->udptl;
29923       }
29924    }
29925 
29926    sip_pvt_unlock(opp);
29927    sip_pvt_unlock(p);
29928    return udptl;
29929 }

static enum ast_rtp_glue_result sip_get_vrtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 30032 of file chan_sip.c.

References ao2_ref, apply_directmedia_ha(), ast_bridged_channel(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.

30033 {
30034    struct sip_pvt *p = NULL;
30035    struct ast_channel *opp_chan;
30036    struct sip_pvt *opp = NULL;
30037    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
30038 
30039    if (!(p = chan->tech_pvt)) {
30040       return AST_RTP_GLUE_RESULT_FORBID;
30041    }
30042 
30043    if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
30044                          (!(opp = opp_chan->tech_pvt)))) {
30045       return AST_RTP_GLUE_RESULT_FORBID;
30046    }
30047 
30048    sip_pvt_lock(p);
30049    while (opp && sip_pvt_trylock(opp)) {
30050       sip_pvt_unlock(p);
30051       usleep(1);
30052       sip_pvt_lock(p);
30053    }
30054 
30055    if (!(p->vrtp)) {
30056       if (opp) {
30057          sip_pvt_unlock(opp);
30058       }
30059       sip_pvt_unlock(p);
30060       return AST_RTP_GLUE_RESULT_FORBID;
30061    }
30062 
30063    ao2_ref(p->vrtp, +1);
30064    *instance = p->vrtp;
30065 
30066    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
30067       res = AST_RTP_GLUE_RESULT_REMOTE;
30068       if (opp && !apply_directmedia_ha(p, opp, "video")) {
30069          res = AST_RTP_GLUE_RESULT_FORBID;
30070       }
30071    }
30072 
30073    if (opp) {
30074       sip_pvt_unlock(opp);
30075    }
30076    sip_pvt_unlock(p);
30077 
30078    return res;
30079 }

static void sip_handle_cc ( struct sip_pvt *  pvt,
struct sip_request *  req,
enum ast_cc_service_type  service 
) [static]

Definition at line 2138 of file chan_sip.c.

References ao2_ref, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_module_ref(), ast_queue_cc_frame(), sip_get_cc_information(), and sip_monitor_instance_init().

Referenced by handle_response(), and handle_response_invite().

02139 {
02140    enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params);
02141    int core_id;
02142    char interface_name[AST_CHANNEL_NAME];
02143 
02144    if (monitor_policy == AST_CC_MONITOR_NEVER) {
02145       /* Don't bother, just return */
02146       return;
02147    }
02148 
02149    if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) {
02150       /* For some reason, CC is invalid, so don't try it! */
02151       return;
02152    }
02153 
02154    ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name));
02155 
02156    if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) {
02157       char subscribe_uri[SIPBUFSIZE];
02158       char device_name[AST_CHANNEL_NAME];
02159       enum ast_cc_service_type offered_service;
02160       struct sip_monitor_instance *monitor_instance;
02161       if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) {
02162          /* If CC isn't being offered to us, or for some reason the CC offer is
02163           * not formatted correctly, then it may still be possible to use generic
02164           * call completion since the monitor policy may be "always"
02165           */
02166          goto generic;
02167       }
02168       ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name));
02169       if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) {
02170          /* Same deal. We can try using generic still */
02171          goto generic;
02172       }
02173       /* We bump the refcount of chan_sip because once we queue this frame, the CC core
02174        * will have a reference to callbacks in this module. We decrement the module
02175        * refcount once the monitor destructor is called
02176        */
02177       ast_module_ref(ast_module_info->self);
02178       ast_queue_cc_frame(pvt->owner, "SIP", pvt->dialstring, offered_service, monitor_instance);
02179       ao2_ref(monitor_instance, -1);
02180       return;
02181    }
02182 
02183 generic:
02184    if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) {
02185       ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service, NULL);
02186    }
02187 }

static int sip_hangup ( struct ast_channel ast  )  [static]

sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup

Definition at line 6490 of file chan_sip.c.

References __sip_semi_ack(), ast_channel::_state, append_history, ast_bridged_channel(), ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, ast_debug, AST_FLAG_ANSWERED_ELSEWHERE, ast_log(), AST_MAX_USER_FIELD, ast_module_unref(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_state2str(), AST_STATE_UP, ast_str_buffer(), ast_str_strlen(), ast_test_flag, CHANNEL_DEADLOCK_AVOIDANCE, disable_dsp_detect(), FALSE, find_sip_method(), hangup_cause2sip(), ast_channel::hangupcause, LOG_WARNING, pbx_builtin_setvar_helper(), pvt_set_needdestroy(), quality, reinvite_timeout(), sip_cancel_destroy(), sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, and update_call_counter().

06491 {
06492    struct sip_pvt *p = ast->tech_pvt;
06493    int needcancel = FALSE;
06494    int needdestroy = 0;
06495    struct ast_channel *oldowner = ast;
06496 
06497    if (!p) {
06498       ast_debug(1, "Asked to hangup channel that was not connected\n");
06499       return 0;
06500    }
06501    if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE) || ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) {
06502       ast_debug(1, "This call was answered elsewhere\n");
06503       if (ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) {
06504          ast_debug(1, "####### It's the cause code, buddy. The cause code!!!\n");
06505       }
06506       append_history(p, "Cancel", "Call answered elsewhere");
06507       p->answered_elsewhere = TRUE;
06508    }
06509 
06510    /* Store hangupcause locally in PVT so we still have it before disconnect */
06511    if (p->owner)
06512       p->hangupcause = p->owner->hangupcause;
06513 
06514    if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
06515       if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
06516          if (sipdebug)
06517             ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
06518          update_call_counter(p, DEC_CALL_LIMIT);
06519       }
06520       ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
06521       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
06522       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
06523       p->needdestroy = 0;
06524       if (p->owner) {
06525          p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt");
06526          sip_pvt_lock(p);
06527          p->owner = NULL;  /* Owner will be gone after we return, so take it away */
06528          sip_pvt_unlock(p);
06529       }
06530       ast_module_unref(ast_module_info->self);
06531       return 0;
06532    }
06533 
06534    ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid);
06535 
06536    sip_pvt_lock(p);
06537    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
06538       if (sipdebug)
06539          ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
06540       update_call_counter(p, DEC_CALL_LIMIT);
06541    }
06542 
06543    /* Determine how to disconnect */
06544    if (p->owner != ast) {
06545       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
06546       sip_pvt_unlock(p);
06547       return 0;
06548    }
06549    /* If the call is not UP, we need to send CANCEL instead of BYE */
06550    /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */
06551    if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) {
06552       needcancel = TRUE;
06553       ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
06554    }
06555 
06556    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
06557 
06558    append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", ast_cause2str(p->hangupcause));
06559 
06560    /* Disconnect */
06561    disable_dsp_detect(p);
06562 
06563    p->owner = NULL;
06564    ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt");
06565 
06566    ast_module_unref(ast_module_info->self);
06567    /* Do not destroy this pvt until we have timeout or
06568       get an answer to the BYE or INVITE/CANCEL
06569       If we get no answer during retransmit period, drop the call anyway.
06570       (Sorry, mother-in-law, you can't deny a hangup by sending
06571       603 declined to BYE...)
06572    */
06573    if (p->alreadygone)
06574       needdestroy = 1;  /* Set destroy flag at end of this function */
06575    else if (p->invitestate != INV_CALLING)
06576       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
06577 
06578    /* Start the process if it's not already started */
06579    if (!p->alreadygone && p->initreq.data && ast_str_strlen(p->initreq.data)) {
06580       if (needcancel) { /* Outgoing call, not up */
06581          if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06582             /* if we can't send right now, mark it pending */
06583             if (p->invitestate == INV_CALLING) {
06584                /* We can't send anything in CALLING state */
06585                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
06586                /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */
06587                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
06588                append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
06589             } else {
06590                struct sip_pkt *cur;
06591 
06592                for (cur = p->packets; cur; cur = cur->next) {
06593                   __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(ast_str_buffer(cur->data)));
06594                }
06595                p->invitestate = INV_CANCELLED;
06596                /* Send a new request: CANCEL */
06597                transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
06598                /* Actually don't destroy us yet, wait for the 487 on our original
06599                   INVITE, but do set an autodestruct just in case we never get it. */
06600                needdestroy = 0;
06601                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
06602             }
06603          } else { /* Incoming call, not up */
06604             const char *res;
06605             AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
06606             if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause)))
06607                transmit_response_reliable(p, res, &p->initreq);
06608             else
06609                transmit_response_reliable(p, "603 Declined", &p->initreq);
06610             p->invitestate = INV_TERMINATED;
06611          }
06612       } else { /* Call is in UP state, send BYE */
06613          if (p->stimer->st_active == TRUE) {
06614             stop_session_timer(p);
06615          }
06616 
06617          if (!p->pendinginvite) {
06618             struct ast_channel *bridge = ast_bridged_channel(oldowner);
06619             char quality_buf[AST_MAX_USER_FIELD], *quality;
06620 
06621             /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt
06622              * to lock the bridge. This may get hairy...
06623              */
06624             while (bridge && ast_channel_trylock(bridge)) {
06625                sip_pvt_unlock(p);
06626                do {
06627                   CHANNEL_DEADLOCK_AVOIDANCE(oldowner);
06628                } while (sip_pvt_trylock(p));
06629                bridge = ast_bridged_channel(oldowner);
06630             }
06631 
06632             if (p->rtp) {
06633                ast_rtp_instance_set_stats_vars(oldowner, p->rtp);
06634             }
06635 
06636             if (bridge) {
06637                struct sip_pvt *q = bridge->tech_pvt;
06638 
06639                if (IS_SIP_TECH(bridge->tech) && q && q->rtp) {
06640                   ast_rtp_instance_set_stats_vars(bridge, q->rtp);
06641                }
06642                ast_channel_unlock(bridge);
06643             }
06644 
06645             /*
06646              * The channel variables are set below just to get the AMI
06647              * VarSet event because the channel is being hungup.
06648              */
06649             if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
06650                if (p->do_history) {
06651                   append_history(p, "RTCPaudio", "Quality:%s", quality);
06652                }
06653                pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", quality);
06654             }
06655             if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
06656                if (p->do_history) {
06657                   append_history(p, "RTCPvideo", "Quality:%s", quality);
06658                }
06659                pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", quality);
06660             }
06661             if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
06662                if (p->do_history) {
06663                   append_history(p, "RTCPtext", "Quality:%s", quality);
06664                }
06665                pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality);
06666             }
06667 
06668             /* Send a hangup */
06669             if (oldowner->_state == AST_STATE_UP) {
06670                transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
06671             }
06672 
06673          } else {
06674             /* Note we will need a BYE when this all settles out
06675                but we can't send one while we have "INVITE" outstanding. */
06676             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
06677             ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
06678             AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
06679             if (sip_cancel_destroy(p)) {
06680                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
06681             }
06682             /* If we have an ongoing reinvite, there is a chance that we have gotten a provisional
06683              * response, but something weird has happened and we will never receive a final response.
06684              * So, just in case, check for pending actions after a bit of time to trigger the pending
06685              * bye that we are setting above */
06686             if (p->ongoing_reinvite && p->reinviteid < 0) {
06687                p->reinviteid = ast_sched_add(sched, 32 * p->timer_t1, reinvite_timeout, dialog_ref(p, "ref for reinvite_timeout"));
06688             }
06689          }
06690       }
06691    }
06692    if (needdestroy) {
06693       pvt_set_needdestroy(p, "hangup");
06694    }
06695    sip_pvt_unlock(p);
06696    return 0;
06697 }

static int sip_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
) [static]

Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.

Returns:
-1 to force ast_indicate to send indication in audio, 0 if SIP can handle the indication by sending a message

Definition at line 7130 of file chan_sip.c.

References ast_channel::_state, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, initialize_udptl(), interpret_t38_parameters(), LOG_ERROR, LOG_WARNING, sip_alreadygone(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_info_with_aoc(), transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), TRUE, update_connectedline(), and update_redirecting().

07131 {
07132    struct sip_pvt *p = ast->tech_pvt;
07133    int res = 0;
07134 
07135    if (!p) {
07136       ast_debug(1, "Asked to indicate condition on channel %s with no pvt; ignoring\n",
07137             ast->name);
07138       return res;
07139    }
07140 
07141    sip_pvt_lock(p);
07142    switch(condition) {
07143    case AST_CONTROL_RINGING:
07144       if (ast->_state == AST_STATE_RING) {
07145          p->invitestate = INV_EARLY_MEDIA;
07146          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
07147              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
07148             /* Send 180 ringing if out-of-band seems reasonable */
07149             transmit_provisional_response(p, "180 Ringing", &p->initreq, 0);
07150             ast_set_flag(&p->flags[0], SIP_RINGING);
07151             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
07152                break;
07153          } else {
07154             /* Well, if it's not reasonable, just send in-band */
07155          }
07156       }
07157       res = -1;
07158       break;
07159    case AST_CONTROL_BUSY:
07160       if (ast->_state != AST_STATE_UP) {
07161          transmit_response_reliable(p, "486 Busy Here", &p->initreq);
07162          p->invitestate = INV_COMPLETED;
07163          sip_alreadygone(p);
07164          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
07165          break;
07166       }
07167       res = -1;
07168       break;
07169    case AST_CONTROL_CONGESTION:
07170       if (ast->_state != AST_STATE_UP) {
07171          transmit_response_reliable(p, "503 Service Unavailable", &p->initreq);
07172          p->invitestate = INV_COMPLETED;
07173          sip_alreadygone(p);
07174          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
07175          break;
07176       }
07177       res = -1;
07178       break;
07179    case AST_CONTROL_INCOMPLETE:
07180       if (ast->_state != AST_STATE_UP) {
07181          switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
07182          case SIP_PAGE2_ALLOWOVERLAP_YES:
07183             transmit_response_reliable(p, "484 Address Incomplete", &p->initreq);
07184             p->invitestate = INV_COMPLETED;
07185             sip_alreadygone(p);
07186             ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
07187             break;
07188          case SIP_PAGE2_ALLOWOVERLAP_DTMF:
07189             /* Just wait for inband DTMF digits */
07190             break;
07191          default:
07192             /* it actually means no support for overlap */
07193             transmit_response_reliable(p, "404 Not Found", &p->initreq);
07194             p->invitestate = INV_COMPLETED;
07195             sip_alreadygone(p);
07196             ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
07197             break;
07198          }
07199       }
07200       break;
07201    case AST_CONTROL_PROCEEDING:
07202       if ((ast->_state != AST_STATE_UP) &&
07203           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
07204           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
07205          transmit_response(p, "100 Trying", &p->initreq);
07206          p->invitestate = INV_PROCEEDING;
07207          break;
07208       }
07209       res = -1;
07210       break;
07211    case AST_CONTROL_PROGRESS:
07212       if ((ast->_state != AST_STATE_UP) &&
07213           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
07214           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
07215          p->invitestate = INV_EARLY_MEDIA;
07216          transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
07217          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
07218          break;
07219       }
07220       res = -1;
07221       break;
07222    case AST_CONTROL_HOLD:
07223       ast_rtp_instance_update_source(p->rtp);
07224       ast_moh_start(ast, data, p->mohinterpret);
07225       break;
07226    case AST_CONTROL_UNHOLD:
07227       ast_rtp_instance_update_source(p->rtp);
07228       ast_moh_stop(ast);
07229       break;
07230    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
07231       if (p->vrtp && !p->novideo) {
07232          transmit_info_with_vidupdate(p);
07233          /* ast_rtcp_send_h261fur(p->vrtp); */
07234       } else
07235          res = -1;
07236       break;
07237    case AST_CONTROL_T38_PARAMETERS:
07238       res = -1;
07239       if (datalen != sizeof(struct ast_control_t38_parameters)) {
07240          ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38_PARAMETERS. Expected %d, got %d\n", (int) sizeof(struct ast_control_t38_parameters), (int) datalen);
07241       } else {
07242          const struct ast_control_t38_parameters *parameters = data;
07243          if (!initialize_udptl(p)) {
07244             res = interpret_t38_parameters(p, parameters);
07245          }
07246       }
07247       break;
07248    case AST_CONTROL_SRCUPDATE:
07249       ast_rtp_instance_update_source(p->rtp);
07250       break;
07251    case AST_CONTROL_SRCCHANGE:
07252       ast_rtp_instance_change_source(p->rtp);
07253       break;
07254    case AST_CONTROL_CONNECTED_LINE:
07255       update_connectedline(p, data, datalen);
07256       break;
07257    case AST_CONTROL_REDIRECTING:
07258       update_redirecting(p, data, datalen);
07259       break;
07260    case AST_CONTROL_AOC:
07261       {
07262          struct ast_aoc_decoded *decoded = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, ast);
07263          if (!decoded) {
07264             ast_log(LOG_ERROR, "Error decoding indicated AOC data\n");
07265             res = -1;
07266             break;
07267          }
07268          switch (ast_aoc_get_msg_type(decoded)) {
07269          case AST_AOC_REQUEST:
07270             if (ast_aoc_get_termination_request(decoded)) {
07271                /* TODO, once there is a way to get AOC-E on hangup, attempt that here
07272                 * before hanging up the channel.*/
07273 
07274                /* The other side has already initiated the hangup. This frame
07275                 * just says they are waiting to get AOC-E before completely tearing
07276                 * the call down.  Since SIP does not support this at the moment go
07277                 * ahead and terminate the call here to avoid an unnecessary timeout. */
07278                ast_debug(1, "AOC-E termination request received on %s. This is not yet supported on sip. Continue with hangup \n", p->owner->name);
07279                ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
07280             }
07281             break;
07282          case AST_AOC_D:
07283          case AST_AOC_E:
07284             if (ast_test_flag(&p->flags[2], SIP_PAGE3_SNOM_AOC)) {
07285                transmit_info_with_aoc(p, decoded);
07286             }
07287             break;
07288          case AST_AOC_S: /* S not supported yet */
07289          default:
07290             break;
07291          }
07292          ast_aoc_destroy_decoded(decoded);
07293       }
07294       break;
07295    case AST_CONTROL_UPDATE_RTP_PEER: /* Absorb this since it is handled by the bridge */
07296       break;
07297    case AST_CONTROL_FLASH: /* We don't currently handle AST_CONTROL_FLASH here, but it is expected, so we don't need to warn either. */
07298       res = -1;
07299       break;
07300    case -1:
07301       res = -1;
07302       break;
07303    default:
07304       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
07305       res = -1;
07306       break;
07307    }
07308    sip_pvt_unlock(p);
07309    return res;
07310 }

static int sip_is_xml_parsable ( void   )  [static]

Definition at line 30468 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by load_module().

30469 {
30470 #ifdef HAVE_LIBXML2
30471    return TRUE;
30472 #else
30473    return FALSE;
30474 #endif
30475 }

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

Definition at line 1844 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

01845 {
01846    struct sip_monitor_instance *monitor_instance1 = obj;
01847    struct sip_monitor_instance *monitor_instance2 = arg;
01848 
01849    return monitor_instance1->core_id == monitor_instance2->core_id ? CMP_MATCH | CMP_STOP : 0;
01850 }

static void sip_monitor_instance_destructor ( void *  data  )  [static]

Definition at line 1852 of file chan_sip.c.

References ao2_t_ref, ast_string_field_free_memory, FALSE, sip_pvt_lock, sip_pvt_unlock, transmit_invite(), and transmit_publish().

Referenced by sip_monitor_instance_init().

01853 {
01854    struct sip_monitor_instance *monitor_instance = data;
01855    if (monitor_instance->subscription_pvt) {
01856       sip_pvt_lock(monitor_instance->subscription_pvt);
01857       monitor_instance->subscription_pvt->expiry = 0;
01858       transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 0, monitor_instance->subscribe_uri);
01859       sip_pvt_unlock(monitor_instance->subscription_pvt);
01860       dialog_unref(monitor_instance->subscription_pvt, "Unref monitor instance ref of subscription pvt");
01861    }
01862    if (monitor_instance->suspension_entry) {
01863       monitor_instance->suspension_entry->body[0] = '\0';
01864       transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri);
01865       ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor");
01866    }
01867    ast_string_field_free_memory(monitor_instance);
01868 }

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

Definition at line 1838 of file chan_sip.c.

Referenced by load_module().

01839 {
01840    const struct sip_monitor_instance *monitor_instance = obj;
01841    return monitor_instance->core_id;
01842 }

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, read]

Definition at line 1870 of file chan_sip.c.

References ao2_alloc, ao2_link, ao2_ref, ast_string_field_init, ast_string_field_set, and sip_monitor_instance_destructor().

Referenced by sip_handle_cc().

01871 {
01872    struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor);
01873 
01874    if (!monitor_instance) {
01875       return NULL;
01876    }
01877 
01878    if (ast_string_field_init(monitor_instance, 256)) {
01879       ao2_ref(monitor_instance, -1);
01880       return NULL;
01881    }
01882 
01883    ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri);
01884    ast_string_field_set(monitor_instance, peername, peername);
01885    ast_string_field_set(monitor_instance, device_name, device_name);
01886    monitor_instance->core_id = core_id;
01887    ao2_link(sip_monitor_instances, monitor_instance);
01888    return monitor_instance;
01889 }

static const char * sip_nat_mode ( const struct sip_pvt *  p  )  [static]

Display SIP nat mode.

Definition at line 3396 of file chan_sip.c.

References ast_test_flag.

Referenced by check_via(), retrans_pkt(), and send_response().

03397 {
03398    return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT";
03399 }

static struct ast_channel* sip_new ( struct sip_pvt *  i,
int  state,
const char *  title,
const char *  linkedid 
) [static, read]

Initiate a call in the SIP channel.

Note:
called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels
Precondition:
i is locked
Returns:
New ast_channel locked.

Definition at line 7323 of file chan_sip.c.

References accountcode, ast_channel::adsicpe, ast_channel::amaflags, ast_party_caller::ani, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), ast_channel_alloc, ast_channel_cc_params_init(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_codec_choose(), ast_copy_string(), ast_debug, ast_exists_extension(), AST_FLAG_DISABLE_DEVSTATE_CACHE, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_get_encoded_str(), ast_getformatname_multiple(), ast_jb_configure(), ast_log(), ast_module_ref(), AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_fd(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_channel::caller, ast_channel::callgroup, ast_channel::context, ast_channel::dialed, enable_dsp_detect(), EVENT_FLAG_SYSTEM, ast_channel::exten, exten, ast_channel::flags, ast_party_redirecting::from, global_jbconf, ast_party_caller::id, language, LOG_WARNING, manager_event, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, parkinglot, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, ast_party_number::presentation, ast_party_name::presentation, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::redirecting, ast_channel::rings, sip_cfg, sip_pvt_lock, sip_pvt_unlock, sip_tech_info, ast_party_dialed::str, ast_party_number::str, ast_party_id::tag, ast_channel::tech, ast_channel::tech_pvt, text, ast_party_number::valid, ast_variable::value, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

07324 {
07325    struct ast_channel *tmp;
07326    struct ast_variable *v = NULL;
07327    format_t fmt;
07328    format_t what;
07329    format_t video;
07330    format_t text;
07331    format_t needvideo = 0;
07332    int needtext = 0;
07333    char buf[SIPBUFSIZE];
07334    char *exten;
07335 
07336    {
07337       const char *my_name; /* pick a good name */
07338    
07339       if (title) {
07340          my_name = title;
07341       } else {
07342          my_name = ast_strdupa(i->fromdomain);
07343       }
07344 
07345       sip_pvt_unlock(i);
07346       /* Don't hold a sip pvt lock while we allocate a channel */
07347       tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "SIP/%s-%08x", my_name, (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
07348    }
07349    if (!tmp) {
07350       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
07351       sip_pvt_lock(i);
07352       return NULL;
07353    }
07354    ast_channel_lock(tmp);
07355    sip_pvt_lock(i);
07356    ast_channel_cc_params_init(tmp, i->cc_params);
07357    tmp->caller.id.tag = ast_strdup(i->cid_tag);
07358 
07359    tmp->tech = ( ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO || ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO) ?  &sip_tech_info : &sip_tech;
07360 
07361    /* Select our native format based on codec preference until we receive
07362       something from another device to the contrary. */
07363    if (i->jointcapability) {  /* The joint capabilities of us and peer */
07364       what = i->jointcapability;
07365       video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
07366       text = i->jointcapability & AST_FORMAT_TEXT_MASK;
07367    } else if (i->capability) {      /* Our configured capability for this peer */
07368       what = i->capability;
07369       video = i->capability & AST_FORMAT_VIDEO_MASK;
07370       text = i->capability & AST_FORMAT_TEXT_MASK;
07371    } else {
07372       what = sip_cfg.capability; /* Global codec support */
07373       video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK;
07374       text = sip_cfg.capability & AST_FORMAT_TEXT_MASK;
07375    }
07376 
07377    /* Set the native formats for audio  and merge in video */
07378    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text;
07379    ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
07380    ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
07381    ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
07382    ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
07383    if (i->prefcodec)
07384       ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
07385 
07386    /* XXX Why are we choosing a codec from the native formats?? */
07387    fmt = ast_best_codec(tmp->nativeformats);
07388 
07389    /* If we have a prefcodec setting, we have an inbound channel that set a
07390       preferred format for this call. Otherwise, we check the jointcapability
07391       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
07392     */
07393    if (i->vrtp) {
07394       if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT))
07395          needvideo = AST_FORMAT_VIDEO_MASK;
07396       else if (i->prefcodec)
07397          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
07398       else
07399          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
07400    }
07401 
07402    if (i->trtp) {
07403       if (i->prefcodec)
07404          needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */
07405       else
07406          needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */
07407    }
07408 
07409    if (needvideo)
07410       ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n");
07411    else
07412       ast_debug(3, "This channel will not be able to handle video.\n");
07413 
07414    enable_dsp_detect(i);
07415 
07416    if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
07417        (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
07418       if (i->rtp) {
07419          ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND);
07420       }
07421    } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) {
07422       if (i->rtp) {
07423          ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_RFC2833);
07424       }
07425    }
07426 
07427    /* Set file descriptors for audio, video, and realtime text.  Since
07428     * UDPTL is created as needed in the lifetime of a dialog, its file
07429     * descriptor is set in initialize_udptl */
07430    if (i->rtp) {
07431       ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
07432       ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1));
07433       ast_rtp_instance_set_write_format(i->rtp, fmt);
07434       ast_rtp_instance_set_read_format(i->rtp, fmt);
07435    }
07436    if (needvideo && i->vrtp) {
07437       ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0));
07438       ast_channel_set_fd(tmp, 3, ast_rtp_instance_fd(i->vrtp, 1));
07439    }
07440    if (needtext && i->trtp) {
07441       ast_channel_set_fd(tmp, 4, ast_rtp_instance_fd(i->trtp, 0));
07442    }
07443    if (i->udptl) {
07444       ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl));
07445    }
07446 
07447    if (state == AST_STATE_RING)
07448       tmp->rings = 1;
07449    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
07450 
07451    tmp->writeformat = fmt;
07452    tmp->rawwriteformat = fmt;
07453 
07454    tmp->readformat = fmt;
07455    tmp->rawreadformat = fmt;
07456 
07457    tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i");
07458 
07459    tmp->callgroup = i->callgroup;
07460    tmp->pickupgroup = i->pickupgroup;
07461    tmp->caller.id.name.presentation = i->callingpres;
07462    tmp->caller.id.number.presentation = i->callingpres;
07463    if (!ast_strlen_zero(i->parkinglot))
07464       ast_string_field_set(tmp, parkinglot, i->parkinglot);
07465    if (!ast_strlen_zero(i->accountcode))
07466       ast_string_field_set(tmp, accountcode, i->accountcode);
07467    if (i->amaflags)
07468       tmp->amaflags = i->amaflags;
07469    if (!ast_strlen_zero(i->language))
07470       ast_string_field_set(tmp, language, i->language);
07471    i->owner = tmp;
07472    ast_module_ref(ast_module_info->self);
07473    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
07474    /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
07475     * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
07476     * structure so that there aren't issues when forming URI's
07477     */
07478    exten = ast_strdupa(i->exten);
07479    sip_pvt_unlock(i);
07480    ast_channel_unlock(tmp);
07481    if (!ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) {
07482       ast_uri_decode(exten);
07483    }
07484    ast_channel_lock(tmp);
07485    sip_pvt_lock(i);
07486    ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
07487 
07488    /* Don't use ast_set_callerid() here because it will
07489     * generate an unnecessary NewCallerID event  */
07490    if (!ast_strlen_zero(i->cid_num)) {
07491       tmp->caller.ani.number.valid = 1;
07492       tmp->caller.ani.number.str = ast_strdup(i->cid_num);
07493    }
07494    if (!ast_strlen_zero(i->rdnis)) {
07495       tmp->redirecting.from.number.valid = 1;
07496       tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
07497    }
07498 
07499    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) {
07500       tmp->dialed.number.str = ast_strdup(i->exten);
07501    }
07502 
07503    tmp->priority = 1;
07504    if (!ast_strlen_zero(i->uri))
07505       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
07506    if (!ast_strlen_zero(i->domain))
07507       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
07508    if (!ast_strlen_zero(i->callid))
07509       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
07510    if (i->rtp)
07511       ast_jb_configure(tmp, &global_jbconf);
07512 
07513    if (!i->relatedpeer) {
07514       tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
07515    }
07516    /* Set channel variables for this call from configuration */
07517    for (v = i->chanvars ; v ; v = v->next) {
07518       char valuebuf[1024];
07519       pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf)));
07520    }
07521 
07522    if (i->do_history)
07523       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
07524 
07525    /* Inform manager user about new channel and their SIP call ID */
07526    if (sip_cfg.callevents)
07527       manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
07528          "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n",
07529          tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact);
07530 
07531    return tmp;
07532 }

static int sip_notify_allocate ( struct sip_pvt *  p  )  [static]

Allocate SIP refer structure.

Definition at line 13961 of file chan_sip.c.

References ast_calloc, and ast_str_create().

Referenced by manager_sipnotify(), and sip_cli_notify().

13962 {
13963    p->notify = ast_calloc(1, sizeof(struct sip_notify));
13964    if (p->notify) {
13965       p->notify->content = ast_str_create(128);
13966    }
13967    return p->notify ? 1 : 0;
13968 }

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

Definition at line 1720 of file chan_sip.c.

References ast_cc_failed(), ast_cc_agent::core_id, ast_cc_agent::device_name, and ast_cc_agent::private_data.

Referenced by sip_cc_agent_start_offer_timer().

01721 {
01722    struct ast_cc_agent *agent = (struct ast_cc_agent *) data;
01723    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01724 
01725    agent_pvt->offer_timer_id = -1;
01726 
01727    return ast_cc_failed(agent->core_id, "SIP agent %s's offer timer expired", agent->device_name);
01728 }

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]

DO NOT hold any locks while calling sip_park

Definition at line 22215 of file chan_sip.c.

References ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_channel::context, copy_request(), deinit_req(), ast_channel::exten, parkinglot, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.

Referenced by handle_request_refer().

22216 {
22217    struct sip_dual *d;
22218    struct ast_channel *transferee, *transferer;
22219    pthread_t th;
22220 
22221    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
22222    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name);
22223    d = ast_calloc(1, sizeof(*d));
22224    if (!transferee || !transferer || !d) {
22225       if (transferee) {
22226          ast_hangup(transferee);
22227       }
22228       if (transferer) {
22229          ast_hangup(transferer);
22230       }
22231       ast_free(d);
22232       return -1;
22233    }
22234    d->park_exten = ast_strdup(park_exten);
22235    d->park_context = ast_strdup(park_context);
22236    if (!d->park_exten || !d->park_context) {
22237       ast_hangup(transferee);
22238       ast_hangup(transferer);
22239       ast_free(d->park_exten);
22240       ast_free(d->park_context);
22241       ast_free(d);
22242       return -1;
22243    }
22244 
22245    /* Make formats okay */
22246    transferee->readformat = chan1->readformat;
22247    transferee->writeformat = chan1->writeformat;
22248 
22249    /* Prepare for taking over the channel */
22250    if (ast_channel_masquerade(transferee, chan1)) {
22251       ast_hangup(transferee);
22252       ast_hangup(transferer);
22253       ast_free(d->park_exten);
22254       ast_free(d->park_context);
22255       ast_free(d);
22256       return -1;
22257    }
22258 
22259    /* Setup the extensions and such */
22260    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
22261    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
22262    transferee->priority = chan1->priority;
22263 
22264    ast_do_masquerade(transferee);
22265 
22266    /* We make a clone of the peer channel too, so we can play
22267       back the announcement */
22268 
22269    /* Make formats okay */
22270    transferer->readformat = chan2->readformat;
22271    transferer->writeformat = chan2->writeformat;
22272    ast_string_field_set(transferer, parkinglot, chan2->parkinglot);
22273 
22274    /* Prepare for taking over the channel */
22275    if (ast_channel_masquerade(transferer, chan2)) {
22276       ast_hangup(transferee);
22277       ast_hangup(transferer);
22278       ast_free(d->park_exten);
22279       ast_free(d->park_context);
22280       ast_free(d);
22281       return -1;
22282    }
22283 
22284    /* Setup the extensions and such */
22285    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
22286    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
22287    transferer->priority = chan2->priority;
22288 
22289    ast_do_masquerade(transferer);
22290 
22291    /* Save original request for followup */
22292    copy_request(&d->req, req);
22293    d->chan1 = transferee;  /* Transferee */
22294    d->chan2 = transferer;  /* Transferer */
22295    d->seqno = seqno;
22296    if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) {
22297       /* Could not start thread */
22298       ast_hangup(transferer);
22299       ast_hangup(transferee);
22300       deinit_req(&d->req);
22301       ast_free(d->park_exten);
22302       ast_free(d->park_context);
22303       ast_free(d);   /* We don't need it anymore. If thread is created, d will be free'd
22304                by sip_park_thread() */
22305       return -1;
22306    }
22307    return 0;
22308 }

static void * sip_park_thread ( void *  stuff  )  [static]

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.

Definition at line 22164 of file chan_sip.c.

References append_history, AST_CAUSE_NORMAL_CLEARING, ast_debug, ast_free, ast_hangup(), ast_log(), AST_LOG_NOTICE, ast_park_call_exten(), ast_set_flag, deinit_req(), ext, ast_channel::hangupcause, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), and TRUE.

Referenced by sip_park().

22165 {
22166    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
22167    struct sip_pvt *transferer_pvt;
22168    struct sip_dual *d;
22169    int ext;
22170    int res;
22171 
22172    d = stuff;
22173    transferee = d->chan1;
22174    transferer = d->chan2;
22175    transferer_pvt = transferer->tech_pvt;
22176 
22177    ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
22178 
22179    res = ast_park_call_exten(transferee, transferer, d->park_exten, d->park_context, 0, &ext);
22180 
22181 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
22182    if (res) {
22183       transmit_message_with_text(transferer_pvt, "Unable to park call.\n");
22184    } else {
22185       /* Then tell the transferer what happened */
22186       sprintf(buf, "Call parked on extension '%d'", ext);
22187       transmit_message_with_text(transferer_pvt, buf);
22188    }
22189 #endif
22190 
22191    /* Any way back to the current call??? */
22192    /* Transmit response to the REFER request */
22193    ast_set_flag(&transferer_pvt->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  
22194    if (!res)   {
22195       /* Transfer succeeded */
22196       append_history(transferer_pvt, "SIPpark", "Parked call on %d", ext);
22197       transmit_notify_with_sipfrag(transferer_pvt, d->seqno, "200 OK", TRUE);
22198       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
22199       ast_debug(1, "SIP Call parked on extension '%d'\n", ext);
22200    } else {
22201       transmit_notify_with_sipfrag(transferer_pvt, d->seqno, "503 Service Unavailable", TRUE);
22202       append_history(transferer_pvt, "SIPpark", "Parking failed\n");
22203       ast_log(AST_LOG_NOTICE, "SIP Call parked failed for %s\n", transferee->name);
22204       ast_hangup(transferee);
22205    }
22206    ast_hangup(transferer);
22207    deinit_req(&d->req);
22208    ast_free(d->park_exten);
22209    ast_free(d->park_context);
22210    ast_free(d);
22211    return NULL;
22212 }

static void sip_peer_hold ( struct sip_pvt *  p,
int  hold 
) [static]

Change onhold state of a peer using a pvt structure.

Definition at line 15032 of file chan_sip.c.

References ast_atomic_fetchadd_int(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_DEVSTATE_NOT_CACHABLE, and AST_FLAG_DISABLE_DEVSTATE_CACHE.

Referenced by change_hold_state(), and update_call_counter().

15033 {
15034    if (!p->relatedpeer) {
15035       return;
15036    }
15037 
15038    /* If they put someone on hold, increment the value... otherwise decrement it */
15039    ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1));
15040 
15041    /* Request device state update */
15042    ast_devstate_changed(AST_DEVICE_UNKNOWN, (p->owner->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE),
15043               "SIP/%s", p->relatedpeer->name);
15044 
15045    return;
15046 }

static int sip_pickup ( struct ast_channel chan  )  [static]

Pickup a call using the subsystem in features.c This is executed in a separate thread.

Definition at line 22333 of file chan_sip.c.

References ast_channel_ref, ast_channel_unref, ast_debug, ast_pthread_create_detached_background, and sip_pickup_thread().

Referenced by handle_request_invite().

22334 {
22335    pthread_t threadid;
22336 
22337    ast_channel_ref(chan);
22338 
22339    if (ast_pthread_create_detached_background(&threadid, NULL, sip_pickup_thread, chan)) {
22340       ast_debug(1, "Unable to start Group pickup thread on channel %s\n", chan->name);
22341       ast_channel_unref(chan);
22342       return -1;
22343    }
22344    ast_debug(1, "Started Group pickup thread on channel %s\n", chan->name);
22345    return 0;
22346 }

static void * sip_pickup_thread ( void *  stuff  )  [static]

SIP pickup support function Starts in a new thread, then pickup the call.

Definition at line 22314 of file chan_sip.c.

References AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_unref, ast_hangup(), ast_pickup_call(), and ast_channel::hangupcause.

Referenced by sip_pickup().

22315 {
22316    struct ast_channel *chan;
22317    chan = stuff;
22318 
22319    if (ast_pickup_call(chan)) {
22320       chan->hangupcause = AST_CAUSE_CALL_REJECTED;
22321    } else {
22322       chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
22323    }
22324    ast_hangup(chan);
22325    ast_channel_unref(chan);
22326    chan = NULL;
22327    return NULL;
22328 }

static void sip_poke_all_peers ( void   )  [static]

Send a poke to all known peers.

Definition at line 30478 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, AST_SCHED_REPLACE_UNREF, ref_peer(), sip_poke_peer_s(), and unref_peer().

Referenced by load_module(), and sip_do_reload().

30479 {
30480    int ms = 0, num = 0;
30481    struct ao2_iterator i;
30482    struct sip_peer *peer;
30483 
30484    if (!speerobjs) { /* No peers, just give up */
30485       return;
30486    }
30487 
30488    i = ao2_iterator_init(peers, 0);
30489    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
30490       ao2_lock(peer);
30491       /* Don't schedule poking on a peer without qualify */
30492       if (peer->maxms) {
30493          if (num == global_qualify_peers) {
30494             ms += global_qualify_gap;
30495             num = 0;
30496          } else {
30497             num++;
30498          }
30499          AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer,
30500                unref_peer(_data, "removing poke peer ref"),
30501                unref_peer(peer, "removing poke peer ref"),
30502                ref_peer(peer, "adding poke peer ref"));
30503       }
30504       ao2_unlock(peer);
30505       unref_peer(peer, "toss iterator peer ptr");
30506    }
30507    ao2_iterator_destroy(&i);
30508 }

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

React to lack of answer to Qualify poke.

Definition at line 27065 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_update_realtime(), DEFAULT_FREQ_NOTOK, dialog_unlink_all(), EVENT_FLAG_SYSTEM, FALSE, LOG_NOTICE, manager_event, ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), and unref_peer().

Referenced by sip_poke_peer(), and sip_show_sched().

27066 {
27067    struct sip_peer *peer = (struct sip_peer *)data;
27068 
27069    peer->pokeexpire = -1;
27070 
27071    if (peer->lastms > -1) {
27072       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
27073       if (sip_cfg.peer_rtupdate) {
27074          ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL);
27075       }
27076       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
27077       if (sip_cfg.regextenonqualify) {
27078          register_peer_exten(peer, FALSE);
27079       }
27080    }
27081 
27082    if (peer->call) {
27083       dialog_unlink_all(peer->call);
27084       peer->call = dialog_unref(peer->call, "unref dialog peer->call");
27085       /* peer->call = sip_destroy(peer->call);*/
27086    }
27087 
27088    /* Don't send a devstate change if nothing changed. */
27089    if (peer->lastms > -1) {
27090       peer->lastms = -1;
27091       ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
27092    }
27093 
27094    /* Try again quickly */
27095    AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
27096          DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer,
27097          unref_peer(_data, "removing poke peer ref"),
27098          unref_peer(peer, "removing poke peer ref"),
27099          ref_peer(peer, "adding poke peer ref"));
27100 
27101    /* Release the ref held by the running scheduler entry */
27102    unref_peer(peer, "release peer poke noanswer ref");
27103 
27104    return 0;
27105 }

static int sip_poke_peer ( struct sip_peer *  peer,
int  force 
) [static]

Check availability of peer, also keep NAT open.

Note:
This is done with 60 seconds between each ping, unless forced by cli or manager. If peer is unreachable, we check every 10th second by default.
Do *not* hold a pvt lock while calling this function. This function calls sip_alloc, which can cause a deadlock if another sip_pvt is held.

Definition at line 27115 of file chan_sip.c.

References ast_copy_flags, ast_copy_string(), ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_sockaddr_stringify_host_remote(), ast_string_field_set, ast_strlen_zero(), ast_tvnow(), build_via(), change_callid_pvt(), copy_socket_data(), dialog_unlink_all(), LOG_NOTICE, obproxy_get(), ref_peer(), ref_proxy(), sip_alloc(), sip_poke_noanswer(), transmit_invite(), and unref_peer().

Referenced by _sip_qualify_peer(), build_peer(), parse_register_contact(), and sip_poke_peer_s().

27116 {
27117    struct sip_pvt *p;
27118    int xmitres = 0;
27119    
27120    if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) {
27121       /* IF we have no IP, or this isn't to be monitored, return
27122         immediately after clearing things out */
27123       AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
27124             unref_peer(peer, "removing poke peer ref"));
27125       
27126       peer->lastms = 0;
27127       if (peer->call) {
27128          peer->call = dialog_unref(peer->call, "unref dialog peer->call");
27129       }
27130       return 0;
27131    }
27132    if (peer->call) {
27133       if (sipdebug) {
27134          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
27135       }
27136       dialog_unlink_all(peer->call);
27137       peer->call = dialog_unref(peer->call, "unref dialog peer->call");
27138       /* peer->call = sip_destroy(peer->call); */
27139    }
27140    if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) {
27141       return -1;
27142    }
27143    peer->call = dialog_ref(p, "copy sip alloc from p to peer->call");
27144 
27145    p->sa = peer->addr;
27146    p->recv = peer->addr;
27147    copy_socket_data(&p->socket, &peer->socket);
27148    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
27149    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
27150    ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
27151 
27152    /* Get the outbound proxy information */
27153    ref_proxy(p, obproxy_get(p, peer));
27154 
27155    /* Send OPTIONs to peer's fullcontact */
27156    if (!ast_strlen_zero(peer->fullcontact)) {
27157       ast_string_field_set(p, fullcontact, peer->fullcontact);
27158    }
27159 
27160    if (!ast_strlen_zero(peer->fromuser)) {
27161       ast_string_field_set(p, fromuser, peer->fromuser);
27162    }
27163 
27164    if (!ast_strlen_zero(peer->tohost)) {
27165       ast_string_field_set(p, tohost, peer->tohost);
27166    } else {
27167       ast_string_field_set(p, tohost, ast_sockaddr_stringify_host_remote(&peer->addr));
27168    }
27169 
27170    /* Recalculate our side, and recalculate Call ID */
27171    ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
27172    build_via(p);
27173 
27174    /* Change the dialog callid. */
27175    change_callid_pvt(p, NULL);
27176 
27177    AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
27178          unref_peer(peer, "removing poke peer ref"));
27179    
27180    if (p->relatedpeer)
27181       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
27182    p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog");
27183    ast_set_flag(&p->flags[0], SIP_OUTGOING);
27184 #ifdef VOCAL_DATA_HACK
27185    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
27186    xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */
27187 #else
27188    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */
27189 #endif
27190    peer->ps = ast_tvnow();
27191    if (xmitres == XMIT_ERROR) {
27192       /* Immediately unreachable, network problems */
27193       sip_poke_noanswer(ref_peer(peer, "add ref for peerexpire (fake, for sip_poke_noanswer to remove)"));
27194    } else if (!force) {
27195       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer,
27196             unref_peer(_data, "removing poke peer ref"),
27197             unref_peer(peer, "removing poke peer ref"),
27198             ref_peer(peer, "adding poke peer ref"));
27199    }
27200    dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope");
27201    return 0;
27202 }

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

Poke peer (send qualify to check if peer is alive and well).

Definition at line 14267 of file chan_sip.c.

References ao2_find, OBJ_POINTER, sip_poke_peer(), and unref_peer().

Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), and sip_show_sched().

14268 {
14269    struct sip_peer *peer = (struct sip_peer *)data;
14270    struct sip_peer *foundpeer;
14271 
14272    peer->pokeexpire = -1;
14273 
14274    foundpeer = ao2_find(peers, peer, OBJ_POINTER);
14275    if (!foundpeer) {
14276       unref_peer(peer, "removing poke peer ref");
14277       return 0;
14278    } else if (foundpeer->name != peer->name) {
14279       unref_peer(foundpeer, "removing above peer ref");
14280       unref_peer(peer, "removing poke peer ref");
14281       return 0;
14282    }
14283 
14284    unref_peer(foundpeer, "removing above peer ref");
14285    sip_poke_peer(peer, 0);
14286    unref_peer(peer, "removing poke peer ref");
14287 
14288    return 0;
14289 }

static int sip_prepare_socket ( struct sip_pvt *  p  )  [static]
Todo:
Get socket for dialog, prepare if needed, and return file handle

Todo:
Check this... This might be wrong, depending on the proxy configuration If proxy is in "force" mode its correct.

Definition at line 26308 of file chan_sip.c.

References ast_tcptls_session_args::accept_fd, ao2_alloc, ao2_ref, ao2_t_ref, ao2_t_unlink, ast_calloc, ast_copy_string(), ast_debug, ast_pthread_create_detached_background, ast_sockaddr_copy(), ast_strdup, ast_strlen_zero(), ast_tcptls_client_create(), ast_tcptls_close_session_file(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tcptls_session_instance::fd, ast_tcptls_session_args::hostname, ast_tcptls_session_args::name, name, ast_tls_config::pvtfile, ast_tcptls_session_args::remote_address, sip_real_dst(), sip_tcp_locate(), sip_tcp_worker_fn(), sip_tcptls_client_args_destructor(), sip_threadinfo_create(), and ast_tcptls_session_args::tls_cfg.

Referenced by __sip_xmit().

26309 {
26310    struct sip_socket *s = &p->socket;
26311    static const char name[] = "SIP socket";
26312    struct sip_threadinfo *th = NULL;
26313    struct ast_tcptls_session_instance *tcptls_session;
26314    struct ast_tcptls_session_args *ca;
26315    struct ast_sockaddr sa_tmp;
26316    pthread_t launched;
26317 
26318    /* check to see if a socket is already active */
26319    if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) {
26320       return s->fd;
26321    }
26322    if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) &&
26323          (s->tcptls_session) &&
26324          (s->tcptls_session->fd != -1)) {
26325       return s->tcptls_session->fd;
26326    }
26327 
26328    /*! \todo Check this... This might be wrong, depending on the proxy configuration
26329       If proxy is in "force" mode its correct.
26330     */
26331    if (p->outboundproxy && p->outboundproxy->transport) {
26332       s->type = p->outboundproxy->transport;
26333    }
26334 
26335    if (s->type == SIP_TRANSPORT_UDP) {
26336       s->fd = sipsock;
26337       return s->fd;
26338    }
26339 
26340    /* At this point we are dealing with a TCP/TLS connection
26341     * 1. We need to check to see if a connection thread exists
26342     *    for this address, if so use that.
26343     * 2. If a thread does not exist for this address, but the tcptls_session
26344     *    exists on the socket, the connection was closed.
26345     * 3. If no tcptls_session thread exists for the address, and no tcptls_session
26346     *    already exists on the socket, create a new one and launch a new thread.
26347     */
26348 
26349    /* 1.  check for existing threads */
26350    ast_sockaddr_copy(&sa_tmp, sip_real_dst(p));
26351    if ((tcptls_session = sip_tcp_locate(&sa_tmp))) {
26352       s->fd = tcptls_session->fd;
26353       if (s->tcptls_session) {
26354          ao2_ref(s->tcptls_session, -1);
26355          s->tcptls_session = NULL;
26356       }
26357       s->tcptls_session = tcptls_session;
26358       return s->fd;
26359    /* 2.  Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */
26360    } else if (s->tcptls_session) {
26361       return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */
26362    }
26363 
26364    /* 3.  Create a new TCP/TLS client connection */
26365    /* create new session arguments for the client connection */
26366    if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) ||
26367       !(ca->name = ast_strdup(name))) {
26368       goto create_tcptls_session_fail;
26369    }
26370    ca->accept_fd = -1;
26371    ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p));
26372    /* if type is TLS, we need to create a tls cfg for this session arg */
26373    if (s->type == SIP_TRANSPORT_TLS) {
26374       if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) {
26375          goto create_tcptls_session_fail;
26376       }
26377       memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg));
26378 
26379       if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) ||
26380          !(ca->tls_cfg->pvtfile = ast_strdup(default_tls_cfg.pvtfile)) ||
26381          !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) ||
26382          !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) ||
26383          !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) {
26384 
26385          goto create_tcptls_session_fail;
26386       }
26387 
26388       /* this host is used as the common name in ssl/tls */
26389       if (!ast_strlen_zero(p->tohost)) {
26390          ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname));
26391       }
26392    }
26393 
26394    /* Create a client connection for address, this does not start the connection, just sets it up. */
26395    if (!(s->tcptls_session = ast_tcptls_client_create(ca))) {
26396       goto create_tcptls_session_fail;
26397    }
26398 
26399    s->fd = s->tcptls_session->fd;
26400 
26401    /* client connections need to have the sip_threadinfo object created before
26402     * the thread is detached.  This ensures the alert_pipe is up before it will
26403     * be used.  Note that this function links the new threadinfo object into the
26404     * threadt container. */
26405    if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) {
26406       goto create_tcptls_session_fail;
26407    }
26408 
26409    /* Give the new thread a reference to the tcptls_session */
26410    ao2_ref(s->tcptls_session, +1);
26411 
26412    if (ast_pthread_create_detached_background(&launched, NULL, sip_tcp_worker_fn, s->tcptls_session)) {
26413       ast_debug(1, "Unable to launch '%s'.", ca->name);
26414       ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */
26415       goto create_tcptls_session_fail;
26416    }
26417 
26418    return s->fd;
26419 
26420 create_tcptls_session_fail:
26421    if (ca) {
26422       ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments");
26423    }
26424    if (s->tcptls_session) {
26425       ast_tcptls_close_session_file(s->tcptls_session);
26426       s->fd = -1;
26427       ao2_ref(s->tcptls_session, -1);
26428       s->tcptls_session = NULL;
26429    }
26430    if (th) {
26431       ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open");
26432    }
26433 
26434    return -1;
26435 }

static char * sip_prune_realtime ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Remove temporary realtime objects from memory (CLI).

Todo:
XXXX Propably needs an overhaul after removal of the devices

Definition at line 17733 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_find, ao2_t_iterator_next, ao2_t_link, ao2_t_unlink, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_copy_string(), ast_sockaddr_isnull(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), FALSE, ast_cli_args::fd, ast_cli_args::n, name, OBJ_POINTER, OBJ_UNLINK, ast_cli_args::pos, TRUE, unlink_marked_peers_from_tables(), unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.

17734 {
17735    struct sip_peer *peer, *pi;
17736    int prunepeer = FALSE;
17737    int multi = FALSE;
17738    const char *name = NULL;
17739    regex_t regexbuf;
17740    int havepattern = 0;
17741    struct ao2_iterator i;
17742    static const char * const choices[] = { "all", "like", NULL };
17743    char *cmplt;
17744    
17745    if (cmd == CLI_INIT) {
17746       e->command = "sip prune realtime [peer|all]";
17747       e->usage =
17748          "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n"
17749          "       Prunes object(s) from the cache.\n"
17750          "       Optional regular expression pattern is used to filter the objects.\n";
17751       return NULL;
17752    } else if (cmd == CLI_GENERATE) {
17753       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) {
17754          cmplt = ast_cli_complete(a->word, choices, a->n);
17755          if (!cmplt)
17756             cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS);
17757          return cmplt;
17758       }
17759       if (a->pos == 5 && !strcasecmp(a->argv[4], "like"))
17760          return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS);
17761       return NULL;
17762    }
17763    switch (a->argc) {
17764    case 4:
17765       name = a->argv[3];
17766       /* we accept a name in position 3, but keywords are not good. */
17767       if (!strcasecmp(name, "peer") || !strcasecmp(name, "like"))
17768          return CLI_SHOWUSAGE;
17769       prunepeer = TRUE;
17770       if (!strcasecmp(name, "all")) {
17771          multi = TRUE;
17772          name = NULL;
17773       }
17774       /* else a single name, already set */
17775       break;
17776    case 5:
17777       /* sip prune realtime {peer|like} name */
17778       name = a->argv[4];
17779       if (!strcasecmp(a->argv[3], "peer"))
17780          prunepeer = TRUE;
17781       else if (!strcasecmp(a->argv[3], "like")) {
17782          prunepeer = TRUE;
17783          multi = TRUE;
17784       } else
17785          return CLI_SHOWUSAGE;
17786       if (!strcasecmp(name, "like"))
17787          return CLI_SHOWUSAGE;
17788       if (!multi && !strcasecmp(name, "all")) {
17789          multi = TRUE;
17790          name = NULL;
17791       }
17792       break;
17793    case 6:
17794       name = a->argv[5];
17795       multi = TRUE;
17796       /* sip prune realtime {peer} like name */
17797       if (strcasecmp(a->argv[4], "like"))
17798          return CLI_SHOWUSAGE;
17799       if (!strcasecmp(a->argv[3], "peer")) {
17800          prunepeer = TRUE;
17801       } else
17802          return CLI_SHOWUSAGE;
17803       break;
17804    default:
17805       return CLI_SHOWUSAGE;
17806    }
17807 
17808    if (multi && name) {
17809       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB)) {
17810          return CLI_SHOWUSAGE;
17811       }
17812       havepattern = 1;
17813    }
17814 
17815    if (multi) {
17816       if (prunepeer) {
17817          int pruned = 0;
17818          
17819          i = ao2_iterator_init(peers, 0);
17820          while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
17821             ao2_lock(pi);
17822             if (name && regexec(&regexbuf, pi->name, 0, NULL, 0)) {
17823                ao2_unlock(pi);
17824                unref_peer(pi, "toss iterator peer ptr before continue");
17825                continue;
17826             };
17827             if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
17828                pi->the_mark = 1;
17829                pruned++;
17830             }
17831             ao2_unlock(pi);
17832             unref_peer(pi, "toss iterator peer ptr");
17833          }
17834          ao2_iterator_destroy(&i);
17835          if (pruned) {
17836             unlink_marked_peers_from_tables();
17837             ast_cli(a->fd, "%d peers pruned.\n", pruned);
17838          } else
17839             ast_cli(a->fd, "No peers found to prune.\n");
17840       }
17841    } else {
17842       if (prunepeer) {
17843          struct sip_peer tmp;
17844          ast_copy_string(tmp.name, name, sizeof(tmp.name));
17845          if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) {
17846             if (!ast_sockaddr_isnull(&peer->addr)) {
17847                ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also");
17848             }
17849             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
17850                ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
17851                /* put it back! */
17852                ao2_t_link(peers, peer, "link peer into peer table");
17853                if (!ast_sockaddr_isnull(&peer->addr)) {
17854                   ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
17855                }
17856             } else
17857                ast_cli(a->fd, "Peer '%s' pruned.\n", name);
17858             unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr");
17859          } else
17860             ast_cli(a->fd, "Peer '%s' not found.\n", name);
17861       }
17862    }
17863 
17864    if (havepattern) {
17865       regfree(&regexbuf);
17866    }
17867 
17868    return CLI_SUCCESS;
17869 }

static struct ast_channel * sip_pvt_lock_full ( struct sip_pvt *  pvt  )  [static, read]

Definition at line 8328 of file chan_sip.c.

References ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, sip_pvt_lock, and sip_pvt_unlock.

Referenced by __sip_autodestruct(), dialog_unlink_all(), handle_request_do(), reinvite_timeout(), send_provisional_keepalive_full(), and sip_queue_hangup_cause().

08329 {
08330    struct ast_channel *chan;
08331 
08332    /* Locking is simple when it is done right.  If you see a deadlock resulting
08333     * in this function, it is not this function's fault, Your problem exists elsewhere.
08334     * This function is perfect... seriously. */
08335    for (;;) {
08336       /* First, get the channel and grab a reference to it */
08337       sip_pvt_lock(pvt);
08338       chan = pvt->owner;
08339       if (chan) {
08340          /* The channel can not go away while we hold the pvt lock.
08341           * Give the channel a ref so it will not go away after we let
08342           * the pvt lock go. */
08343          ast_channel_ref(chan);
08344       } else {
08345          /* no channel, return pvt locked */
08346          return NULL;
08347       }
08348 
08349       /* We had to hold the pvt lock while getting a ref to the owner channel
08350        * but now we have to let this lock go in order to preserve proper
08351        * locking order when grabbing the channel lock */
08352       sip_pvt_unlock(pvt);
08353 
08354       /* Look, no deadlock avoidance, hooray! */
08355       ast_channel_lock(chan);
08356       sip_pvt_lock(pvt);
08357 
08358       if (pvt->owner == chan) {
08359          /* done */
08360          break;
08361       }
08362 
08363       /* If the owner changed while everything was unlocked, no problem,
08364        * just start over and everthing will work.  This is rare, do not be
08365        * confused by this loop and think this it is an expensive operation.
08366        * The majority of the calls to this function will never involve multiple
08367        * executions of this loop. */
08368       ast_channel_unlock(chan);
08369       ast_channel_unref(chan);
08370       sip_pvt_unlock(pvt);
08371    }
08372 
08373    /* If owner exists, it is locked and reffed */
08374    return pvt->owner;
08375 }

static char * sip_qualify_peer ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Send an OPTIONS packet to a SIP peer.

Definition at line 18018 of file chan_sip.c.

References _sip_qualify_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

18019 {
18020    switch (cmd) {
18021    case CLI_INIT:
18022       e->command = "sip qualify peer";
18023       e->usage =
18024          "Usage: sip qualify peer <name> [load]\n"
18025          "       Requests a response from one SIP peer and the current status.\n"
18026          "       Option \"load\" forces lookup of peer in realtime storage.\n";
18027       return NULL;
18028    case CLI_GENERATE:
18029       return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
18030    }
18031    return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
18032 }

static int sip_queryoption ( struct ast_channel chan,
int  option,
void *  data,
int *  datalen 
) [static]

Query an option on a SIP dialog.

Definition at line 4554 of file chan_sip.c.

References ast_copy_string(), ast_debug, ast_log(), AST_OPTION_DEVICE_NAME, AST_OPTION_DIGIT_DETECT, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_T38_STATE, ast_test_flag, LOG_ERROR, sip_pvt_lock, sip_pvt_unlock, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, and ast_channel::tech_pvt.

04555 {
04556    int res = -1;
04557    enum ast_t38_state state = T38_STATE_UNAVAILABLE;
04558    struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt;
04559    char *cp;
04560 
04561    sip_pvt_lock(p);
04562 
04563    switch (option) {
04564    case AST_OPTION_T38_STATE:
04565       /* Make sure we got an ast_t38_state enum passed in */
04566       if (*datalen != sizeof(enum ast_t38_state)) {
04567          ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
04568          break;
04569       }
04570 
04571       /* Now if T38 support is enabled we need to look and see what the current state is to get what we want to report back */
04572       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
04573          switch (p->t38.state) {
04574          case T38_LOCAL_REINVITE:
04575          case T38_PEER_REINVITE:
04576             state = T38_STATE_NEGOTIATING;
04577             break;
04578          case T38_ENABLED:
04579             state = T38_STATE_NEGOTIATED;
04580             break;
04581          default:
04582             state = T38_STATE_UNKNOWN;
04583          }
04584       }
04585 
04586       *((enum ast_t38_state *) data) = state;
04587       res = 0;
04588 
04589       break;
04590    case AST_OPTION_DIGIT_DETECT:
04591       cp = (char *) data;
04592       *cp = p->dsp ? 1 : 0;
04593       ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name);
04594       break;
04595    case AST_OPTION_SECURE_SIGNALING:
04596       *((unsigned int *) data) = p->req_secure_signaling;
04597       res = 0;
04598       break;
04599    case AST_OPTION_SECURE_MEDIA:
04600       *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0;
04601       res = 0;
04602       break;
04603    case AST_OPTION_DEVICE_NAME:
04604       if (p && p->outgoing_call) {
04605          cp = (char *) data;
04606          ast_copy_string(cp, p->dialstring, *datalen);
04607          res = 0;
04608       }
04609       /* We purposely break with a return of -1 in the
04610        * implied else case here
04611        */
04612       break;
04613    default:
04614       break;
04615    }
04616 
04617    sip_pvt_unlock(p);
04618 
04619    return res;
04620 }

static void sip_queue_hangup_cause ( struct sip_pvt *  p,
int  cause 
) [static]

Definition at line 20667 of file chan_sip.c.

References ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_set_hangupsource(), ast_strdupa, name, sip_pvt_lock_full(), and sip_pvt_unlock.

Referenced by handle_request_bye(), handle_request_cancel(), and handle_response_invite().

20668 {
20669    struct ast_channel *owner = p->owner;
20670    const char *name = ast_strdupa(owner->name);
20671 
20672    /* Cannot hold any channel/private locks when calling. */
20673    ast_channel_ref(owner);
20674    ast_channel_unlock(owner);
20675    sip_pvt_unlock(p);
20676    ast_set_hangupsource(owner, name, 0);
20677    if (cause) {
20678       ast_queue_hangup_with_cause(owner, cause);
20679    } else {
20680       ast_queue_hangup(owner);
20681    }
20682    ast_channel_unref(owner);
20683 
20684    /* Relock things. */
20685    owner = sip_pvt_lock_full(p);
20686    if (owner) {
20687       ast_channel_unref(owner);
20688    }
20689 }

static struct ast_frame * sip_read ( struct ast_channel ast  )  [static, read]

Read SIP RTP from channel.

Definition at line 7782 of file chan_sip.c.

References ast_channel::_state, ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), AST_FRAME_VOICE, ast_frfree, ast_log(), ast_null_frame, AST_STATE_UP, ast_test_flag, ast_verbose, ast_channel::caller, ast_channel::context, ast_channel::exten, FALSE, ast_frame::frametype, ast_party_caller::id, LOG_NOTICE, ast_channel::macrocontext, ast_party_id::number, pbx_builtin_setvar_helper(), S_COR, S_OR, sip_pvt_lock, sip_pvt_unlock, sip_rtp_read(), ast_party_number::str, ast_channel::tech_pvt, ast_party_number::valid, and VERBOSE_PREFIX_2.

07783 {
07784    struct ast_frame *fr;
07785    struct sip_pvt *p = ast->tech_pvt;
07786    int faxdetected = FALSE;
07787 
07788    sip_pvt_lock(p);
07789    fr = sip_rtp_read(ast, p, &faxdetected);
07790    p->lastrtprx = time(NULL);
07791 
07792    /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */
07793    if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) {
07794       if (strcmp(ast->exten, "fax")) {
07795          const char *target_context = S_OR(ast->macrocontext, ast->context);
07796          /* We need to unlock 'ast' here because
07797           * ast_exists_extension has the potential to start and
07798           * stop an autoservice on the channel. Such action is
07799           * prone to deadlock if the channel is locked.
07800           */
07801          sip_pvt_unlock(p);
07802          ast_channel_unlock(ast);
07803          if (ast_exists_extension(ast, target_context, "fax", 1,
07804             S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
07805             ast_channel_lock(ast);
07806             sip_pvt_lock(p);
07807             ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to CNG detection\n", ast->name);
07808             pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
07809             if (ast_async_goto(ast, target_context, "fax", 1)) {
07810                ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
07811             }
07812             ast_frfree(fr);
07813             fr = &ast_null_frame;
07814          } else {
07815             ast_channel_lock(ast);
07816             sip_pvt_lock(p);
07817             ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n");
07818          }
07819       }
07820    }
07821 
07822    /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
07823    if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
07824       ast_frfree(fr);
07825       fr = &ast_null_frame;
07826    }
07827 
07828    sip_pvt_unlock(p);
07829 
07830    return fr;
07831 }

static struct ast_sockaddr * sip_real_dst ( const struct sip_pvt *  p  )  [static, read]

The real destination address for a write.

Definition at line 3386 of file chan_sip.c.

References ast_test_flag.

Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), show_channels_cb(), sip_debug_test_pvt(), and sip_prepare_socket().

03387 {
03388    if (p->outboundproxy) {
03389       return &p->outboundproxy->ip;
03390    }
03391 
03392    return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT) ? &p->recv : &p->sa;
03393 }

static const char* sip_reason_code_to_str ( enum AST_REDIRECTING_REASON  code  )  [static]

Definition at line 2286 of file chan_sip.c.

References ARRAY_LEN, sip_reason_table, and sip_reasons::text.

Referenced by add_diversion_header().

02287 {
02288    if (code >= 0 && code < ARRAY_LEN(sip_reason_table)) {
02289       return sip_reason_table[code].text;
02290    }
02291 
02292    return "unknown";
02293 }

static enum AST_REDIRECTING_REASON sip_reason_str_to_code ( const char *  text  )  [static]

Definition at line 2271 of file chan_sip.c.

References ARRAY_LEN, AST_REDIRECTING_REASON_UNKNOWN, sip_reasons::code, and sip_reason_table.

Referenced by get_rdnis().

02272 {
02273    enum AST_REDIRECTING_REASON ast = AST_REDIRECTING_REASON_UNKNOWN;
02274    int i;
02275 
02276    for (i = 0; i < ARRAY_LEN(sip_reason_table); ++i) {
02277       if (!strcasecmp(text, sip_reason_table[i].text)) {
02278          ast = sip_reason_table[i].code;
02279          break;
02280       }
02281    }
02282 
02283    return ast;
02284 }

static int sip_refer_allocate ( struct sip_pvt *  p  )  [static]

Allocate SIP refer structure.

Definition at line 13954 of file chan_sip.c.

References ast_calloc.

Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().

13955 {
13956    p->refer = ast_calloc(1, sizeof(struct sip_refer));
13957    return p->refer ? 1 : 0;
13958 }

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

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.

Definition at line 13612 of file chan_sip.c.

References __sip_pretend_ack(), ast_dnsmgr_refresh(), ast_log(), EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, pvt_set_needdestroy(), REG_STATE_UNREGISTERED, registry_unref(), regstate2str(), sip_pvt_lock, sip_pvt_unlock, and transmit_register().

Referenced by sip_show_sched(), and transmit_register().

13613 {
13614 
13615    /* if we are here, our registration timed out, so we'll just do it over */
13616    struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */
13617    struct sip_pvt *p;
13618 
13619    /* if we couldn't get a reference to the registry object, punt */
13620    if (!r) {
13621       return 0;
13622    }
13623 
13624    if (r->dnsmgr) {
13625       /* If the registration has timed out, maybe the IP changed.  Force a refresh. */
13626       ast_dnsmgr_refresh(r->dnsmgr);
13627    }
13628 
13629    /* If the initial tranmission failed, we may not have an existing dialog,
13630     * so it is possible that r->call == NULL.
13631     * Otherwise destroy it, as we have a timeout so we don't want it.
13632     */
13633    if (r->call) {
13634       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
13635          in the single SIP manager thread. */
13636       p = r->call;
13637       sip_pvt_lock(p);
13638       pvt_set_needdestroy(p, "registration timeout");
13639       /* Pretend to ACK anything just in case */
13640       __sip_pretend_ack(p);
13641       sip_pvt_unlock(p);
13642 
13643       /* decouple the two objects */
13644       /* p->registry == r, so r has 2 refs, and the unref won't take the object away */
13645       if (p->registry) {
13646          p->registry = registry_unref(p->registry, "p->registry unreffed");
13647       }
13648       r->call = dialog_unref(r->call, "unrefing r->call");
13649    }
13650    /* If we have a limit, stop registration and give up */
13651    r->timeout = -1;
13652    if (global_regattempts_max && r->regattempts >= global_regattempts_max) {
13653       /* Ok, enough is enough. Don't try any more */
13654       /* We could add an external notification here...
13655          steal it from app_voicemail :-) */
13656       ast_log(LOG_NOTICE, "   -- Last Registration Attempt #%d failed, Giving up forever trying to register '%s@%s'\n", r->regattempts, r->username, r->hostname);
13657       r->regstate = REG_STATE_FAILED;
13658    } else {
13659       r->regstate = REG_STATE_UNREGISTERED;
13660       transmit_register(r, SIP_REGISTER, NULL, NULL);
13661       ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts);
13662    }
13663    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));
13664    registry_unref(r, "unreffing registry_unref r");
13665    return 0;
13666 }

static int sip_register ( const char *  value,
int  lineno 
) [static]

create sip_registry object from register=> line in sip.conf and link into reg container

Definition at line 8545 of file chan_sip.c.

References ast_atomic_fetchadd_int(), ast_calloc_with_stringfields, ast_log(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, LOG_ERROR, registry_unref(), regl, and sip_parse_register_line().

Referenced by build_peer(), and reload_config().

08546 {
08547    struct sip_registry *reg;
08548 
08549    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
08550       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
08551       return -1;
08552    }
08553 
08554    ast_atomic_fetchadd_int(&regobjs, 1);
08555    ASTOBJ_INIT(reg);
08556 
08557    if (sip_parse_register_line(reg, default_expiry, value, lineno)) {
08558       registry_unref(reg, "failure to parse, unref the reg pointer");
08559       return -1;
08560    }
08561 
08562    /* set default expiry if necessary */
08563    if (reg->refresh && !reg->expiry && !reg->configured_expiry) {
08564       reg->refresh = reg->expiry = reg->configured_expiry = default_expiry;
08565    }
08566 
08567    /* Add the new registry entry to the list */
08568    ASTOBJ_CONTAINER_LINK(&regl, reg);
08569 
08570    /* release the reference given by ASTOBJ_INIT. The container has another reference */
08571    registry_unref(reg, "unref the reg pointer");
08572 
08573    return 0;
08574 }

static void sip_register_tests ( void   )  [static]
static void sip_registry_destroy ( struct sip_registry *  reg  )  [static]

Destroy registry object Objects created with the register= statement in static configuration.

Definition at line 5928 of file chan_sip.c.

References ast_atomic_fetchadd_int(), ast_debug, ast_free, AST_SCHED_DEL, ast_string_field_free_memory, dialog_unlink_all(), and registry_unref().

Referenced by registry_unref(), reload_config(), and unload_module().

05929 {
05930    /* Really delete */
05931    ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
05932 
05933    if (reg->call) {
05934       /* Clear registry before destroying to ensure
05935          we don't get reentered trying to grab the registry lock */
05936       reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry");
05937       ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
05938       dialog_unlink_all(reg->call);
05939       reg->call = dialog_unref(reg->call, "unref reg->call");
05940       /* reg->call = sip_destroy(reg->call); */
05941    }
05942    AST_SCHED_DEL(sched, reg->expire);
05943    AST_SCHED_DEL(sched, reg->timeout);
05944 
05945    ast_string_field_free_memory(reg);
05946    ast_atomic_fetchadd_int(&regobjs, -1);
05947    ast_free(reg);
05948 }

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

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.

Definition at line 20519 of file chan_sip.c.

References ast_channel_trylock, ast_channel_unlock, ast_set_flag, check_pendings(), sip_pvt_lock, and sip_pvt_unlock.

Referenced by handle_response_invite(), and sip_show_sched().

20520 {
20521    struct sip_pvt *p = (struct sip_pvt *) data;
20522    struct ast_channel *owner;
20523 
20524    sip_pvt_lock(p); /* called from schedule thread which requires a lock */
20525    while ((owner = p->owner) && ast_channel_trylock(owner)) {
20526       sip_pvt_unlock(p);
20527       usleep(1);
20528       sip_pvt_lock(p);
20529    }
20530    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
20531    p->waitid = -1;
20532    check_pendings(p);
20533    sip_pvt_unlock(p);
20534    if (owner) {
20535       ast_channel_unlock(owner);
20536    }
20537    dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr");
20538    return 0;
20539 }

static char * sip_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Force reload of module from cli.

Definition at line 30631 of file chan_sip.c.

References ao2_t_ref, ast_clear_flag, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, ast_verbose, BOGUS_PEER_MD5SECRET, CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, LOG_ERROR, restart_monitor(), temp_peer(), TRUE, and ast_cli_entry::usage.

Referenced by reload().

30632 {
30633    static struct sip_peer *tmp_peer, *new_peer;
30634    
30635    switch (cmd) {
30636    case CLI_INIT:
30637       e->command = "sip reload";
30638       e->usage =
30639          "Usage: sip reload\n"
30640          "       Reloads SIP configuration from sip.conf\n";
30641       return NULL;
30642    case CLI_GENERATE:
30643       return NULL;
30644    }
30645 
30646    ast_mutex_lock(&sip_reload_lock);
30647    if (sip_reloading) {
30648       ast_verbose("Previous SIP reload not yet done\n");
30649    } else {
30650       sip_reloading = TRUE;
30651       sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD;
30652    }
30653    ast_mutex_unlock(&sip_reload_lock);
30654    restart_monitor();
30655 
30656    tmp_peer = bogus_peer;
30657    /* Create new bogus peer possibly with new global settings. */
30658    if ((new_peer = temp_peer("(bogus_peer)"))) {
30659       ast_string_field_set(new_peer, md5secret, BOGUS_PEER_MD5SECRET);
30660       ast_clear_flag(&new_peer->flags[0], SIP_INSECURE);
30661       bogus_peer = new_peer;
30662       ao2_t_ref(tmp_peer, -1, "unref the old bogus_peer during reload");
30663    } else {
30664       ast_log(LOG_ERROR, "Could not update the fake authentication peer.\n");
30665       /* You probably have bigger (memory?) issues to worry about though.. */
30666    }
30667 
30668    return CLI_SUCCESS;
30669 }

static int sip_removeheader ( struct ast_channel chan,
const char *  data 
) [static]

Remove SIP headers added previously with SipAddHeader application.

Definition at line 30377 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_strlen_zero(), ast_var_delete(), ast_var_name(), ast_var_value(), inbuf(), and ast_channel::varshead.

Referenced by load_module().

30378 {
30379    struct ast_var_t *newvariable;
30380    struct varshead *headp;
30381    int removeall = 0;
30382    char *inbuf = (char *) data;
30383 
30384    if (ast_strlen_zero(inbuf)) {
30385       removeall = 1;
30386    }
30387    ast_channel_lock(chan);
30388 
30389    headp=&chan->varshead;
30390    AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) {
30391       if (strncasecmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) {
30392          if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) {
30393             if (sipdebug)
30394                ast_debug(1,"removing SIP Header \"%s\" as %s\n",
30395                   ast_var_value(newvariable),
30396                   ast_var_name(newvariable));
30397             AST_LIST_REMOVE_CURRENT(entries);
30398             ast_var_delete(newvariable);
30399          }
30400       }
30401    }
30402    AST_LIST_TRAVERSE_SAFE_END;
30403 
30404    ast_channel_unlock(chan);
30405    return 0;
30406 }

static struct ast_channel * sip_request_call ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int *  cause 
) [static, read]

PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.

 *	SIP Dial string syntax:
 *		SIP/devicename
 *	or	SIP/username@domain (SIP uri)
 *	or	SIP/username[:password[:md5secret[:authname[:transport]]]]@host[:port]
 *	or	SIP/devicename/extension
 *	or	SIP/devicename/extension/IPorHost
 *	or	SIP/username@domain//IPorHost
 *	and there is an optional [!dnid] argument you can append to alter the
 *	To: header.
 * 

Definition at line 27319 of file chan_sip.c.

References args, AST_APP_ARG, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_channel_unlock, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), AST_NONSTANDARD_APP_ARGS, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_via(), change_callid_pvt(), create_addr(), dialog_unlink_all(), EVENT_FLAG_SYSTEM, ext, exten, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, proxy_from_config(), restart_monitor(), secret, set_socket_transport(), sip_alloc(), sip_cfg, sip_new(), sip_pvt_lock, sip_pvt_unlock, and TRUE.

27320 {
27321    struct sip_pvt *p;
27322    struct ast_channel *tmpc = NULL;
27323    char *ext = NULL, *host;
27324    char tmp[256];
27325    char *dest = data;
27326    char *dnid;
27327    char *secret = NULL;
27328    char *md5secret = NULL;
27329    char *authname = NULL;
27330    char *trans = NULL;
27331    char dialstring[256];
27332    char *remote_address;
27333    enum sip_transport transport = 0;
27334    format_t oldformat = format;
27335    AST_DECLARE_APP_ARGS(args,
27336       AST_APP_ARG(peerorhost);
27337       AST_APP_ARG(exten);
27338       AST_APP_ARG(remote_address);
27339    );
27340 
27341    /* mask request with some set of allowed formats.
27342     * XXX this needs to be fixed.
27343     * The original code uses AST_FORMAT_AUDIO_MASK, but it is
27344     * unclear what to use here. We have global_capabilities, which is
27345     * configured from sip.conf, and sip_tech.capabilities, which is
27346     * hardwired to all audio formats.
27347     */
27348    format &= AST_FORMAT_AUDIO_MASK;
27349    if (!format) {
27350       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(sip_cfg.capability));
27351       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
27352       return NULL;
27353    }
27354    ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
27355 
27356    if (ast_strlen_zero(dest)) {
27357       ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
27358       *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
27359       return NULL;
27360    }
27361 
27362    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) {
27363       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest);
27364       *cause = AST_CAUSE_SWITCH_CONGESTION;
27365       return NULL;
27366    }
27367 
27368    p->outgoing_call = TRUE;
27369 
27370    snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest);
27371    ast_string_field_set(p, dialstring, dialstring);
27372 
27373    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
27374       dialog_unlink_all(p);
27375       dialog_unref(p, "unref dialog p from mem fail");
27376       /* sip_destroy(p); */
27377       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
27378       *cause = AST_CAUSE_SWITCH_CONGESTION;
27379       return NULL;
27380    }
27381 
27382    /* Save the destination, the SIP dial string */
27383    ast_copy_string(tmp, dest, sizeof(tmp));
27384 
27385    /* Find DNID and take it away */
27386    dnid = strchr(tmp, '!');
27387    if (dnid != NULL) {
27388       *dnid++ = '\0';
27389       ast_string_field_set(p, todnid, dnid);
27390    }
27391 
27392    /* Divvy up the items separated by slashes */
27393    AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
27394 
27395    /* Find at sign - @ */
27396    host = strchr(args.peerorhost, '@');
27397    if (host) {
27398       *host++ = '\0';
27399       ext = args.peerorhost;
27400       secret = strchr(ext, ':');
27401    }
27402    if (secret) {
27403       *secret++ = '\0';
27404       md5secret = strchr(secret, ':');
27405    }
27406    if (md5secret) {
27407       *md5secret++ = '\0';
27408       authname = strchr(md5secret, ':');
27409    }
27410    if (authname) {
27411       *authname++ = '\0';
27412       trans = strchr(authname, ':');
27413    }
27414    if (trans) {
27415       *trans++ = '\0';
27416       if (!strcasecmp(trans, "tcp"))
27417          transport = SIP_TRANSPORT_TCP;
27418       else if (!strcasecmp(trans, "tls"))
27419          transport = SIP_TRANSPORT_TLS;
27420       else {
27421          if (strcasecmp(trans, "udp"))
27422             ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans);
27423          transport = SIP_TRANSPORT_UDP;
27424       }
27425    } else { /* use default */
27426       transport = SIP_TRANSPORT_UDP;
27427    }
27428 
27429    if (!host) {
27430       ext = args.exten;
27431       host = args.peerorhost;
27432       remote_address = args.remote_address;
27433    } else {
27434       remote_address = args.remote_address;
27435       if (!ast_strlen_zero(args.exten)) {
27436          ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten);
27437       }
27438    }
27439 
27440    if (!ast_strlen_zero(remote_address)) {
27441       p->options->outboundproxy = proxy_from_config(remote_address, 0, NULL);
27442       if (!p->options->outboundproxy) {
27443          ast_log(LOG_WARNING, "Unable to parse outboundproxy %s. We will not use this remote IP address\n", remote_address);
27444       }
27445    }
27446 
27447    set_socket_transport(&p->socket, transport);
27448 
27449    /* We now have
27450       host = peer name, DNS host name or DNS domain (for SRV)
27451       ext = extension (user part of URI)
27452       dnid = destination of the call (applies to the To: header)
27453    */
27454    if (create_addr(p, host, NULL, 1)) {
27455       *cause = AST_CAUSE_UNREGISTERED;
27456       ast_debug(3, "Cant create SIP call - target device not registered\n");
27457       dialog_unlink_all(p);
27458       dialog_unref(p, "unref dialog p UNREGISTERED");
27459       /* sip_destroy(p); */
27460       return NULL;
27461    }
27462    if (ast_strlen_zero(p->peername) && ext)
27463       ast_string_field_set(p, peername, ext);
27464    /* Recalculate our side, and recalculate Call ID */
27465    ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
27466    build_via(p);
27467 
27468    /* Change the dialog callid. */
27469    change_callid_pvt(p, NULL);
27470 
27471    /* We have an extension to call, don't use the full contact here */
27472    /* This to enable dialing registered peers with extension dialling,
27473       like SIP/peername/extension   
27474       SIP/peername will still use the full contact
27475     */
27476    if (ext) {
27477       ast_string_field_set(p, username, ext);
27478       ast_string_field_set(p, fullcontact, NULL);
27479    }
27480    if (secret && !ast_strlen_zero(secret))
27481       ast_string_field_set(p, peersecret, secret);
27482 
27483    if (md5secret && !ast_strlen_zero(md5secret))
27484       ast_string_field_set(p, peermd5secret, md5secret);
27485 
27486    if (authname && !ast_strlen_zero(authname))
27487       ast_string_field_set(p, authname, authname);
27488 #if 0
27489    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
27490 #endif
27491    p->prefcodec = oldformat;           /* Format for this call */
27492    p->jointcapability = oldformat & p->capability;
27493    sip_pvt_lock(p);
27494    tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */
27495    if (sip_cfg.callevents)
27496       manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
27497          "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
27498          p->owner ? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername);
27499    sip_pvt_unlock(p);
27500    if (!tmpc) {
27501       dialog_unlink_all(p);
27502       /* sip_destroy(p); */
27503    } else {
27504       ast_channel_unlock(tmpc);
27505    }
27506    dialog_unref(p, "toss pvt ptr at end of sip_request_call");
27507    ast_update_use_count();
27508    restart_monitor();
27509    return tmpc;
27510 }

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

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.

Definition at line 13569 of file chan_sip.c.

References __sip_do_register(), append_history, ast_log(), LOG_NOTICE, and registry_unref().

Referenced by handle_response_register(), sip_send_all_registers(), and sip_show_sched().

13570 {
13571    /* if we are here, we know that we need to reregister. */
13572    struct sip_registry *r = (struct sip_registry *) data;
13573 
13574    /* if we couldn't get a reference to the registry object, punt */
13575    if (!r) {
13576       return 0;
13577    }
13578 
13579    if (r->call && r->call->do_history) {
13580       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
13581    }
13582    /* Since registry's are only added/removed by the the monitor thread, this
13583       may be overkill to reference/dereference at all here */
13584    if (sipdebug) {
13585       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
13586    }
13587 
13588    r->expire = -1;
13589    r->expiry = r->configured_expiry;
13590    __sip_do_register(r);
13591    registry_unref(r, "unref the re-register scheduled event");
13592    return 0;
13593 }

static struct ast_frame* sip_rtp_read ( struct ast_channel ast,
struct sip_pvt *  p,
int *  faxdetect 
) [static, read]

Read RTP from network.

Definition at line 7691 of file chan_sip.c.

References ast_debug, ast_dsp_free(), ast_dsp_process(), ast_dsp_set_features(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), ast_verbose, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DSP_FEATURE_DIGIT_DETECT, f, ast_channel::fdno, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, and ast_frame::subclass.

Referenced by sip_read().

07692 {
07693    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
07694    struct ast_frame *f;
07695    
07696    if (!p->rtp) {
07697       /* We have no RTP allocated for this channel */
07698       return &ast_null_frame;
07699    }
07700 
07701    switch(ast->fdno) {
07702    case 0:
07703       f = ast_rtp_instance_read(p->rtp, 0);  /* RTP Audio */
07704       break;
07705    case 1:
07706       f = ast_rtp_instance_read(p->rtp, 1);  /* RTCP Control Channel */
07707       break;
07708    case 2:
07709       f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */
07710       break;
07711    case 3:
07712       f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */
07713       break;
07714    case 4:
07715       f = ast_rtp_instance_read(p->trtp, 0); /* RTP Text */
07716       if (sipdebug_text) {
07717          int i;
07718          unsigned char* arr = f->data.ptr;
07719          for (i=0; i < f->datalen; i++)
07720             ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.');
07721          ast_verbose(" -> ");
07722          for (i=0; i < f->datalen; i++)
07723             ast_verbose("%02X ", (unsigned)arr[i]);
07724          ast_verbose("\n");
07725       }
07726       break;
07727    case 5:
07728       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
07729       break;
07730    default:
07731       f = &ast_null_frame;
07732    }
07733    /* Don't forward RFC2833 if we're not supposed to */
07734    if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) &&
07735        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) {
07736       ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass.integer);
07737       ast_frfree(f);
07738       return &ast_null_frame;
07739    }
07740 
07741    /* We already hold the channel lock */
07742    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
07743       return f;
07744 
07745    if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
07746       if (!(f->subclass.codec & p->jointcapability)) {
07747          ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
07748             ast_getformatname(f->subclass.codec), p->owner->name);
07749          ast_frfree(f);
07750          return &ast_null_frame;
07751       }
07752       ast_debug(1, "Oooh, format changed to %s\n",
07753          ast_getformatname(f->subclass.codec));
07754       p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec;
07755       ast_set_read_format(p->owner, p->owner->readformat);
07756       ast_set_write_format(p->owner, p->owner->writeformat);
07757    }
07758 
07759    if (f && p->dsp) {
07760       f = ast_dsp_process(p->owner, p->dsp, f);
07761       if (f && f->frametype == AST_FRAME_DTMF) {
07762          if (f->subclass.integer == 'f') {
07763             ast_debug(1, "Fax CNG detected on %s\n", ast->name);
07764             *faxdetect = 1;
07765             /* If we only needed this DSP for fax detection purposes we can just drop it now */
07766             if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
07767                ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT);
07768             } else {
07769                ast_dsp_free(p->dsp);
07770                p->dsp = NULL;
07771             }
07772          } else {
07773             ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
07774          }
07775       }
07776    }
07777 
07778    return f;
07779 }

static const char* sip_sanitized_host ( const char *  host  )  [static]

Definition at line 13668 of file chan_sip.c.

References ast_sockaddr_parse(), ast_sockaddr_stringify_host_remote(), and PARSE_PORT_FORBID.

Referenced by transmit_register().

13669 {
13670    struct ast_sockaddr addr = { { 0, 0, }, };
13671 
13672    /* peer/sip_pvt->tohost and sip_registry->hostname should never have a port
13673     * in them, so we use PARSE_PORT_FORBID here. If this lookup fails, we return
13674     * the original host which is most likely a host name and not an IP. */
13675    if (!ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID)) {
13676       return host;
13677    }
13678    return ast_sockaddr_stringify_host_remote(&addr);
13679 }

void sip_scheddestroy ( struct sip_pvt *  p,
int  ms 
)

Schedule destruction of SIP dialog.

Definition at line 4103 of file chan_sip.c.

References __sip_autodestruct(), append_history, ast_log(), ast_sched_add(), ast_verbose, LOG_WARNING, sip_cancel_destroy(), sip_debug_test_pvt(), sip_methods, stop_session_timer(), cfsip_methods::text, and TRUE.

Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), manager_sipnotify(), receive_message(), sip_cli_notify(), sip_hangup(), sip_scheddestroy_final(), sip_send_mwi_to_peer(), sip_sipredirect(), transmit_fake_auth_response(), and transmit_publish().

04104 {
04105    if (p->final_destruction_scheduled) {
04106       return; /* already set final destruction */
04107    }
04108 
04109    if (ms < 0) {
04110       if (p->timer_t1 == 0) {
04111          p->timer_t1 = global_t1;   /* Set timer T1 if not set (RFC 3261) */
04112       }
04113       if (p->timer_b == 0) {
04114          p->timer_b = global_timer_b;  /* Set timer B if not set (RFC 3261) */
04115       }
04116       ms = p->timer_t1 * 64;
04117    }
04118    if (sip_debug_test_pvt(p)) {
04119       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
04120    }
04121    if (sip_cancel_destroy(p)) {
04122       ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
04123    }
04124 
04125    if (p->do_history) {
04126       append_history(p, "SchedDestroy", "%d ms", ms);
04127    }
04128    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct"));
04129 
04130    if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) {
04131       stop_session_timer(p);
04132    }
04133 }

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.

Definition at line 4090 of file chan_sip.c.

References sip_scheddestroy().

Referenced by handle_request_bye().

04091 {
04092    if (p->final_destruction_scheduled) {
04093       return; /* already set final destruction */
04094    }
04095 
04096    sip_scheddestroy(p, ms);
04097    if (p->autokillid != -1) {
04098       p->final_destruction_scheduled = 1;
04099    }
04100 }

static void sip_send_all_mwi_subscriptions ( void   )  [static]

Send all MWI subscriptions.

Definition at line 30535 of file chan_sip.c.

References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and submwil.

Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().

30536 {
30537    ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
30538       struct sip_subscription_mwi *saved;
30539       ASTOBJ_WRLOCK(iterator);
30540       AST_SCHED_DEL(sched, iterator->resub);
30541       saved = ASTOBJ_REF(iterator);
30542       if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, saved)) < 0) {
30543          ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy);
30544       }
30545       ASTOBJ_UNLOCK(iterator);
30546    } while (0));
30547 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

Definition at line 30511 of file chan_sip.c.

References AST_SCHED_REPLACE_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, registry_addref(), registry_unref(), regl, and sip_reregister().

Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().

30512 {
30513    int ms;
30514    int regspacing;
30515    if (!regobjs)
30516       return;
30517    regspacing = default_expiry * 1000/regobjs;
30518    if (regspacing > 100) {
30519       regspacing = 100;
30520    }
30521    ms = regspacing;
30522    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
30523       ASTOBJ_WRLOCK(iterator);
30524       ms += regspacing;
30525       AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator,
30526                         registry_unref(_data, "REPLACE sched del decs the refcount"),
30527                         registry_unref(iterator, "REPLACE sched add failure decs the refcount"),
30528                         registry_addref(iterator, "REPLACE sched add incs the refcount"));
30529       ASTOBJ_UNLOCK(iterator);
30530    } while (0)
30531    );
30532 }

static int sip_send_mwi_to_peer ( struct sip_peer *  peer,
int  cache_only 
) [static]

Send message waiting indication to alert peer that they've got voicemail.

Note:
Both peer and associated sip_pvt must be unlocked prior to calling this function

Definition at line 26467 of file chan_sip.c.

References ao2_lock, ao2_unlock, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_str_alloca, ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), change_callid_pvt(), create_addr_from_peer(), dialog_unlink_all(), get_cached_mwi(), peer_mailboxes_to_str(), set_socket_transport(), sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_notify_with_mwi(), and update_peer_lastmsgssent().

Referenced by build_peer(), handle_request_subscribe(), mwi_event_cb(), and register_verify().

26468 {
26469    /* Called with peer lock, but releases it */
26470    struct sip_pvt *p;
26471    int newmsgs = 0, oldmsgs = 0;
26472    const char *vmexten = NULL;
26473 
26474    ao2_lock(peer);
26475 
26476    if (peer->vmexten) {
26477       vmexten = ast_strdupa(peer->vmexten);
26478    }
26479 
26480    if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) {
26481       update_peer_lastmsgssent(peer, -1, 1);
26482       ao2_unlock(peer);
26483       return 0;
26484    }
26485 
26486    /* Do we have an IP address? If not, skip this peer */
26487    if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) {
26488       update_peer_lastmsgssent(peer, -1, 1);
26489       ao2_unlock(peer);
26490       return 0;
26491    }
26492 
26493    /* Attempt to use cached mwi to get message counts. */
26494    if (!get_cached_mwi(peer, &newmsgs, &oldmsgs) && !cache_only) {
26495       /* Fall back to manually checking the mailbox if not cache_only and get_cached_mwi failed */
26496       struct ast_str *mailbox_str = ast_str_alloca(512);
26497       peer_mailboxes_to_str(&mailbox_str, peer);
26498       ao2_unlock(peer);
26499       /* If there is no mailbox do nothing */
26500       if (!ast_str_strlen(mailbox_str)) {
26501          update_peer_lastmsgssent(peer, -1, 0);
26502          return 0;
26503       }
26504       ast_app_inboxcount(ast_str_buffer(mailbox_str), &newmsgs, &oldmsgs);
26505       ao2_lock(peer);
26506    }
26507 
26508    if (peer->mwipvt) {
26509       /* Base message on subscription */
26510       p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt");
26511       ao2_unlock(peer);
26512    } else {
26513       ao2_unlock(peer);
26514       /* Build temporary dialog for this message */
26515       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
26516          update_peer_lastmsgssent(peer, -1, 0);
26517          return -1;
26518       }
26519 
26520       /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer
26521        * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy
26522        * the peer's socket information to the sip_pvt we just allocated
26523        */
26524       set_socket_transport(&p->socket, 0);
26525       if (create_addr_from_peer(p, peer)) {
26526          /* Maybe they're not registered, etc. */
26527          dialog_unlink_all(p);
26528          dialog_unref(p, "unref dialog p just created via sip_alloc");
26529          update_peer_lastmsgssent(peer, -1, 0);
26530          return 0;
26531       }
26532       /* Recalculate our side, and recalculate Call ID */
26533       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
26534       build_via(p);
26535 
26536       ao2_lock(peer);
26537       if (!ast_strlen_zero(peer->mwi_from)) {
26538          ast_string_field_set(p, mwi_from, peer->mwi_from);
26539       } else if (!ast_strlen_zero(default_mwi_from)) {
26540          ast_string_field_set(p, mwi_from, default_mwi_from);
26541       }
26542       ao2_unlock(peer);
26543 
26544       /* Change the dialog callid. */
26545       change_callid_pvt(p, NULL);
26546 
26547       /* Destroy this session after 32 secs */
26548       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
26549    }
26550 
26551    /* We have multiple threads (mwi events and monitor retransmits) working with this PVT and as we modify the sip history if that's turned on,
26552       we really need to have a lock on it */
26553    sip_pvt_lock(p);
26554 
26555    /* Send MWI */
26556    ast_set_flag(&p->flags[0], SIP_OUTGOING);
26557    /* the following will decrement the refcount on p as it finishes */
26558    transmit_notify_with_mwi(p, newmsgs, oldmsgs, vmexten);
26559    sip_pvt_unlock(p);
26560    dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer.");
26561 
26562    update_peer_lastmsgssent(peer, ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)), 0);
26563 
26564    return 0;
26565 }

static int sip_senddigit_begin ( struct ast_channel ast,
char  digit 
) [static]

Definition at line 6913 of file chan_sip.c.

References ast_debug, ast_rtp_instance_dtmf_begin(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

06914 {
06915    struct sip_pvt *p = ast->tech_pvt;
06916    int res = 0;
06917 
06918    if (!p) {
06919       ast_debug(1, "Asked to begin DTMF digit on channel %s with no pvt; ignoring\n",
06920             ast->name);
06921       return res;
06922    }
06923 
06924    sip_pvt_lock(p);
06925    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
06926    case SIP_DTMF_INBAND:
06927       res = -1; /* Tell Asterisk to generate inband indications */
06928       break;
06929    case SIP_DTMF_RFC2833:
06930       if (p->rtp)
06931          ast_rtp_instance_dtmf_begin(p->rtp, digit);
06932       break;
06933    default:
06934       break;
06935    }
06936    sip_pvt_unlock(p);
06937 
06938    return res;
06939 }

static int sip_senddigit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.

Definition at line 6943 of file chan_sip.c.

References ast_debug, ast_rtp_instance_dtmf_end_with_duration(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_info_with_digit().

06944 {
06945    struct sip_pvt *p = ast->tech_pvt;
06946    int res = 0;
06947 
06948    if (!p) {
06949       ast_debug(1, "Asked to end DTMF digit on channel %s with no pvt; ignoring\n",
06950             ast->name);
06951       return res;
06952    }
06953 
06954    sip_pvt_lock(p);
06955    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
06956    case SIP_DTMF_INFO:
06957    case SIP_DTMF_SHORTINFO:
06958       transmit_info_with_digit(p, digit, duration);
06959       break;
06960    case SIP_DTMF_RFC2833:
06961       if (p->rtp)
06962          ast_rtp_instance_dtmf_end_with_duration(p->rtp, digit, duration);
06963       break;
06964    case SIP_DTMF_INBAND:
06965       res = -1; /* Tell Asterisk to stop inband indications */
06966       break;
06967    }
06968    sip_pvt_unlock(p);
06969 
06970    return res;
06971 }

static int sip_sendhtml ( struct ast_channel chan,
int  subclass,
const char *  data,
int  datalen 
) [static]

Send message with Access-URL header, if this is an HTML URL only!

Definition at line 4638 of file chan_sip.c.

References ast_channel::_state, ast_debug, AST_HTML_URL, ast_log(), ast_set_flag, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_string_field_build, ast_test_flag, FALSE, LOG_WARNING, sip_debug_test_pvt(), ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_response(), and url.

04639 {
04640    struct sip_pvt *p = chan->tech_pvt;
04641 
04642    if (subclass != AST_HTML_URL)
04643       return -1;
04644 
04645    ast_string_field_build(p, url, "<%s>;mode=active", data);
04646 
04647    if (sip_debug_test_pvt(p))
04648       ast_debug(1, "Send URL %s, state = %u!\n", data, chan->_state);
04649 
04650    switch (chan->_state) {
04651    case AST_STATE_RING:
04652       transmit_response(p, "100 Trying", &p->initreq);
04653       break;
04654    case AST_STATE_RINGING:
04655       transmit_response(p, "180 Ringing", &p->initreq);
04656       break;
04657    case AST_STATE_UP:
04658       if (!p->pendinginvite) {      /* We are up, and have no outstanding invite */
04659          transmit_reinvite_with_sdp(p, FALSE, FALSE);
04660       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04661          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
04662       }  
04663       break;
04664    default:
04665       ast_log(LOG_WARNING, "Don't know how to send URI when state is %u!\n", chan->_state);
04666    }
04667 
04668    return 0;
04669 }

static int sip_sendtext ( struct ast_channel ast,
const char *  text 
) [static]

Definition at line 4682 of file chan_sip.c.

References ast_debug, ast_verbose, is_method_allowed(), sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().

04683 {
04684    struct sip_pvt *dialog = ast->tech_pvt;
04685    int debug;
04686 
04687    if (!dialog) {
04688       return -1;
04689    }
04690    /* NOT ast_strlen_zero, because a zero-length message is specifically
04691     * allowed by RFC 3428 (See section 10, Examples) */
04692    if (!text) {
04693       return 0;
04694    }
04695    if(!is_method_allowed(&dialog->allowed_methods, SIP_MESSAGE)) {
04696       ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n");
04697       return(0);
04698    }
04699 
04700    debug = sip_debug_test_pvt(dialog);
04701    if (debug) {
04702       ast_verbose("Sending text %s on %s\n", text, ast->name);
04703    }
04704 
04705    transmit_message_with_text(dialog, text);
04706    return 0;   
04707 }

static char * sip_set_history ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Enable/Disable SIP History logging (CLI).

Definition at line 19769 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, TRUE, and ast_cli_entry::usage.

19770 {
19771    switch (cmd) {
19772    case CLI_INIT:
19773       e->command = "sip set history {on|off}";
19774       e->usage =
19775          "Usage: sip set history {on|off}\n"
19776          "       Enables/Disables recording of SIP dialog history for debugging purposes.\n"
19777          "       Use 'sip show history' to view the history of a call number.\n";
19778       return NULL;
19779    case CLI_GENERATE:
19780       return NULL;
19781    }
19782 
19783    if (a->argc != e->args)
19784       return CLI_SHOWUSAGE;
19785 
19786    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
19787       recordhistory = TRUE;
19788       ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n");
19789    } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
19790       recordhistory = FALSE;
19791       ast_cli(a->fd, "SIP History Recording Disabled\n");
19792    } else {
19793       return CLI_SHOWUSAGE;
19794    }
19795    return CLI_SUCCESS;
19796 }

static void sip_set_redirstr ( struct sip_pvt *  p,
char *  reason 
) [static]

Translate referring cause.

Definition at line 15566 of file chan_sip.c.

References ast_string_field_set.

Referenced by get_rdnis().

15566                                                               {
15567 
15568    if (!strcmp(reason, "unknown")) {
15569       ast_string_field_set(p, redircause, "UNKNOWN");
15570    } else if (!strcmp(reason, "user-busy")) {
15571       ast_string_field_set(p, redircause, "BUSY");
15572    } else if (!strcmp(reason, "no-answer")) {
15573       ast_string_field_set(p, redircause, "NOANSWER");
15574    } else if (!strcmp(reason, "unavailable")) {
15575       ast_string_field_set(p, redircause, "UNREACHABLE");
15576    } else if (!strcmp(reason, "unconditional")) {
15577       ast_string_field_set(p, redircause, "UNCONDITIONAL");
15578    } else if (!strcmp(reason, "time-of-day")) {
15579       ast_string_field_set(p, redircause, "UNKNOWN");
15580    } else if (!strcmp(reason, "do-not-disturb")) {
15581       ast_string_field_set(p, redircause, "UNKNOWN");
15582    } else if (!strcmp(reason, "deflection")) {
15583       ast_string_field_set(p, redircause, "UNKNOWN");
15584    } else if (!strcmp(reason, "follow-me")) {
15585       ast_string_field_set(p, redircause, "UNKNOWN");
15586    } else if (!strcmp(reason, "out-of-service")) {
15587       ast_string_field_set(p, redircause, "UNREACHABLE");
15588    } else if (!strcmp(reason, "away")) {
15589       ast_string_field_set(p, redircause, "UNREACHABLE");
15590    } else {
15591       ast_string_field_set(p, redircause, "UNKNOWN");
15592    }
15593 }

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,
format_t  codecs,
int  nat_active 
) [static]

Definition at line 30130 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, ast_debug, ast_rtp_instance_fd(), ast_rtp_instance_get_and_cmp_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), AST_STATE_UP, ast_test_flag, FALSE, sip_cfg, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_reinvite_with_sdp().

Referenced by sip_fixup().

30131 {
30132    struct sip_pvt *p;
30133    int changed = 0;
30134 
30135    /* Lock the channel and the private safely. */
30136    ast_channel_lock(chan);
30137    p = chan->tech_pvt;
30138    if (!p) {
30139       ast_channel_unlock(chan);
30140       return -1;
30141    }
30142    sip_pvt_lock(p);
30143    if (p->owner != chan) {
30144       /* I suppose it could be argued that if this happens it is a bug. */
30145       ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name);
30146       sip_pvt_unlock(p);
30147       ast_channel_unlock(chan);
30148       return 0;
30149    }
30150 
30151    /* Disable early RTP bridge  */
30152    if ((instance || vinstance || tinstance) &&
30153       !ast_bridged_channel(chan) &&
30154       !sip_cfg.directrtpsetup) {
30155       sip_pvt_unlock(p);
30156       ast_channel_unlock(chan);
30157       return 0;
30158    }
30159 
30160    if (p->alreadygone) {
30161       /* If we're destroyed, don't bother */
30162       sip_pvt_unlock(p);
30163       ast_channel_unlock(chan);
30164       return 0;
30165    }
30166 
30167    /* if this peer cannot handle reinvites of the media stream to devices
30168       that are known to be behind a NAT, then stop the process now
30169    */
30170    if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
30171       sip_pvt_unlock(p);
30172       ast_channel_unlock(chan);
30173       return 0;
30174    }
30175 
30176    if (instance) {
30177       changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip);
30178 
30179       if (p->rtp) {
30180          /* Prevent audio RTCP reads */
30181          ast_channel_set_fd(chan, 1, -1);
30182          /* Silence RTCP while audio RTP is inactive */
30183          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0);
30184       }
30185    } else if (!ast_sockaddr_isnull(&p->redirip)) {
30186       memset(&p->redirip, 0, sizeof(p->redirip));
30187       changed = 1;
30188 
30189       if (p->rtp) {
30190          /* Enable RTCP since it will be inactive if we're coming back
30191           * from a reinvite */
30192          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1);
30193          /* Enable audio RTCP reads */
30194          ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(p->rtp, 1));
30195       }
30196    }
30197 
30198    if (vinstance) {
30199       changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip);
30200 
30201       if (p->vrtp) {
30202          /* Prevent video RTCP reads */
30203          ast_channel_set_fd(chan, 3, -1);
30204          /* Silence RTCP while video RTP is inactive */
30205          ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 0);
30206       }
30207    } else if (!ast_sockaddr_isnull(&p->vredirip)) {
30208       memset(&p->vredirip, 0, sizeof(p->vredirip));
30209       changed = 1;
30210 
30211       if (p->vrtp) {
30212          /* Enable RTCP since it will be inactive if we're coming back
30213           * from a reinvite */
30214          ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 1);
30215          /* Enable video RTCP reads */
30216          ast_channel_set_fd(chan, 3, ast_rtp_instance_fd(p->vrtp, 1));
30217       }
30218    }
30219 
30220    if (tinstance) {
30221       changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip);
30222    } else if (!ast_sockaddr_isnull(&p->tredirip)) {
30223       memset(&p->tredirip, 0, sizeof(p->tredirip));
30224       changed = 1;
30225    }
30226    if (codecs && (p->redircodecs != codecs)) {
30227       p->redircodecs = codecs;
30228       changed = 1;
30229    }
30230 
30231    if (ast_test_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING) && !p->outgoing_call) {
30232       /* We only wish to withhold sending the initial direct media reinvite on the incoming dialog.
30233        * Further direct media reinvites beyond the initial should be sent. In order to allow further
30234        * direct media reinvites to be sent, we clear this flag.
30235        */
30236       ast_clear_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING);
30237       sip_pvt_unlock(p);
30238       ast_channel_unlock(chan);
30239       return 0;
30240    }
30241 
30242    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
30243       if (chan->_state != AST_STATE_UP) {     /* We are in early state */
30244          if (p->do_history)
30245             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
30246          ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
30247       } else if (!p->pendinginvite) {   /* We are up, and have no outstanding invite */
30248          ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
30249          transmit_reinvite_with_sdp(p, FALSE, FALSE);
30250       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
30251          ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
30252          /* We have a pending Invite. Send re-invite when we're done with the invite */
30253          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
30254       }
30255    }
30256    /* Reset lastrtprx timer */
30257    p->lastrtprx = p->lastrtptx = time(NULL);
30258    sip_pvt_unlock(p);
30259    ast_channel_unlock(chan);
30260    return 0;
30261 }

static int sip_set_udptl_peer ( struct ast_channel chan,
struct ast_udptl udptl 
) [static]

Definition at line 29931 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_debug, ast_set_flag, ast_sockaddr_stringify(), ast_test_flag, ast_udptl_get_peer(), FALSE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and TRUE.

29932 {
29933    struct sip_pvt *p;
29934 
29935    /* Lock the channel and the private safely. */
29936    ast_channel_lock(chan);
29937    p = chan->tech_pvt;
29938    if (!p) {
29939       ast_channel_unlock(chan);
29940       return -1;
29941    }
29942    sip_pvt_lock(p);
29943    if (p->owner != chan) {
29944       /* I suppose it could be argued that if this happens it is a bug. */
29945       ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name);
29946       sip_pvt_unlock(p);
29947       ast_channel_unlock(chan);
29948       return 0;
29949    }
29950 
29951    if (udptl) {
29952       ast_udptl_get_peer(udptl, &p->udptlredirip);
29953    } else {
29954       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
29955    }
29956    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
29957       if (!p->pendinginvite) {
29958          ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s\n",
29959                p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip));
29960          transmit_reinvite_with_sdp(p, TRUE, FALSE);
29961       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
29962          ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s\n",
29963                p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip));
29964          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
29965       }
29966    }
29967    /* Reset lastrtprx timer */
29968    p->lastrtprx = p->lastrtptx = time(NULL);
29969    sip_pvt_unlock(p);
29970    ast_channel_unlock(chan);
29971    return 0;
29972 }

static int sip_setoption ( struct ast_channel chan,
int  option,
void *  data,
int  datalen 
) [static]

Set an option on a SIP dialog.

Definition at line 4494 of file chan_sip.c.

References ast_debug, ast_log(), AST_OPTION_DIGIT_DETECT, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_MAKE_COMPATIBLE, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_rtp_instance_make_compatible(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), ast_set2_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_ERROR, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

04495 {
04496    int res = -1;
04497    struct sip_pvt *p = chan->tech_pvt;
04498 
04499         if (!p) {
04500          ast_log(LOG_ERROR, "Attempt to Ref a null pointer.  sip private structure is gone!\n");
04501          return -1;
04502         }
04503 
04504    sip_pvt_lock(p);
04505 
04506    switch (option) {
04507    case AST_OPTION_FORMAT_READ:
04508       if (p->rtp) {
04509          res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data);
04510       }
04511       break;
04512    case AST_OPTION_FORMAT_WRITE:
04513       if (p->rtp) {
04514          res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data);
04515       }
04516       break;
04517    case AST_OPTION_MAKE_COMPATIBLE:
04518       if (p->rtp) {
04519          res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data);
04520       }
04521       break;
04522    case AST_OPTION_DIGIT_DETECT:
04523       if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
04524           (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
04525          char *cp = (char *) data;
04526 
04527          ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name);
04528          if (*cp) {
04529             enable_dsp_detect(p);
04530          } else {
04531             disable_dsp_detect(p);
04532          }
04533          res = 0;
04534       }
04535       break;
04536    case AST_OPTION_SECURE_SIGNALING:
04537       p->req_secure_signaling = *(unsigned int *) data;
04538       res = 0;
04539       break;
04540    case AST_OPTION_SECURE_MEDIA:
04541       ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP);
04542       res = 0;
04543       break;
04544    default:
04545       break;
04546    }
04547 
04548    sip_pvt_unlock(p);
04549 
04550    return res;
04551 }

static char * sip_show_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show details of one active dialog.

Definition at line 19228 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_cli(), AST_CLI_YESNO, ast_getformatname_multiple(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipch(), dtmfmode2str(), ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, stmode2str(), strefresher2str(), strefresherparam2str(), subscription_type2str(), transfermode2str(), transport2str(), TRUE, ast_cli_entry::usage, and ast_cli_args::word.

19229 {
19230    struct sip_pvt *cur;
19231    size_t len;
19232    int found = 0;
19233    struct ao2_iterator i;
19234 
19235    switch (cmd) {
19236    case CLI_INIT:
19237       e->command = "sip show channel";
19238       e->usage =
19239          "Usage: sip show channel <call-id>\n"
19240          "       Provides detailed status on a given SIP dialog (identified by SIP call-id).\n";
19241       return NULL;
19242    case CLI_GENERATE:
19243       return complete_sipch(a->line, a->word, a->pos, a->n);
19244    }
19245 
19246    if (a->argc != 4)
19247       return CLI_SHOWUSAGE;
19248    len = strlen(a->argv[3]);
19249    
19250    i = ao2_iterator_init(dialogs, 0);
19251    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
19252       sip_pvt_lock(cur);
19253 
19254       if (!strncasecmp(cur->callid, a->argv[3], len)) {
19255          char formatbuf[SIPBUFSIZE/2];
19256          ast_cli(a->fd, "\n");
19257          if (cur->subscribed != NONE)
19258             ast_cli(a->fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
19259          else
19260             ast_cli(a->fd, "  * SIP Call\n");
19261          ast_cli(a->fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
19262          ast_cli(a->fd, "  Call-ID:                %s\n", cur->callid);
19263          ast_cli(a->fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
19264          ast_cli(a->fd, "  Our Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability));
19265          ast_cli(a->fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
19266          ast_cli(a->fd, "  Their Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability));
19267          ast_cli(a->fd, "  Joint Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability));
19268          ast_cli(a->fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
19269          ast_cli(a->fd, "  T.38 support            %s\n", AST_CLI_YESNO(cur->udptl != NULL));
19270          ast_cli(a->fd, "  Video support           %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
19271          ast_cli(a->fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
19272          ast_cli(a->fd, "  Theoretical Address:    %s\n", ast_sockaddr_stringify(&cur->sa));
19273          ast_cli(a->fd, "  Received Address:       %s\n", ast_sockaddr_stringify(&cur->recv));
19274          ast_cli(a->fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
19275          ast_cli(a->fd, "  Force rport:            %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT)));
19276          if (ast_sockaddr_isnull(&cur->redirip)) {
19277             ast_cli(a->fd,
19278                "  Audio IP:               %s (local)\n",
19279                ast_sockaddr_stringify_addr(&cur->ourip));
19280          } else {
19281             ast_cli(a->fd,
19282                "  Audio IP:               %s (Outside bridge)\n",
19283                ast_sockaddr_stringify_addr(&cur->redirip));
19284          }
19285          ast_cli(a->fd, "  Our Tag:                %s\n", cur->tag);
19286          ast_cli(a->fd, "  Their Tag:              %s\n", cur->theirtag);
19287          ast_cli(a->fd, "  SIP User agent:         %s\n", cur->useragent);
19288          if (!ast_strlen_zero(cur->username))
19289             ast_cli(a->fd, "  Username:               %s\n", cur->username);
19290          if (!ast_strlen_zero(cur->peername))
19291             ast_cli(a->fd, "  Peername:               %s\n", cur->peername);
19292          if (!ast_strlen_zero(cur->uri))
19293             ast_cli(a->fd, "  Original uri:           %s\n", cur->uri);
19294          if (!ast_strlen_zero(cur->cid_num))
19295             ast_cli(a->fd, "  Caller-ID:              %s\n", cur->cid_num);
19296          ast_cli(a->fd, "  Need Destroy:           %s\n", AST_CLI_YESNO(cur->needdestroy));
19297          ast_cli(a->fd, "  Last Message:           %s\n", cur->lastmsg);
19298          ast_cli(a->fd, "  Promiscuous Redir:      %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR)));
19299          ast_cli(a->fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
19300          ast_cli(a->fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
19301          ast_cli(a->fd, "  SIP Options:            ");
19302          if (cur->sipoptions) {
19303             int x;
19304             for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
19305                if (cur->sipoptions & sip_options[x].id)
19306                   ast_cli(a->fd, "%s ", sip_options[x].text);
19307             }
19308             ast_cli(a->fd, "\n");
19309          } else
19310             ast_cli(a->fd, "(none)\n");
19311 
19312          if (!cur->stimer)
19313             ast_cli(a->fd, "  Session-Timer:          Uninitiallized\n");
19314          else {
19315             ast_cli(a->fd, "  Session-Timer:          %s\n", cur->stimer->st_active ? "Active" : "Inactive");
19316             if (cur->stimer->st_active == TRUE) {
19317                ast_cli(a->fd, "  S-Timer Interval:       %d\n", cur->stimer->st_interval);
19318                ast_cli(a->fd, "  S-Timer Refresher:      %s\n", strefresher2str(cur->stimer->st_ref));
19319                ast_cli(a->fd, "  S-Timer Sched Id:       %d\n", cur->stimer->st_schedid);
19320                ast_cli(a->fd, "  S-Timer Peer Sts:       %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive");
19321                ast_cli(a->fd, "  S-Timer Cached Min-SE:  %d\n", cur->stimer->st_cached_min_se);
19322                ast_cli(a->fd, "  S-Timer Cached SE:      %d\n", cur->stimer->st_cached_max_se);
19323                ast_cli(a->fd, "  S-Timer Cached Ref:     %s\n", strefresherparam2str(cur->stimer->st_cached_ref));
19324                ast_cli(a->fd, "  S-Timer Cached Mode:    %s\n", stmode2str(cur->stimer->st_cached_mode));
19325             }
19326          }
19327 
19328          /* add transport and media types */
19329          ast_cli(a->fd, "  Transport:              %s\n", transport2str(cur->socket.type));
19330          ast_cli(a->fd, "  Media:                  %s\n", cur->srtp ? "SRTP" : cur->rtp ? "RTP" : "None");
19331 
19332          ast_cli(a->fd, "\n\n");
19333 
19334          found++;
19335       }
19336 
19337       sip_pvt_unlock(cur);
19338 
19339       ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next");
19340    }
19341    ao2_iterator_destroy(&i);
19342 
19343    if (!found)
19344       ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
19345 
19346    return CLI_SUCCESS;
19347 }

static char* sip_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

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.

Definition at line 19035 of file chan_sip.c.

References ao2_t_callback, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ESS, ast_cli_args::fd, FORMAT2, FORMAT3, OBJ_NODATA, show_channels_cb(), and ast_cli_entry::usage.

19036 {
19037    struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
19038 
19039 
19040    if (cmd == CLI_INIT) {
19041       e->command = "sip show {channels|subscriptions}";
19042       e->usage =
19043          "Usage: sip show channels\n"
19044          "       Lists all currently active SIP calls (dialogs).\n"
19045          "Usage: sip show subscriptions\n"
19046          "       Lists active SIP subscriptions.\n";
19047       return NULL;
19048    } else if (cmd == CLI_GENERATE)
19049       return NULL;
19050 
19051    if (a->argc != e->args)
19052       return CLI_SHOWUSAGE;
19053    arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions");
19054    if (!arg.subscriptions)
19055       ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer");
19056    else
19057       ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
19058 
19059    /* iterate on the container and invoke the callback on each item */
19060    ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels");
19061    
19062    /* print summary information */
19063    ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans,
19064       (arg.subscriptions ? "subscription" : "dialog"),
19065       ESS(arg.numchans));  /* ESS(n) returns an "s" if n>1 */
19066    return CLI_SUCCESS;
19067 #undef FORMAT
19068 #undef FORMAT2
19069 #undef FORMAT3
19070 }

static char * sip_show_channelstats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

SIP show channelstats CLI (main function).

Definition at line 18656 of file chan_sip.c.

References ao2_t_callback, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT2, OBJ_NODATA, show_chanstats_cb(), and ast_cli_entry::usage.

18657 {
18658    struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
18659 
18660    switch (cmd) {
18661    case CLI_INIT:
18662       e->command = "sip show channelstats";
18663       e->usage =
18664          "Usage: sip show channelstats\n"
18665          "       Lists all currently active SIP channel's RTCP statistics.\n"
18666          "       Note that calls in the much optimized RTP P2P bridge mode will not show any packets here.";
18667       return NULL;
18668    case CLI_GENERATE:
18669       return NULL;
18670    }
18671 
18672    if (a->argc != 3)
18673       return CLI_SHOWUSAGE;
18674 
18675    ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter");
18676    /* iterate on the container and invoke the callback on each item */
18677    ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats");
18678    ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : "");
18679    return CLI_SUCCESS;
18680 }

static char * sip_show_domains ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command to list local domains.

Definition at line 17904 of file chan_sip.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, domain_mode_to_text(), ast_cli_args::fd, FORMAT, S_OR, and ast_cli_entry::usage.

17905 {
17906    struct domain *d;
17907 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
17908 
17909    switch (cmd) {
17910    case CLI_INIT:
17911       e->command = "sip show domains";
17912       e->usage =
17913          "Usage: sip show domains\n"
17914          "       Lists all configured SIP local domains.\n"
17915          "       Asterisk only responds to SIP messages to local domains.\n";
17916       return NULL;
17917    case CLI_GENERATE:
17918       return NULL;
17919    }
17920 
17921    if (AST_LIST_EMPTY(&domain_list)) {
17922       ast_cli(a->fd, "SIP Domain support not enabled.\n\n");
17923       return CLI_SUCCESS;
17924    } else {
17925       ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
17926       AST_LIST_LOCK(&domain_list);
17927       AST_LIST_TRAVERSE(&domain_list, d, list)
17928          ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
17929             domain_mode_to_text(d->mode));
17930       AST_LIST_UNLOCK(&domain_list);
17931       ast_cli(a->fd, "\n");
17932       return CLI_SUCCESS;
17933    }
17934 }

static char * sip_show_history ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show history details of one dialog.

Definition at line 19350 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_history(), ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, ast_cli_entry::usage, and ast_cli_args::word.

19351 {
19352    struct sip_pvt *cur;
19353    size_t len;
19354    int found = 0;
19355    struct ao2_iterator i;
19356 
19357    switch (cmd) {
19358    case CLI_INIT:
19359       e->command = "sip show history";
19360       e->usage =
19361          "Usage: sip show history <call-id>\n"
19362          "       Provides detailed dialog history on a given SIP call (specified by call-id).\n";
19363       return NULL;
19364    case CLI_GENERATE:
19365       return complete_sip_show_history(a->line, a->word, a->pos, a->n);
19366    }
19367 
19368    if (a->argc != 4)
19369       return CLI_SHOWUSAGE;
19370 
19371    if (!recordhistory)
19372       ast_cli(a->fd, "\n***Note: History recording is currently DISABLED.  Use 'sip set history on' to ENABLE.\n");
19373 
19374    len = strlen(a->argv[3]);
19375 
19376    i = ao2_iterator_init(dialogs, 0);
19377    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
19378       sip_pvt_lock(cur);
19379       if (!strncasecmp(cur->callid, a->argv[3], len)) {
19380          struct sip_history *hist;
19381          int x = 0;
19382 
19383          ast_cli(a->fd, "\n");
19384          if (cur->subscribed != NONE)
19385             ast_cli(a->fd, "  * Subscription\n");
19386          else
19387             ast_cli(a->fd, "  * SIP Call\n");
19388          if (cur->history)
19389             AST_LIST_TRAVERSE(cur->history, hist, list)
19390                ast_cli(a->fd, "%d. %s\n", ++x, hist->event);
19391          if (x == 0)
19392             ast_cli(a->fd, "Call '%s' has no history\n", cur->callid);
19393          found++;
19394       }
19395       sip_pvt_unlock(cur);
19396       ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next");
19397    }
19398    ao2_iterator_destroy(&i);
19399 
19400    if (!found)
19401       ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
19402 
19403    return CLI_SUCCESS;
19404 }

static char * sip_show_inuse ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI Command to show calls within limits set by call_limit.

Definition at line 16938 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, FORMAT2, TRUE, unref_peer(), and ast_cli_entry::usage.

16939 {
16940 #define FORMAT "%-25.25s %-15.15s %-15.15s \n"
16941 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
16942    char ilimits[40];
16943    char iused[40];
16944    int showall = FALSE;
16945    struct ao2_iterator i;
16946    struct sip_peer *peer;
16947    
16948    switch (cmd) {
16949    case CLI_INIT:
16950       e->command = "sip show inuse";
16951       e->usage =
16952          "Usage: sip show inuse [all]\n"
16953          "       List all SIP devices usage counters and limits.\n"
16954          "       Add option \"all\" to show all devices, not only those with a limit.\n";
16955       return NULL;
16956    case CLI_GENERATE:
16957       return NULL;
16958    }
16959 
16960    if (a->argc < 3)
16961       return CLI_SHOWUSAGE;
16962 
16963    if (a->argc == 4 && !strcmp(a->argv[3], "all"))
16964       showall = TRUE;
16965    
16966    ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit");
16967 
16968    i = ao2_iterator_init(peers, 0);
16969    while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) {
16970       ao2_lock(peer);
16971       if (peer->call_limit)
16972          snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit);
16973       else
16974          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
16975       snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold);
16976       if (showall || peer->call_limit)
16977          ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits);
16978       ao2_unlock(peer);
16979       unref_peer(peer, "toss iterator pointer");
16980    }
16981    ao2_iterator_destroy(&i);
16982 
16983    return CLI_SUCCESS;
16984 #undef FORMAT
16985 #undef FORMAT2
16986 }

static char * sip_show_mwi ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 18914 of file chan_sip.c.

References ast_cli(), AST_CLI_YESNO, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, submwil, and ast_cli_entry::usage.

18915 {
18916 #define FORMAT  "%-30.30s  %-12.12s  %-10.10s  %-10.10s\n"
18917    char host[80];
18918    
18919    switch (cmd) {
18920    case CLI_INIT:
18921       e->command = "sip show mwi";
18922       e->usage =
18923          "Usage: sip show mwi\n"
18924          "       Provides a list of MWI subscriptions and status.\n";
18925       return NULL;
18926    case CLI_GENERATE:
18927       return NULL;
18928    }
18929    
18930    ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed");
18931    
18932    ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
18933       ASTOBJ_RDLOCK(iterator);
18934       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
18935       ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed));
18936       ASTOBJ_UNLOCK(iterator);
18937    } while(0));
18938 
18939    return CLI_SUCCESS;
18940 #undef FORMAT
18941 }

static char * sip_show_objects ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

List all allocated SIP Objects (realtime or static).

Definition at line 17525 of file chan_sip.c.

References ao2_t_callback, ast_cli_args::argc, ast_cli(), ASTOBJ_CONTAINER_DUMP, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialog_dump_func(), ast_cli_args::fd, OBJ_NODATA, peer_dump_func(), regl, and ast_cli_entry::usage.

17526 {
17527    char tmp[256];
17528    
17529    switch (cmd) {
17530    case CLI_INIT:
17531       e->command = "sip show objects";
17532       e->usage =
17533          "Usage: sip show objects\n"
17534          "       Lists status of known SIP objects\n";
17535       return NULL;
17536    case CLI_GENERATE:
17537       return NULL;
17538    }  
17539 
17540    if (a->argc != 3)
17541       return CLI_SHOWUSAGE;
17542    ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
17543    ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers");
17544    ast_cli(a->fd, "-= Peer objects by IP =-\n\n"); 
17545    ao2_t_callback(peers_by_ip, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers_by_ip");
17546    ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs);
17547    ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &regl);
17548    ast_cli(a->fd, "-= Dialog objects:\n\n");
17549    ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs");
17550    return CLI_SUCCESS;
17551 }

static char * sip_show_peer ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show one peer in detail.

Definition at line 17959 of file chan_sip.c.

References _sip_show_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

17960 {
17961    switch (cmd) {
17962    case CLI_INIT:
17963       e->command = "sip show peer";
17964       e->usage =
17965          "Usage: sip show peer <name> [load]\n"
17966          "       Shows all details on one SIP peer and the current status.\n"
17967          "       Option \"load\" forces lookup of peer in realtime storage.\n";
17968       return NULL;
17969    case CLI_GENERATE:
17970       return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
17971    }
17972    return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
17973 }

static char * sip_show_peers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI Show Peers command.

Definition at line 17261 of file chan_sip.c.

References _sip_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

17262 {
17263    switch (cmd) {
17264    case CLI_INIT:
17265       e->command = "sip show peers";
17266       e->usage =
17267          "Usage: sip show peers [like <pattern>]\n"
17268          "       Lists all known SIP peers.\n"
17269          "       Optional regular expression pattern is used to filter the peer list.\n";
17270       return NULL;
17271    case CLI_GENERATE:
17272       return NULL;
17273    }
17274 
17275    return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
17276 }

static char * sip_show_registry ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show SIP Registry (registrations with other SIP proxies.

Definition at line 18494 of file chan_sip.c.

References ast_cli_args::argc, ast_cli(), ast_localtime(), ast_strftime(), ast_strlen_zero(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, regl, regstate2str(), and ast_cli_entry::usage.

18495 {
18496 #define FORMAT2 "%-39.39s %-6.6s %-12.12s  %8.8s %-20.20s %-25.25s\n"
18497 #define FORMAT  "%-39.39s %-6.6s %-12.12s  %8d %-20.20s %-25.25s\n"
18498    char host[80];
18499    char user[80];
18500    char tmpdat[256];
18501    struct ast_tm tm;
18502    int counter = 0;
18503 
18504    switch (cmd) {
18505    case CLI_INIT:
18506       e->command = "sip show registry";
18507       e->usage =
18508          "Usage: sip show registry\n"
18509          "       Lists all registration requests and status.\n";
18510       return NULL;
18511    case CLI_GENERATE:
18512       return NULL;
18513    }
18514 
18515    if (a->argc != 3)
18516       return CLI_SHOWUSAGE;
18517    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time");
18518    
18519    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
18520       ASTOBJ_RDLOCK(iterator);
18521       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
18522       snprintf(user, sizeof(user), "%s", iterator->username);
18523       if (!ast_strlen_zero(iterator->regdomain)) {
18524          snprintf(tmpdat, sizeof(tmpdat), "%s", user);
18525          snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);}
18526       if (iterator->regdomainport) {
18527          snprintf(tmpdat, sizeof(tmpdat), "%s", user);
18528          snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);}
18529       if (iterator->regtime.tv_sec) {
18530          ast_localtime(&iterator->regtime, &tm, NULL);
18531          ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
18532       } else
18533          tmpdat[0] = '\0';
18534       ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
18535       ASTOBJ_UNLOCK(iterator);
18536       counter++;
18537    } while(0));
18538    ast_cli(a->fd, "%d SIP registrations.\n", counter);
18539    return CLI_SUCCESS;
18540 #undef FORMAT
18541 #undef FORMAT2
18542 }

static char * sip_show_sched ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 18451 of file chan_sip.c.

References __sip_autodestruct(), ast_cli(), ast_sched_report(), ast_str_alloca, ast_str_buffer(), auto_congest(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, expire_register(), ast_cli_args::fd, retrans_pkt(), sip_poke_noanswer(), sip_poke_peer_s(), sip_reg_timeout(), sip_reinvite_retry(), sip_reregister(), and ast_cli_entry::usage.

18452 {
18453    struct ast_str *cbuf;
18454    struct ast_cb_names cbnames = {9, { "retrans_pkt",
18455                                         "__sip_autodestruct",
18456                                         "expire_register",
18457                                         "auto_congest",
18458                                         "sip_reg_timeout",
18459                                         "sip_poke_peer_s",
18460                                         "sip_poke_noanswer",
18461                                         "sip_reregister",
18462                                         "sip_reinvite_retry"},
18463                            { retrans_pkt,
18464                                      __sip_autodestruct,
18465                                      expire_register,
18466                                      auto_congest,
18467                                      sip_reg_timeout,
18468                                      sip_poke_peer_s,
18469                                      sip_poke_noanswer,
18470                                      sip_reregister,
18471                                      sip_reinvite_retry}};
18472    
18473    switch (cmd) {
18474    case CLI_INIT:
18475       e->command = "sip show sched";
18476       e->usage =
18477          "Usage: sip show sched\n"
18478          "       Shows stats on what's in the sched queue at the moment\n";
18479       return NULL;
18480    case CLI_GENERATE:
18481       return NULL;
18482    }
18483 
18484    cbuf = ast_str_alloca(2048);
18485 
18486    ast_cli(a->fd, "\n");
18487    ast_sched_report(sched, &cbuf, &cbnames);
18488    ast_cli(a->fd, "%s", ast_str_buffer(cbuf));
18489 
18490    return CLI_SUCCESS;
18491 }

static char * sip_show_settings ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

List global settings for the SIP channel.

Definition at line 18685 of file chan_sip.c.

References ast_ha::addr, allowoverlap2str(), ao2_t_ref, ast_cli_args::argc, ast_check_realtime(), ast_cli(), AST_CLI_ONOFF, AST_CLI_YESNO, ast_getformatname_multiple(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_tos2str(), bindaddr, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, default_prefs, dtmfmode2str(), ast_tls_config::enabled, externaddr, FALSE, faxec2str(), ast_cli_args::fd, get_transport(), get_transport_list(), global_jbconf, ast_jb_conf::impl, ast_tcptls_session_args::local_address, ast_jb_conf::max_size, ast_ha::netmask, ast_ha::next, prefix, print_codec_to_cli(), ast_jb_conf::resync_threshold, S_OR, sip_cfg, stmode2str(), strefresherparam2str(), ast_jb_conf::target_extra, transfermode2str(), and ast_cli_entry::usage.

18686 {
18687    int realtimepeers;
18688    int realtimeregs;
18689    char codec_buf[SIPBUFSIZE];
18690    const char *msg;  /* temporary msg pointer */
18691    struct sip_auth_container *credentials;
18692 
18693    switch (cmd) {
18694    case CLI_INIT:
18695       e->command = "sip show settings";
18696       e->usage =
18697          "Usage: sip show settings\n"
18698          "       Provides detailed list of the configuration of the SIP channel.\n";
18699       return NULL;
18700    case CLI_GENERATE:
18701       return NULL;
18702    }
18703 
18704    if (a->argc != 3)
18705       return CLI_SHOWUSAGE;
18706 
18707    realtimepeers = ast_check_realtime("sippeers");
18708    realtimeregs = ast_check_realtime("sipregs");
18709 
18710    ast_mutex_lock(&authl_lock);
18711    credentials = authl;
18712    if (credentials) {
18713       ao2_t_ref(credentials, +1, "Ref global auth for show");
18714    }
18715    ast_mutex_unlock(&authl_lock);
18716 
18717    ast_cli(a->fd, "\n\nGlobal Settings:\n");
18718    ast_cli(a->fd, "----------------\n");
18719    ast_cli(a->fd, "  UDP Bindaddress:        %s\n", ast_sockaddr_stringify(&bindaddr));
18720    if (ast_sockaddr_is_ipv6(&bindaddr) && ast_sockaddr_is_any(&bindaddr)) {
18721       ast_cli(a->fd, "  ** Additional Info:\n");
18722       ast_cli(a->fd, "     [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n");
18723    }
18724    ast_cli(a->fd, "  TCP SIP Bindaddress:    %s\n",
18725       sip_cfg.tcp_enabled != FALSE ?
18726             ast_sockaddr_stringify(&sip_tcp_desc.local_address) :
18727             "Disabled");
18728    ast_cli(a->fd, "  TLS SIP Bindaddress:    %s\n",
18729       default_tls_cfg.enabled != FALSE ?
18730             ast_sockaddr_stringify(&sip_tls_desc.local_address) :
18731             "Disabled");
18732    ast_cli(a->fd, "  Videosupport:           %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT)));
18733    ast_cli(a->fd, "  Textsupport:            %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT)));
18734    ast_cli(a->fd, "  Ignore SDP sess. ver.:  %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION)));
18735    ast_cli(a->fd, "  AutoCreate Peer:        %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer));
18736    ast_cli(a->fd, "  Match Auth Username:    %s\n", AST_CLI_YESNO(global_match_auth_username));
18737    ast_cli(a->fd, "  Allow unknown access:   %s\n", AST_CLI_YESNO(sip_cfg.allowguest));
18738    ast_cli(a->fd, "  Allow subscriptions:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
18739    ast_cli(a->fd, "  Allow overlap dialing:  %s\n", allowoverlap2str(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)));
18740    ast_cli(a->fd, "  Allow promisc. redir:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR)));
18741    ast_cli(a->fd, "  Enable call counters:   %s\n", AST_CLI_YESNO(global_callcounter));
18742    ast_cli(a->fd, "  SIP domain support:     %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list)));
18743    ast_cli(a->fd, "  Realm. auth:            %s\n", AST_CLI_YESNO(credentials != NULL));
18744    if (credentials) {
18745       struct sip_auth *auth;
18746 
18747       AST_LIST_TRAVERSE(&credentials->list, auth, node) {
18748          ast_cli(a->fd, "  Realm. auth entry:      Realm %-15.15s User %-10.20s %s\n",
18749             auth->realm,
18750             auth->username,
18751             !ast_strlen_zero(auth->secret)
18752                ? "<Secret set>"
18753                : (!ast_strlen_zero(auth->md5secret)
18754                   ? "<MD5secret set>" : "<Not set>"));
18755       }
18756       ao2_t_ref(credentials, -1, "Unref global auth for show");
18757    }
18758    ast_cli(a->fd, "  Our auth realm          %s\n", sip_cfg.realm);
18759    ast_cli(a->fd, "  Use domains as realms:  %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm));
18760    ast_cli(a->fd, "  Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains));
18761    ast_cli(a->fd, "  URI user is phone no:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE)));
18762    ast_cli(a->fd, "  Always auth rejects:    %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject));
18763    ast_cli(a->fd, "  Direct RTP setup:       %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup));
18764    ast_cli(a->fd, "  User Agent:             %s\n", global_useragent);
18765    ast_cli(a->fd, "  SDP Session Name:       %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
18766    ast_cli(a->fd, "  SDP Owner Name:         %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner);
18767    ast_cli(a->fd, "  Reg. context:           %s\n", S_OR(sip_cfg.regcontext, "(not set)"));
18768    ast_cli(a->fd, "  Regexten on Qualify:    %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify));
18769    ast_cli(a->fd, "  Legacy userfield parse: %s\n", AST_CLI_YESNO(sip_cfg.legacy_useroption_parsing));
18770    ast_cli(a->fd, "  Caller ID:              %s\n", default_callerid);
18771    if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) {
18772       ast_cli(a->fd, "  From: Domain:           %s:%d\n", default_fromdomain, default_fromdomainport);
18773    } else {
18774       ast_cli(a->fd, "  From: Domain:           %s\n", default_fromdomain);
18775    }
18776    ast_cli(a->fd, "  Record SIP history:     %s\n", AST_CLI_ONOFF(recordhistory));
18777    ast_cli(a->fd, "  Call Events:            %s\n", AST_CLI_ONOFF(sip_cfg.callevents));
18778    ast_cli(a->fd, "  Auth. Failure Events:   %s\n", AST_CLI_ONOFF(global_authfailureevents));
18779 
18780    ast_cli(a->fd, "  T.38 support:           %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
18781    ast_cli(a->fd, "  T.38 EC mode:           %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
18782    ast_cli(a->fd, "  T.38 MaxDtgrm:          %u\n", global_t38_maxdatagram);
18783    if (!realtimepeers && !realtimeregs)
18784       ast_cli(a->fd, "  SIP realtime:           Disabled\n" );
18785    else
18786       ast_cli(a->fd, "  SIP realtime:           Enabled\n" );
18787    ast_cli(a->fd, "  Qualify Freq :          %d ms\n", global_qualifyfreq);
18788    ast_cli(a->fd, "  Q.850 Reason header:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON)));
18789    ast_cli(a->fd, "  Store SIP_CAUSE:        %s\n", AST_CLI_YESNO(global_store_sip_cause));
18790    ast_cli(a->fd, "\nNetwork QoS Settings:\n");
18791    ast_cli(a->fd, "---------------------------\n");
18792    ast_cli(a->fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
18793    ast_cli(a->fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
18794    ast_cli(a->fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
18795    ast_cli(a->fd, "  IP ToS RTP text:        %s\n", ast_tos2str(global_tos_text));
18796    ast_cli(a->fd, "  802.1p CoS SIP:         %u\n", global_cos_sip);
18797    ast_cli(a->fd, "  802.1p CoS RTP audio:   %u\n", global_cos_audio);
18798    ast_cli(a->fd, "  802.1p CoS RTP video:   %u\n", global_cos_video);
18799    ast_cli(a->fd, "  802.1p CoS RTP text:    %u\n", global_cos_text);
18800    ast_cli(a->fd, "  Jitterbuffer enabled:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED)));
18801    if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) {
18802       ast_cli(a->fd, "  Jitterbuffer forced:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED)));
18803       ast_cli(a->fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
18804       ast_cli(a->fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
18805       ast_cli(a->fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
18806       if (!strcasecmp(global_jbconf.impl, "adaptive")) {
18807          ast_cli(a->fd, "  Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra);
18808       }
18809       ast_cli(a->fd, "  Jitterbuffer log:       %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG)));
18810    }
18811 
18812    ast_cli(a->fd, "\nNetwork Settings:\n");
18813    ast_cli(a->fd, "---------------------------\n");
18814    /* determine if/how SIP address can be remapped */
18815    if (localaddr == NULL)
18816       msg = "Disabled, no localnet list";
18817    else if (ast_sockaddr_isnull(&externaddr))
18818       msg = "Disabled";
18819    else if (!ast_strlen_zero(externhost))
18820       msg = "Enabled using externhost";
18821    else
18822       msg = "Enabled using externaddr";
18823    ast_cli(a->fd, "  SIP address remapping:  %s\n", msg);
18824    ast_cli(a->fd, "  Externhost:             %s\n", S_OR(externhost, "<none>"));
18825    ast_cli(a->fd, "  Externaddr:             %s\n", ast_sockaddr_stringify(&externaddr));
18826    ast_cli(a->fd, "  Externrefresh:          %d\n", externrefresh);
18827    {
18828       struct ast_ha *d;
18829       const char *prefix = "Localnet:";
18830 
18831       for (d = localaddr; d ; prefix = "", d = d->next) {
18832          const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr));
18833          const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask));
18834          ast_cli(a->fd, "  %-24s%s/%s\n", prefix, addr, mask);
18835       }
18836    }
18837    ast_cli(a->fd, "\nGlobal Signalling Settings:\n");
18838    ast_cli(a->fd, "---------------------------\n");
18839    ast_cli(a->fd, "  Codecs:                 ");
18840    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability);
18841    ast_cli(a->fd, "%s\n", codec_buf);
18842    ast_cli(a->fd, "  Codec Order:            ");
18843    print_codec_to_cli(a->fd, &default_prefs);
18844    ast_cli(a->fd, "\n");
18845    ast_cli(a->fd, "  Relax DTMF:             %s\n", AST_CLI_YESNO(global_relaxdtmf));
18846    ast_cli(a->fd, "  RFC2833 Compensation:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE)));
18847    ast_cli(a->fd, "  Symmetric RTP:          %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP)));
18848    ast_cli(a->fd, "  Compact SIP headers:    %s\n", AST_CLI_YESNO(sip_cfg.compactheaders));
18849    ast_cli(a->fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
18850    ast_cli(a->fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
18851    ast_cli(a->fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
18852    ast_cli(a->fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
18853    ast_cli(a->fd, "  DNS SRV lookup:         %s\n", AST_CLI_YESNO(sip_cfg.srvlookup));
18854    ast_cli(a->fd, "  Pedantic SIP support:   %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking));
18855    ast_cli(a->fd, "  Reg. min duration       %d secs\n", min_expiry);
18856    ast_cli(a->fd, "  Reg. max duration:      %d secs\n", max_expiry);
18857    ast_cli(a->fd, "  Reg. default duration:  %d secs\n", default_expiry);
18858    ast_cli(a->fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
18859    ast_cli(a->fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
18860    ast_cli(a->fd, "  Outbound reg. retry 403:%d\n", global_reg_retry_403);
18861    ast_cli(a->fd, "  Notify ringing state:   %s\n", AST_CLI_YESNO(sip_cfg.notifyringing));
18862    if (sip_cfg.notifyringing) {
18863       ast_cli(a->fd, "    Include CID:          %s%s\n",
18864             AST_CLI_YESNO(sip_cfg.notifycid),
18865             sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : "");
18866    }
18867    ast_cli(a->fd, "  Notify hold state:      %s\n", AST_CLI_YESNO(sip_cfg.notifyhold));
18868    ast_cli(a->fd, "  SIP Transfer mode:      %s\n", transfermode2str(sip_cfg.allowtransfer));
18869    ast_cli(a->fd, "  Max Call Bitrate:       %d kbps\n", default_maxcallbitrate);
18870    ast_cli(a->fd, "  Auto-Framing:           %s\n", AST_CLI_YESNO(global_autoframing));
18871    ast_cli(a->fd, "  Outb. proxy:            %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name,
18872                      sip_cfg.outboundproxy.force ? "(forced)" : "");
18873    ast_cli(a->fd, "  Session Timers:         %s\n", stmode2str(global_st_mode));
18874    ast_cli(a->fd, "  Session Refresher:      %s\n", strefresherparam2str(global_st_refresher));
18875    ast_cli(a->fd, "  Session Expires:        %d secs\n", global_max_se);
18876    ast_cli(a->fd, "  Session Min-SE:         %d secs\n", global_min_se);
18877    ast_cli(a->fd, "  Timer T1:               %d\n", global_t1);
18878    ast_cli(a->fd, "  Timer T1 minimum:       %d\n", global_t1min);
18879    ast_cli(a->fd, "  Timer B:                %d\n", global_timer_b);
18880    ast_cli(a->fd, "  No premature media:     %s\n", AST_CLI_YESNO(global_prematuremediafilter));
18881    ast_cli(a->fd, "  Max forwards:           %d\n", sip_cfg.default_max_forwards);
18882 
18883    ast_cli(a->fd, "\nDefault Settings:\n");
18884    ast_cli(a->fd, "-----------------\n");
18885    ast_cli(a->fd, "  Allowed transports:     %s\n", get_transport_list(default_transports));
18886    ast_cli(a->fd, "  Outbound transport:    %s\n", get_transport(default_primary_transport));
18887    ast_cli(a->fd, "  Context:                %s\n", sip_cfg.default_context);
18888    ast_cli(a->fd, "  Force rport:            %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT)));
18889    ast_cli(a->fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
18890    ast_cli(a->fd, "  Qualify:                %d\n", default_qualify);
18891    ast_cli(a->fd, "  Use ClientCode:         %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE)));
18892    ast_cli(a->fd, "  Progress inband:        %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_NO)));
18893    ast_cli(a->fd, "  Language:               %s\n", default_language);
18894    ast_cli(a->fd, "  MOH Interpret:          %s\n", default_mohinterpret);
18895    ast_cli(a->fd, "  MOH Suggest:            %s\n", default_mohsuggest);
18896    ast_cli(a->fd, "  Voice Mail Extension:   %s\n", default_vmexten);
18897 
18898    
18899    if (realtimepeers || realtimeregs) {
18900       ast_cli(a->fd, "\nRealtime SIP Settings:\n");
18901       ast_cli(a->fd, "----------------------\n");
18902       ast_cli(a->fd, "  Realtime Peers:         %s\n", AST_CLI_YESNO(realtimepeers));
18903       ast_cli(a->fd, "  Realtime Regs:          %s\n", AST_CLI_YESNO(realtimeregs));
18904       ast_cli(a->fd, "  Cache Friends:          %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)));
18905       ast_cli(a->fd, "  Update:                 %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate));
18906       ast_cli(a->fd, "  Ignore Reg. Expire:     %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire));
18907       ast_cli(a->fd, "  Save sys. name:         %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname));
18908       ast_cli(a->fd, "  Auto Clear:             %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled");
18909    }
18910    ast_cli(a->fd, "\n----\n");
18911    return CLI_SUCCESS;
18912 }

static char* sip_show_tcp ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show active TCP connections.

Definition at line 17076 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli(), ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, get_transport(), and ast_cli_entry::usage.

17077 {
17078    struct sip_threadinfo *th;
17079    struct ao2_iterator i;
17080 
17081 #define FORMAT2 "%-47.47s %9.9s %6.6s\n"
17082 #define FORMAT  "%-47.47s %-9.9s %-6.6s\n"
17083 
17084    switch (cmd) {
17085    case CLI_INIT:
17086       e->command = "sip show tcp";
17087       e->usage =
17088          "Usage: sip show tcp\n"
17089          "       Lists all active TCP/TLS sessions.\n";
17090       return NULL;
17091    case CLI_GENERATE:
17092       return NULL;
17093    }
17094 
17095    if (a->argc != 3)
17096       return CLI_SHOWUSAGE;
17097 
17098    ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type");
17099 
17100    i = ao2_iterator_init(threadt, 0);
17101    while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
17102       ast_cli(a->fd, FORMAT,
17103          ast_sockaddr_stringify(&th->tcptls_session->remote_address),
17104          get_transport(th->type),
17105          (th->tcptls_session->client ? "Client" : "Server"));
17106       ao2_t_ref(th, -1, "decrement ref from iterator");
17107    }
17108    ao2_iterator_destroy(&i);
17109 
17110    return CLI_SUCCESS;
17111 #undef FORMAT
17112 #undef FORMAT2
17113 }

static char* sip_show_user ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show one user in detail.

Definition at line 18375 of file chan_sip.c.

References ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), AST_CLI_YESNO, ast_describe_caller_presentation(), ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_user(), FALSE, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, print_codec_to_cli(), print_group(), stmode2str(), strefresherparam2str(), transfermode2str(), TRUE, unref_peer(), ast_cli_entry::usage, ast_variable::value, and ast_cli_args::word.

18376 {
18377    char cbuf[256];
18378    struct sip_peer *user;
18379    struct ast_variable *v;
18380    int load_realtime;
18381 
18382    switch (cmd) {
18383    case CLI_INIT:
18384       e->command = "sip show user";
18385       e->usage =
18386          "Usage: sip show user <name> [load]\n"
18387          "       Shows all details on one SIP user and the current status.\n"
18388          "       Option \"load\" forces lookup of peer in realtime storage.\n";
18389       return NULL;
18390    case CLI_GENERATE:
18391       return complete_sip_show_user(a->line, a->word, a->pos, a->n);
18392    }
18393 
18394    if (a->argc < 4)
18395       return CLI_SHOWUSAGE;
18396 
18397    /* Load from realtime storage? */
18398    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE;
18399 
18400    if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) {
18401       ao2_lock(user);
18402       ast_cli(a->fd, "\n\n");
18403       ast_cli(a->fd, "  * Name       : %s\n", user->name);
18404       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
18405       ast_cli(a->fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
18406       ast_cli(a->fd, "  Context      : %s\n", user->context);
18407       ast_cli(a->fd, "  Language     : %s\n", user->language);
18408       if (!ast_strlen_zero(user->accountcode))
18409          ast_cli(a->fd, "  Accountcode  : %s\n", user->accountcode);
18410       ast_cli(a->fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
18411       ast_cli(a->fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
18412       ast_cli(a->fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
18413       ast_cli(a->fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
18414       ast_cli(a->fd, "  Call limit   : %d\n", user->call_limit);
18415       ast_cli(a->fd, "  Callgroup    : ");
18416       print_group(a->fd, user->callgroup, 0);
18417       ast_cli(a->fd, "  Pickupgroup  : ");
18418       print_group(a->fd, user->pickupgroup, 0);
18419       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
18420       ast_cli(a->fd, "  ACL          : %s\n", AST_CLI_YESNO(user->ha != NULL));
18421       ast_cli(a->fd, "  Sess-Timers  : %s\n", stmode2str(user->stimer.st_mode_oper));
18422       ast_cli(a->fd, "  Sess-Refresh : %s\n", strefresherparam2str(user->stimer.st_ref));
18423       ast_cli(a->fd, "  Sess-Expires : %d secs\n", user->stimer.st_max_se);
18424       ast_cli(a->fd, "  Sess-Min-SE  : %d secs\n", user->stimer.st_min_se);
18425       ast_cli(a->fd, "  RTP Engine   : %s\n", user->engine);
18426 
18427       ast_cli(a->fd, "  Codec Order  : (");
18428       print_codec_to_cli(a->fd, &user->prefs);
18429       ast_cli(a->fd, ")\n");
18430 
18431       ast_cli(a->fd, "  Auto-Framing:  %s \n", AST_CLI_YESNO(user->autoframing));
18432       if (user->chanvars) {
18433          ast_cli(a->fd, "  Variables    :\n");
18434          for (v = user->chanvars ; v ; v = v->next)
18435             ast_cli(a->fd, "                 %s = %s\n", v->name, v->value);
18436       }
18437 
18438       ast_cli(a->fd, "\n");
18439 
18440       ao2_unlock(user);
18441       unref_peer(user, "sip show user");
18442    } else {
18443       ast_cli(a->fd, "User %s not found.\n", a->argv[3]);
18444       ast_cli(a->fd, "\n");
18445    }
18446 
18447    return CLI_SUCCESS;
18448 }

static char* sip_show_users ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI Command 'SIP Show Users'.

Definition at line 17116 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_YESNO, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, TRUE, unref_peer(), and ast_cli_entry::usage.

17117 {
17118    regex_t regexbuf;
17119    int havepattern = FALSE;
17120    struct ao2_iterator user_iter;
17121    struct sip_peer *user;
17122 
17123 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
17124 
17125    switch (cmd) {
17126    case CLI_INIT:
17127       e->command = "sip show users";
17128       e->usage =
17129          "Usage: sip show users [like <pattern>]\n"
17130          "       Lists all known SIP users.\n"
17131          "       Optional regular expression pattern is used to filter the user list.\n";
17132       return NULL;
17133    case CLI_GENERATE:
17134       return NULL;
17135    }
17136 
17137    switch (a->argc) {
17138    case 5:
17139       if (!strcasecmp(a->argv[3], "like")) {
17140          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
17141             return CLI_SHOWUSAGE;
17142          havepattern = TRUE;
17143       } else
17144          return CLI_SHOWUSAGE;
17145    case 3:
17146       break;
17147    default:
17148       return CLI_SHOWUSAGE;
17149    }
17150 
17151    ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "Forcerport");
17152 
17153    user_iter = ao2_iterator_init(peers, 0);
17154    while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) {
17155       ao2_lock(user);
17156       if (!(user->type & SIP_TYPE_USER)) {
17157          ao2_unlock(user);
17158          unref_peer(user, "sip show users");
17159          continue;
17160       }
17161 
17162       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0)) {
17163          ao2_unlock(user);
17164          unref_peer(user, "sip show users");
17165          continue;
17166       }
17167 
17168       ast_cli(a->fd, FORMAT, user->name,
17169          user->secret,
17170          user->accountcode,
17171          user->context,
17172          AST_CLI_YESNO(user->ha != NULL),
17173          AST_CLI_YESNO(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT)));
17174       ao2_unlock(user);
17175       unref_peer(user, "sip show users");
17176    }
17177    ao2_iterator_destroy(&user_iter);
17178 
17179    if (havepattern)
17180       regfree(&regexbuf);
17181 
17182    return CLI_SUCCESS;
17183 #undef FORMAT
17184 }

static int sip_sipredirect ( struct sip_pvt *  p,
const char *  dest 
) [static]

Transfer call before connect with a 302 redirect.

Note:
Called by the transfer() dialplan application through the sip_transfer() pbx interface function if the call is in ringing state
Todo:
Fix this function so that we wait for reply to the REFER and react to errors, denials or other issues the other end might have.

Definition at line 30414 of file chan_sip.c.

References AST_CONTROL_TRANSFER, ast_copy_string(), ast_log(), ast_queue_control_data(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), AST_TRANSFER_SUCCESS, get_header(), LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), and transmit_response_reliable().

Referenced by sip_transfer().

30415 {
30416    char *cdest;
30417    char *extension, *domain;
30418 
30419    cdest = ast_strdupa(dest);
30420 
30421    extension = strsep(&cdest, "@");
30422    domain = cdest;
30423    if (ast_strlen_zero(extension)) {
30424       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
30425       return 0;
30426    }
30427 
30428    /* we'll issue the redirect message here */
30429    if (!domain) {
30430       char *local_to_header;
30431       char to_header[256];
30432 
30433       ast_copy_string(to_header, get_header(&p->initreq, "To"), sizeof(to_header));
30434       if (ast_strlen_zero(to_header)) {
30435          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
30436          return 0;
30437       }
30438       if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:")))
30439          && (local_to_header = strchr(local_to_header, '@'))) {
30440          char ldomain[256];
30441 
30442          memset(ldomain, 0, sizeof(ldomain));
30443          local_to_header++;
30444          /* This is okey because lhost and lport are as big as tmp */
30445          sscanf(local_to_header, "%256[^<>; ]", ldomain);
30446          if (ast_strlen_zero(ldomain)) {
30447             ast_log(LOG_ERROR, "Can't find the host address\n");
30448             return 0;
30449          }
30450          domain = ast_strdupa(ldomain);
30451       }
30452    }
30453 
30454    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain);
30455    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
30456 
30457    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
30458    sip_alreadygone(p);
30459 
30460    if (p->owner) {
30461       enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
30462       ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
30463    }
30464    /* hangup here */
30465    return 0;
30466 }

static struct sip_st_dlg * sip_st_alloc ( struct sip_pvt *const   p  )  [static, read]

Allocate Session-Timers struct w/in dialog.

Definition at line 7944 of file chan_sip.c.

References ast_calloc, ast_log(), and LOG_ERROR.

Referenced by handle_request_invite_st(), and st_get_mode().

07945 {
07946    struct sip_st_dlg *stp;
07947 
07948    if (p->stimer) {
07949       ast_log(LOG_ERROR, "Session-Timer struct already allocated\n");
07950       return p->stimer;
07951    }
07952 
07953    if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg))))
07954       return NULL;
07955 
07956    p->stimer = stp;
07957 
07958    stp->st_schedid = -1;           /* Session-Timers ast_sched scheduler id */
07959 
07960    return p->stimer;
07961 }

static int sip_standard_port ( enum sip_transport  type,
int  port 
) [static]

Returns the port to use for this socket.

Parameters:
type The type of transport used
port Port we are checking to see if it's the standard port.
Note:
port is expected in host byte order

Definition at line 26243 of file chan_sip.c.

Referenced by initreqprep(), and transmit_notify_with_mwi().

26244 {
26245    if (type & SIP_TRANSPORT_TLS)
26246       return port == STANDARD_TLS_PORT;
26247    else
26248       return port == STANDARD_SIP_PORT;
26249 }

static int sip_subscribe_mwi ( const char *  value,
int  lineno 
) [static]

Parse mwi=> line in sip.conf and add to list.

--- SIP MWI Subscription support

Definition at line 8577 of file chan_sip.c.

References ast_calloc_with_stringfields, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, hostname, LOG_WARNING, mailbox, secret, sip_subscribe_mwi_destroy(), and submwil.

Referenced by reload_config().

08578 {
08579    struct sip_subscription_mwi *mwi;
08580    int portnum = 0;
08581    enum sip_transport transport = SIP_TRANSPORT_UDP;
08582    char buf[256] = "";
08583    char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL;
08584 
08585    if (!value) {
08586       return -1;
08587    }
08588 
08589    ast_copy_string(buf, value, sizeof(buf));
08590 
08591    username = buf;
08592 
08593    if ((hostname = strrchr(buf, '@'))) {
08594       *hostname++ = '\0';
08595    } else {
08596       return -1;
08597    }
08598 
08599    if ((secret = strchr(username, ':'))) {
08600       *secret++ = '\0';
08601       if ((authuser = strchr(secret, ':'))) {
08602          *authuser++ = '\0';
08603       }
08604    }
08605 
08606    if ((mailbox = strchr(hostname, '/'))) {
08607       *mailbox++ = '\0';
08608    }
08609 
08610    if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) {
08611       ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno);
08612       return -1;
08613    }
08614 
08615    if ((porta = strchr(hostname, ':'))) {
08616       *porta++ = '\0';
08617       if (!(portnum = atoi(porta))) {
08618          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08619          return -1;
08620       }
08621    }
08622 
08623    if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) {
08624       return -1;
08625    }
08626 
08627    ASTOBJ_INIT(mwi);
08628    ast_string_field_set(mwi, username, username);
08629    if (secret) {
08630       ast_string_field_set(mwi, secret, secret);
08631    }
08632    if (authuser) {
08633       ast_string_field_set(mwi, authuser, authuser);
08634    }
08635    ast_string_field_set(mwi, hostname, hostname);
08636    ast_string_field_set(mwi, mailbox, mailbox);
08637    mwi->resub = -1;
08638    mwi->portno = portnum;
08639    mwi->transport = transport;
08640 
08641    ASTOBJ_CONTAINER_LINK(&submwil, mwi);
08642    ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
08643 
08644    return 0;
08645 }

static void sip_subscribe_mwi_destroy ( struct sip_subscription_mwi *  mwi  )  [static]

Destroy MWI subscription object.

Definition at line 5951 of file chan_sip.c.

References ast_free, AST_SCHED_DEL, and ast_string_field_free_memory.

Referenced by __sip_subscribe_mwi_do(), handle_response_subscribe(), sip_send_all_mwi_subscriptions(), sip_subscribe_mwi(), sip_subscribe_mwi_do(), and unload_module().

05952 {
05953    if (mwi->call) {
05954       mwi->call->mwi = NULL;
05955       mwi->call = dialog_unref(mwi->call, "sip_subscription_mwi destruction");
05956    }
05957 
05958    AST_SCHED_DEL(sched, mwi->resub);
05959    ast_string_field_free_memory(mwi);
05960    ast_free(mwi);
05961 }

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

Send a subscription or resubscription for MWI.

Definition at line 12780 of file chan_sip.c.

References __sip_subscribe_mwi_do(), ASTOBJ_UNREF, and sip_subscribe_mwi_destroy().

Referenced by handle_response_subscribe(), and sip_send_all_mwi_subscriptions().

12781 {
12782    struct sip_subscription_mwi *mwi = (struct sip_subscription_mwi*)data;
12783    
12784    if (!mwi) {
12785       return -1;
12786    }
12787    
12788    mwi->resub = -1;
12789    __sip_subscribe_mwi_do(mwi);
12790    ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
12791    
12792    return 0;
12793 }

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

Called to deny a T38 reinvite if the core does not respond to our request.

Definition at line 22923 of file chan_sip.c.

References change_t38_state(), sip_pvt_lock, sip_pvt_unlock, and transmit_response_reliable().

Referenced by handle_request_invite().

22924 {
22925    struct sip_pvt *p = (struct sip_pvt *) data;
22926 
22927    sip_pvt_lock(p);
22928    /* an application may have taken ownership of the T.38 negotiation on this
22929     * channel while we were waiting to grab the lock... if it did, the scheduler
22930     * id will have been reset to -1, which is our indication that we do *not*
22931     * want to abort the negotiation process
22932     */
22933    if (p->t38id != -1) {
22934       change_t38_state(p, T38_DISABLED);
22935       transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
22936       p->t38id = -1;
22937       dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr");
22938    }
22939    sip_pvt_unlock(p);
22940    return 0;
22941 }

static struct ast_tcptls_session_instance* sip_tcp_locate ( struct ast_sockaddr s  )  [static, read]

Find thread for TCP/TLS session (based on IP/Port.

Note:
This function returns an astobj2 reference

Definition at line 26268 of file chan_sip.c.

References ao2_callback, ao2_ref, ao2_t_ref, and threadinfo_locate_cb().

Referenced by sip_prepare_socket().

26269 {
26270    struct sip_threadinfo *th;
26271    struct ast_tcptls_session_instance *tcptls_instance = NULL;
26272 
26273    if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) {
26274       tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session);
26275       ao2_t_ref(th, -1, "decrement ref from callback");
26276    }
26277 
26278    return tcptls_instance;
26279 }

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

SIP TCP connection handler.

Definition at line 2469 of file chan_sip.c.

References _sip_tcp_helper_thread().

Referenced by sip_prepare_socket().

02470 {
02471    struct ast_tcptls_session_instance *tcptls_session = data;
02472 
02473    return _sip_tcp_helper_thread(tcptls_session);
02474 }

static void sip_tcptls_client_args_destructor ( void *  obj  )  [static]

Definition at line 2349 of file chan_sip.c.

References args, ast_free, ast_ssl_teardown(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tcptls_session_args::name, ast_tls_config::pvtfile, and ast_tcptls_session_args::tls_cfg.

Referenced by sip_prepare_socket().

02350 {
02351    struct ast_tcptls_session_args *args = obj;
02352    if (args->tls_cfg) {
02353       ast_free(args->tls_cfg->certfile);
02354       ast_free(args->tls_cfg->pvtfile);
02355       ast_free(args->tls_cfg->cipher);
02356       ast_free(args->tls_cfg->cafile);
02357       ast_free(args->tls_cfg->capath);
02358 
02359       ast_ssl_teardown(args->tls_cfg);
02360    }
02361    ast_free(args->tls_cfg);
02362    ast_free((char *) args->name);
02363 }

static int sip_tcptls_read ( struct sip_request *  req,
struct ast_tcptls_session_instance tcptls_session,
int  authenticated,
time_t  start 
) [static]

Read SIP request or response from a TCP/TLS connection.

Parameters:
req The request structure to be filled in
tcptls_session The TCP/TLS connection from which to read
Return values:
-1 Failed to read data
0 Successfully read data

Definition at line 2661 of file chan_sip.c.

References ast_debug, ast_log(), ast_sockaddr_stringify(), ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), ast_tcptls_server_read(), ast_wait_for_input(), check_message_integrity(), ast_tcptls_session_instance::client, errno, ast_tcptls_session_instance::fd, LOG_WARNING, MESSAGE_FRAGMENT, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::remote_address, and sip_check_authtimeout().

Referenced by _sip_tcp_helper_thread().

02663 {
02664    enum message_integrity message_integrity = MESSAGE_FRAGMENT;
02665 
02666    while (message_integrity == MESSAGE_FRAGMENT) {
02667       size_t datalen;
02668 
02669       if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
02670          char readbuf[4097];
02671          int timeout;
02672          int res;
02673          if (!tcptls_session->client && !authenticated) {
02674             if ((timeout = sip_check_authtimeout(start)) < 0) {
02675                return -1;
02676             }
02677 
02678             if (timeout == 0) {
02679                ast_debug(2, "SIP TCP/TLS server timed out\n");
02680                return -1;
02681             }
02682          } else {
02683             timeout = -1;
02684          }
02685          res = ast_wait_for_input(tcptls_session->fd, timeout);
02686          if (res < 0) {
02687             ast_debug(2, "SIP TCP/TLS server :: ast_wait_for_input returned %d\n", res);
02688             return -1;
02689          } else if (res == 0) {
02690             ast_debug(2, "SIP TCP/TLS server timed out\n");
02691             return -1;
02692          }
02693 
02694          res = ast_tcptls_server_read(tcptls_session, readbuf, sizeof(readbuf) - 1);
02695          if (res < 0) {
02696             if (errno == EAGAIN || errno == EINTR) {
02697                continue;
02698             }
02699             ast_debug(2, "SIP TCP/TLS server error when receiving data\n");
02700             return -1;
02701          } else if (res == 0) {
02702             ast_debug(2, "SIP TCP/TLS server has shut down\n");
02703             return -1;
02704          }
02705          readbuf[res] = '\0';
02706          ast_str_append(&req->data, 0, "%s", readbuf);
02707       } else {
02708          ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf));
02709          ast_str_reset(tcptls_session->overflow_buf);
02710       }
02711 
02712       datalen = ast_str_strlen(req->data);
02713       if (datalen > SIP_MAX_PACKET_SIZE) {
02714          ast_log(LOG_WARNING, "Rejecting TCP/TLS packet from '%s' because way too large: %zu\n",
02715             ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
02716          return -1;
02717       }
02718 
02719       message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf);
02720    }
02721 
02722    return 0;
02723 }

static int sip_tcptls_write ( struct ast_tcptls_session_instance tcptls_session,
const void *  buf,
size_t  len 
) [static]

used to indicate to a tcptls thread that data is ready to be written

Definition at line 2411 of file chan_sip.c.

References ao2_alloc, ao2_lock, ao2_t_find, ao2_t_ref, ao2_unlock, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_str_create(), ast_str_set(), errno, ast_tcptls_session_instance::fd, ast_tcptls_session_instance::lock, LOG_ERROR, OBJ_POINTER, and tcptls_packet_destructor().

Referenced by __sip_xmit().

02412 {
02413    int res = len;
02414    struct sip_threadinfo *th = NULL;
02415    struct tcptls_packet *packet = NULL;
02416    struct sip_threadinfo tmp = {
02417       .tcptls_session = tcptls_session,
02418    };
02419    enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA;
02420 
02421    if (!tcptls_session) {
02422       return XMIT_ERROR;
02423    }
02424 
02425    ast_mutex_lock(&tcptls_session->lock);
02426 
02427    if ((tcptls_session->fd == -1) ||
02428       !(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")) ||
02429       !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) ||
02430       !(packet->data = ast_str_create(len))) {
02431       goto tcptls_write_setup_error;
02432    }
02433 
02434    /* goto tcptls_write_error should _NOT_ be used beyond this point */
02435    ast_str_set(&packet->data, 0, "%s", (char *) buf);
02436    packet->len = len;
02437 
02438    /* alert tcptls thread handler that there is a packet to be sent.
02439     * must lock the thread info object to guarantee control of the
02440     * packet queue */
02441    ao2_lock(th);
02442    if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) {
02443       ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno));
02444       ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet");
02445       packet = NULL;
02446       res = XMIT_ERROR;
02447    } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */
02448       AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry);
02449    }
02450    ao2_unlock(th);
02451 
02452    ast_mutex_unlock(&tcptls_session->lock);
02453    ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it");
02454    return res;
02455 
02456 tcptls_write_setup_error:
02457    if (th) {
02458       ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet");
02459    }
02460    if (packet) {
02461       ao2_t_ref(packet, -1, "could not allocate packet's data");
02462    }
02463    ast_mutex_unlock(&tcptls_session->lock);
02464 
02465    return XMIT_ERROR;
02466 }

static struct sip_threadinfo* sip_threadinfo_create ( struct ast_tcptls_session_instance tcptls_session,
int  transport 
) [static, read]

creates a sip_threadinfo object and links it into the threadt table.

Definition at line 2387 of file chan_sip.c.

References ao2_alloc, ao2_t_link, ao2_t_ref, ast_log(), errno, LOG_ERROR, sip_threadinfo_destructor(), and ast_tcptls_session_instance::ssl.

Referenced by _sip_tcp_helper_thread(), and sip_prepare_socket().

02388 {
02389    struct sip_threadinfo *th;
02390 
02391    if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) {
02392       return NULL;
02393    }
02394 
02395    th->alert_pipe[0] = th->alert_pipe[1] = -1;
02396 
02397    if (pipe(th->alert_pipe) == -1) {
02398       ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo");
02399       ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno));
02400       return NULL;
02401    }
02402    ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object");
02403    th->tcptls_session = tcptls_session;
02404    th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP);
02405    ao2_t_link(threadt, th, "Adding new tcptls helper thread");
02406    ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains");
02407    return th;
02408 }

static void sip_threadinfo_destructor ( void *  obj  )  [static]

Definition at line 2365 of file chan_sip.c.

References ao2_t_ref, and AST_LIST_REMOVE_HEAD.

Referenced by sip_threadinfo_create().

02366 {
02367    struct sip_threadinfo *th = obj;
02368    struct tcptls_packet *packet;
02369    if (th->alert_pipe[1] > -1) {
02370       close(th->alert_pipe[0]);
02371    }
02372    if (th->alert_pipe[1] > -1) {
02373       close(th->alert_pipe[1]);
02374    }
02375    th->alert_pipe[0] = th->alert_pipe[1] = -1;
02376 
02377    while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) {
02378       ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue");
02379    }
02380 
02381    if (th->tcptls_session) {
02382       ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object");
02383    }
02384 }

static int sip_transfer ( struct ast_channel ast,
const char *  dest 
) [static]

Transfer SIP call.

Definition at line 6974 of file chan_sip.c.

References ast_channel::_state, ast_debug, AST_STATE_RING, sip_pvt_lock, sip_pvt_unlock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().

06975 {
06976    struct sip_pvt *p = ast->tech_pvt;
06977    int res;
06978 
06979    if (!p) {
06980       ast_debug(1, "Asked to transfer channel %s with no pvt; ignoring\n",
06981             ast->name);
06982       return -1;
06983    }
06984 
06985    if (dest == NULL) /* functions below do not take a NULL */
06986       dest = "";
06987    sip_pvt_lock(p);
06988    if (ast->_state == AST_STATE_RING)
06989       res = sip_sipredirect(p, dest);
06990    else
06991       res = transmit_refer(p, dest);
06992    sip_pvt_unlock(p);
06993    return res;
06994 }

static char * sip_unregister ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Unregister (force expiration) a SIP peer in the registry via CLI.

Note:
This function does not tell the SIP device what's going on, so use it with great care.

Definition at line 18548 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_SCHED_DEL_UNREF, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_unregister(), expire_register(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ref_peer(), TRUE, unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.

18549 {
18550    struct sip_peer *peer;
18551    int load_realtime = 0;
18552 
18553    switch (cmd) {
18554    case CLI_INIT:
18555       e->command = "sip unregister";
18556       e->usage =
18557          "Usage: sip unregister <peer>\n"
18558          "       Unregister (force expiration) a SIP peer from the registry\n";
18559       return NULL;
18560    case CLI_GENERATE:
18561       return complete_sip_unregister(a->line, a->word, a->pos, a->n);
18562    }
18563    
18564    if (a->argc != 3)
18565       return CLI_SHOWUSAGE;
18566    
18567    if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) {
18568       if (peer->expire > 0) {
18569          AST_SCHED_DEL_UNREF(sched, peer->expire,
18570             unref_peer(peer, "remove register expire ref"));
18571          expire_register(ref_peer(peer, "ref for expire_register"));
18572          ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
18573       } else {
18574          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
18575       }
18576       unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call");
18577    } else {
18578       ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]);
18579    }
18580    
18581    return CLI_SUCCESS;
18582 }

static void sip_unregister_tests ( void   )  [static]
static int sip_write ( struct ast_channel ast,
struct ast_frame frame 
) [static]

Send frame to media channel (rtp).

Definition at line 6764 of file chan_sip.c.

References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_rtp_instance_update_source(), ast_rtp_instance_write(), ast_rtp_red_buffer(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), ast_frame_subclass::codec, ast_frame::frametype, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt_lock, sip_pvt_unlock, ast_frame::subclass, ast_channel::tech_pvt, transmit_provisional_response(), TRUE, and ast_channel::writeformat.

06765 {
06766    struct sip_pvt *p = ast->tech_pvt;
06767    int res = 0;
06768 
06769    switch (frame->frametype) {
06770    case AST_FRAME_VOICE:
06771       if (!(frame->subclass.codec & ast->nativeformats)) {
06772          char s1[512], s2[512], s3[512];
06773          ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n",
06774             ast_getformatname(frame->subclass.codec),
06775             ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK),
06776             ast_getformatname_multiple(s2, sizeof(s2), ast->readformat),
06777             ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat));
06778          return 0;
06779       }
06780       if (p) {
06781          sip_pvt_lock(p);
06782          if (p->t38.state == T38_ENABLED) {
06783             /* drop frame, can't sent VOICE frames while in T.38 mode */
06784             sip_pvt_unlock(p);
06785             break;
06786          } else if (p->rtp) {
06787             /* If channel is not up, activate early media session */
06788             if ((ast->_state != AST_STATE_UP) &&
06789                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06790                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06791                ast_rtp_instance_update_source(p->rtp);
06792                if (!global_prematuremediafilter) {
06793                   p->invitestate = INV_EARLY_MEDIA;
06794                   transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
06795                   ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
06796                }
06797             }
06798             p->lastrtptx = time(NULL);
06799             res = ast_rtp_instance_write(p->rtp, frame);
06800          }
06801          sip_pvt_unlock(p);
06802       }
06803       break;
06804    case AST_FRAME_VIDEO:
06805       if (p) {
06806          sip_pvt_lock(p);
06807          if (p->vrtp) {
06808             /* Activate video early media */
06809             if ((ast->_state != AST_STATE_UP) &&
06810                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06811                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06812                p->invitestate = INV_EARLY_MEDIA;
06813                transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
06814                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
06815             }
06816             p->lastrtptx = time(NULL);
06817             res = ast_rtp_instance_write(p->vrtp, frame);
06818          }
06819          sip_pvt_unlock(p);
06820       }
06821       break;
06822    case AST_FRAME_TEXT:
06823       if (p) {
06824          sip_pvt_lock(p);
06825          if (p->red) {
06826             ast_rtp_red_buffer(p->trtp, frame);
06827          } else {
06828             if (p->trtp) {
06829                /* Activate text early media */
06830                if ((ast->_state != AST_STATE_UP) &&
06831                    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06832                    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06833                   p->invitestate = INV_EARLY_MEDIA;
06834                   transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
06835                   ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
06836                }
06837                p->lastrtptx = time(NULL);
06838                res = ast_rtp_instance_write(p->trtp, frame);
06839             }
06840          }
06841          sip_pvt_unlock(p);
06842       }
06843       break;
06844    case AST_FRAME_IMAGE:
06845       return 0;
06846       break;
06847    case AST_FRAME_MODEM:
06848       if (p) {
06849          sip_pvt_lock(p);
06850          /* UDPTL requires two-way communication, so early media is not needed here.
06851             we simply forget the frames if we get modem frames before the bridge is up.
06852             Fax will re-transmit.
06853          */
06854          if ((ast->_state == AST_STATE_UP) &&
06855              p->udptl &&
06856              (p->t38.state == T38_ENABLED)) {
06857             res = ast_udptl_write(p->udptl, frame);
06858          }
06859          sip_pvt_unlock(p);
06860       }
06861       break;
06862    default:
06863       ast_log(LOG_WARNING, "Can't send %u type frames with SIP write\n", frame->frametype);
06864       return 0;
06865    }
06866 
06867    return res;
06868 }

static int sipsock_read ( int *  id,
int  fd,
short  events,
void *  ignore 
) [static]

Read data from SIP UDP socket.

Note:
sipsock_read locks the owner channel while we are processing the SIP message
Returns:
1 on error, 0 on success
Note:
Successful messages is connected to SIP call and forwarded to handle_incoming()

Definition at line 26113 of file chan_sip.c.

References AST_DYNSTR_BUILD_FAILED, ast_log(), ast_recvfrom(), ast_sockaddr_port, ast_str_create(), ast_str_set(), bindaddr, deinit_req(), errno, handle_request_do(), LOG_NOTICE, LOG_WARNING, and set_socket_transport().

Referenced by do_monitor().

26114 {
26115    struct sip_request req;
26116    struct ast_sockaddr addr;
26117    int res;
26118    static char readbuf[65535];
26119 
26120    memset(&req, 0, sizeof(req));
26121    res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr);
26122    if (res < 0) {
26123 #if !defined(__FreeBSD__)
26124       if (errno == EAGAIN)
26125          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
26126       else
26127 #endif
26128       if (errno != ECONNREFUSED)
26129          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
26130       return 1;
26131    }
26132 
26133    readbuf[res] = '\0';
26134 
26135    if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
26136       return 1;
26137    }
26138 
26139    if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) {
26140       return -1;
26141    }
26142 
26143    req.socket.fd = sipsock;
26144    set_socket_transport(&req.socket, SIP_TRANSPORT_UDP);
26145    req.socket.tcptls_session  = NULL;
26146    req.socket.port = htons(ast_sockaddr_port(&bindaddr));
26147 
26148    handle_request_do(&req, &addr);
26149    deinit_req(&req);
26150 
26151    return 1;
26152 }

static int sockaddr_is_null_or_any ( const struct ast_sockaddr addr  )  [static]

Definition at line 9082 of file chan_sip.c.

References ast_sockaddr_is_any(), and ast_sockaddr_isnull().

Referenced by process_sdp().

09083 {
09084    return ast_sockaddr_isnull(addr) || ast_sockaddr_is_any(addr);
09085 }

enum st_mode st_get_mode ( struct sip_pvt *  p,
int  no_cached 
) [static]

Get the session-timer mode.

Parameters:
p pointer to the SIP dialog
no_cached,set this to true in order to force a peername lookup on the session timer mode.

Definition at line 27042 of file chan_sip.c.

References sip_st_alloc().

Referenced by add_supported_header(), handle_request_invite_st(), handle_response_invite(), and transmit_invite().

27043 {
27044    if (!p->stimer) {
27045       sip_st_alloc(p);
27046       if (!p->stimer) {
27047          return SESSION_TIMER_MODE_INVALID;
27048       }
27049    }
27050 
27051    if (!no_cached && p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID)
27052       return p->stimer->st_cached_mode;
27053 
27054    if (p->relatedpeer) {
27055       p->stimer->st_cached_mode = p->relatedpeer->stimer.st_mode_oper;
27056       return p->stimer->st_cached_mode;
27057    }
27058 
27059    p->stimer->st_cached_mode = global_st_mode;
27060    return global_st_mode;
27061 }

enum st_refresher st_get_refresher ( struct sip_pvt *  p  )  [static]

Get the entity (UAC or UAS) that's acting as the session-timer refresher.

Note:
This is only called when processing an INVITE, so in that case Asterisk is always currently the UAS. If this is ever used to process responses, the function will have to be changed.
Parameters:
p pointer to the SIP dialog

Definition at line 27020 of file chan_sip.c.

Referenced by handle_request_invite_st().

27021 {
27022    if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) {
27023       return p->stimer->st_cached_ref;
27024    }
27025 
27026    if (p->relatedpeer) {
27027       p->stimer->st_cached_ref = (p->relatedpeer->stimer.st_ref == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
27028       return p->stimer->st_cached_ref;
27029    }
27030    
27031    p->stimer->st_cached_ref = (global_st_refresher == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
27032    return p->stimer->st_cached_ref;
27033 }

int st_get_se ( struct sip_pvt *  p,
int  max 
) [static]

Get Max or Min SE (session timer expiry).

Parameters:
p pointer to the SIP dialog
max if true, get max se, otherwise min se

Definition at line 26988 of file chan_sip.c.

References TRUE.

Referenced by handle_request_invite_st(), handle_response_invite(), reqprep(), and transmit_invite().

26989 {
26990    if (max == TRUE) {
26991       if (p->stimer->st_cached_max_se) {
26992          return  p->stimer->st_cached_max_se;
26993       }
26994       if (p->relatedpeer) {
26995          p->stimer->st_cached_max_se = p->relatedpeer->stimer.st_max_se;
26996          return (p->stimer->st_cached_max_se);
26997       }
26998       p->stimer->st_cached_max_se = global_max_se;
26999       return (p->stimer->st_cached_max_se);
27000    } 
27001    /* Find Min SE timer */
27002    if (p->stimer->st_cached_min_se) {
27003       return p->stimer->st_cached_min_se;
27004    } 
27005    if (p->relatedpeer) {
27006       p->stimer->st_cached_min_se = p->relatedpeer->stimer.st_min_se;
27007       return (p->stimer->st_cached_min_se);
27008    }
27009    p->stimer->st_cached_min_se = global_min_se;
27010    return (p->stimer->st_cached_min_se);
27011 }

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

Session-Timers: Start session timer.

Definition at line 26770 of file chan_sip.c.

References ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, LOG_ERROR, MIN, proc_session_timer(), and TRUE.

Referenced by handle_response_invite(), restart_session_timer(), and sip_answer().

26771 {
26772    unsigned int timeout_ms;
26773 
26774    if (p->stimer->st_schedid > -1) {
26775       /* in the event a timer is already going, stop it */
26776       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
26777       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
26778          dialog_unref(p, "unref stimer->st_schedid from dialog"));
26779    }
26780 
26781    /*
26782     * RFC 4028 Section 10
26783     * If the side not performing refreshes does not receive a
26784     * session refresh request before the session expiration, it SHOULD send
26785     * a BYE to terminate the session, slightly before the session
26786     * expiration.  The minimum of 32 seconds and one third of the session
26787     * interval is RECOMMENDED.
26788     */
26789 
26790    timeout_ms = (1000 * p->stimer->st_interval);
26791    if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) {
26792       timeout_ms /= 2;
26793    } else {
26794       timeout_ms -= MIN(timeout_ms / 3, 32000);
26795    }
26796 
26797    p->stimer->st_schedid = ast_sched_add(sched, timeout_ms, proc_session_timer,
26798          dialog_ref(p, "adding session timer ref"));
26799 
26800    if (p->stimer->st_schedid < 0) {
26801       dialog_unref(p, "removing session timer ref");
26802       ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid);
26803    } else {
26804       p->stimer->st_active = TRUE;
26805       ast_debug(2, "Session timer started: %d - %s %ums\n", p->stimer->st_schedid, p->callid, timeout_ms);
26806    }
26807 }

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 
) [static]

Builds XML portion of NOTIFY messages for presence or dialog updates.

Definition at line 12966 of file chan_sip.c.

References ast_alloca, ast_channel_callback(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), AST_MAX_EXTENSION, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, ast_str_append(), ast_strdupa, ast_xml_escape(), ast_channel::caller, cid_num, ast_channel::connected, find_calling_channel(), ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, NONE, ast_party_id::number, ast_party_name::presentation, ast_party_number::presentation, S_COR, sip_cfg, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by transmit_state_notify().

12967 {
12968    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
12969    const char *statestring = "terminated";
12970    const char *pidfstate = "--";
12971    const char *pidfnote= "Ready";
12972    char hint[AST_MAX_EXTENSION];
12973 
12974    switch (state) {
12975    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
12976       statestring = (sip_cfg.notifyringing) ? "early" : "confirmed";
12977       local_state = NOTIFY_INUSE;
12978       pidfstate = "busy";
12979       pidfnote = "Ringing";
12980       break;
12981    case AST_EXTENSION_RINGING:
12982       statestring = "early";
12983       local_state = NOTIFY_INUSE;
12984       pidfstate = "busy";
12985       pidfnote = "Ringing";
12986       break;
12987    case AST_EXTENSION_INUSE:
12988       statestring = "confirmed";
12989       local_state = NOTIFY_INUSE;
12990       pidfstate = "busy";
12991       pidfnote = "On the phone";
12992       break;
12993    case AST_EXTENSION_BUSY:
12994       statestring = "confirmed";
12995       local_state = NOTIFY_CLOSED;
12996       pidfstate = "busy";
12997       pidfnote = "On the phone";
12998       break;
12999    case AST_EXTENSION_UNAVAILABLE:
13000       statestring = "terminated";
13001       local_state = NOTIFY_CLOSED;
13002       pidfstate = "away";
13003       pidfnote = "Unavailable";
13004       break;
13005    case AST_EXTENSION_ONHOLD:
13006       statestring = "confirmed";
13007       local_state = NOTIFY_CLOSED;
13008       pidfstate = "busy";
13009       pidfnote = "On hold";
13010       break;
13011    case AST_EXTENSION_NOT_INUSE:
13012    default:
13013       /* Default setting */
13014       break;
13015    }
13016 
13017    /* Check which device/devices we are watching  and if they are registered */
13018    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) {
13019       char *hint2 = hint, *individual_hint = NULL;
13020       int hint_count = 0, unavailable_count = 0;
13021 
13022       while ((individual_hint = strsep(&hint2, "&"))) {
13023          hint_count++;
13024 
13025          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
13026             unavailable_count++;
13027       }
13028 
13029       /* If none of the hinted devices are registered, we will
13030        * override notification and show no availability.
13031        */
13032       if (hint_count > 0 && hint_count == unavailable_count) {
13033          local_state = NOTIFY_CLOSED;
13034          pidfstate = "away";
13035          pidfnote = "Not online";
13036       }
13037    }
13038 
13039    switch (subscribed) {
13040    case XPIDF_XML:
13041    case CPIM_PIDF_XML:
13042       ast_str_append(tmp, 0,
13043          "<?xml version=\"1.0\"?>\n"
13044          "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
13045          "<presence>\n");
13046       ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
13047       ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten);
13048       ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
13049       ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
13050       ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
13051       ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n");
13052       break;
13053    case PIDF_XML: /* Eyebeam supports this format */
13054       ast_str_append(tmp, 0,
13055          "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
13056          "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
13057       ast_str_append(tmp, 0, "<pp:person><status>\n");
13058       if (pidfstate[0] != '-') {
13059          ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
13060       }
13061       ast_str_append(tmp, 0, "</status></pp:person>\n");
13062       ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */
13063       ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */
13064       ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto);
13065       if (pidfstate[0] == 'b') /* Busy? Still open ... */
13066          ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n");
13067       else
13068          ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
13069       ast_str_append(tmp, 0, "</tuple>\n</presence>\n");
13070       break;
13071    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
13072       ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>\n");
13073       ast_str_append(tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%u\" state=\"%s\" entity=\"%s\">\n", p->dialogver, full ? "full" : "partial", mto);
13074 
13075       if ((state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) {
13076          /* Twice the extension length should be enough for XML encoding */
13077          char local_display[AST_MAX_EXTENSION * 2];
13078          char remote_display[AST_MAX_EXTENSION * 2];
13079          char *local_target = ast_strdupa(mto);
13080          /* It may seem odd to base the remote_target on the To header here,
13081           * but testing by reporters on issue ASTERISK-16735 found that basing
13082           * on the From header would cause ringing state hints to not work
13083           * properly on certain SNOM devices. If you are using notifycid properly
13084           * (i.e. in the same extension and context as the dialed call) then this
13085           * should not be an issue since the data will be overwritten shortly
13086           * with channel caller ID
13087           */
13088          char *remote_target = ast_strdupa(mto);
13089 
13090          ast_xml_escape(exten, local_display, sizeof(local_display));
13091          ast_xml_escape(exten, remote_display, sizeof(remote_display));
13092 
13093          /* There are some limitations to how this works.  The primary one is that the
13094             callee must be dialing the same extension that is being monitored.  Simply dialing
13095             the hint'd device is not sufficient. */
13096          if (sip_cfg.notifycid) {
13097             struct ast_channel *caller;
13098 
13099             if ((caller = ast_channel_callback(find_calling_channel, NULL, p, 0))) {
13100                static char *anonymous = "anonymous";
13101                static char *invalid = "anonymous.invalid";
13102                char *cid_num;
13103                char *connected_num;
13104                int need;
13105                int cid_num_restricted, connected_num_restricted;
13106 
13107                ast_channel_lock(caller);
13108 
13109                cid_num_restricted = (caller->caller.id.number.presentation &
13110                            AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED;
13111                cid_num = S_COR(caller->caller.id.number.valid,
13112                      S_COR(cid_num_restricted, anonymous,
13113                            caller->caller.id.number.str), "");
13114 
13115                need = strlen(cid_num) + (cid_num_restricted ? strlen(invalid) :
13116                           strlen(p->fromdomain)) + sizeof("sip:@");
13117 
13118                remote_target = ast_alloca(need);
13119                snprintf(remote_target, need, "sip:%s@%s", cid_num,
13120                    cid_num_restricted ? invalid : p->fromdomain);
13121 
13122                ast_xml_escape(S_COR(caller->caller.id.name.valid,
13123                           S_COR((caller->caller.id.name.presentation &
13124                              AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED, anonymous,
13125                            caller->caller.id.name.str), ""),
13126                          remote_display, sizeof(remote_display));
13127 
13128                connected_num_restricted = (caller->connected.id.number.presentation &
13129                             AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED;
13130                connected_num = S_COR(caller->connected.id.number.valid,
13131                            S_COR(connected_num_restricted, anonymous,
13132                             caller->connected.id.number.str), "");
13133 
13134                need = strlen(connected_num) + (connected_num_restricted ? strlen(invalid) :
13135                            strlen(p->fromdomain)) + sizeof("sip:@");
13136                local_target = ast_alloca(need);
13137 
13138                snprintf(local_target, need, "sip:%s@%s", connected_num,
13139                    connected_num_restricted ? invalid : p->fromdomain);
13140 
13141                ast_xml_escape(S_COR(caller->connected.id.name.valid,
13142                           S_COR((caller->connected.id.name.presentation &
13143                              AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED, anonymous,
13144                             caller->connected.id.name.str), ""),
13145                          local_display, sizeof(local_display));
13146 
13147                ast_channel_unlock(caller);
13148                caller = ast_channel_unref(caller);
13149             }
13150 
13151             /* We create a fake call-id which the phone will send back in an INVITE
13152                Replaces header which we can grab and do some magic with. */
13153             if (sip_cfg.pedanticsipchecking) {
13154                ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n",
13155                   exten, p->callid, p->theirtag, p->tag);
13156             } else {
13157                ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n",
13158                   exten, p->callid);
13159             }
13160             ast_str_append(tmp, 0,
13161                   "<remote>\n"
13162                   /* See the limitations of this above.  Luckily the phone seems to still be
13163                      happy when these values are not correct. */
13164                   "<identity display=\"%s\">%s</identity>\n"
13165                   "<target uri=\"%s\"/>\n"
13166                   "</remote>\n"
13167                   "<local>\n"
13168                   "<identity display=\"%s\">%s</identity>\n"
13169                   "<target uri=\"%s\"/>\n"
13170                   "</local>\n",
13171                   remote_display, remote_target, remote_target, local_display, local_target, local_target);
13172          } else {
13173             ast_str_append(tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", exten);
13174          }
13175 
13176       } else {
13177          ast_str_append(tmp, 0, "<dialog id=\"%s\">\n", exten);
13178       }
13179       ast_str_append(tmp, 0, "<state>%s</state>\n", statestring);
13180       if (state == AST_EXTENSION_ONHOLD) {
13181             ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n"
13182                                              "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
13183                                              "</target>\n</local>\n", mto);
13184       }
13185       ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n");
13186       break;
13187    case NONE:
13188    default:
13189       break;
13190    }
13191 }

static const char* stmode2str ( enum st_mode  m  )  [static]

Definition at line 17012 of file chan_sip.c.

References map_x_s().

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

17013 {
17014    return map_x_s(stmodes, m, "Unknown");
17015 }

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

Immediately stop RTP, VRTP and UDPTL as applicable.

Definition at line 21702 of file chan_sip.c.

References ast_rtp_instance_stop(), and ast_udptl_stop().

Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().

21703 {
21704    /* Immediately stop RTP, VRTP and UDPTL as applicable */
21705    if (p->rtp)
21706       ast_rtp_instance_stop(p->rtp);
21707    if (p->vrtp)
21708       ast_rtp_instance_stop(p->vrtp);
21709    if (p->trtp)
21710       ast_rtp_instance_stop(p->trtp);
21711    if (p->udptl)
21712       ast_udptl_stop(p->udptl);
21713 }

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

Session-Timers: Stop session timer.

Definition at line 26758 of file chan_sip.c.

References ast_debug, AST_SCHED_DEL_UNREF, FALSE, and TRUE.

Referenced by __sip_destroy(), dialog_unlink_all(), handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().

26759 {
26760    if (p->stimer->st_active == TRUE) {
26761       p->stimer->st_active = FALSE;
26762       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
26763       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
26764             dialog_unref(p, "removing session timer ref"));
26765    }
26766 }

static int str2dtmfmode ( const char *  str  )  [static]

maps a string to dtmfmode, returns -1 on error

Definition at line 17576 of file chan_sip.c.

References map_s_x().

17577 {
17578    return map_s_x(dtmfstr, str, -1);
17579 }

static enum st_mode str2stmode ( const char *  s  )  [static]

Definition at line 17017 of file chan_sip.c.

References map_s_x().

Referenced by build_peer(), and reload_config().

17018 {
17019    return map_s_x(stmodes, s, -1);
17020 }

static enum st_refresher str2strefresherparam ( const char *  s  )  [static]

Definition at line 17042 of file chan_sip.c.

References map_s_x().

Referenced by build_peer(), and reload_config().

17043 {
17044    return map_s_x(strefresher_params, s, -1);
17045 }

static const char* strefresher2str ( enum st_refresher  r  )  [static]

Definition at line 17047 of file chan_sip.c.

References map_x_s().

Referenced by sip_show_channel().

17048 {
17049    return map_x_s(strefreshers, r, "Unknown");
17050 }

static const char * strefresherparam2str ( enum st_refresher  r  )  [static]

Definition at line 17037 of file chan_sip.c.

References map_x_s().

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

17038 {
17039    return map_x_s(strefresher_params, r, "Unknown");
17040 }

static const char * subscription_type2str ( enum subscriptiontype  subtype  )  [static]

Show subscription type in string format.

Definition at line 18945 of file chan_sip.c.

References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.

Referenced by show_channels_cb(), and sip_show_channel().

18946 {
18947    int i;
18948 
18949    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
18950       if (subscription_types[i].type == subtype) {
18951          return subscription_types[i].text;
18952       }
18953    }
18954    return subscription_types[0].text;
18955 }

static unsigned int t38_get_rate ( enum ast_control_t38_rate  rate  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

Definition at line 11502 of file chan_sip.c.

References AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, and AST_T38_RATE_9600.

Referenced by add_sdp().

11503 {
11504    switch (rate) {
11505    case AST_T38_RATE_2400:
11506       return 2400;
11507    case AST_T38_RATE_4800:
11508       return 4800;
11509    case AST_T38_RATE_7200:
11510       return 7200;
11511    case AST_T38_RATE_9600:
11512       return 9600;
11513    case AST_T38_RATE_12000:
11514       return 12000;
11515    case AST_T38_RATE_14400:
11516       return 14400;
11517    default:
11518       return 0;
11519    }
11520 }

static void tcptls_packet_destructor ( void *  obj  )  [static]

Definition at line 2342 of file chan_sip.c.

References ast_free.

Referenced by sip_tcptls_write().

02343 {
02344    struct tcptls_packet *packet = obj;
02345 
02346    ast_free(packet->data);
02347 }

static struct sip_peer * temp_peer ( const char *  name  )  [static, read]

Create temporary peer (used in autocreatepeer mode).

Definition at line 28011 of file chan_sip.c.

References ao2_t_alloc, ao2_t_ref, ast_atomic_fetchadd_int(), ast_cc_config_params_init, ast_copy_string(), ast_string_field_init, default_prefs, reg_source_db(), set_peer_defaults(), sip_destroy_peer_fn(), and TRUE.

Referenced by load_module(), register_verify(), and sip_reload().

28012 {
28013    struct sip_peer *peer;
28014 
28015    if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
28016       return NULL;
28017 
28018    if (ast_string_field_init(peer, 512)) {
28019       ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
28020       return NULL;
28021    }
28022    
28023    if (!(peer->cc_params = ast_cc_config_params_init())) {
28024       ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
28025       return NULL;
28026    }
28027 
28028    ast_atomic_fetchadd_int(&apeerobjs, 1);
28029    set_peer_defaults(peer);
28030 
28031    ast_copy_string(peer->name, name, sizeof(peer->name));
28032 
28033    peer->selfdestruct = TRUE;
28034    peer->host_dynamic = TRUE;
28035    peer->prefs = default_prefs;
28036    reg_source_db(peer);
28037 
28038    return peer;
28039 }

static void temp_pvt_cleanup ( void *  data  )  [static]

Definition at line 10923 of file chan_sip.c.

References ast_free, and ast_string_field_free_memory.

10924 {
10925    struct sip_pvt *p = data;
10926 
10927    ast_string_field_free_memory(p);
10928 
10929    ast_free(data);
10930 }

static int temp_pvt_init ( void *  data  )  [static]

Definition at line 10915 of file chan_sip.c.

References ast_string_field_init.

10916 {
10917    struct sip_pvt *p = data;
10918 
10919    p->do_history = 0;   /* XXX do we need it ? isn't already all 0 ? */
10920    return ast_string_field_init(p, 512);
10921 }

static char* terminate_uri ( char *  uri  )  [static]

Terminate the uri at the first ';' or space. Technically we should ignore escaped space per RFC3261 (19.1.1 etc) but don't do it for the time being. Remember the uri format is: (User-parameters was added after RFC 3261)

 *
 *	sip:user:password;user-parameters@host:port;uri-parameters?headers
 *	sips:user:password;user-parameters@host:port;uri-parameters?headers
 *
 *
Todo:
As this function does not support user-parameters, it's considered broken and needs fixing.

Definition at line 15236 of file chan_sip.c.

Referenced by check_user_full(), and register_verify().

15237 {
15238    char *t = uri;
15239    while (*t && *t > ' ' && *t != ';') {
15240       t++;
15241    }
15242    *t = '\0';
15243    return uri;
15244 }

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

Definition at line 26251 of file chan_sip.c.

References ast_sockaddr_cmp(), CMP_MATCH, and CMP_STOP.

Referenced by sip_tcp_locate().

26252 {
26253    struct sip_threadinfo *th = obj;
26254    struct ast_sockaddr *s = arg;
26255 
26256    if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) {
26257       return CMP_MATCH | CMP_STOP;
26258    }
26259 
26260    return 0;
26261 }

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

Definition at line 30817 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

30818 {
30819    struct sip_threadinfo *th = obj, *th2 = arg;
30820 
30821    return (th->tcptls_session == th2->tcptls_session) ? CMP_MATCH | CMP_STOP : 0;
30822 }

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

Definition at line 30810 of file chan_sip.c.

References ast_sockaddr_hash().

Referenced by load_module().

30811 {
30812    const struct sip_threadinfo *th = obj;
30813 
30814    return ast_sockaddr_hash(&th->tcptls_session->remote_address);
30815 }

static char * transfermode2str ( enum transfermodes  mode  )  [static]

Convert transfer mode to text string.

Definition at line 16990 of file chan_sip.c.

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

16991 {
16992    if (mode == TRANSFER_OPENFORALL)
16993       return "open";
16994    else if (mode == TRANSFER_CLOSED)
16995       return "closed";
16996    return "strict";
16997 }

static int transmit_cc_notify ( struct ast_cc_agent agent,
struct sip_pvt *  subscription,
enum sip_cc_notify_state  state 
) [static]

Definition at line 13193 of file chan_sip.c.

References add_content(), add_header(), ast_log(), generate_uri(), LOG_WARNING, ast_cc_agent::private_data, reqprep(), send_request(), sip_cc_notify_state_map, state_string, and TRUE.

Referenced by sip_cc_agent_recall(), and sip_cc_agent_respond().

13194 {
13195    struct sip_request req;
13196    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
13197    char uri[SIPBUFSIZE];
13198    char state_str[64];
13199    char subscription_state_hdr[64];
13200 
13201    if (state < CC_QUEUED || state > CC_READY) {
13202       ast_log(LOG_WARNING, "Invalid state provided for transmit_cc_notify (%u)\n", state);
13203       return -1;
13204    }
13205 
13206    reqprep(&req, subscription, SIP_NOTIFY, 0, TRUE);
13207    snprintf(state_str, sizeof(state_str), "%s\r\n", sip_cc_notify_state_map[state].state_string);
13208    add_header(&req, "Event", "call-completion");
13209    add_header(&req, "Content-Type", "application/call-completion");
13210    snprintf(subscription_state_hdr, sizeof(subscription_state_hdr), "active;expires=%d", subscription->expiry);
13211    add_header(&req, "Subscription-State", subscription_state_hdr);
13212    if (state == CC_READY) {
13213       generate_uri(subscription, agent_pvt->notify_uri, sizeof(agent_pvt->notify_uri));
13214       snprintf(uri, sizeof(uri) - 1, "cc-URI: %s\r\n", agent_pvt->notify_uri);
13215    }
13216    add_content(&req, state_str);
13217    if (state == CC_READY) {
13218       add_content(&req, uri);
13219    }
13220    return send_request(subscription, &req, XMIT_RELIABLE, subscription->ocseq);
13221 }

static void transmit_fake_auth_response ( struct sip_pvt *  p,
struct sip_request *  req,
enum xmittype  reliable 
) [static]

Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.

Definition at line 15135 of file chan_sip.c.

References __transmit_response(), AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), set_nonce_randdata(), sip_scheddestroy(), and transmit_response_with_auth().

Referenced by register_verify().

15136 {
15137    /* We have to emulate EXACTLY what we'd get with a good peer
15138     * and a bad password, or else we leak information. */
15139    const char *response = "401 Unauthorized";
15140    const char *reqheader = "Authorization";
15141    const char *respheader = "WWW-Authenticate";
15142    const char *authtoken;
15143    struct ast_str *buf;
15144    char *c;
15145 
15146    /* table of recognised keywords, and their value in the digest */
15147    enum keys { K_NONCE, K_LAST };
15148    struct x {
15149       const char *key;
15150       const char *s;
15151    } *i, keys[] = {
15152       [K_NONCE] = { "nonce=", "" },
15153       [K_LAST] = { NULL, NULL}
15154    };
15155 
15156    authtoken = get_header(req, reqheader);
15157    if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
15158       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
15159        * information */
15160       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
15161       /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
15162       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15163       return;
15164    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
15165       /* We have no auth, so issue challenge and request authentication */
15166       set_nonce_randdata(p, 1);
15167       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
15168       /* Schedule auto destroy in 32 seconds */
15169       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15170       return;
15171    }
15172 
15173    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
15174       __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
15175       return;
15176    }
15177 
15178    /* Make a copy of the response and parse it */
15179    if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
15180       __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
15181       return;
15182    }
15183 
15184    c = buf->str;
15185 
15186    while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
15187       for (i = keys; i->key != NULL; i++) {
15188          const char *separator = ",";  /* default */
15189 
15190          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
15191             continue;
15192          }
15193          /* Found. Skip keyword, take text in quotes or up to the separator. */
15194          c += strlen(i->key);
15195          if (*c == '"') { /* in quotes. Skip first and look for last */
15196             c++;
15197             separator = "\"";
15198          }
15199          i->s = c;
15200          strsep(&c, separator);
15201          break;
15202       }
15203       if (i->key == NULL) { /* not found, jump after space or comma */
15204          strsep(&c, " ,");
15205       }
15206    }
15207 
15208    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
15209    if (strcasecmp(p->randdata, keys[K_NONCE].s)) {
15210       if (!req->ignore) {
15211          set_nonce_randdata(p, 1);
15212       }
15213       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
15214 
15215       /* Schedule auto destroy in 32 seconds */
15216       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15217    } else {
15218       __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
15219    }
15220 }

static int transmit_info_with_aoc ( struct sip_pvt *  p,
struct ast_aoc_decoded decoded 
) [static]

Send SIP INFO advice of charge message.

Definition at line 14048 of file chan_sip.c.

References add_header(), ast_aoc_unit_entry::amount, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_UNIT, AST_AOC_D, AST_AOC_E, ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier_decimal(), ast_aoc_get_currency_name(), ast_aoc_get_msg_type(), ast_aoc_get_unit_info(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_strlen_zero(), reqprep(), send_request(), and str.

Referenced by sip_indicate().

14049 {
14050    struct sip_request req;
14051    struct ast_str *str = ast_str_alloca(512);
14052    const struct ast_aoc_unit_entry *unit_entry = ast_aoc_get_unit_info(decoded, 0);
14053    enum ast_aoc_charge_type charging = ast_aoc_get_charge_type(decoded);
14054 
14055    reqprep(&req, p, SIP_INFO, 0, 1);
14056 
14057    if (ast_aoc_get_msg_type(decoded) == AST_AOC_D) {
14058       ast_str_append(&str, 0, "type=active;");
14059    } else if (ast_aoc_get_msg_type(decoded) == AST_AOC_E) {
14060       ast_str_append(&str, 0, "type=terminated;");
14061    } else {
14062       /* unsupported message type */
14063       return -1;
14064    }
14065 
14066    switch (charging) {
14067    case AST_AOC_CHARGE_FREE:
14068       ast_str_append(&str, 0, "free-of-charge;");
14069       break;
14070    case AST_AOC_CHARGE_CURRENCY:
14071       ast_str_append(&str, 0, "charging;");
14072       ast_str_append(&str, 0, "charging-info=currency;");
14073       ast_str_append(&str, 0, "amount=%u;", ast_aoc_get_currency_amount(decoded));
14074       ast_str_append(&str, 0, "multiplier=%s;", ast_aoc_get_currency_multiplier_decimal(decoded));
14075       if (!ast_strlen_zero(ast_aoc_get_currency_name(decoded))) {
14076          ast_str_append(&str, 0, "currency=%s;", ast_aoc_get_currency_name(decoded));
14077       }
14078       break;
14079    case AST_AOC_CHARGE_UNIT:
14080       ast_str_append(&str, 0, "charging;");
14081       ast_str_append(&str, 0, "charging-info=pulse;");
14082       if (unit_entry) {
14083          ast_str_append(&str, 0, "recorded-units=%u;", unit_entry->amount);
14084       }
14085       break;
14086    default:
14087       ast_str_append(&str, 0, "not-available;");
14088    };
14089 
14090    add_header(&req, "AOC", ast_str_buffer(str));
14091 
14092    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
14093 }

static int transmit_info_with_digit ( struct sip_pvt *  p,
const char  digit,
unsigned int  duration 
) [static]

Send SIP INFO dtmf message, see Cisco documentation on cisco.com.

Definition at line 14096 of file chan_sip.c.

References add_digit(), ast_test_flag, reqprep(), and send_request().

Referenced by sip_senddigit_end().

14097 {
14098    struct sip_request req;
14099    
14100    reqprep(&req, p, SIP_INFO, 0, 1);
14101    add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO));
14102    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
14103 }

static int transmit_info_with_vidupdate ( struct sip_pvt *  p  )  [static]

Send SIP INFO with video update request.

Definition at line 14106 of file chan_sip.c.

References add_vidupdate(), reqprep(), and send_request().

Referenced by sip_indicate().

14107 {
14108    struct sip_request req;
14109    
14110    reqprep(&req, p, SIP_INFO, 0, 1);
14111    add_vidupdate(&req);
14112    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
14113 }

static int transmit_invite ( struct sip_pvt *  p,
int  sipmethod,
int  sdp,
int  init,
const char *const   explicit_uri 
) [static]

Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.

Parameters:
p sip_pvt structure
sipmethod 
sdp unknown
init 0 = Prepare request within dialog, 1= prepare request, new branch, 2= prepare new request and new dialog. do_proxy_auth calls this with init!=2
explicit_uri 

Definition at line 12610 of file chan_sip.c.

References add_content(), add_diversion_header(), add_header(), add_rpid(), add_sdp(), add_supported_header(), append_date(), ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), build_via(), FALSE, initialize_initreq(), initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, reqprep(), send_request(), st_get_mode(), st_get_se(), TRUE, try_suggested_sip_codec(), ast_variable::value, var, and ast_channel::varshead.

Referenced by __sip_subscribe_mwi_do(), cc_handle_publish_error(), do_proxy_auth(), manager_sipnotify(), proc_422_rsp(), sip_call(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_monitor_instance_destructor(), sip_poke_peer(), and transmit_publish().

12611 {
12612    struct sip_request req;
12613    struct ast_variable *var;
12614 
12615    if (init) {/* Bump branch even on initial requests */
12616       p->branch ^= ast_random();
12617       p->invite_branch = p->branch;
12618       build_via(p);
12619    }
12620    if (init > 1) {
12621       initreqprep(&req, p, sipmethod, explicit_uri);
12622    } else {
12623       /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */
12624       reqprep(&req, p, sipmethod, 0, init ? 0 : 1);
12625    }
12626 
12627    if (p->options && p->options->auth) {
12628       add_header(&req, p->options->authheader, p->options->auth);
12629    }
12630    append_date(&req);
12631    if (sipmethod == SIP_REFER) { /* Call transfer */
12632       if (p->refer) {
12633          char buf[SIPBUFSIZE];
12634          if (!ast_strlen_zero(p->refer->refer_to)) {
12635             add_header(&req, "Refer-To", p->refer->refer_to);
12636          }
12637          if (!ast_strlen_zero(p->refer->referred_by)) {
12638             snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
12639             add_header(&req, "Referred-By", buf);
12640          }
12641       }
12642    } else if (sipmethod == SIP_SUBSCRIBE) {
12643       char buf[SIPBUFSIZE];
12644       if (p->subscribed == MWI_NOTIFICATION) {
12645          add_header(&req, "Event", "message-summary");
12646          add_header(&req, "Accept", "application/simple-message-summary");
12647       } else if (p->subscribed == CALL_COMPLETION) {
12648          add_header(&req, "Event", "call-completion");
12649          add_header(&req, "Accept", "application/call-completion");
12650       }
12651       snprintf(buf, sizeof(buf), "%d", p->expiry);
12652       add_header(&req, "Expires", buf);
12653    }
12654 
12655    /* This new INVITE is part of an attended transfer. Make sure that the
12656    other end knows and replace the current call with this new call */
12657    if (p->options && !ast_strlen_zero(p->options->replaces)) {
12658       add_header(&req, "Replaces", p->options->replaces);
12659       add_header(&req, "Require", "replaces");
12660    }
12661 
12662    /* Add Session-Timers related headers */
12663    if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE
12664       || (st_get_mode(p, 0) == SESSION_TIMER_MODE_ACCEPT
12665          && st_get_se(p, FALSE) != DEFAULT_MIN_SE)) {
12666       char i2astr[10];
12667 
12668       if (!p->stimer->st_interval) {
12669          p->stimer->st_interval = st_get_se(p, TRUE);
12670       }
12671 
12672       p->stimer->st_active = TRUE;
12673       if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 
12674          snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval);
12675          add_header(&req, "Session-Expires", i2astr);
12676       }
12677 
12678       snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE));
12679       add_header(&req, "Min-SE", i2astr);
12680    }
12681 
12682    add_header(&req, "Allow", ALLOWED_METHODS);
12683    add_supported_header(p, &req);
12684 
12685    if (p->options && p->options->addsipheaders && p->owner) {
12686       struct ast_channel *chan = p->owner; /* The owner channel */
12687       struct varshead *headp;
12688    
12689       ast_channel_lock(chan);
12690 
12691       headp = &chan->varshead;
12692 
12693       if (!headp) {
12694          ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n");
12695       } else {
12696          const struct ast_var_t *current;
12697          AST_LIST_TRAVERSE(headp, current, entries) {
12698             /* SIPADDHEADER: Add SIP header to outgoing call */
12699             if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
12700                char *content, *end;
12701                const char *header = ast_var_value(current);
12702                char *headdup = ast_strdupa(header);
12703 
12704                /* Strip of the starting " (if it's there) */
12705                if (*headdup == '"') {
12706                   headdup++;
12707                }
12708                if ((content = strchr(headdup, ':'))) {
12709                   *content++ = '\0';
12710                   content = ast_skip_blanks(content); /* Skip white space */
12711                   /* Strip the ending " (if it's there) */
12712                   end = content + strlen(content) -1; 
12713                   if (*end == '"') {
12714                      *end = '\0';
12715                   }
12716                
12717                   add_header(&req, headdup, content);
12718                   if (sipdebug) {
12719                      ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
12720                   }
12721                }
12722             }
12723          }
12724       }
12725 
12726       ast_channel_unlock(chan);
12727    }
12728    if ((sipmethod == SIP_INVITE || sipmethod == SIP_UPDATE) && ast_test_flag(&p->flags[0], SIP_SENDRPID))
12729       add_rpid(&req, p);
12730    if (sipmethod == SIP_INVITE) {
12731       add_diversion_header(&req, p);
12732    }
12733    if (sdp) {
12734       memset(p->offered_media, 0, sizeof(p->offered_media));
12735       if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
12736          ast_debug(1, "T38 is in state %u on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12737          add_sdp(&req, p, FALSE, FALSE, TRUE);
12738       } else if (p->rtp) {
12739          try_suggested_sip_codec(p);
12740          add_sdp(&req, p, FALSE, TRUE, FALSE);
12741       }
12742    } else if (p->notify) {
12743       for (var = p->notify->headers; var; var = var->next) {
12744          add_header(&req, var->name, var->value);
12745       }
12746       if (ast_str_strlen(p->notify->content)) {
12747          add_content(&req, ast_str_buffer(p->notify->content));
12748       }
12749    } else if (sipmethod == SIP_PUBLISH) {
12750       char expires[SIPBUFSIZE];
12751 
12752       switch (p->epa_entry->static_data->event) {
12753       case CALL_COMPLETION:
12754          snprintf(expires, sizeof(expires), "%d", p->expiry);
12755          add_header(&req, "Event", "call-completion");
12756          add_header(&req, "Expires", expires);
12757          if (p->epa_entry->publish_type != SIP_PUBLISH_INITIAL) {
12758             add_header(&req, "SIP-If-Match", p->epa_entry->entity_tag);
12759          }
12760 
12761          if (!ast_strlen_zero(p->epa_entry->body)) {
12762             add_header(&req, "Content-Type", "application/pidf+xml");
12763             add_content(&req, p->epa_entry->body);
12764          }
12765       default:
12766          break;
12767       }
12768    }
12769 
12770    if (!p->initreq.headers || init > 2) {
12771       initialize_initreq(p, &req);
12772    }
12773    if (sipmethod == SIP_INVITE || sipmethod == SIP_SUBSCRIBE) {
12774       p->lastinvite = p->ocseq;
12775    }
12776    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
12777 }

static int transmit_message_with_text ( struct sip_pvt *  p,
const char *  text 
) [static]

Transmit text with SIP MESSAGE method.

Definition at line 13944 of file chan_sip.c.

References add_text(), reqprep(), and send_request().

Referenced by sip_park_thread(), and sip_sendtext().

13945 {
13946    struct sip_request req;
13947    
13948    reqprep(&req, p, SIP_MESSAGE, 0, 1);
13949    add_text(&req, text);
13950    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
13951 }

static int transmit_notify_with_mwi ( struct sip_pvt *  p,
int  newmsgs,
int  oldmsgs,
const char *  vmexten 
) [static]

Notify user of messages waiting in voicemail (RFC3842).

Note:
- Notification only works for registered peers with mailbox= definitions in sip.conf
  • We use the SIP Event package message-summary MIME type defaults to "application/simple-message-summary";

Definition at line 13331 of file chan_sip.c.

References add_content(), add_header(), ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_test_flag, exten, get_transport(), initialize_initreq(), initreqprep(), ourport, S_OR, send_request(), and sip_standard_port().

Referenced by sip_send_mwi_to_peer().

13332 {
13333    struct sip_request req;
13334    struct ast_str *out = ast_str_alloca(500);
13335    int ourport = (p->fromdomainport && (p->fromdomainport != STANDARD_SIP_PORT)) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
13336    const char *domain;
13337    const char *exten = S_OR(vmexten, default_vmexten);
13338 
13339    initreqprep(&req, p, SIP_NOTIFY, NULL);
13340    add_header(&req, "Event", "message-summary");
13341    add_header(&req, "Content-Type", default_notifymime);
13342    ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
13343 
13344    /* domain initialization occurs here because initreqprep changes ast_sockaddr_stringify string. */
13345    domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip));
13346 
13347    if (!sip_standard_port(p->socket.type, ourport)) {
13348       if (p->socket.type == SIP_TRANSPORT_UDP) {
13349          ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport);
13350       } else {
13351          ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, get_transport(p->socket.type));
13352       }
13353    } else {
13354       if (p->socket.type == SIP_TRANSPORT_UDP) {
13355          ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain);
13356       } else {
13357          ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, get_transport(p->socket.type));
13358       }
13359    }
13360    /* Cisco has a bug in the SIP stack where it can't accept the
13361       (0/0) notification. This can temporarily be disabled in
13362       sip.conf with the "buggymwi" option */
13363    ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n",
13364       newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)"));
13365 
13366    if (p->subscribed) {
13367       if (p->expiry) {
13368          add_header(&req, "Subscription-State", "active");
13369       } else { /* Expired */
13370          add_header(&req, "Subscription-State", "terminated;reason=timeout");
13371       }
13372    }
13373 
13374    add_content(&req, ast_str_buffer(out));
13375 
13376    if (!p->initreq.headers) {
13377       initialize_initreq(p, &req);
13378    }
13379    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
13380 }

static int transmit_notify_with_sipfrag ( struct sip_pvt *  p,
int  cseq,
char *  message,
int  terminate 
) [static]

Notify a transferring party of the status of transfer (RFC3515).

Definition at line 13383 of file chan_sip.c.

References add_content(), add_header(), add_supported_header(), initialize_initreq(), reqprep(), and send_request().

Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().

13384 {
13385    struct sip_request req;
13386    char tmp[SIPBUFSIZE/2];
13387    
13388    reqprep(&req, p, SIP_NOTIFY, 0, 1);
13389    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
13390    add_header(&req, "Event", tmp);
13391    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
13392    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
13393    add_header(&req, "Allow", ALLOWED_METHODS);
13394    add_supported_header(p, &req);
13395 
13396    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
13397    add_content(&req, tmp);
13398 
13399    if (!p->initreq.headers) {
13400       initialize_initreq(p, &req);
13401    }
13402 
13403    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
13404 }

static int transmit_provisional_response ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
int  with_sdp 
) [static]

Definition at line 11189 of file chan_sip.c.

References FALSE, transmit_response(), transmit_response_with_sdp(), and update_provisional_keepalive().

Referenced by handle_request_invite(), sip_indicate(), and sip_write().

11190 {
11191    int res;
11192 
11193    if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) {
11194       p->last_provisional = msg;
11195       update_provisional_keepalive(p, with_sdp);
11196    }
11197 
11198    return res;
11199 }

static int transmit_publish ( struct sip_epa_entry *  epa_entry,
enum sip_publish_type  publish_type,
const char *const   explicit_uri 
) [static]

Definition at line 12566 of file chan_sip.c.

References ao2_ref, ast_set_flag, ast_sip_ouraddrfor(), create_addr(), dialog_unlink_all(), FALSE, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_invite(), and TRUE.

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

12567 {
12568    struct sip_pvt *pvt;
12569    int expires;
12570 
12571    epa_entry->publish_type = publish_type;
12572 
12573    if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL))) {
12574       return -1;
12575    }
12576 
12577    sip_pvt_lock(pvt);
12578 
12579    if (create_addr(pvt, epa_entry->destination, NULL, TRUE)) {
12580       sip_pvt_unlock(pvt);
12581       dialog_unlink_all(pvt);
12582       dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog");
12583       return -1;
12584    }
12585    ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt);
12586    ast_set_flag(&pvt->flags[0], SIP_OUTGOING);
12587    expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES;
12588    pvt->expiry = expires;
12589 
12590    /* Bump refcount for sip_pvt's reference */
12591    ao2_ref(epa_entry, +1);
12592    pvt->epa_entry = epa_entry;
12593 
12594    transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri);
12595    sip_pvt_unlock(pvt);
12596    sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT);
12597    dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH");
12598    return 0;
12599 }

static int transmit_refer ( struct sip_pvt *  p,
const char *  dest 
) [static]

Transmit SIP REFER message (initiated by the transfer() dialplan application.

Note:
this is currently broken as we have no way of telling the dialplan engine whether a transfer succeeds or fails.
Todo:
Fix the transfer() dialplan function so that a transfer may fail

Todo:
In theory, we should hang around and wait for a reply, before returning to the dial plan here. Don't know really how that would affect the transfer() app or the pbx, but, well, to make this useful we should have a STATUS code on transfer().

Definition at line 13975 of file chan_sip.c.

References add_header(), add_supported_header(), ast_copy_string(), ast_debug, ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, FALSE, get_header(), get_in_brackets(), LOG_NOTICE, reqprep(), send_request(), sip_refer_allocate(), and TRUE.

Referenced by sip_transfer().

13976 {
13977    struct sip_request req = {
13978       .headers = 0,  
13979    };
13980    char from[256];
13981    const char *of;
13982    char *c;
13983    char referto[256];
13984    int   use_tls=FALSE;
13985 
13986    if (sipdebug) {
13987       ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest);
13988    }
13989 
13990    /* Are we transfering an inbound or outbound call ? */
13991    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
13992       of = get_header(&p->initreq, "To");
13993    } else {
13994       of = get_header(&p->initreq, "From");
13995    }
13996 
13997    ast_copy_string(from, of, sizeof(from));
13998    of = get_in_brackets(from);
13999    ast_string_field_set(p, from, of);
14000    if (!strncasecmp(of, "sip:", 4)) {
14001       of += 4;
14002    } else if (!strncasecmp(of, "sips:", 5)) {
14003       of += 5;
14004       use_tls = TRUE;
14005    } else {
14006       ast_log(LOG_NOTICE, "From address missing 'sip(s):', assuming sip:\n");
14007    }
14008    /* Get just the username part */
14009    if (strchr(dest, '@')) {
14010       c = NULL;
14011    } else if ((c = strchr(of, '@'))) {
14012       *c++ = '\0';
14013    }
14014    if (c) {
14015       snprintf(referto, sizeof(referto), "<sip%s:%s@%s>", use_tls ? "s" : "", dest, c);
14016    } else {
14017       snprintf(referto, sizeof(referto), "<sip%s:%s>", use_tls ? "s" : "", dest);
14018    }
14019 
14020    /* save in case we get 407 challenge */
14021    sip_refer_allocate(p);
14022    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
14023    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
14024    p->refer->status = REFER_SENT;   /* Set refer status */
14025 
14026    reqprep(&req, p, SIP_REFER, 0, 1);
14027 
14028    add_header(&req, "Refer-To", referto);
14029    add_header(&req, "Allow", ALLOWED_METHODS);
14030    add_supported_header(p, &req);
14031    if (!ast_strlen_zero(p->our_contact)) {
14032       add_header(&req, "Referred-By", p->our_contact);
14033    }
14034 
14035    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
14036 
14037    /* We should propably wait for a NOTIFY here until we ack the transfer */
14038    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
14039 
14040    /*! \todo In theory, we should hang around and wait for a reply, before
14041    returning to the dial plan here. Don't know really how that would
14042    affect the transfer() app or the pbx, but, well, to make this
14043    useful we should have a STATUS code on transfer().
14044    */
14045 }

static int transmit_register ( struct sip_registry *  r,
int  sipmethod,
const char *  auth,
const char *  authheader 
) [static]

Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()).

Definition at line 13684 of file chan_sip.c.

References add_header(), add_header_max_forwards(), append_history, ast_debug, ast_dnsmgr_lookup_cb(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_cmp(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ast_verbose, build_callid_registry(), build_contact(), build_localtag_registry(), build_reply_digest(), build_via(), create_addr(), dialog_unlink_all(), exten, FALSE, find_peer(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), init_req(), initialize_initreq(), internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), on_dns_update_peer(), on_dns_update_registry(), REG_STATE_AUTHSENT, REG_STATE_REGSENT, registry_addref(), registry_unref(), S_OR, send_request(), set_socket_transport(), sip_alloc(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_reg_timeout(), sip_sanitized_host(), cfsip_methods::text, TRUE, and unref_peer().

Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().

13685 {
13686    struct sip_request req;
13687    char from[256];
13688    char to[256];
13689    char tmp[80];
13690    char addr[80];
13691    struct sip_pvt *p;
13692    struct sip_peer *peer = NULL;
13693    int res;
13694    int portno = 0;
13695 
13696    /* exit if we are already in process with this registrar ?*/
13697    if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) {
13698       if (r) {
13699          ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
13700       }
13701       return 0;
13702    }
13703 
13704    if (r->dnsmgr == NULL) {
13705       char transport[MAXHOSTNAMELEN];
13706       peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0);
13707       snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static get_transport function */
13708       r->us.ss.ss_family = get_address_family_filter(r->transport); /* Filter address family */
13709 
13710       /* No point in doing a DNS lookup of the register hostname if we're just going to
13711        * end up using an outbound proxy. obproxy_get is safe to call with either of r->call
13712        * or peer NULL. Since we're only concerned with its existence, we're not going to
13713        * bother getting a ref to the proxy*/
13714       if (!obproxy_get(r->call, peer)) {
13715          registry_addref(r, "add reg ref for dnsmgr");
13716          ast_dnsmgr_lookup_cb(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r);
13717          if (!r->dnsmgr) {
13718             /*dnsmgr refresh disabled, no reference added! */
13719             registry_unref(r, "remove reg ref, dnsmgr disabled");
13720          }
13721       }
13722       if (peer) {
13723          peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup");
13724       }
13725    }
13726 
13727    if (r->call) { /* We have a registration */
13728       if (!auth) {
13729          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
13730          return 0;
13731       } else {
13732          p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register");
13733          ast_string_field_set(p, theirtag, NULL);  /* forget their old tag, so we don't match tags when getting response */
13734       }
13735    } else {
13736       /* Build callid for registration if we haven't registered before */
13737       if (!r->callid_valid) {
13738          build_callid_registry(r, &internip, default_fromdomain);
13739          build_localtag_registry(r);
13740          r->callid_valid = TRUE;
13741       }
13742       /* Allocate SIP dialog for registration */
13743       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) {
13744          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
13745          return 0;
13746       }
13747 
13748       /* reset tag to consistent value from registry */
13749       ast_string_field_set(p, tag, r->localtag);
13750 
13751       if (p->do_history) {
13752          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
13753       }
13754 
13755       p->socket.type = r->transport;
13756 
13757       /* Use port number specified if no SRV record was found */
13758       if (!ast_sockaddr_isnull(&r->us)) {
13759          if (!ast_sockaddr_port(&r->us) && r->portno) {
13760             ast_sockaddr_set_port(&r->us, r->portno);
13761          }
13762 
13763          /* It is possible that DNS was unavailable at the time the peer was created.
13764           * Here, if we've updated the address in the registry via manually calling
13765           * ast_dnsmgr_lookup_cb() above, then we call the same function that dnsmgr would
13766           * call if it was updating a peer's address */
13767          if ((peer = find_peer(S_OR(r->peername, r->hostname), NULL, TRUE, FINDPEERS, FALSE, 0))) {
13768             if (ast_sockaddr_cmp(&peer->addr, &r->us)) {
13769                on_dns_update_peer(&peer->addr, &r->us, peer);
13770             }
13771             peer = unref_peer(peer, "unref after find_peer");
13772          }
13773       }
13774 
13775       /* Find address to hostname */
13776       if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0)) {
13777          /* we have what we hope is a temporary network error,
13778           * probably DNS.  We need to reschedule a registration try */
13779          dialog_unlink_all(p);
13780          p = dialog_unref(p, "unref dialog after unlink_all");
13781          if (r->timeout > -1) {
13782             AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r,
13783                               registry_unref(_data, "del for REPLACE of registry ptr"),
13784                               registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"),
13785                               registry_addref(r,"add for REPLACE registry ptr"));
13786             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
13787          } else {
13788             r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr"));
13789             ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout);
13790          }
13791          r->regattempts++;
13792          return 0;
13793       }
13794 
13795       /* Copy back Call-ID in case create_addr changed it */
13796       ast_string_field_set(r, callid, p->callid);
13797 
13798       if (!r->dnsmgr && r->portno) {
13799          ast_sockaddr_set_port(&p->sa, r->portno);
13800          ast_sockaddr_set_port(&p->recv, r->portno);
13801       }
13802       if (!ast_strlen_zero(p->fromdomain)) {
13803          portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT;
13804       } else if (!ast_strlen_zero(r->regdomain)) {
13805          portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT;
13806       } else {
13807          portno = ast_sockaddr_port(&p->sa);
13808       }
13809 
13810       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
13811       r->call = dialog_ref(p, "copying dialog into registry r->call");     /* Save pointer to SIP dialog */
13812       p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */
13813       if (!ast_strlen_zero(r->secret)) {  /* Secret (password) */
13814          ast_string_field_set(p, peersecret, r->secret);
13815       }
13816       if (!ast_strlen_zero(r->md5secret))
13817          ast_string_field_set(p, peermd5secret, r->md5secret);
13818       /* User name in this realm
13819       - if authuser is set, use that, otherwise use username */
13820       if (!ast_strlen_zero(r->authuser)) {
13821          ast_string_field_set(p, peername, r->authuser);
13822          ast_string_field_set(p, authname, r->authuser);
13823       } else if (!ast_strlen_zero(r->username)) {
13824          ast_string_field_set(p, peername, r->username);
13825          ast_string_field_set(p, authname, r->username);
13826          ast_string_field_set(p, fromuser, r->username);
13827       }
13828       if (!ast_strlen_zero(r->username)) {
13829          ast_string_field_set(p, username, r->username);
13830       }
13831       /* Save extension in packet */
13832       if (!ast_strlen_zero(r->callback)) {
13833          ast_string_field_set(p, exten, r->callback);
13834       }
13835 
13836       /* Set transport and port so the correct contact is built */
13837       set_socket_transport(&p->socket, r->transport);
13838       if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) {
13839          p->socket.port =
13840              htons(ast_sockaddr_port(&sip_tcp_desc.local_address));
13841       }
13842 
13843       /*
13844         check which address we should use in our contact header
13845         based on whether the remote host is on the external or
13846         internal network so we can register through nat
13847        */
13848       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
13849       build_contact(p);
13850    }
13851 
13852    /* set up a timeout */
13853    if (auth == NULL)  {
13854       if (r->timeout > -1) {
13855          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
13856       }
13857       AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r,
13858                         registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"),
13859                         registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"),
13860                         registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE"));
13861       ast_debug(1, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
13862    }
13863 
13864    snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->tag);
13865    if (!ast_strlen_zero(p->theirtag)) {
13866       snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->theirtag);
13867    } else {
13868       snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)));
13869    }
13870 
13871    /* Fromdomain is what we are registering to, regardless of actual
13872       host name from SRV */
13873    if (portno && portno != STANDARD_SIP_PORT) {
13874       snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname))), portno);
13875    } else {
13876       snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname))));
13877    }
13878 
13879    ast_string_field_set(p, uri, addr);
13880 
13881    p->branch ^= ast_random();
13882 
13883    init_req(&req, sipmethod, addr);
13884 
13885    /* Add to CSEQ */
13886    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
13887    p->ocseq = r->ocseq;
13888 
13889    build_via(p);
13890    add_header(&req, "Via", p->via);
13891    add_header_max_forwards(p, &req);
13892    add_header(&req, "From", from);
13893    add_header(&req, "To", to);
13894    add_header(&req, "Call-ID", p->callid);
13895    add_header(&req, "CSeq", tmp);
13896    if (!ast_strlen_zero(global_useragent))
13897       add_header(&req, "User-Agent", global_useragent);
13898 
13899    if (auth) {    /* Add auth header */
13900       add_header(&req, authheader, auth);
13901    } else if (!ast_strlen_zero(r->nonce)) {
13902       char digest[1024];
13903 
13904       /* We have auth data to reuse, build a digest header.
13905        * Note, this is not always useful because some parties do not
13906        * like nonces to be reused (for good reasons!) so they will
13907        * challenge us anyways.
13908        */
13909       if (sipdebug) {
13910          ast_debug(1, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
13911       }
13912       ast_string_field_set(p, realm, r->realm);
13913       ast_string_field_set(p, nonce, r->nonce);
13914       ast_string_field_set(p, domain, r->authdomain);
13915       ast_string_field_set(p, opaque, r->opaque);
13916       ast_string_field_set(p, qop, r->qop);
13917       p->noncecount = ++r->noncecount;
13918 
13919       memset(digest, 0, sizeof(digest));
13920       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
13921          add_header(&req, "Authorization", digest);
13922       } else {
13923          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
13924       }
13925    }
13926 
13927    snprintf(tmp, sizeof(tmp), "%d", r->expiry);
13928    add_header(&req, "Expires", tmp);
13929    add_header(&req, "Contact", p->our_contact);
13930 
13931    initialize_initreq(p, &req);
13932    if (sip_debug_test_pvt(p)) {
13933       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
13934    }
13935    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
13936    r->regattempts++; /* Another attempt */
13937    ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
13938    res = send_request(p, &req, XMIT_CRITICAL, p->ocseq);
13939    dialog_unref(p, "p is finished here at the end of transmit_register");
13940    return res;
13941 }

static int transmit_reinvite_with_sdp ( struct sip_pvt *  p,
int  t38version,
int  oldsdp 
) [static]

Transmit reinvite with SDP.

Note:
A re-invite is basically a new INVITE with the same CALL-ID and TAG as the INVITE that opened the SIP dialogue We reinvite so that the audio stream (RTP) go directly between the SIP UAs. SIP Signalling stays with * in the path.

If t38version is TRUE, we send T38 SDP for re-invite from audio/video to T38 UDPTL transmission on the channel

If oldsdp is TRUE then the SDP version number is not incremented. This is needed for Session-Timers so we can send a re-invite to refresh the SIP session without modifying the media session.

Definition at line 12260 of file chan_sip.c.

References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_set_flag, ast_test_flag, FALSE, initialize_initreq(), reqprep(), send_request(), TRUE, and try_suggested_sip_codec().

Referenced by check_pendings(), handle_response_invite(), interpret_t38_parameters(), proc_session_timer(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().

12261 {
12262    struct sip_request req;
12263    
12264    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
12265 
12266    add_header(&req, "Allow", ALLOWED_METHODS);
12267    add_supported_header(p, &req);
12268    if (sipdebug) {
12269       if (oldsdp == TRUE)
12270          add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)");
12271       else
12272          add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
12273    }
12274 
12275    if (ast_test_flag(&p->flags[0], SIP_SENDRPID))
12276       add_rpid(&req, p);
12277 
12278    if (p->do_history) {
12279       append_history(p, "ReInv", "Re-invite sent");
12280    }
12281    memset(p->offered_media, 0, sizeof(p->offered_media));
12282 
12283    try_suggested_sip_codec(p);
12284    if (t38version) {
12285       add_sdp(&req, p, oldsdp, FALSE, TRUE);
12286    } else {
12287       add_sdp(&req, p, oldsdp, TRUE, FALSE);
12288    }
12289 
12290    /* Use this as the basis */
12291    initialize_initreq(p, &req);
12292    p->lastinvite = p->ocseq;
12293    ast_set_flag(&p->flags[0], SIP_OUTGOING);       /* Change direction of this dialog */
12294    p->ongoing_reinvite = 1;
12295    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
12296 }

static int transmit_request ( struct sip_pvt *  p,
int  sipmethod,
uint32_t  seqno,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).

Definition at line 14118 of file chan_sip.c.

References add_header(), reqprep(), and send_request().

Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().

14119 {
14120    struct sip_request resp;
14121    
14122    reqprep(&resp, p, sipmethod, seqno, newbranch);
14123    if (sipmethod == SIP_CANCEL && p->answered_elsewhere) {
14124       add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
14125    }
14126 
14127    if (sipmethod == SIP_ACK) {
14128       p->invitestate = INV_CONFIRMED;
14129    }
14130 
14131    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
14132 }

static int transmit_request_with_auth ( struct sip_pvt *  p,
int  sipmethod,
uint32_t  seqno,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit SIP request, auth added.

Definition at line 14150 of file chan_sip.c.

References add_header(), ast_cause2str(), ast_log(), ast_strlen_zero(), ast_test_flag, auth_headers(), build_reply_digest(), dummy(), LOG_WARNING, reqprep(), and send_request().

Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().

14151 {
14152    struct sip_request resp;
14153    
14154    reqprep(&resp, p, sipmethod, seqno, newbranch);
14155    if (!ast_strlen_zero(p->realm)) {
14156       char digest[1024];
14157 
14158       memset(digest, 0, sizeof(digest));
14159       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
14160          char *dummy, *response;
14161          enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */
14162          auth_headers(code, &dummy, &response);
14163          add_header(&resp, response, digest);
14164       } else {
14165          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
14166       }
14167    }
14168    /* If we are hanging up and know a cause for that, send it in clear text to make
14169       debugging easier. */
14170    if (sipmethod == SIP_BYE)  {
14171       char buf[20];
14172 
14173       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && p->hangupcause) {
14174          sprintf(buf, "Q.850;cause=%i", p->hangupcause & 0x7f);
14175          add_header(&resp, "Reason", buf);
14176       }
14177 
14178       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause));
14179       snprintf(buf, sizeof(buf), "%d", p->hangupcause);
14180       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
14181    }
14182 
14183    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
14184 }

static int transmit_response ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]
static int transmit_response_reliable ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

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.

Definition at line 11019 of file chan_sip.c.

References __transmit_response().

Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_invite_st(), interpret_t38_parameters(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().

11020 {
11021    return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL);
11022 }

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 
) [static]

Transmit response, no retransmits, using a temporary pvt structure.

Definition at line 10933 of file chan_sip.c.

References __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_threadstorage_get(), build_via(), copy_socket_data(), do_setnat(), internip, LOG_ERROR, and make_our_tag().

Referenced by find_call().

10934 {
10935    struct sip_pvt *p = NULL;
10936 
10937    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
10938       ast_log(LOG_ERROR, "Failed to get temporary pvt\n");
10939       return -1;
10940    }
10941 
10942    /* XXX the structure may be dirty from previous usage.
10943     * Here we should state clearly how we should reinitialize it
10944     * before using it.
10945     * E.g. certainly the threadstorage should be left alone,
10946     * but other thihngs such as flags etc. maybe need cleanup ?
10947     */
10948 
10949    /* Initialize the bare minimum */
10950    p->method = intended_method;
10951 
10952    if (!addr) {
10953       ast_sockaddr_copy(&p->ourip, &internip);
10954    } else {
10955       ast_sockaddr_copy(&p->sa, addr);
10956       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
10957    }
10958 
10959    p->branch = ast_random();
10960    make_our_tag(p);
10961    p->ocseq = INITIAL_CSEQ;
10962 
10963    if (useglobal_nat && addr) {
10964       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
10965       ast_sockaddr_copy(&p->recv, addr);
10966       do_setnat(p);
10967    }
10968 
10969    ast_string_field_set(p, fromdomain, default_fromdomain);
10970    p->fromdomainport = default_fromdomainport;
10971    build_via(p);
10972    ast_string_field_set(p, callid, callid);
10973 
10974    copy_socket_data(&p->socket, &req->socket);
10975 
10976    /* Use this temporary pvt structure to send the message */
10977    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
10978 
10979    /* Free the string fields, but not the pool space */
10980    ast_string_field_init(p, 0);
10981 
10982    return 0;
10983 }

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

Append Accept header, content length before transmitting response.

Definition at line 11055 of file chan_sip.c.

References add_header(), respprep(), and send_response().

Referenced by handle_incoming(), and handle_request_options().

11056 {
11057    struct sip_request resp;
11058    respprep(&resp, p, msg, req);
11059    add_header(&resp, "Accept", "application/sdp");
11060    return send_response(p, &resp, reliable, 0);
11061 }

static int transmit_response_with_auth ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
const char *  rand,
enum xmittype  reliable,
const char *  header,
int  stale 
) [static]

Respond with authorization request.

Definition at line 11076 of file chan_sip.c.

References add_header(), append_history, ast_log(), get_header(), get_realm(), LOG_WARNING, respprep(), and send_response().

Referenced by check_auth(), and transmit_fake_auth_response().

11077 {
11078    struct sip_request resp;
11079    char tmp[512];
11080    uint32_t seqno = 0;
11081 
11082    if (reliable && (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1)) {
11083       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
11084       return -1;
11085    }
11086    /* Choose Realm */
11087    get_realm(p, req);
11088 
11089    /* Stale means that they sent us correct authentication, but
11090       based it on an old challenge (nonce) */
11091    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, randdata, stale ? ", stale=true" : "");
11092    respprep(&resp, p, msg, req);
11093    add_header(&resp, header, tmp);
11094    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
11095    return send_response(p, &resp, reliable, seqno);
11096 }

static int transmit_response_with_date ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

Append date and content length before transmitting response.

Definition at line 11046 of file chan_sip.c.

References append_date(), respprep(), and send_response().

Referenced by handle_response_subscribe(), and register_verify().

11047 {
11048    struct sip_request resp;
11049    respprep(&resp, p, msg, req);
11050    append_date(&resp);
11051    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
11052 }

static int transmit_response_with_minexpires ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

Append Min-Expires header, content length before transmitting response.

Definition at line 11064 of file chan_sip.c.

References add_header(), respprep(), and send_response().

Referenced by handle_request_publish(), and handle_request_subscribe().

11065 {
11066    struct sip_request resp;
11067    char tmp[32];
11068 
11069    snprintf(tmp, sizeof(tmp), "%d", min_expiry);
11070    respprep(&resp, p, msg, req);
11071    add_header(&resp, "Min-Expires", tmp);
11072    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
11073 }

static int transmit_response_with_minse ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
int  minse_int 
) [static]

Transmit 422 response with Min-SE header (Session-Timers).

Definition at line 11002 of file chan_sip.c.

References add_header(), append_date(), respprep(), and send_response().

Referenced by handle_request_invite_st().

11003 {
11004    struct sip_request resp;
11005    char minse_str[20];
11006 
11007    respprep(&resp, p, msg, req);
11008    append_date(&resp);
11009 
11010    snprintf(minse_str, sizeof(minse_str), "%d", minse_int);
11011    add_header(&resp, "Min-SE", minse_str);
11012    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
11013 }

static int transmit_response_with_retry_after ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
const char *  seconds 
) [static]

Append Retry-After header field when transmitting response.

Definition at line 11037 of file chan_sip.c.

References add_header(), respprep(), and send_response().

Referenced by handle_incoming().

11038 {
11039    struct sip_request resp;
11040    respprep(&resp, p, msg, req);
11041    add_header(&resp, "Retry-After", seconds);
11042    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
11043 }

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 
) [static]

Used for 200 OK and 183 early media.

Returns:
Will return XMIT_ERROR for network errors.

Definition at line 12169 of file chan_sip.c.

References add_cc_call_info_to_response(), add_required_respheader(), add_rpid(), add_sdp(), ast_debug, ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_instance_activate(), ast_rtp_instance_get_codecs(), ast_test_flag, FALSE, get_header(), LOG_ERROR, LOG_WARNING, respprep(), send_response(), TRUE, and try_suggested_sip_codec().

Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().

12170 {
12171    struct sip_request resp;
12172    uint32_t seqno;
12173    if (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1) {
12174       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
12175       return -1;
12176    }
12177    respprep(&resp, p, msg, req);
12178    if (rpid == TRUE) {
12179       add_rpid(&resp, p);
12180    }
12181    if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) {
12182       add_cc_call_info_to_response(p, &resp);
12183    }
12184    if (p->rtp) {
12185       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
12186          ast_debug(1, "Setting framing from config on incoming call\n");
12187          ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
12188       }
12189       ast_rtp_instance_activate(p->rtp);
12190       try_suggested_sip_codec(p);
12191       if (p->t38.state == T38_ENABLED) {
12192          add_sdp(&resp, p, oldsdp, TRUE, TRUE);
12193       } else {
12194          add_sdp(&resp, p, oldsdp, TRUE, FALSE);
12195       }
12196    } else
12197       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
12198    if (reliable && !p->pendinginvite)
12199       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
12200    add_required_respheader(&resp);
12201    return send_response(p, &resp, reliable, seqno);
12202 }

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]

Definition at line 10902 of file chan_sip.c.

References add_header(), create_new_sip_etag(), respprep(), and send_response().

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

10903 {
10904    struct sip_request resp;
10905 
10906    if (need_new_etag) {
10907       create_new_sip_etag(esc_entry, 1);
10908    }
10909    respprep(&resp, p, msg, req);
10910    add_header(&resp, "SIP-ETag", esc_entry->entity_tag);
10911 
10912    return send_response(p, &resp, 0, 0);
10913 }

static int transmit_response_with_t38_sdp ( struct sip_pvt *  p,
char *  msg,
struct sip_request *  req,
int  retrans 
) [static]

Used for 200 OK and 183 early media.

Definition at line 12085 of file chan_sip.c.

References add_sdp(), ast_log(), get_header(), LOG_ERROR, LOG_WARNING, respprep(), and send_response().

Referenced by handle_request_invite(), and interpret_t38_parameters().

12086 {
12087    struct sip_request resp;
12088    uint32_t seqno;
12089    
12090    if (sscanf(get_header(req, "CSeq"), "%30u ", &seqno) != 1) {
12091       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
12092       return -1;
12093    }
12094    respprep(&resp, p, msg, req);
12095    if (p->udptl) {
12096       add_sdp(&resp, p, 0, 0, 1);
12097    } else
12098       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
12099    if (retrans && !p->pendinginvite)
12100       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
12101    return send_response(p, &resp, retrans, seqno);
12102 }

static int transmit_response_with_unsupported ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
const char *  unsupported 
) [static]

Transmit response, no retransmits.

Definition at line 10992 of file chan_sip.c.

References add_header(), append_date(), respprep(), and send_response().

Referenced by handle_request_bye(), handle_request_invite(), and handle_request_invite_st().

10993 {
10994    struct sip_request resp;
10995    respprep(&resp, p, msg, req);
10996    append_date(&resp);
10997    add_header(&resp, "Unsupported", unsupported);
10998    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
10999 }

static int transmit_state_notify ( struct sip_pvt *  p,
int  state,
int  full,
int  timeout 
) [static]

Used in the SUBSCRIBE notification subsystem (RFC3265).

Definition at line 13224 of file chan_sip.c.

References add_content(), add_header(), ast_copy_string(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_log(), ast_str_alloca, ast_str_buffer(), ast_test_flag, cfsubscription_types::event, find_subscription_type(), get_header(), get_in_brackets(), LOG_WARNING, cfsubscription_types::mediatype, NONE, remove_uri_parameters(), reqprep(), send_request(), and state_notify_build_xml().

Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().

13225 {
13226    struct ast_str *tmp = ast_str_alloca(4000);
13227    char from[256], to[256];
13228    char *c, *mfrom, *mto;
13229    struct sip_request req;
13230    const struct cfsubscription_types *subscriptiontype;
13231 
13232    /* If the subscription has not yet been accepted do not send a NOTIFY */
13233    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
13234       return 0;
13235    }
13236 
13237    memset(from, 0, sizeof(from));
13238    memset(to, 0, sizeof(to));
13239 
13240    subscriptiontype = find_subscription_type(p->subscribed);
13241 
13242    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
13243    c = get_in_brackets(from);
13244    if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
13245       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
13246       return -1;
13247    }
13248 
13249    mfrom = remove_uri_parameters(c);
13250 
13251    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
13252    c = get_in_brackets(to);
13253    if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
13254       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
13255       return -1;
13256    }
13257    mto = remove_uri_parameters(c);
13258 
13259    reqprep(&req, p, SIP_NOTIFY, 0, 1);
13260 
13261    switch(state) {
13262    case AST_EXTENSION_DEACTIVATED:
13263       if (timeout)
13264          add_header(&req, "Subscription-State", "terminated;reason=timeout");
13265       else {
13266          add_header(&req, "Subscription-State", "terminated;reason=probation");
13267          add_header(&req, "Retry-After", "60");
13268       }
13269       break;
13270    case AST_EXTENSION_REMOVED:
13271       add_header(&req, "Subscription-State", "terminated;reason=noresource");
13272       break;
13273    default:
13274       if (p->expiry)
13275          add_header(&req, "Subscription-State", "active");
13276       else  /* Expired */
13277          add_header(&req, "Subscription-State", "terminated;reason=timeout");
13278    }
13279 
13280    switch (p->subscribed) {
13281    case XPIDF_XML:
13282    case CPIM_PIDF_XML:
13283       add_header(&req, "Event", subscriptiontype->event);
13284       state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
13285       add_header(&req, "Content-Type", subscriptiontype->mediatype);
13286       p->dialogver++;
13287       break;
13288    case PIDF_XML: /* Eyebeam supports this format */
13289       add_header(&req, "Event", subscriptiontype->event);
13290       state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
13291       add_header(&req, "Content-Type", subscriptiontype->mediatype);
13292       p->dialogver++;
13293       break;
13294    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
13295       add_header(&req, "Event", subscriptiontype->event);
13296       state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
13297       add_header(&req, "Content-Type", subscriptiontype->mediatype);
13298       p->dialogver++;
13299       break;
13300    case NONE:
13301    default:
13302       break;
13303    }
13304 
13305    add_content(&req, ast_str_buffer(tmp));
13306 
13307    p->pendinginvite = p->ocseq;  /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
13308 
13309    /* Send as XMIT_CRITICAL as we may never receive a 200 OK Response which clears p->pendinginvite.
13310     *
13311     * extensionstate_update() uses p->pendinginvite for queuing control.
13312     * Updates stall if pendinginvite <> 0.
13313     *
13314     * The most appropriate solution is to remove the subscription when the NOTIFY transaction fails.
13315     * The client will re-subscribe after restarting or maxexpiry timeout.
13316     */
13317 
13318    /* RFC6665 4.2.2.  Sending State Information to Subscribers
13319     * If the NOTIFY request fails due to expiration of SIP Timer F (transaction timeout),
13320     * the notifier SHOULD remove the subscription.
13321     */
13322    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
13323 }

static const char* transport2str ( enum sip_transport  transport  )  [static]

Definition at line 19213 of file chan_sip.c.

Referenced by sip_show_channel().

19214 {
19215    switch (transport) {
19216    case SIP_TRANSPORT_TLS:
19217       return "TLS";
19218    case SIP_TRANSPORT_UDP:
19219       return "UDP";
19220    case SIP_TRANSPORT_TCP:
19221       return "TCP";
19222    }
19223 
19224    return "Undefined";
19225 }

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

Definition at line 17615 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer().

17616 {
17617    return map_x_s(trust_id_outboundstr, mode, "<error>");
17618 }

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

Try setting codec suggested by the SIP_CODEC channel variable.

Definition at line 6700 of file chan_sip.c.

References ast_getformatbyname(), ast_log(), LOG_NOTICE, and pbx_builtin_getvar_helper().

Referenced by sip_answer(), transmit_invite(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp().

06701 {
06702    format_t fmt;
06703    const char *codec;
06704 
06705    if (p->outgoing_call) {
06706       codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND");
06707    } else if (!(codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) {
06708       codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
06709    }
06710 
06711    if (!codec) 
06712       return;
06713 
06714    fmt = ast_getformatbyname(codec);
06715    if (fmt) {
06716       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
06717       if (p->jointcapability & fmt) {
06718          p->jointcapability &= fmt;
06719          p->capability &= fmt;
06720       } else
06721          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
06722    } else
06723       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
06724    return;  
06725 }

static void unlink_all_peers_from_tables ( void   )  [static]

Definition at line 3042 of file chan_sip.c.

References SIP_PEERS_ALL, and unlink_peers_from_tables().

Referenced by unload_module().

03043 {
03044    unlink_peers_from_tables(SIP_PEERS_ALL);
03045 }

static void unlink_marked_peers_from_tables ( void   )  [static]

Definition at line 3037 of file chan_sip.c.

References SIP_PEERS_MARKED, and unlink_peers_from_tables().

Referenced by sip_do_reload(), and sip_prune_realtime().

static void unlink_peers_from_tables ( peer_unlink_flag_t  flag  )  [static]

Definition at line 3028 of file chan_sip.c.

References ao2_t_callback, match_and_cleanup_peer_sched(), OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by unlink_all_peers_from_tables(), and unlink_marked_peers_from_tables().

03029 {
03030    ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
03031       match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers");
03032    ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
03033       match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers");
03034 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 31966 of file chan_sip.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ARRAY_LEN, ast_cc_agent_unregister(), ast_cc_monitor_unregister(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_config_destroy(), ast_context_destroy(), ast_context_find(), ast_custom_function_unregister(), ast_data_unregister, ast_debug, ast_dnsmgr_release(), ast_free, ast_free_ha(), ast_io_remove(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), ast_sched_dump(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_ssl_teardown(), ast_tcptls_server_stop(), AST_TEST_UNREGISTER, ast_udptl_proto_unregister(), ast_unload_realtime(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, cleanup_all_regs(), clear_sip_domains(), destroy_escs(), dialog_unlink_all(), io_context_destroy(), ast_tcptls_session_args::master, network_change_event_unsubscribe(), ast_tls_config::pvtfile, regl, sched_context_destroy(), sip_cfg, sip_epa_unregister_all(), sip_registry_destroy(), sip_reqresp_parser_exit(), sip_subscribe_mwi_destroy(), sip_unregister_tests(), submwil, thread, ast_tcptls_session_args::tls_cfg, and unlink_all_peers_from_tables().

31967 {
31968    struct sip_pvt *p;
31969    struct sip_threadinfo *th;
31970    struct ast_context *con;
31971    struct ao2_iterator i;
31972    int wait_count;
31973 
31974    network_change_event_unsubscribe();
31975 
31976    ast_sched_dump(sched);
31977    
31978    /* First, take us out of the channel type list */
31979    ast_channel_unregister(&sip_tech);
31980 
31981    /* Unregister dial plan functions */
31982    ast_custom_function_unregister(&sipchaninfo_function);
31983    ast_custom_function_unregister(&sippeer_function);
31984    ast_custom_function_unregister(&sip_header_function);
31985    ast_custom_function_unregister(&checksipdomain_function);
31986 
31987    /* Unregister dial plan applications */
31988    ast_unregister_application(app_dtmfmode);
31989    ast_unregister_application(app_sipaddheader);
31990    ast_unregister_application(app_sipremoveheader);
31991 
31992 #ifdef TEST_FRAMEWORK
31993    AST_TEST_UNREGISTER(test_sip_peers_get);
31994    AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse);
31995    AST_TEST_UNREGISTER(test_tcp_message_fragmentation);
31996    AST_TEST_UNREGISTER(get_in_brackets_const_test);
31997 #endif
31998    /* Unregister all the AstData providers */
31999    ast_data_unregister(NULL);
32000 
32001    /* Unregister CLI commands */
32002    ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip));
32003 
32004    /* Disconnect from UDPTL */
32005    ast_udptl_proto_unregister(&sip_udptl);
32006 
32007    /* Disconnect from RTP engine */
32008    ast_rtp_glue_unregister(&sip_rtp_glue);
32009 
32010    /* Unregister AMI actions */
32011    ast_manager_unregister("SIPpeers");
32012    ast_manager_unregister("SIPshowpeer");
32013    ast_manager_unregister("SIPqualifypeer");
32014    ast_manager_unregister("SIPshowregistry");
32015    ast_manager_unregister("SIPnotify");
32016    
32017    /* Kill TCP/TLS server threads */
32018    if (sip_tcp_desc.master) {
32019       ast_tcptls_server_stop(&sip_tcp_desc);
32020    }
32021    if (sip_tls_desc.master) {
32022       ast_tcptls_server_stop(&sip_tls_desc);
32023    }
32024    ast_ssl_teardown(sip_tls_desc.tls_cfg);
32025 
32026    /* Kill all existing TCP/TLS threads */
32027    i = ao2_iterator_init(threadt, 0);
32028    while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
32029       pthread_t thread = th->threadid;
32030       th->stop = 1;
32031       pthread_kill(thread, SIGURG);
32032       ao2_t_ref(th, -1, "decrement ref from iterator");
32033    }
32034    ao2_iterator_destroy(&i);
32035 
32036    /* Hangup all dialogs if they have an owner */
32037    i = ao2_iterator_init(dialogs, 0);
32038    while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
32039       if (p->owner)
32040          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
32041       ao2_t_ref(p, -1, "toss dialog ptr from iterator_next");
32042    }
32043    ao2_iterator_destroy(&i);
32044 
32045    unlink_all_peers_from_tables();
32046 
32047    ast_mutex_lock(&monlock);
32048    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
32049       pthread_t th = monitor_thread;
32050       monitor_thread = AST_PTHREADT_STOP;
32051       pthread_cancel(th);
32052       pthread_kill(th, SIGURG);
32053       ast_mutex_unlock(&monlock);
32054       pthread_join(th, NULL);
32055    } else {
32056       monitor_thread = AST_PTHREADT_STOP;
32057       ast_mutex_unlock(&monlock);
32058    }
32059 
32060    /* Destroy all the dialogs and free their memory */
32061    i = ao2_iterator_init(dialogs, 0);
32062    while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
32063       dialog_unlink_all(p);
32064       ao2_t_ref(p, -1, "throw away iterator result");
32065    }
32066    ao2_iterator_destroy(&i);
32067 
32068    /* Free memory for local network address mask */
32069    ast_free_ha(localaddr);
32070 
32071    ast_mutex_lock(&authl_lock);
32072    if (authl) {
32073       ao2_t_ref(authl, -1, "Removing global authentication");
32074       authl = NULL;
32075    }
32076    ast_mutex_unlock(&authl_lock);
32077 
32078    sip_epa_unregister_all();
32079    destroy_escs();
32080 
32081    ast_free(default_tls_cfg.certfile);
32082    ast_free(default_tls_cfg.pvtfile);
32083    ast_free(default_tls_cfg.cipher);
32084    ast_free(default_tls_cfg.cafile);
32085    ast_free(default_tls_cfg.capath);
32086 
32087    cleanup_all_regs();
32088    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
32089    ASTOBJ_CONTAINER_DESTROY(&regl);
32090 
32091    ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
32092       ASTOBJ_WRLOCK(iterator);
32093       if (iterator->dnsmgr) {
32094          ast_dnsmgr_release(iterator->dnsmgr);
32095          iterator->dnsmgr = NULL;
32096          ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy);
32097       }
32098       ASTOBJ_UNLOCK(iterator);
32099    } while(0));
32100    ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy);
32101    ASTOBJ_CONTAINER_DESTROY(&submwil);
32102 
32103    /*
32104     * Wait awhile for the TCP/TLS thread container to become empty.
32105     *
32106     * XXX This is a hack, but the worker threads cannot be created
32107     * joinable.  They can die on their own and remove themselves
32108     * from the container thus resulting in a huge memory leak.
32109     */
32110    wait_count = 1000;
32111    while (ao2_container_count(threadt) && --wait_count) {
32112       sched_yield();
32113    }
32114    if (!wait_count) {
32115       ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
32116    }
32117 
32118    ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
32119 
32120    ao2_t_ref(peers, -1, "unref the peers table");
32121    ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table");
32122    ao2_t_ref(dialogs, -1, "unref the dialogs table");
32123    ao2_t_ref(dialogs_to_destroy, -1, "unref dialogs_to_destroy");
32124    ao2_t_ref(threadt, -1, "unref the thread table");
32125    ao2_t_ref(sip_monitor_instances, -1, "unref the sip_monitor_instances table");
32126 
32127    clear_sip_domains();
32128    ast_free_ha(sip_cfg.contact_ha);
32129    if (sipsock_read_id) {
32130       ast_io_remove(io, sipsock_read_id);
32131       sipsock_read_id = NULL;
32132    }
32133    close(sipsock);
32134    io_context_destroy(io);
32135    sched_context_destroy(sched);
32136    con = ast_context_find(used_context);
32137    if (con) {
32138       ast_context_destroy(con, "SIP");
32139    }
32140    ast_unload_realtime("sipregs");
32141    ast_unload_realtime("sippeers");
32142    ast_cc_monitor_unregister(&sip_cc_monitor_callbacks);
32143    ast_cc_agent_unregister(&sip_cc_agent_callbacks);
32144 
32145    sip_reqresp_parser_exit();
32146    sip_unregister_tests();
32147 
32148    if (notify_types) {
32149       ast_config_destroy(notify_types);
32150       notify_types = NULL;
32151    }
32152 
32153    return 0;
32154 }

static void* unref_peer ( struct sip_peer *  peer,
char *  tag 
) [static]
static int update_call_counter ( struct sip_pvt *  fup,
int  event 
) [static]

update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.

Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.

Thought: For realtime, we should probably update storage with inuse counter...

Returns:
0 if call is ok (no call limit, below threshold) -1 on rejection of call

Definition at line 6143 of file chan_sip.c.

References ao2_lock, ao2_unlock, ast_clear_flag, ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_ERROR, LOG_NOTICE, name, ref_peer(), sip_cfg, sip_peer_hold(), sip_pvt_lock, sip_pvt_unlock, and unref_peer().

Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().

06144 {
06145    char name[256];
06146    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
06147    int outgoing = fup->outgoing_call;
06148    struct sip_peer *p = NULL;
06149 
06150    ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
06151 
06152 
06153    /* Test if we need to check call limits, in order to avoid
06154       realtime lookups if we do not need it */
06155    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
06156       return 0;
06157 
06158    ast_copy_string(name, fup->username, sizeof(name));
06159 
06160    /* Check the list of devices */
06161    if (fup->relatedpeer) {
06162       p = ref_peer(fup->relatedpeer, "ref related peer for update_call_counter");
06163       inuse = &p->inUse;
06164       call_limit = &p->call_limit;
06165       inringing = &p->inRinging;
06166       ast_copy_string(name, fup->peername, sizeof(name));
06167    }
06168    if (!p) {
06169       ast_debug(2, "%s is not a local device, no call limit\n", name);
06170       return 0;
06171    }
06172 
06173    switch(event) {
06174    /* incoming and outgoing affects the inUse counter */
06175    case DEC_CALL_LIMIT:
06176       /* Decrement inuse count if applicable */
06177       if (inuse) {
06178          sip_pvt_lock(fup);
06179          ao2_lock(p);
06180          if (*inuse > 0) {
06181             if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
06182                (*inuse)--;
06183                ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
06184             }
06185          } else {
06186             *inuse = 0;
06187          }
06188          ao2_unlock(p);
06189          sip_pvt_unlock(fup);
06190       }
06191 
06192       /* Decrement ringing count if applicable */
06193       if (inringing) {
06194          sip_pvt_lock(fup);
06195          ao2_lock(p);
06196          if (*inringing > 0) {
06197             if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
06198                (*inringing)--;
06199                ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
06200             }
06201          } else {
06202             *inringing = 0;
06203          }
06204          ao2_unlock(p);
06205          sip_pvt_unlock(fup);
06206       }
06207 
06208       /* Decrement onhold count if applicable */
06209       sip_pvt_lock(fup);
06210       ao2_lock(p);
06211       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && sip_cfg.notifyhold) {
06212          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
06213          ao2_unlock(p);
06214          sip_pvt_unlock(fup);
06215          sip_peer_hold(fup, FALSE);
06216       } else {
06217          ao2_unlock(p);
06218          sip_pvt_unlock(fup);
06219       }
06220       if (sipdebug)
06221          ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit);
06222       break;
06223 
06224    case INC_CALL_RINGING:
06225    case INC_CALL_LIMIT:
06226       /* If call limit is active and we have reached the limit, reject the call */
06227       if (*call_limit > 0 ) {
06228          if (*inuse >= *call_limit) {
06229             ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit);
06230             unref_peer(p, "update_call_counter: unref peer p, call limit exceeded");
06231             return -1;
06232          }
06233       }
06234       if (inringing && (event == INC_CALL_RINGING)) {
06235          sip_pvt_lock(fup);
06236          ao2_lock(p);
06237          if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
06238             (*inringing)++;
06239             ast_set_flag(&fup->flags[0], SIP_INC_RINGING);
06240          }
06241          ao2_unlock(p);
06242          sip_pvt_unlock(fup);
06243       }
06244       if (inuse) {
06245          sip_pvt_lock(fup);
06246          ao2_lock(p);
06247          if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
06248             (*inuse)++;
06249             ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
06250          }
06251          ao2_unlock(p);
06252          sip_pvt_unlock(fup);
06253       }
06254       if (sipdebug) {
06255          ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit);
06256       }
06257       break;
06258 
06259    case DEC_CALL_RINGING:
06260       if (inringing) {
06261          sip_pvt_lock(fup);
06262          ao2_lock(p);
06263          if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
06264             if (*inringing > 0) {
06265                (*inringing)--;
06266             }
06267             ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
06268          }
06269          ao2_unlock(p);
06270          sip_pvt_unlock(fup);
06271       }
06272       break;
06273 
06274    default:
06275       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
06276    }
06277 
06278    if (p) {
06279       ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", p->name);
06280       unref_peer(p, "update_call_counter: unref_peer from call counter");
06281    }
06282    return 0;
06283 }

static void update_connectedline ( struct sip_pvt *  p,
const void *  data,
size_t  datalen 
) [static]

Notify peer that the connected line has changed.

Definition at line 13480 of file chan_sip.c.

References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_clear_flag, ast_debug, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, FALSE, initialize_initreq(), is_method_allowed(), reqprep(), respprep(), S_COR, send_request(), send_response(), and TRUE.

Referenced by sip_indicate().

13481 {
13482 
13483    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
13484       return;
13485    }
13486    if (!p->owner->connected.id.number.valid
13487       || ast_strlen_zero(p->owner->connected.id.number.str)) {
13488       return;
13489    }
13490 
13491    append_history(p, "ConnectedLine", "%s party is now %s <%s>",
13492       ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called",
13493       S_COR(p->owner->connected.id.name.valid, p->owner->connected.id.name.str, ""),
13494       S_COR(p->owner->connected.id.number.valid, p->owner->connected.id.number.str, ""));
13495 
13496    if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
13497       struct sip_request req;
13498 
13499       if (!p->pendinginvite && (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED)) {
13500          reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
13501 
13502          add_header(&req, "Allow", ALLOWED_METHODS);
13503          add_supported_header(p, &req);
13504          add_rpid(&req, p);
13505          add_sdp(&req, p, FALSE, TRUE, FALSE);
13506 
13507          initialize_initreq(p, &req);
13508          p->lastinvite = p->ocseq;
13509          ast_set_flag(&p->flags[0], SIP_OUTGOING);
13510          p->invitestate = INV_CALLING;
13511          send_request(p, &req, XMIT_CRITICAL, p->ocseq);
13512       } else if ((is_method_allowed(&p->allowed_methods, SIP_UPDATE)) && (!ast_strlen_zero(p->okcontacturi))) { 
13513          reqprep(&req, p, SIP_UPDATE, 0, 1);
13514          add_rpid(&req, p);
13515          add_header(&req, "X-Asterisk-rpid-update", "Yes");
13516          send_request(p, &req, XMIT_CRITICAL, p->ocseq);
13517       } else {
13518          /* We cannot send the update yet, so we have to wait until we can */
13519          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
13520       }
13521    } else {
13522       ast_set_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND);
13523       if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPID_IMMEDIATE)) {
13524          struct sip_request resp;
13525 
13526          if ((p->owner->_state == AST_STATE_RING) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) {
13527             ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND);
13528             respprep(&resp, p, "180 Ringing", &p->initreq);
13529             add_rpid(&resp, p);
13530             send_response(p, &resp, XMIT_UNRELIABLE, 0);
13531             ast_set_flag(&p->flags[0], SIP_RINGING);
13532          } else if (p->owner->_state == AST_STATE_RINGING) {
13533             ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND);
13534             respprep(&resp, p, "183 Session Progress", &p->initreq);
13535             add_rpid(&resp, p);
13536             send_response(p, &resp, XMIT_UNRELIABLE, 0);
13537             ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
13538          } else {
13539             ast_debug(1, "Unable able to send update to '%s' in state '%s'\n", p->owner->name, ast_state2str(p->owner->_state));
13540          }
13541       }
13542    }
13543 }

static void update_peer ( struct sip_peer *  p,
int  expire 
) [static]

Update peer data in database (if used).

Definition at line 4882 of file chan_sip.c.

References ast_test_flag, realtime_update_peer(), and sip_cfg.

Referenced by register_verify().

04883 {
04884    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
04885    if (sip_cfg.peer_rtupdate &&
04886        (p->is_realtime || rtcachefriends)) {
04887       realtime_update_peer(p->name, &p->addr, p->username, p->fullcontact, p->useragent, expire, p->deprecated_username, p->lastms);
04888    }
04889 }

static void update_peer_lastmsgssent ( struct sip_peer *  peer,
int  value,
int  locked 
) [static]

Definition at line 15260 of file chan_sip.c.

References ao2_lock, and ao2_unlock.

Referenced by register_verify(), and sip_send_mwi_to_peer().

15261 {
15262    if (!locked) {
15263       ao2_lock(peer);
15264    }
15265    peer->lastmsgssent = value;
15266    if (!locked) {
15267       ao2_unlock(peer);
15268    }
15269 }

static void update_provisional_keepalive ( struct sip_pvt *  pvt,
int  with_sdp 
) [static]

Definition at line 4339 of file chan_sip.c.

References ast_sched_add(), AST_SCHED_DEL_UNREF, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

Referenced by transmit_provisional_response().

04340 {
04341    AST_SCHED_DEL_UNREF(sched, pvt->provisional_keepalive_sched_id, dialog_unref(pvt, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
04342 
04343    pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT,
04344       with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback"));
04345 }

static void update_redirecting ( struct sip_pvt *  p,
const void *  data,
size_t  datalen 
) [static]

Send a provisional response indicating that a call was redirected.

Definition at line 13466 of file chan_sip.c.

References add_diversion_header(), AST_STATE_UP, ast_test_flag, respprep(), and send_response().

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

13467 {
13468    struct sip_request resp;
13469 
13470    if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
13471       return;
13472    }
13473 
13474    respprep(&resp, p, "181 Call is being forwarded", &p->initreq);
13475    add_diversion_header(&resp, p);
13476    send_response(p, &resp, XMIT_UNRELIABLE, 0);
13477 }


Variable Documentation

struct _map_x_s allowoverlapstr[] [static]

Definition at line 17595 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 755 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 30278 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 30279 of file chan_sip.c.

char* app_sipremoveheader = "SIPRemoveHeader" [static]

Definition at line 30280 of file chan_sip.c.

struct sip_auth_container* authl = NULL [static]

Authentication container for realm authentication.

Definition at line 1124 of file chan_sip.c.

int authlimit = DEFAULT_AUTHLIMIT [static]

Definition at line 552 of file chan_sip.c.

Definition at line 553 of file chan_sip.c.

struct sip_peer* bogus_peer [static]

A bogus peer, to be used when authentication should fail.

Definition at line 1103 of file chan_sip.c.

int can_parse_xml [static]

We use libxml2 in order to parse XML that may appear in the body of a SIP message. Currently, the only usage is for parsing PIDF bodies of incoming PUBLISH requests in the call-completion event package. This variable is set at module load time and may be checked at runtime to determine if XML parsing support was found.

Definition at line 748 of file chan_sip.c.

struct epa_static_data cc_epa_static_data [static]

Definition at line 887 of file chan_sip.c.

unsigned int chan_idx [static]

used in naming sip channel

Definition at line 695 of file chan_sip.c.

Initial value:
 {
   .name = "CHECKSIPDOMAIN",
   .read = func_check_sipdomain,
}

Definition at line 20107 of file chan_sip.c.

struct ast_cli_entry cli_sip[] [static]

SIP Cli commands definition.

Definition at line 30855 of file chan_sip.c.

const char config[] = "sip.conf" [static]

Main configuration file

Definition at line 567 of file chan_sip.c.

struct ast_sockaddr debugaddr [static]

Definition at line 1190 of file chan_sip.c.

Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().

char default_callerid[AST_MAX_EXTENSION] [static]

Default caller ID for sip messages

Definition at line 668 of file chan_sip.c.

char default_engine[256] [static]

Default RTP engine

Definition at line 679 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 548 of file chan_sip.c.

Referenced by AST_TEST_DEFINE().

char default_fromdomain[AST_MAX_EXTENSION] [static]

Default domain on outound messages

Definition at line 670 of file chan_sip.c.

int default_fromdomainport [static]

Default domain port on outbound messages

Definition at line 671 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Note:
Values shown here match the defaults shown in sip.conf.sample

Definition at line 557 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Default language setting for new channels

Definition at line 667 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

Definition at line 680 of file chan_sip.c.

char default_mohinterpret[MAX_MUSICCLASS] [static]

Global setting for moh class to use when put on hold

Definition at line 675 of file chan_sip.c.

char default_mohsuggest[MAX_MUSICCLASS] [static]

Global setting for moh class to suggest when putting a bridged channel on hold

Definition at line 676 of file chan_sip.c.

char default_mwi_from[80] [static]

Default caller ID for MWI updates

Definition at line 669 of file chan_sip.c.

char default_notifymime[AST_MAX_EXTENSION] [static]

Default MIME media type for MWI notify messages

Definition at line 672 of file chan_sip.c.

char default_parkinglot[AST_MAX_CONTEXT] [static]

Parkinglot

Definition at line 678 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

Definition at line 681 of file chan_sip.c.

Referenced by reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().

unsigned int default_primary_transport [static]

Default primary Transport (enum sip_transport) for outbound connections to devices

Definition at line 683 of file chan_sip.c.

const int DEFAULT_PUBLISH_EXPIRES = 3600 [static]

Definition at line 930 of file chan_sip.c.

int default_qualify [static]

Default Qualify= setting

Definition at line 674 of file chan_sip.c.

Default TLS connection configuration.

Definition at line 2193 of file chan_sip.c.

unsigned int default_transports [static]

Default Transports (enum sip_transport) that are acceptable

Definition at line 682 of file chan_sip.c.

char default_vmexten[AST_MAX_EXTENSION] [static]

Default From Username on MWI updates

Definition at line 673 of file chan_sip.c.

struct ao2_container* dialogs [static]

Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items.

Definition at line 1090 of file chan_sip.c.

This container holds the dialogs that will be destroyed immediately.

Definition at line 1080 of file chan_sip.c.

struct _map_x_s dtmfstr[] [static]

mapping between dtmf flags and strings

Definition at line 17560 of file chan_sip.c.

Referenced by conf_run(), and send_dtmf().

unsigned int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 719 of file chan_sip.c.

int esc_etag_counter [static]

Used to create new entity IDs by ESCs.

Definition at line 929 of file chan_sip.c.

const int ESC_MAX_BUCKETS = 37 [static]

Definition at line 964 of file chan_sip.c.

The Event State Compositors.

An Event State Compositor is an entity which accepts PUBLISH requests and acts appropriately based on these requests.

The actual event_state_compositor structure is simply an ao2_container of sip_esc_entrys. When an incoming PUBLISH is received, we can match the appropriate sip_esc_entry using the entity ID of the incoming PUBLISH.

Referenced by destroy_escs(), get_esc(), and initialize_escs().

struct ast_sockaddr externaddr [static]

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:

+ with "externaddr = host[:port]" we specify the address/port explicitly. The address is looked up only once when (re)loading the config file;

+ with "externhost = host[:port]" we do a similar thing, but the hostname is stored in externhost, and the hostname->IP mapping is refreshed every 'externrefresh' seconds;

Other variables (externhost, externexpire, externrefresh) are used to support the above functions. External IP address if we are behind NAT

Definition at line 1171 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().

time_t externexpire [static]

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1175 of file chan_sip.c.

char externhost[MAXHOSTNAMELEN] [static]

External host name

Definition at line 1174 of file chan_sip.c.

int externrefresh = 10 [static]

Refresh timer for DNS-based external address (dyndns)

Definition at line 1176 of file chan_sip.c.

uint16_t externtcpport [static]

external tcp port

Definition at line 1177 of file chan_sip.c.

uint16_t externtlsport [static]

external tls port

Definition at line 1178 of file chan_sip.c.

struct _map_x_s faxecmodes[] [static]

Definition at line 18048 of file chan_sip.c.

Whether we send authentication failure manager events or not. Default no.

Definition at line 723 of file chan_sip.c.

unsigned int global_autoframing [static]

Turn autoframing on or off.

Definition at line 727 of file chan_sip.c.

int global_callcounter [static]

Enable call counters for all devices. This is currently enabled by setting the peer call-limit to INT_MAX. When we remove the call-limit from the code, we can make it with just a boolean flag in the device structure

Definition at line 707 of file chan_sip.c.

unsigned int global_cos_audio [static]

802.1p class of service for audio RTP packets

Definition at line 715 of file chan_sip.c.

unsigned int global_cos_sip [static]

802.1p class of service for SIP packets

Definition at line 714 of file chan_sip.c.

unsigned int global_cos_text [static]

802.1p class of service for text RTP packets

Definition at line 717 of file chan_sip.c.

unsigned int global_cos_video [static]

802.1p class of service for video RTP packets

Definition at line 716 of file chan_sip.c.

Exclude static peers from contact registrations

Definition at line 739 of file chan_sip.c.

struct ast_flags global_flags[3] = {{0}} [static]

global SIP_ flags

Definition at line 759 of file chan_sip.c.

struct ast_jb_conf global_jbconf [static]

Global jitterbuffer configuration

Definition at line 565 of file chan_sip.c.

Referenced by reload_config(), sip_get_rtp_peer(), sip_new(), and sip_show_settings().

Match auth username if available instead of From: Default off.

Definition at line 696 of file chan_sip.c.

int global_max_se [static]

Highest threshold for session refresh interval

Definition at line 735 of file chan_sip.c.

int global_min_se [static]

Lowest threshold for session refresh interval

Definition at line 734 of file chan_sip.c.

Enable/disable premature frames in a call (causing 183 early media)

Definition at line 699 of file chan_sip.c.

int global_qualify_gap [static]

Time between our group of peer pokes

Definition at line 729 of file chan_sip.c.

int global_qualify_peers [static]

Number of peers to poke at a given time

Definition at line 730 of file chan_sip.c.

int global_qualifyfreq [static]

Qualify frequency

Definition at line 728 of file chan_sip.c.

int global_reg_retry_403 [static]

Treat 403 responses to registrations as 401 responses

Definition at line 705 of file chan_sip.c.

int global_reg_timeout [static]

Global time between attempts for outbound registrations

Definition at line 703 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 704 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 698 of file chan_sip.c.

int global_rtpholdtimeout [static]

Time out call if no RTP during hold

Definition at line 701 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 702 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 700 of file chan_sip.c.

char global_sdpowner[AST_MAX_EXTENSION] [static]

SDP owner name for the SIP channel

Definition at line 722 of file chan_sip.c.

char global_sdpsession[AST_MAX_EXTENSION] [static]

SDP session name for the SIP channel

Definition at line 721 of file chan_sip.c.

int global_shrinkcallerid [static]

enable or disable shrinking of caller id

Definition at line 706 of file chan_sip.c.

enum st_mode global_st_mode [static]

Mode of operation for Session-Timers

Definition at line 732 of file chan_sip.c.

enum st_refresher_param global_st_refresher [static]

Session-Timer refresher

Definition at line 733 of file chan_sip.c.

int global_store_sip_cause [static]

Whether the MASTER_CHANNEL(HASH(SIP_CAUSE,[chan_name])) var should be set

Definition at line 737 of file chan_sip.c.

int global_t1 [static]

T1 time

Definition at line 724 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

Definition at line 725 of file chan_sip.c.

unsigned int global_t38_maxdatagram [static]

global T.38 FaxMaxDatagram override

Definition at line 760 of file chan_sip.c.

int global_timer_b [static]

Timer B - RFC 3261 Section 17.1.1.2

Definition at line 726 of file chan_sip.c.

unsigned int global_tos_audio [static]

IP type of service for audio RTP packets

Definition at line 711 of file chan_sip.c.

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 710 of file chan_sip.c.

unsigned int global_tos_text [static]

IP type of service for text RTP packets

Definition at line 713 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 712 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

Definition at line 720 of file chan_sip.c.

const int HASH_DIALOG_SIZE = 563 [static]

Definition at line 817 of file chan_sip.c.

const int HASH_PEER_SIZE = 563 [static]

Size of peer hash table, prime number preferred!

Definition at line 816 of file chan_sip.c.

struct _map_x_s insecurestr[] [static]

Definition at line 17581 of file chan_sip.c.

struct ast_sockaddr internip [static]

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.

Definition at line 1154 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), sip_alloc(), transmit_register(), and transmit_response_using_temp().

Readable descriptions of device states.

Note:
Should be aligned to above table as index

Referenced by show_chanstats_cb().

struct io_context* io [static]

The IO context

Definition at line 783 of file chan_sip.c.

struct ast_ha* localaddr [static]

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.

List of local networks, on the same side of NAT as this Asterisk

Definition at line 1186 of file chan_sip.c.

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 547 of file chan_sip.c.

struct ast_sockaddr media_address [static]

External RTP IP address if we are behind NAT

Definition at line 1172 of file chan_sip.c.

Referenced by get_our_media_address(), and reload_config().

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

Definition at line 546 of file chan_sip.c.

pthread_t monitor_thread = AST_PTHREADT_NULL [static]

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 777 of file chan_sip.c.

int mwi_expiry = DEFAULT_MWI_EXPIRY [static]

Definition at line 549 of file chan_sip.c.

int network_change_event_sched_id = -1 [static]

Definition at line 763 of file chan_sip.c.

subscription id for network change events

Definition at line 762 of file chan_sip.c.

const char notify_config[] = "sip_notify.conf" [static]

Configuration file for sending Notify with CLI commands to reconfigure or reboot phones

Definition at line 568 of file chan_sip.c.

struct ast_config* notify_types = NULL [static]

The list of manual NOTIFY types we know how to send

Definition at line 1192 of file chan_sip.c.

int ourport_tcp [static]

The port used for TCP connections

Definition at line 1188 of file chan_sip.c.

int ourport_tls [static]

The port used for TCP/TLS connections

Definition at line 1189 of file chan_sip.c.

struct ao2_container* peers [static]

The peer list: Users, Peers and Friends.

Definition at line 1099 of file chan_sip.c.

struct ao2_container* peers_by_ip [static]

Definition at line 1100 of file chan_sip.c.

Initial value:

Definition at line 31804 of file chan_sip.c.

unsigned int recordhistory [static]

Record SIP history. Off by default

Definition at line 718 of file chan_sip.c.

struct _map_x_s referstatusstrings[] [static]

Definition at line 798 of file chan_sip.c.

struct ast_register_list regl [static]

The register list: Other SIP proxies we register with and receive calls from.

Referenced by cleanup_all_regs(), load_module(), manager_show_registry(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().

int regobjs = 0 [static]

Registry objects

Definition at line 756 of file chan_sip.c.

struct _map_x_s regstatestrings[] [static]

Definition at line 13545 of file chan_sip.c.

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 754 of file chan_sip.c.

The scheduling context

Definition at line 782 of file chan_sip.c.

const char* service_string

Definition at line 822 of file chan_sip.c.

Definition at line 1642 of file chan_sip.c.

Definition at line 1909 of file chan_sip.c.

struct { ... } sip_cc_notify_state_map[] [static]

Referenced by transmit_cc_notify().

struct { ... } sip_cc_service_map[] [static]
struct sip_settings sip_cfg [static]
Initial value:
 {
   AST_DATA_ENTRY("asterisk/channel/sip/peers", &peers_data_provider),
}

Definition at line 31809 of file chan_sip.c.

Initial value:
 {
   .name = "SIP_HEADER",
   .read = func_header_read,
}

Definition at line 20088 of file chan_sip.c.

struct cfsip_methods sip_methods[] [static]

Definition at line 1836 of file chan_sip.c.

struct sip_reasons sip_reason_table[] [static]

Diversion header reasons.

The core defines a bunch of constants used to define redirecting reasons. This provides a translation table between those and the strings which may be present in a SIP Diversion header

Referenced by sip_reason_code_to_str(), and sip_reason_str_to_code().

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 779 of file chan_sip.c.

Reason for last reload/load of configuration

Definition at line 780 of file chan_sip.c.

struct ast_rtp_glue sip_rtp_glue [static]

Definition at line 30269 of file chan_sip.c.

The TCP server definition.

Definition at line 2196 of file chan_sip.c.

Definition of this channel for PBX channel registration.

Definition at line 1596 of file chan_sip.c.

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.

Definition at line 1631 of file chan_sip.c.

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

struct ast_tls_config sip_tls_cfg [static]

Working TLS connection configuration.

Definition at line 2190 of file chan_sip.c.

The TCP/TLS server definition.

Definition at line 2207 of file chan_sip.c.

struct ast_udptl_protocol sip_udptl [static]
Initial value:
 {
   .type = "SIP",
   .get_udptl_info = sip_get_udptl_peer,
   .set_udptl_peer = sip_set_udptl_peer,
}

Interface structure with callbacks used to connect to UDPTL module.

Definition at line 3169 of file chan_sip.c.

Initial value:
 {
   .name = "SIPCHANINFO",
   .read = function_sipchaninfo_read,
}

Structure to declare a dialplan function: SIPCHANINFO.

Definition at line 20277 of file chan_sip.c.

enum sip_debug_e sipdebug [static]

Definition at line 790 of file chan_sip.c.

int sipdebug_text [static]

extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.

Note:
It should either go away or be implemented properly.

Definition at line 796 of file chan_sip.c.

Initial value:
 {
   .name = "SIPPEER",
   .read = function_sippeer,
}

Structure to declare a dialplan function: SIPPEER.

Definition at line 20206 of file chan_sip.c.

int sipsock = -1 [static]

Main socket for UDP SIP communication.

sipsock is shared between the SIP manager thread (which handles reload requests), the udp io handler (sipsock_read()) and the user routines that issue udp writes (using __sip_xmit()). The socket is -1 only when opening fails (this is a permanent condition), or when we are handling a reload() that changes its address (this is a transient situation during which we might have a harmless race, see below). Because the conditions for the race to be possible are extremely rare, we don't want to pay the cost of locking on every I/O. Rather, we remember that when the race may occur, communication is bound to fail anyways, so we just live with this event and let the protocol handle this above us.

Definition at line 1144 of file chan_sip.c.

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

Definition at line 784 of file chan_sip.c.

int speerobjs = 0 [static]

Static peers

Definition at line 753 of file chan_sip.c.

enum sip_cc_notify_state state

Definition at line 842 of file chan_sip.c.

const char* state_string

Definition at line 843 of file chan_sip.c.

Referenced by transmit_cc_notify().

struct _map_x_s stmodes[] [static]

Report Peer status in character string.

Returns:
0 if peer is unreachable, 1 if peer is online, -1 if unmonitored

Definition at line 17005 of file chan_sip.c.

struct _map_x_s strefresher_params[] [static]

Definition at line 17023 of file chan_sip.c.

struct _map_x_s strefreshers[] [static]

Definition at line 17030 of file chan_sip.c.

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.

Referenced by find_subscription_type(), and subscription_type2str().

struct ao2_container* threadt [static]

The table of TCP threads.

Definition at line 1096 of file chan_sip.c.

struct _map_x_s trust_id_outboundstr[] [static]

Definition at line 17608 of file chan_sip.c.

int unauth_sessions = 0 [static]

Definition at line 551 of file chan_sip.c.

char used_context[AST_MAX_CONTEXT] [static]

name of automatically created context for unloading

Definition at line 765 of file chan_sip.c.


Generated on 15 Apr 2016 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1