Wed Oct 29 05:09:38 2014

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_peer_from_tables (struct sip_peer *peer)
static void unlink_peers_from_tables (peer_unlink_flag_t flag)
static int unload_module (void)
 PBX unload module API.
static 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 14831 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 31622 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 18979 of file chan_sip.c.

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

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

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

Definition at line 18979 of file chan_sip.c.

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

Definition at line 18979 of file chan_sip.c.

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

Definition at line 18979 of file chan_sip.c.

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

Definition at line 18979 of file chan_sip.c.

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

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

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

Definition at line 18978 of file chan_sip.c.

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

Definition at line 18978 of file chan_sip.c.

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

Definition at line 18978 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 18977 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 18976 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 17287 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_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 14393 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().

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

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

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

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

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

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

Execute destruction of SIP dialog structure, release memory.

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

05969 {
05970    struct sip_request *req;
05971 
05972    /* Destroy Session-Timers if allocated */
05973    if (p->stimer) {
05974       p->stimer->quit_flag = 1;
05975       stop_session_timer(p);
05976       ast_free(p->stimer);
05977       p->stimer = NULL;
05978    }
05979 
05980    if (sip_debug_test_pvt(p))
05981       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
05982 
05983    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05984       update_call_counter(p, DEC_CALL_LIMIT);
05985       ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
05986    }
05987 
05988    /* Unlink us from the owner if we have one */
05989    if (p->owner) {
05990       if (lockowner)
05991          ast_channel_lock(p->owner);
05992       ast_debug(1, "Detaching from %s\n", p->owner->name);
05993       p->owner->tech_pvt = NULL;
05994       /* Make sure that the channel knows its backend is going away */
05995       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05996       if (lockowner)
05997          ast_channel_unlock(p->owner);
05998       /* Give the channel a chance to react before deallocation */
05999       usleep(1);
06000    }
06001 
06002    /* Remove link from peer to subscription of MWI */
06003    if (p->relatedpeer && p->relatedpeer->mwipvt == p)
06004       p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
06005    if (p->relatedpeer && p->relatedpeer->call == p)
06006       p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
06007    
06008    if (p->relatedpeer)
06009       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy");
06010    
06011    if (p->registry) {
06012       if (p->registry->call == p)
06013          p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all");
06014       p->registry = registry_unref(p->registry, "delete p->registry");
06015    }
06016    
06017    if (p->mwi) {
06018       p->mwi->call = NULL;
06019       p->mwi = NULL;
06020    }
06021 
06022    if (dumphistory)
06023       sip_dump_history(p);
06024 
06025    if (p->options) {
06026       if (p->options->outboundproxy) {
06027          ao2_ref(p->options->outboundproxy, -1);
06028       }
06029       ast_free(p->options);
06030       p->options = 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 4225 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().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

References ast_str_append().

Referenced by send_request(), and send_response().

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

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

28015 {
28016    char *next, *mbox, *context;
28017 
28018    next = ast_strdupa(value);
28019 
28020    while ((mbox = context = strsep(&next, ","))) {
28021       struct sip_mailbox *mailbox;
28022       int duplicate = 0;
28023       /* remove leading/trailing whitespace from mailbox string */
28024       mbox = ast_strip(mbox);
28025       strsep(&context, "@");
28026 
28027       if (ast_strlen_zero(mbox)) {
28028          continue;
28029       }
28030 
28031       /* Check whether the mailbox is already in the list */
28032       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
28033          if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) {
28034             duplicate = 1;
28035             break;
28036          }
28037       }
28038       if (duplicate) {
28039          continue;
28040       }
28041 
28042       if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) {
28043          continue;
28044       }
28045 
28046       if (!ast_strlen_zero(context)) {
28047          mailbox->context = mailbox->mailbox + strlen(mbox) + 1;
28048          strcpy(mailbox->context, context); /* SAFE */
28049       }
28050       strcpy(mailbox->mailbox, mbox); /* SAFE */
28051 
28052       AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
28053    }
28054 }

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

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

25269 {
25270    struct sip_mailbox *mailbox;
25271 
25272    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
25273       if (mailbox->event_sub) {
25274          ast_event_unsubscribe(mailbox->event_sub);
25275       }
25276 
25277       mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer,
25278          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
25279          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
25280          AST_EVENT_IE_END);
25281    }
25282 }

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

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

27815 {
27816    char *authcopy;
27817    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
27818    struct sip_auth *auth;
27819 
27820    if (ast_strlen_zero(configuration)) {
27821       /* Nothing to add */
27822       return;
27823    }
27824 
27825    ast_debug(1, "Auth config ::  %s\n", configuration);
27826 
27827    authcopy = ast_strdupa(configuration);
27828    username = authcopy;
27829 
27830    /* split user[:secret] and relm */
27831    realm = strrchr(username, '@');
27832    if (realm)
27833       *realm++ = '\0';
27834    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
27835       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
27836       return;
27837    }
27838 
27839    /* parse username at ':' for secret, or '#" for md5secret */
27840    if ((secret = strchr(username, ':'))) {
27841       *secret++ = '\0';
27842    } else if ((md5secret = strchr(username, '#'))) {
27843       *md5secret++ = '\0';
27844    }
27845 
27846    /* Create the continer if needed. */
27847    if (!*credentials) {
27848       *credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication,
27849          "Create realm auth container.");
27850       if (!*credentials) {
27851          /* Failed to create the credentials container. */
27852          return;
27853       }
27854    }
27855 
27856    /* Create the authentication credential entry. */
27857    auth = ast_calloc(1, sizeof(*auth));
27858    if (!auth) {
27859       return;
27860    }
27861    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
27862    ast_copy_string(auth->username, username, sizeof(auth->username));
27863    if (secret)
27864       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
27865    if (md5secret)
27866       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
27867 
27868    /* Add credential to container list. */
27869    AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node);
27870 
27871    ast_verb(3, "Added authentication for realm %s\n", realm);
27872 }

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

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

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

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

27724 {
27725    struct domain *d;
27726 
27727    if (ast_strlen_zero(domain)) {
27728       ast_log(LOG_WARNING, "Zero length domain.\n");
27729       return 1;
27730    }
27731 
27732    if (!(d = ast_calloc(1, sizeof(*d))))
27733       return 0;
27734 
27735    ast_copy_string(d->domain, domain, sizeof(d->domain));
27736 
27737    if (!ast_strlen_zero(context))
27738       ast_copy_string(d->context, context, sizeof(d->context));
27739 
27740    d->mode = mode;
27741 
27742    AST_LIST_LOCK(&domain_list);
27743    AST_LIST_INSERT_TAIL(&domain_list, d, list);
27744    AST_LIST_UNLOCK(&domain_list);
27745 
27746    if (sipdebug)  
27747       ast_debug(1, "Added local SIP domain '%s'\n", domain);
27748 
27749    return 1;
27750 }

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

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

Referenced by build_peer().

27904 {
27905    struct ast_variable *tmpvar = NULL;
27906    char *varname = ast_strdupa(buf), *varval = NULL;
27907    
27908    if ((varval = strchr(varname, '='))) {
27909       *varval++ = '\0';
27910       if ((tmpvar = ast_variable_new(varname, varval, ""))) {
27911          tmpvar->next = list;
27912          list = tmpvar;
27913       }
27914    }
27915    return list;
27916 }

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

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

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

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

References append_history_va().

03720 {
03721    va_list ap;
03722 
03723    if (!p) {
03724       return;
03725    }
03726 
03727    if (!p->do_history && !recordhistory && !dumphistory) {
03728       return;
03729    }
03730 
03731    va_start(ap, fmt);
03732    append_history_va(p, fmt, ap);
03733    va_end(ap);
03734 
03735    return;
03736 }

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

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, and AST_LIST_REMOVE_HEAD.

Referenced by append_history_full().

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

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

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

29843 {
29844    struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
29845    int res = AST_SENSE_ALLOW;
29846 
29847    ast_rtp_instance_get_remote_address(p1->rtp, &them);
29848    ast_rtp_instance_get_local_address(p1->rtp, &us);
29849 
29850    /* If p2 is a guest call, there will be no peer. If there is no peer, there
29851     * is no directmediaha, so go ahead and allow it */
29852    if (!p2->relatedpeer) {
29853       return res;
29854    }
29855 
29856    if ((res = ast_apply_ha(p2->relatedpeer->directmediaha, &them)) == AST_SENSE_DENY) {
29857       const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us));
29858       const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them));
29859 
29860       ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
29861          op, them_addr, us_addr);
29862    }
29863 
29864    return res;
29865 }

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

22340 {
22341    if (chan && chan->_state == AST_STATE_UP) {
22342       if (ast_test_flag(chan, AST_FLAG_MOH))
22343          ast_moh_stop(chan);
22344       else if (chan->generatordata)
22345          ast_deactivate_generator(chan);
22346    }
22347 }

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

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

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

30682 {
30683    return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(SIP_TRANSPORT_UDP));
30684 }

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

30658 {
30659    struct ast_sockaddr *addrs;
30660    int addrs_cnt;
30661 
30662    addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
30663    if (addrs_cnt <= 0) {
30664       return 1;
30665    }
30666    if (addrs_cnt > 1) {
30667       ast_debug(1, "Multiple addresses, using the first one only\n");
30668    }
30669 
30670    ast_sockaddr_copy(addr, &addrs[0]);
30671 
30672    ast_free(addrs);
30673    return 0;
30674 }

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

30692 {
30693         return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(transport));
30694 }

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

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

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

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

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

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

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

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

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

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

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

Build a Via header for a request.

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

03569 {
03570    /* Work around buggy UNIDEN UIP200 firmware */
03571    const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : "";
03572 
03573    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
03574    snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s",
03575        get_transport_pvt(p),
03576        ast_sockaddr_stringify_remote(&p->ourip),
03577        (unsigned)p->branch, rport);
03578 }

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

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

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

Definition at line 15086 of file chan_sip.c.

Referenced by handle_request_subscribe().

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

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

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

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

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

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

Change the T38 state on a SIP dialog.

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

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

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

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

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

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

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 20470 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(), and sip_reinvite_retry().

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

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

26544 {
26545    /* If we have no RTP or no active owner, no need to check timers */
26546    if (!dialog->rtp || !dialog->owner)
26547       return;
26548    /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */
26549 
26550    if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip))
26551       return;
26552 
26553    /* If the call is involved in a T38 fax session do not check RTP timeout */
26554    if (dialog->t38.state == T38_ENABLED)
26555       return;
26556 
26557    /* If we have no timers set, return now */
26558    if (!ast_rtp_instance_get_keepalive(dialog->rtp) && !ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) {
26559       return;
26560    }
26561 
26562    /* Check AUDIO RTP keepalives */
26563    if (dialog->lastrtptx && ast_rtp_instance_get_keepalive(dialog->rtp) &&
26564           (t > dialog->lastrtptx + ast_rtp_instance_get_keepalive(dialog->rtp))) {
26565       /* Need to send an empty RTP packet */
26566       dialog->lastrtptx = time(NULL);
26567       ast_rtp_instance_sendcng(dialog->rtp, 0);
26568    }
26569 
26570    /*! \todo Check video RTP keepalives
26571 
26572       Do we need to move the lastrtptx to the RTP structure to have one for audio and one
26573       for video? It really does belong to the RTP structure.
26574    */
26575 
26576    /* Check AUDIO RTP timers */
26577    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))) {
26578       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)))) {
26579          /* Needs a hangup */
26580          if (ast_rtp_instance_get_timeout(dialog->rtp)) {
26581             if (!dialog->owner || ast_channel_trylock(dialog->owner)) {
26582                /*
26583                 * Don't block, just try again later.
26584                 * If there was no owner, the call is dead already.
26585                 */
26586                return;
26587             }
26588             ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
26589                dialog->owner->name, (long) (t - dialog->lastrtprx));
26590             /* Issue a softhangup */
26591             ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV);
26592             ast_channel_unlock(dialog->owner);
26593             /* forget the timeouts for this call, since a hangup
26594                has already been requested and we don't want to
26595                repeatedly request hangups
26596             */
26597             ast_rtp_instance_set_timeout(dialog->rtp, 0);
26598             ast_rtp_instance_set_hold_timeout(dialog->rtp, 0);
26599             if (dialog->vrtp) {
26600                ast_rtp_instance_set_timeout(dialog->vrtp, 0);
26601                ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0);
26602             }
26603          }
26604       }
26605    }
26606 }

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

27754 {
27755    struct domain *d;
27756    int result = 0;
27757 
27758    AST_LIST_LOCK(&domain_list);
27759    AST_LIST_TRAVERSE(&domain_list, d, list) {
27760       if (strcasecmp(d->domain, domain)) {
27761          continue;
27762       }
27763 
27764       if (len && !ast_strlen_zero(d->context))
27765          ast_copy_string(context, d->context, len);
27766       
27767       result = 1;
27768       break;
27769    }
27770    AST_LIST_UNLOCK(&domain_list);
27771 
27772    return result;
27773 }

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

References check_user_full().

Referenced by handle_request_options(), and handle_request_publish().

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

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

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

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

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

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

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

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

static void cleanup_all_regs ( void   )  [static]

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

28742 {
28743       /* First, destroy all outstanding registry calls */
28744       /* This is needed, since otherwise active registry entries will not be destroyed */
28745       ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {  /* regl is locked */
28746             ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */
28747             if (iterator->call) {
28748                ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
28749                /* This will also remove references to the registry */
28750                dialog_unlink_all(iterator->call);
28751                iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal");
28752             }
28753             if (iterator->expire > -1) {
28754                AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config"));
28755             }
28756             if (iterator->timeout > -1) {
28757                AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config"));
28758             }
28759             if (iterator->dnsmgr) {
28760                ast_dnsmgr_release(iterator->dnsmgr);
28761                iterator->dnsmgr = NULL;
28762                registry_unref(iterator, "reg ptr unref from dnsmgr");
28763             }
28764             ASTOBJ_UNLOCK(iterator);
28765       } while(0));
28766 }

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

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

Referenced by reload_config().

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

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

Destroy all peer-related mailbox subscriptions

Definition at line 4814 of file chan_sip.c.

References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.

Referenced by set_peer_defaults(), and sip_destroy_peer().

04815 {
04816    struct sip_mailbox *mailbox;
04817 
04818    while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry)))
04819       destroy_mailbox(mailbox);
04820 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

27777 {
27778    struct domain *d;
27779 
27780    AST_LIST_LOCK(&domain_list);
27781    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
27782       ast_free(d);
27783    AST_LIST_UNLOCK(&domain_list);
27784 }

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

Do completion on peer name.

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

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

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

Do completion on registered peer name.

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

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

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

References complete_sipch().

Referenced by sip_show_history().

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

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

References complete_sip_peer().

Referenced by sip_qualify_peer(), and sip_show_peer().

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

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

References complete_sip_user().

Referenced by sip_show_user().

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

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

References complete_sip_registered_peer().

Referenced by sip_unregister().

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

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

Do completion on user name.

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

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

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

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

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

Support routine for 'sip notify' CLI.

Definition at line 19183 of file chan_sip.c.

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

Referenced by sip_cli_notify().

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

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

05404 {
05405    if (to_sock->tcptls_session) {
05406       ao2_ref(to_sock->tcptls_session, -1);
05407       to_sock->tcptls_session = NULL;
05408    }
05409 
05410    if (from_sock->tcptls_session) {
05411       ao2_ref(from_sock->tcptls_session, +1);
05412    }
05413 
05414    *to_sock = *from_sock;
05415 }

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

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

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

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

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

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

05626 {
05627    return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
05628 }

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

References ast_event_unsubscribe(), and ast_free.

Referenced by build_peer(), and clear_peer_mailboxes().

04807 {
04808    if (mailbox->event_sub)
04809       ast_event_unsubscribe(mailbox->event_sub);
04810    ast_free(mailbox);
04811 }

static void destroy_realm_authentication ( void *  obj  )  [static]

Definition at line 27794 of file chan_sip.c.

References ast_free, and AST_LIST_REMOVE_HEAD.

Referenced by add_realm_authentication().

27795 {
27796    struct sip_auth_container *credentials = obj;
27797    struct sip_auth *auth;
27798 
27799    while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) {
27800       ast_free(auth);
27801    }
27802 }

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

References ast_assert, and ast_strlen_zero().

Referenced by handle_request_publish().

24761 {
24762    int etag_present = !ast_strlen_zero(etag);
24763    int body_present = req->lines > 0;
24764 
24765    ast_assert(expires_int != NULL);
24766 
24767    if (ast_strlen_zero(expires)) {
24768       /* Section 6, item 4, second bullet point of RFC 3903 says to
24769        * use a locally-configured default expiration if none is provided
24770        * in the request
24771        */
24772       *expires_int = DEFAULT_PUBLISH_EXPIRES;
24773    } else if (sscanf(expires, "%30d", expires_int) != 1) {
24774       return SIP_PUBLISH_UNKNOWN;
24775    }
24776 
24777    if (*expires_int == 0) {
24778       return SIP_PUBLISH_REMOVE;
24779    } else if (!etag_present && body_present) {
24780       return SIP_PUBLISH_INITIAL;
24781    } else if (etag_present && !body_present) {
24782       return SIP_PUBLISH_REFRESH;
24783    } else if (etag_present && body_present) {
24784       return SIP_PUBLISH_MODIFY;
24785    }
24786 
24787    return SIP_PUBLISH_UNKNOWN;
24788 }

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

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

30821 {
30822    struct sip_pvt *pvt = obj, *pvt2 = arg;
30823 
30824    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0;
30825 }

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

Definition at line 17511 of file chan_sip.c.

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

Referenced by sip_show_objects().

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

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

References CMP_MATCH.

Referenced by find_call().

30811 {
30812    struct sip_pvt *pvt = obj, *pvt2 = arg;
30813 
30814    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0;
30815 }

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

References ast_str_case_hash().

Referenced by load_module().

30801 {
30802    const struct sip_pvt *pvt = obj;
30803 
30804    return ast_str_case_hash(pvt->callid);
30805 }

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

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

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

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

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

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

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

Definition at line 17721 of file chan_sip.c.

References CMP_MATCH, and dialog_unlink_all().

Referenced by do_monitor().

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

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

References ast_dsp_free().

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

04490 {
04491    if (p->dsp) {
04492       ast_dsp_free(p->dsp);
04493       p->dsp = NULL;
04494    }
04495 }

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

Definition at line 28729 of file chan_sip.c.

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

Referenced by reload_config().

28729                                                                                       {
28730    int global_nat, specific_nat;
28731 
28732    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))) {
28733       ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the  global setting can make\n");
28734       ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n");
28735       ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n");
28736       ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n");
28737       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));
28738    }
28739 }

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

22888 {
22889    struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2);
22890    struct ast_app *pickup = pbx_findapp("Pickup");
22891 
22892    if (!pickup) {
22893       ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n");
22894       return -1;
22895    }
22896 
22897    ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context);
22898 
22899    ast_debug(2, "About to call Pickup(%s)\n", ast_str_buffer(str));
22900 
22901    /* There is no point in capturing the return value since pickup_exec
22902       doesn't return anything meaningful unless the passed data is an empty
22903       string (which in our case it will not be) */
22904    pbx_exec(channel, pickup, ast_str_buffer(str));
22905 
22906    return 0;
22907 }

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

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

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

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

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

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

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

Set nat mode on the various data sockets.

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

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

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

Print domain mode to cli.

Definition at line 17890 of file chan_sip.c.

Referenced by sip_show_domains().

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

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

Convert DTMF mode to printable string.

Definition at line 17569 of file chan_sip.c.

References map_x_s().

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

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

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

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

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

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(), unlink_peer_from_tables(), 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       unlink_peer_from_tables(peer);
14249    } else if (!ast_sockaddr_isnull(&peer->addr)) {
14250       /* If we aren't self-destructing a temp_peer, we still need to unlink the peer
14251        * from the peers_by_ip table, otherwise we end up with multiple copies hanging
14252        * around each time a registration expires and the peer re-registers. */
14253       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
14254    }
14255 
14256    /* Only clear the addr after we check for destruction.  The addr must remain
14257     * in order to unlink from the peers_by_ip container correctly */
14258    memset(&peer->addr, 0, sizeof(peer->addr));
14259 
14260    unref_peer(peer, "removing peer ref for expire_register");
14261 
14262    return 0;
14263 }

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

References ast_sockaddr_split_hostport(), and PARSE_PORT_IGNORE.

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

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

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

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

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

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

References CMP_MATCH, CMP_STOP, and match().

Referenced by find_peer().

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

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

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

04631 {
04632    char last_char = '\0';
04633    const char *s;
04634    for (s = start; *s && s != lim; last_char = *s++) {
04635       if (*s == '"' && last_char != '\\')
04636          break;
04637    }
04638    return s;
04639 }

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

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

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

Definition at line 27883 of file chan_sip.c.

References AST_LIST_TRAVERSE.

Referenced by build_reply_digest().

27884 {
27885    struct sip_auth *auth;
27886 
27887    if (credentials) {
27888       AST_LIST_TRAVERSE(&credentials->list, auth, node) {
27889          if (!strcasecmp(auth->realm, realm)) {
27890             break;
27891          }
27892       }
27893    } else {
27894       auth = NULL;
27895    }
27896 
27897    return auth;
27898 }

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

03357 {
03358    int i, res = 0;
03359    
03360    if (ast_strlen_zero(msg)) {
03361       return 0;
03362    }
03363    for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) {
03364       if (method_match(i, msg)) {
03365          res = sip_methods[i].id;
03366       }
03367    }
03368    return res;
03369 }

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

References ARRAY_LEN, subscription_types, and type.

Referenced by transmit_state_notify().

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

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

Remove route from route list.

Definition at line 14674 of file chan_sip.c.

References ast_free.

Referenced by __sip_destroy(), and build_route().

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

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

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

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

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

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

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

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

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

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

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

26262 {
26263    const struct ast_sockaddr *addr = NULL;
26264 
26265    if ((transport == SIP_TRANSPORT_UDP) || !transport) {
26266       addr = &bindaddr;
26267    }
26268    else if (transport == SIP_TRANSPORT_TCP) {
26269       addr = &sip_tcp_desc.local_address;
26270    }
26271    else if (transport == SIP_TRANSPORT_TLS) {
26272       addr = &sip_tls_desc.local_address;
26273    }
26274 
26275    if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) {
26276       return 0;
26277    }
26278 
26279    return addr->ss.ss_family;
26280 }

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

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

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

26417 {
26418    struct sip_mailbox *mailbox;
26419    int in_cache;
26420 
26421    in_cache = 0;
26422    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
26423       struct ast_event *event;
26424       event = ast_event_get_cached(AST_EVENT_MWI,
26425          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
26426          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
26427          AST_EVENT_IE_END);
26428       if (!event)
26429          continue;
26430       *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
26431       *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
26432       ast_event_destroy(event);
26433       in_cache = 1;
26434    }
26435 
26436    return in_cache;
26437 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Return protocol string for srv dns query.

Definition at line 3478 of file chan_sip.c.

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

03479 {
03480    switch (t) {
03481    case SIP_TRANSPORT_UDP:
03482       return "udp";
03483    case SIP_TRANSPORT_TLS:
03484    case SIP_TRANSPORT_TCP:
03485       return "tcp";
03486    }
03487 
03488    return "udp";
03489 }

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

Return service string for srv dns query.

Definition at line 3492 of file chan_sip.c.

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

03493 {
03494    switch (t) {
03495    case SIP_TRANSPORT_TCP:
03496    case SIP_TRANSPORT_UDP:
03497       return "sip";
03498    case SIP_TRANSPORT_TLS:
03499       return "sips";
03500    }
03501    return "sip";
03502 }

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

Return transport as string.

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

03464 {
03465    switch (t) {
03466    case SIP_TRANSPORT_UDP:
03467       return "UDP";
03468    case SIP_TRANSPORT_TCP:
03469       return "TCP";
03470    case SIP_TRANSPORT_TLS:
03471       return "TLS";
03472    }
03473 
03474    return "UNKNOWN";
03475 }

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

Return configuration of transports for a device.

Definition at line 3442 of file chan_sip.c.

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

03442                                                                       {
03443    switch (transports) {
03444       case SIP_TRANSPORT_UDP:
03445          return "UDP";
03446       case SIP_TRANSPORT_TCP:
03447          return "TCP";
03448       case SIP_TRANSPORT_TLS:
03449          return "TLS";
03450       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP:
03451          return "TCP,UDP";
03452       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS:
03453          return "TLS,UDP";
03454       case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS:
03455          return "TLS,TCP";
03456       default:
03457          return transports ?
03458             "TLS,TCP,UDP" : "UNKNOWN"; 
03459    }
03460 }

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

References get_transport(), and set_socket_transport().

Referenced by __sip_xmit(), and build_via().

03511 {
03512    if (p->outboundproxy && p->outboundproxy->transport) {
03513       set_socket_transport(&p->socket, p->outboundproxy->transport);
03514    }
03515 
03516    return get_transport(p->socket.type);
03517 }

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

References ast_strlen_zero().

Referenced by __set_address_from_contact(), and parse_register_contact().

03421 {
03422    int res = 0;
03423 
03424    if (ast_strlen_zero(transport)) {
03425       return res;
03426    }
03427 
03428    if (!strcasecmp(transport, "udp")) {
03429       res |= SIP_TRANSPORT_UDP;
03430    }
03431    if (!strcasecmp(transport, "tcp")) {
03432       res |= SIP_TRANSPORT_TCP;
03433    }
03434    if (!strcasecmp(transport, "tls")) {
03435       res |= SIP_TRANSPORT_TLS;
03436    }
03437 
03438    return res;
03439 }

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

References ast_copy_string(), and get_header().

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

22427 {
22428    const char *thetag;
22429 
22430    if (!tagbuf)
22431       return NULL;
22432    tagbuf[0] = '\0';    /* reset the buffer */
22433    thetag = get_header(req, header);
22434    thetag = strcasestr(thetag, ";tag=");
22435    if (thetag) {
22436       thetag += 5;
22437       ast_copy_string(tagbuf, thetag, tagbufsize);
22438       return strsep(&tagbuf, ";");
22439    }
22440    return NULL;
22441 }

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

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

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

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

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

25285 {
25286    const char *uri = REQ_OFFSET_TO_STR(req, rlPart2);
25287    char *param_separator;
25288    struct ast_cc_agent *agent;
25289    struct sip_cc_agent_pvt *agent_pvt;
25290    const char *expires_str = get_header(req, "Expires");
25291    int expires = -1; /* Just need it to be non-zero */
25292 
25293    if (!ast_strlen_zero(expires_str)) {
25294       sscanf(expires_str, "%d", &expires);
25295    }
25296 
25297    if ((param_separator = strchr(uri, ';'))) {
25298       *param_separator = '\0';
25299    }
25300 
25301    p->subscribed = CALL_COMPLETION;
25302 
25303    if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) {
25304       if (!expires) {
25305          /* Typically, if a 0 Expires reaches us and we can't find
25306           * the corresponding agent, it means that the CC transaction
25307           * has completed and so the calling side is just trying to
25308           * clean up its subscription. We'll just respond with a
25309           * 200 OK and be done with it
25310           */
25311          transmit_response(p, "200 OK", req);
25312          return 0;
25313       }
25314       ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri);
25315       transmit_response(p, "404 Not Found", req);
25316       return -1;
25317    }
25318 
25319    agent_pvt = agent->private_data;
25320 
25321    if (!expires) {
25322       /* We got sent a SUBSCRIBE and found an agent. This means that CC
25323        * is being canceled.
25324        */
25325       ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name);
25326       transmit_response(p, "200 OK", req);
25327       ao2_ref(agent, -1);
25328       return 0;
25329    }
25330 
25331    agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog");
25332    ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE",
25333          agent->device_name);
25334 
25335    /* We don't send a response here. That is done in the agent's ack callback or in the
25336     * agent destructor, should a failure occur before we have responded
25337     */
25338    ao2_ref(agent, -1);
25339    return 0;
25340 }

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

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

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

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

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

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

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

Handle incoming BYE request.

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

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

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

Handle incoming CANCEL request.

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

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

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

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

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

Receive SIP INFO Message.

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

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

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

References __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_FAILURE, ast_cc_agent_set_interfaces_chanvar(), ast_channel_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().

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

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

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

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

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

Handle incoming MESSAGE request.

Definition at line 24749 of file chan_sip.c.

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

Referenced by handle_incoming().

24750 {
24751    if (!req->ignore) {
24752       if (req->debug)
24753          ast_verbose("Receiving message!\n");
24754       receive_message(p, req);
24755    } else
24756       transmit_response(p, "202 Accepted", req);
24757    return 1;
24758 }

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

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

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

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

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

25182 {
25183    const char *etag = get_header(req, "SIP-If-Match");
25184    const char *event = get_header(req, "Event");
25185    struct event_state_compositor *esc;
25186    enum sip_publish_type publish_type;
25187    const char *expires_str = get_header(req, "Expires");
25188    int expires_int;
25189    int auth_result;
25190    int handler_result = -1;
25191 
25192    if (ast_strlen_zero(event)) {
25193       transmit_response(p, "489 Bad Event", req);
25194       pvt_set_needdestroy(p, "missing Event: header");
25195       return -1;
25196    }
25197 
25198    if (!(esc = get_esc(event))) {
25199       transmit_response(p, "489 Bad Event", req);
25200       pvt_set_needdestroy(p, "unknown event package in publish");
25201       return -1;
25202    }
25203 
25204    auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_UNRELIABLE, addr);
25205    if (auth_result == AUTH_CHALLENGE_SENT) {
25206       p->lastinvite = seqno;
25207       return 0;
25208    } else if (auth_result < 0) {
25209       ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
25210       transmit_response(p, "403 Forbidden", req);
25211       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
25212       ast_string_field_set(p, theirtag, NULL);
25213       return 0;
25214    } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) {
25215       /* We need to stop retransmitting the 401 */
25216       __sip_ack(p, p->lastinvite, 1, 0);
25217    }
25218 
25219    publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int);
25220 
25221    if (expires_int > max_expiry) {
25222       expires_int = max_expiry;
25223    } else if (expires_int < min_expiry && expires_int > 0) {
25224       transmit_response_with_minexpires(p, "423 Interval too small", req);
25225       pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
25226       return 0;
25227    }
25228    p->expiry = expires_int;
25229 
25230    /* It is the responsibility of these handlers to formulate any response
25231     * sent for a PUBLISH
25232     */
25233    switch (publish_type) {
25234    case SIP_PUBLISH_UNKNOWN:
25235       transmit_response(p, "400 Bad Request", req);
25236       break;
25237    case SIP_PUBLISH_INITIAL:
25238       handler_result = handle_sip_publish_initial(p, req, esc, expires_int);
25239       break;
25240    case SIP_PUBLISH_REFRESH:
25241       handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int);
25242       break;
25243    case SIP_PUBLISH_MODIFY:
25244       handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int);
25245       break;
25246    case SIP_PUBLISH_REMOVE:
25247       handler_result = handle_sip_publish_remove(p, req, esc, etag);
25248       break;
25249    default:
25250       transmit_response(p, "400 Impossible Condition", req);
25251       break;
25252    }
25253    if (!handler_result && p->expiry > 0) {
25254       sip_scheddestroy(p, (p->expiry + 10) * 1000);
25255    } else {
25256       pvt_set_needdestroy(p, "forcing expiration");
25257    }
25258 
25259    return handler_result;
25260 }

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

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

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

25728 {
25729    enum check_auth_result res;
25730 
25731    /* If this is not the intial request, and the initial request isn't
25732     * a register, something screwy happened, so bail */
25733    if (p->initreq.headers && p->initreq.method != SIP_REGISTER) {
25734       ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid);
25735       return -1;
25736    }
25737 
25738    /* Use this as the basis */
25739    copy_request(&p->initreq, req);
25740    if (sipdebug)
25741       ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
25742    check_via(p, req);
25743    if ((res = register_verify(p, addr, req, e)) < 0) {
25744       const char *reason;
25745 
25746       switch (res) {
25747       case AUTH_SECRET_FAILED:
25748          reason = "Wrong password";
25749          break;
25750       case AUTH_USERNAME_MISMATCH:
25751          reason = "Username/auth name mismatch";
25752          break;
25753       case AUTH_NOT_FOUND:
25754          reason = "No matching peer found";
25755          break;
25756       case AUTH_UNKNOWN_DOMAIN:
25757          reason = "Not a local domain";
25758          break;
25759       case AUTH_PEER_NOT_DYNAMIC:
25760          reason = "Peer is not supposed to register";
25761          break;
25762       case AUTH_ACL_FAILED:
25763          reason = "Device does not match ACL";
25764          break;
25765       case AUTH_BAD_TRANSPORT:
25766          reason = "Device not configured to use this transport type";
25767          break;
25768       default:
25769          reason = "Unknown failure";
25770          break;
25771       }
25772       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
25773          get_header(req, "To"), ast_sockaddr_stringify(addr),
25774          reason);
25775       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
25776    } else {
25777       req->authenticated = 1;
25778       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
25779    }
25780 
25781    if (res < 1) {
25782       /* Destroy the session, but keep us around for just a bit in case they don't
25783          get our 200 OK */
25784       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
25785    }
25786    return res;
25787 }

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

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

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

22942 {
22943    if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) {
22944       transmit_response(p, "501 Method Not Implemented", req);
22945       return 0;
22946    }
22947    if (!p->owner) {
22948       transmit_response(p, "481 Call/Transaction Does Not Exist", req);
22949       return 0;
22950    }
22951    if (get_rpid(p, req)) {
22952       struct ast_party_connected_line connected;
22953       struct ast_set_party_connected_line update_connected;
22954 
22955       ast_party_connected_line_init(&connected);
22956       memset(&update_connected, 0, sizeof(update_connected));
22957 
22958       update_connected.id.number = 1;
22959       connected.id.number.valid = 1;
22960       connected.id.number.str = (char *) p->cid_num;
22961       connected.id.number.presentation = p->callingpres;
22962 
22963       update_connected.id.name = 1;
22964       connected.id.name.valid = 1;
22965       connected.id.name.str = (char *) p->cid_name;
22966       connected.id.name.presentation = p->callingpres;
22967 
22968       connected.id.tag = (char *) p->cid_tag;
22969       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
22970       ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
22971    }
22972    transmit_response(p, "200 OK", req);
22973    return 0;
22974 }

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

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

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

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

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

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

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

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

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

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

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

Handle qualification responses (OPTIONS).

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by handle_response().

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

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

25076 {
25077    struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires);
25078    int res = 0;
25079 
25080    if (!esc_entry) {
25081       transmit_response(p, "503 Internal Server Failure", req);
25082       return -1;
25083    }
25084 
25085    if (esc->callbacks->initial_handler) {
25086       res = esc->callbacks->initial_handler(p, req, esc, esc_entry);
25087    }
25088 
25089    if (!res) {
25090       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0);
25091    }
25092 
25093    ao2_ref(esc_entry, -1);
25094    return res;
25095 }

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

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

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

25098 {
25099    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
25100    int expires_ms = expires * 1000;
25101    int res = 0;
25102 
25103    if (!esc_entry) {
25104       transmit_response(p, "412 Conditional Request Failed", req);
25105       return -1;
25106    }
25107 
25108    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
25109          ao2_ref(_data, -1),
25110          ao2_ref(esc_entry, -1),
25111          ao2_ref(esc_entry, +1));
25112 
25113    if (esc->callbacks->refresh_handler) {
25114       res = esc->callbacks->refresh_handler(p, req, esc, esc_entry);
25115    }
25116 
25117    if (!res) {
25118       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
25119    }
25120 
25121    ao2_ref(esc_entry, -1);
25122    return res;
25123 }

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

25154 {
25155    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
25156    int res = 0;
25157 
25158    if (!esc_entry) {
25159       transmit_response(p, "412 Conditional Request Failed", req);
25160       return -1;
25161    }
25162 
25163    AST_SCHED_DEL(sched, esc_entry->sched_id);
25164    /* Scheduler's ref of the esc_entry */
25165    ao2_ref(esc_entry, -1);
25166 
25167    if (esc->callbacks->remove_handler) {
25168       res = esc->callbacks->remove_handler(p, req, esc, esc_entry);
25169    }
25170 
25171    if (!res) {
25172       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
25173    }
25174 
25175    /* Ref from finding the esc_entry earlier in function */
25176    ao2_unlink(esc->compositor, esc_entry);
25177    ao2_ref(esc_entry, -1);
25178    return res;
25179 }

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

27513 {
27514    int res = 1;
27515 
27516    if (!strcasecmp(v->name, "t38pt_udptl")) {
27517       char *buf = ast_strdupa(v->value);
27518       char *word, *next = buf;
27519 
27520       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT);
27521 
27522       while ((word = strsep(&next, ","))) {
27523          if (ast_true(word) || !strcasecmp(word, "fec")) {
27524             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27525             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC);
27526          } else if (!strcasecmp(word, "redundancy")) {
27527             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27528             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY);
27529          } else if (!strcasecmp(word, "none")) {
27530             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
27531             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL);
27532          } else if (!strncasecmp(word, "maxdatagram=", 12)) {
27533             if (sscanf(&word[12], "%30u", maxdatagram) != 1) {
27534                ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config);
27535                *maxdatagram = global_t38_maxdatagram;
27536             }
27537          }
27538       }
27539    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
27540       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
27541       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
27542    } else {
27543       res = 0;
27544    }
27545 
27546    return res;
27547 }

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

03207 {
03208    if (p->initreq.headers) {
03209       ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
03210    } else {
03211       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
03212    }
03213    /* Use this as the basis */
03214    copy_request(&p->initreq, req);
03215    parse_request(&p->initreq);
03216    if (req->debug) {
03217       ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
03218    }
03219 }

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

References map_x_s().

Referenced by _sip_show_peer().

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

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

References ast_verbose.

Referenced by build_route().

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

static int load_module ( void   )  [static]

PBX load module - initialization.

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

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

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

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

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

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

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

Qualify SIP peers in the manager API.

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

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

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

Show SIP peers in the manager API.

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

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

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

Show SIP peers in the manager API.

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

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

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

References len(), sip_methods, and text.

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

03347 {
03348    int len = strlen(sip_methods[id].text);
03349    int l_name = name ? strlen(name) : 0;
03350    /* true if the string is long enough, and ends with whitespace, and matches */
03351    return (l_name >= len && name && name[len] < 33 &&
03352       !strncasecmp(sip_methods[id].text, name, len));
03353 }

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

Receive MWI events that we have subscribed to.

Definition at line 15048 of file chan_sip.c.

References sip_send_mwi_to_peer().

Referenced by add_peer_mwi_subs().

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

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

Definition at line 15078 of file chan_sip.c.

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

Referenced by network_change_event_subscribe().

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

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

Definition at line 15070 of file chan_sip.c.

References sip_send_all_mwi_subscriptions(), and sip_send_all_registers().

Referenced by network_change_event_cb().

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

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

References append_history, ast_debug, and sip_cfg.

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

03312 {
03313    if (dialog && dialog->options && dialog->options->outboundproxy) {
03314       if (sipdebug) {
03315          ast_debug(1, "OBPROXY: Applying dialplan set OBproxy to this call\n");
03316       }
03317       append_history(dialog, "OBproxy", "Using dialplan obproxy %s", dialog->options->outboundproxy->name);
03318       return dialog->options->outboundproxy;
03319    }
03320    if (peer && peer->outboundproxy) {
03321       if (sipdebug) {
03322          ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n");
03323       }
03324       append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name);
03325       return peer->outboundproxy;
03326    }
03327    if (sip_cfg.outboundproxy.name[0]) {
03328       if (sipdebug) {
03329          ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n");
03330       }
03331       append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name);
03332       return &sip_cfg.outboundproxy;
03333    }
03334    if (sipdebug) {
03335       ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n");
03336    }
03337    return NULL;
03338 }

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

References copy_request(), and parse_request().

Referenced by send_request(), and send_response().

04267 {
04268    copy_request(dst, src);
04269    parse_request(dst);
04270 }

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

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

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

26857 {
26858    if (ast_strlen_zero(p_hdrval)) {
26859       ast_log(LOG_WARNING, "Null Min-SE header\n");
26860       return -1;
26861    }
26862 
26863    *p_interval = 0;
26864    p_hdrval = ast_skip_blanks(p_hdrval);
26865    if (!sscanf(p_hdrval, "%30d", p_interval)) {
26866       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
26867       return -1;
26868    }
26869 
26870    ast_debug(2, "Received Min-SE: %d\n", *p_interval);
26871    return 0;
26872 }

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

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

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

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

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

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

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

26877 {
26878    char *p_token;
26879    int  ref_idx;
26880    char *p_se_hdr;
26881 
26882    if (ast_strlen_zero(p_hdrval)) {
26883       ast_log(LOG_WARNING, "Null Session-Expires header\n");
26884       return -1;
26885    }
26886 
26887    *p_ref = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN;
26888    *p_interval = 0;
26889 
26890    p_se_hdr = ast_strdupa(p_hdrval);
26891    p_se_hdr = ast_skip_blanks(p_se_hdr);
26892 
26893    while ((p_token = strsep(&p_se_hdr, ";"))) {
26894       p_token = ast_skip_blanks(p_token);
26895       if (!sscanf(p_token, "%30d", p_interval)) {
26896          ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n");
26897          return -1;
26898       }
26899 
26900       ast_debug(2, "Session-Expires: %d\n", *p_interval);
26901 
26902       if (!p_se_hdr)
26903          continue;
26904 
26905       p_se_hdr = ast_skip_blanks(p_se_hdr);
26906       ref_idx = strlen("refresher=");
26907       if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
26908          p_se_hdr += ref_idx;
26909          p_se_hdr = ast_skip_blanks(p_se_hdr);
26910 
26911          if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) {
26912             *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAC;
26913             ast_debug(2, "Refresher: UAC\n");
26914          } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) {
26915             *p_ref = SESSION_TIMER_REFRESHER_PARAM_UAS;
26916             ast_debug(2, "Refresher: UAS\n");
26917          } else {
26918             ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr);
26919             return -1;
26920          }
26921          break;
26922       }
26923    }
26924    return 0;
26925 }

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

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

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

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

30710 {
30711    struct sip_peer *peer = obj, *peer2 = arg;
30712 
30713    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
30714 }

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

Definition at line 17500 of file chan_sip.c.

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

Referenced by sip_show_objects().

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

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

References ast_str_case_hash().

Referenced by load_module().

30700 {
30701    const struct sip_peer *peer = obj;
30702 
30703    return ast_str_case_hash(peer->name);
30704 }

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

30758 {
30759    struct sip_peer *peer = obj, *peer2 = arg;
30760 
30761    if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) {
30762       /* IP doesn't match */
30763       return 0;
30764    }
30765 
30766    /* We matched the IP, check to see if we need to match by port as well. */
30767    if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) {
30768       /* peer matching on port is not possible with TCP/TLS */
30769       return CMP_MATCH | CMP_STOP;
30770    } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
30771       /* We are allowing match without port for peers configured that
30772        * way in this pass through the peers. */
30773       return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ?
30774             (CMP_MATCH | CMP_STOP) : 0;
30775    }
30776 
30777    /* Now only return a match if the port matches, as well. */
30778    return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ?
30779          (CMP_MATCH | CMP_STOP) : 0;
30780 }

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

References ast_log(), ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.

Referenced by load_module().

30722 {
30723    const struct sip_peer *peer = obj;
30724    int ret = 0;
30725 
30726    if (ast_sockaddr_isnull(&peer->addr)) {
30727       ast_log(LOG_ERROR, "Empty address\n");
30728    }
30729 
30730    ret = ast_sockaddr_hash(&peer->addr);
30731 
30732    if (ret < 0) {
30733       ret = -ret;
30734    }
30735 
30736    return ret;
30737 }

static void peer_mailboxes_to_str ( struct ast_str **  mailbox_str,
struct sip_peer *  peer 
) [static]

list peer mailboxes to CLI

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

18035 {
18036    struct sip_mailbox *mailbox;
18037 
18038    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
18039       ast_str_append(mailbox_str, 0, "%s%s%s%s",
18040          mailbox->mailbox,
18041          ast_strlen_zero(mailbox->context) ? "" : "@",
18042          S_OR(mailbox->context, ""),
18043          AST_LIST_NEXT(mailbox, entry) ? "," : "");
18044    }
18045 }

static int peer_markall_func ( void *  device,
void *  arg,
int  flags 
) [static]

Definition at line 28722 of file chan_sip.c.

Referenced by reload_config().

28723 {
28724    struct sip_peer *peer = device;
28725    peer->the_mark = 1;
28726    return 0;
28727 }

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

References ast_copy_string().

Referenced by _sip_show_peer(), _sip_show_peers_one(), and function_sippeer().

17052 {
17053    int res = 0;
17054    if (peer->maxms) {
17055       if (peer->lastms < 0) {
17056          ast_copy_string(status, "UNREACHABLE", statuslen);
17057       } else if (peer->lastms > peer->maxms) {
17058          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
17059          res = 1;
17060       } else if (peer->lastms) {
17061          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
17062          res = 1;
17063       } else {
17064          ast_copy_string(status, "UNKNOWN", statuslen);
17065       }
17066    } else {
17067       ast_copy_string(status, "Unmonitored", statuslen);
17068       /* Checking if port is 0 */
17069       res = -1;
17070    }
17071    return res;
17072 }

int peercomparefunc ( const void *  a,
const void *  b 
)

Definition at line 17279 of file chan_sip.c.

Referenced by _sip_show_peers().

17280 {
17281    struct sip_peer **ap = (struct sip_peer **)a;
17282    struct sip_peer **bp = (struct sip_peer **)b;
17283    return strcmp((*ap)->name, (*bp)->name);
17284 }

static int peers_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
) [static]

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

31669 {
31670    struct sip_peer *peer;
31671    struct ao2_iterator i;
31672    struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node;
31673    struct ast_data *data_sip_options;
31674    int total_mailboxes, x;
31675    struct sip_mailbox *mailbox;
31676 
31677    i = ao2_iterator_init(peers, 0);
31678    while ((peer = ao2_iterator_next(&i))) {
31679       ao2_lock(peer);
31680 
31681       data_peer = ast_data_add_node(data_root, "peer");
31682       if (!data_peer) {
31683          ao2_unlock(peer);
31684          ao2_ref(peer, -1);
31685          continue;
31686       }
31687 
31688       ast_data_add_structure(sip_peer, data_peer, peer);
31689 
31690       /* transfer mode */
31691       enum_node = ast_data_add_node(data_peer, "allowtransfer");
31692       if (!enum_node) {
31693          ao2_unlock(peer);
31694          ao2_ref(peer, -1);
31695          continue;
31696       }
31697       ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer));
31698       ast_data_add_int(enum_node, "value", peer->allowtransfer);
31699 
31700       /* transports */
31701       ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports));
31702 
31703       /* peer type */
31704       if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) {
31705          ast_data_add_str(data_peer, "type", "friend");
31706       } else if (peer->type & SIP_TYPE_PEER) {
31707          ast_data_add_str(data_peer, "type", "peer");
31708       } else if (peer->type & SIP_TYPE_USER) {
31709          ast_data_add_str(data_peer, "type", "user");
31710       }
31711 
31712       /* mailboxes */
31713       total_mailboxes = 0;
31714       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
31715          if (!total_mailboxes) {
31716             data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes");
31717             if (!data_peer_mailboxes) {
31718                break;
31719             }
31720             total_mailboxes++;
31721          }
31722 
31723          data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox");
31724          if (!data_peer_mailbox) {
31725             continue;
31726          }
31727          ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox);
31728          ast_data_add_str(data_peer_mailbox, "context", mailbox->context);
31729       }
31730 
31731       /* amaflags */
31732       enum_node = ast_data_add_node(data_peer, "amaflags");
31733       if (!enum_node) {
31734          ao2_unlock(peer);
31735          ao2_ref(peer, -1);
31736          continue;
31737       }
31738       ast_data_add_int(enum_node, "value", peer->amaflags);
31739       ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags));
31740 
31741       /* sip options */
31742       data_sip_options = ast_data_add_node(data_peer, "sipoptions");
31743       if (!data_sip_options) {
31744          ao2_unlock(peer);
31745          ao2_ref(peer, -1);
31746          continue;
31747       }
31748       for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
31749          ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id);
31750       }
31751 
31752       /* callingpres */
31753       enum_node = ast_data_add_node(data_peer, "callingpres");
31754       if (!enum_node) {
31755          ao2_unlock(peer);
31756          ao2_ref(peer, -1);
31757          continue;
31758       }
31759       ast_data_add_int(enum_node, "value", peer->callingpres);
31760       ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres));
31761 
31762       /* codecs */
31763       ast_data_add_codecs(data_peer, "codecs", peer->capability);
31764 
31765       if (!ast_data_search_match(search, data_peer)) {
31766          ast_data_remove_node(data_root, data_peer);
31767       }
31768 
31769       ao2_unlock(peer);
31770       ao2_ref(peer, -1);
31771    }
31772    ao2_iterator_destroy(&i);
31773 
31774    return 0;
31775 }

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

References ast_strlen_zero().

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

03301 {
03302    int port = standard;
03303    if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) {
03304       port = standard;
03305    }
03306 
03307    return port;
03308 }

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

17872 {
17873    int x;
17874    format_t codec;
17875 
17876    for(x = 0; x < 64 ; x++) {
17877       codec = ast_codec_pref_index(pref, x);
17878       if (!codec)
17879          break;
17880       ast_cli(fd, "%s", ast_getformatname(codec));
17881       ast_cli(fd, ":%d", pref->framing[x]);
17882       if (x < 31 && ast_codec_pref_index(pref, x + 1))
17883          ast_cli(fd, ",");
17884    }
17885    if (!x)
17886       ast_cli(fd, "none");
17887 }

static void print_group ( int  fd,
ast_group_t  group,
int  crlf 
) [static]

Print call group and pickup group.

Definition at line 17552 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

17553 {
17554    char buf[256];
17555    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
17556 }

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

26936 {
26937    int rtn;
26938    const char *p_hdrval;
26939    int minse;
26940 
26941    p_hdrval = get_header(rsp, "Min-SE");
26942    if (ast_strlen_zero(p_hdrval)) {
26943       ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval);
26944       return;
26945    }
26946    rtn = parse_minse(p_hdrval, &minse);
26947    if (rtn != 0) {
26948       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
26949       return;
26950    }
26951    p->stimer->st_cached_min_se = minse;
26952    if (p->stimer->st_interval < minse) {
26953       p->stimer->st_interval = minse;
26954    }
26955    transmit_invite(p, SIP_INVITE, 1, 2, NULL);
26956 }

static int proc_session_timer ( const void *  vp  )  [static]

Session-Timers: Process session refresh timeout event.

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

26787 {
26788    struct sip_pvt *p = (struct sip_pvt *) vp;
26789    int res = 0;
26790 
26791    if (!p->stimer) {
26792       ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid);
26793       goto return_unref;
26794    }
26795 
26796    ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid);
26797 
26798    if (!p->owner) {
26799       goto return_unref;
26800    }
26801 
26802    if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) {
26803       goto return_unref;
26804    }
26805 
26806    if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) {
26807       res = 1;
26808       if (T38_ENABLED == p->t38.state) {
26809          transmit_reinvite_with_sdp(p, TRUE, TRUE);
26810       } else {
26811          transmit_reinvite_with_sdp(p, FALSE, TRUE);
26812       }
26813    } else {
26814       if (p->stimer->quit_flag) {
26815          goto return_unref;
26816       }
26817       ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
26818       sip_pvt_lock(p);
26819       while (p->owner && ast_channel_trylock(p->owner)) {
26820          sip_pvt_unlock(p);
26821          usleep(1);
26822          if (p->stimer && p->stimer->quit_flag) {
26823             goto return_unref;
26824          }
26825          sip_pvt_lock(p);
26826       }
26827 
26828       ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
26829       ast_channel_unlock(p->owner);
26830       sip_pvt_unlock(p);
26831    }
26832 
26833 return_unref:
26834    if (!res) {
26835       /* An error occurred.  Stop session timer processing */
26836       if (p->stimer) {
26837          ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
26838          /* Don't pass go, don't collect $200.. we are the scheduled
26839           * callback. We can rip ourself out here. */
26840          p->stimer->st_schedid = -1;
26841          /* Calling stop_session_timer is nice for consistent debug
26842           * logs. */
26843          stop_session_timer(p);
26844       }
26845 
26846       /* If we are not asking to be rescheduled, then we need to release our
26847        * reference to the dialog. */
26848       dialog_unref(p, "removing session timer ref");
26849    }
26850 
26851    return res;
26852 }

static int process_crypto ( struct sip_pvt *  p,
struct ast_rtp_instance rtp,
struct sip_srtp **  srtp,
const char *  a 
) [static]

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

30538 {
30539    /* If no RTP instance exists for this media stream don't bother processing the crypto line */
30540    if (!rtp) {
30541       ast_debug(3, "Received offer with crypto line for media stream that is not enabled\n");
30542       return FALSE;
30543    }
30544 
30545    if (strncasecmp(a, "crypto:", 7)) {
30546       return FALSE;
30547    }
30548    if (!*srtp) {
30549       if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
30550          ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
30551          return FALSE;
30552       }
30553 
30554       if (setup_srtp(srtp) < 0) {
30555          return FALSE;
30556       }
30557    }
30558 
30559    if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) {
30560       return FALSE;
30561    }
30562 
30563    if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) {
30564       return FALSE;
30565    }
30566 
30567    ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK);
30568 
30569    return TRUE;
30570 }

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

03254 {
03255    char *mutable_proxy, *sep, *name;
03256    int allocated = 0;
03257 
03258    if (!dest) {
03259       dest = ao2_alloc(sizeof(struct sip_proxy), NULL);
03260       if (!dest) {
03261          ast_log(LOG_WARNING, "Unable to allocate config storage for proxy\n");
03262          return NULL;
03263       }
03264       allocated = 1;
03265    }
03266 
03267    /* Format is: [transport://]name[:port][,force] */
03268    mutable_proxy = ast_skip_blanks(ast_strdupa(proxy));
03269    sep = strchr(mutable_proxy, ',');
03270    if (sep) {
03271       *sep++ = '\0';
03272       dest->force = !strncasecmp(ast_skip_blanks(sep), "force", 5);
03273    } else {
03274       dest->force = FALSE;
03275    }
03276 
03277    sip_parse_host(mutable_proxy, sipconf_lineno, &name, &dest->port, &dest->transport);
03278 
03279    /* Check that there is a name at all */
03280    if (ast_strlen_zero(name)) {
03281       if (allocated) {
03282          ao2_ref(dest, -1);
03283       } else {
03284          dest->name[0] = '\0';
03285       }
03286       return NULL;
03287    }
03288    ast_copy_string(dest->name, name, sizeof(dest->name));
03289 
03290    /* Resolve host immediately */
03291    proxy_update(dest);
03292 
03293    return dest;
03294 }

static int proxy_update ( struct sip_proxy *  proxy  )  [static]

Resolve DNS srv name or host name in a sip_proxy structure

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

03230 {
03231    /* if it's actually an IP address and not a name,
03232            there's no need for a managed lookup */
03233    if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) {
03234       /* Ok, not an IP address, then let's check if it's a domain or host */
03235       /* XXX Todo - if we have proxy port, don't do SRV */
03236       proxy->ip.ss.ss_family = get_address_family_filter(SIP_TRANSPORT_UDP); /* Filter address family */
03237       if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) {
03238             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
03239             return FALSE;
03240       }
03241 
03242    }
03243 
03244    ast_sockaddr_set_port(&proxy->ip, proxy->port);
03245 
03246    proxy->last_dnsupdate = time(NULL);
03247    return TRUE;
03248 }

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

03195 {
03196    if (pvt->final_destruction_scheduled) {
03197       return; /* This is already scheduled for final destruction, let the scheduler take care of it. */
03198    }
03199    append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason);
03200    pvt->needdestroy = 1;
03201 }

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

05150 {
05151    struct sip_peer *peer = NULL;
05152    struct ast_variable *var = NULL;
05153    struct ast_variable *varregs = NULL;
05154    char ipaddr[INET6_ADDRSTRLEN];
05155    int realtimeregs = ast_check_realtime("sipregs");
05156 
05157    if (addr) {
05158       ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
05159    } else {
05160       ipaddr[0] = '\0';
05161    }
05162 
05163    if (newpeername && realtime_peer_by_name(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) {
05164       ;
05165    } else if (addr && realtime_peer_by_addr(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) {
05166       ;
05167    } else {
05168       return NULL;
05169    }
05170 
05171    /* If we're looking for users, don't return peers (although this check
05172     * should probably be done in realtime_peer_by_* instead...) */
05173    if (which_objects == FINDUSERS) {
05174       struct ast_variable *tmp;
05175       for (tmp = var; tmp; tmp = tmp->next) {
05176          if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer"))) {
05177             goto cleanup;
05178          }
05179       }
05180    }
05181 
05182    /* Peer found in realtime, now build it in memory */
05183    peer = build_peer(newpeername, var, varregs, TRUE, devstate_only);
05184    if (!peer) {
05185       goto cleanup;
05186    }
05187 
05188    /* Previous versions of Asterisk did not require the type field to be
05189     * set for real time peers.  This statement preserves that behavior. */
05190    if  (peer->type == 0) {
05191       if (which_objects == FINDUSERS) {
05192          peer->type = SIP_TYPE_USER;
05193       } else if (which_objects == FINDPEERS) {
05194          peer->type = SIP_TYPE_PEER;
05195       } else {
05196          peer->type = SIP_TYPE_PEER | SIP_TYPE_USER;
05197       }
05198    }
05199 
05200    ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
05201 
05202    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) {
05203       /* Cache peer */
05204       ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
05205       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
05206          AST_SCHED_REPLACE_UNREF(peer->expire, sched, sip_cfg.rtautoclear * 1000, expire_register, peer,
05207                unref_peer(_data, "remove registration ref"),
05208                unref_peer(peer, "remove registration ref"),
05209                ref_peer(peer, "add registration ref"));
05210       }
05211       ao2_t_link(peers, peer, "link peer into peers table");
05212       if (!ast_sockaddr_isnull(&peer->addr)) {
05213          ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
05214       }
05215    }
05216    peer->is_realtime = 1;
05217 
05218 cleanup:
05219    ast_variables_destroy(var);
05220    ast_variables_destroy(varregs);
05221    return peer;
05222 }

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

05081 {
05082    char portstring[6]; /* up to 5 digits plus null terminator */
05083    ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring));
05084 
05085    /* We're not finding this peer by this name anymore. Reset it. */
05086    *name = NULL;
05087 
05088    /* First check for fixed IP hosts */
05089    if ((*var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL))) {
05090       ;
05091    /* Check for registered hosts (in sipregs) */
05092    } else if (varregs && (*varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL)) &&
05093          (*var = realtime_peer_get_sippeer_helper(name, varregs))) {
05094       ;
05095    /* Check for registered hosts (in sippeers) */
05096    } else if (!varregs && (*var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL))) {
05097       ;
05098    /* We couldn't match on ipaddress and port, so we need to check if port is insecure */
05099    } else if ((*var = get_insecure_variable_from_sippeers("host", ipaddr))) {
05100       ;
05101    /* Same as above, but try the IP address field (in sipregs)
05102     * Observe that it fetches the name/var at the same time, without the
05103     * realtime_peer_get_sippeer_helper. Also note that it is quite inefficient.
05104     * Avoid sipregs if possible. */
05105    } else if (varregs && (*varregs = get_insecure_variable_from_sipregs("ipaddr", ipaddr, var))) {
05106       ;
05107    /* Same as above, but try the IP address field (in sippeers) */
05108    } else if (!varregs && (*var = get_insecure_variable_from_sippeers("ipaddr", ipaddr))) {
05109       ;
05110    }
05111 
05112    /* Nothing found? */
05113    if (!*var) {
05114       return 0;
05115    }
05116 
05117    /* Check peer name. It must not be empty. There may exist a
05118     * different match that does have a name, but it's too late for
05119     * that now. */
05120    if (!*name && !(*name = get_name_from_variable(*var))) {
05121       ast_log(LOG_WARNING, "Found peer for IP %s but it has no name\n", ipaddr);
05122       ast_variables_destroy(*var);
05123       *var = NULL;
05124       if (varregs && *varregs) {
05125          ast_variables_destroy(*varregs);
05126          *varregs = NULL;
05127       }
05128       return 0;
05129    }
05130 
05131    /* Make sure varregs is populated if var is. The inverse,
05132     * ensuring that var is set when varregs is, is taken
05133     * care of by realtime_peer_get_sippeer_helper(). */
05134    if (varregs && !*varregs) {
05135       *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL);
05136    }
05137    return 1;
05138 }

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

05009 {
05010    /* Peer by name and host=dynamic */
05011    if ((*var = ast_load_realtime("sippeers", "name", *name, "host", "dynamic", SENTINEL))) {
05012       ;
05013    /* Peer by name and host=IP */
05014    } else if (addr && !(*var = ast_load_realtime("sippeers", "name", *name, "host", ipaddr, SENTINEL))) {
05015       ;
05016    /* Peer by name and host=HOSTNAME */
05017    } else if ((*var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) {
05018       /*!\note
05019        * If this one loaded something, then we need to ensure that the host
05020        * field matched.  The only reason why we can't have this as a criteria
05021        * is because we only have the IP address and the host field might be
05022        * set as a name (and the reverse PTR might not match).
05023        */
05024       if (addr) {
05025          struct ast_variable *tmp;
05026          for (tmp = *var; tmp; tmp = tmp->next) {
05027             if (!strcasecmp(tmp->name, "host")) {
05028                struct ast_sockaddr *addrs = NULL;
05029 
05030                if (ast_sockaddr_resolve(&addrs,
05031                          tmp->value,
05032                          PARSE_PORT_FORBID,
05033                          get_address_family_filter(SIP_TRANSPORT_UDP)) <= 0 ||
05034                          ast_sockaddr_cmp(&addrs[0], addr)) {
05035                   /* No match */
05036                   ast_variables_destroy(*var);
05037                   *var = NULL;
05038                }
05039                ast_free(addrs);
05040                break;
05041             }
05042          }
05043       }
05044    }
05045 
05046    /* Did we find anything? */
05047    if (*var) {
05048       if (varregs) {
05049          *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL);
05050       }
05051       return 1;
05052    }
05053    return 0;
05054 }

static struct ast_variable* realtime_peer_get_sippeer_helper ( const char **  name,
struct ast_variable **  varregs 
) [static, read]

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

05062                                                                                                                {
05063    struct ast_variable *var = NULL;
05064    const char *old_name = *name;
05065    *name = get_name_from_variable(*varregs);
05066    if (!*name || !(var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) {
05067       if (!*name) {
05068          ast_log(LOG_WARNING, "Found sipreg but it has no name\n");
05069       }
05070       ast_variables_destroy(*varregs);
05071       *varregs = NULL;
05072       *name = old_name;
05073    }
05074    return var;
05075 }

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

04719 {
04720    char port[10];
04721    char ipaddr[INET6_ADDRSTRLEN];
04722    char regseconds[20];
04723    char *tablename = NULL;
04724    char str_lastms[20];
04725 
04726    const char *sysname = ast_config_AST_SYSTEM_NAME;
04727    char *syslabel = NULL;
04728 
04729    time_t nowtime = time(NULL) + expirey;
04730    const char *fc = fullcontact ? "fullcontact" : NULL;
04731 
04732    int realtimeregs = ast_check_realtime("sipregs");
04733 
04734    tablename = realtimeregs ? "sipregs" : "sippeers";
04735    
04736 
04737    snprintf(str_lastms, sizeof(str_lastms), "%d", lastms);
04738    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
04739    ast_copy_string(ipaddr, ast_sockaddr_isnull(addr) ? "" : ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
04740    ast_copy_string(port, ast_sockaddr_port(addr) ? ast_sockaddr_stringify_port(addr) : "", sizeof(port));
04741 
04742    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04743       sysname = NULL;
04744    else if (sip_cfg.rtsave_sysname)
04745       syslabel = "regserver";
04746 
04747    /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you
04748          *  must also add it to contrib/scripts/asterisk.ldap-schema,
04749          *  contrib/scripts/asterisk.ldif,
04750          *  and to configs/res_ldap.conf.sample as described in
04751          *  bugs 15156 and 15895 
04752          */
04753    if (fc) {
04754       ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
04755          "port", port, "regseconds", regseconds,
04756          deprecated_username ? "username" : "defaultuser", defaultuser,
04757          "useragent", useragent, "lastms", str_lastms,
04758          fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */
04759    } else {
04760       ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
04761          "port", port, "regseconds", regseconds,
04762          "useragent", useragent, "lastms", str_lastms,
04763          deprecated_username ? "username" : "defaultuser", defaultuser,
04764          syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */
04765    }
04766 }

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

16886 {
16887    char buf[1400];   
16888    char *bufp;
16889    struct ast_frame f;
16890    const char *content_type = get_header(req, "Content-Type");
16891 
16892    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
16893       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
16894       if (!p->owner)
16895          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16896       return;
16897    }
16898 
16899    if (get_msg_text(buf, sizeof(buf), req)) {
16900       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
16901       transmit_response(p, "500 Internal Server Error", req);
16902       if (!p->owner) {
16903          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16904       }
16905       return;
16906    }
16907 
16908    /* Strip trailing line feeds from message body. (get_msg_text may add
16909     * a trailing linefeed and we don't need any at the end) */
16910    bufp = buf + strlen(buf);
16911    while (--bufp >= buf && *bufp == '\n') {
16912       *bufp = '\0';
16913    }
16914 
16915    if (p->owner) {
16916       if (sip_debug_test_pvt(p))
16917          ast_verbose("SIP Text message received: '%s'\n", buf);
16918       memset(&f, 0, sizeof(f));
16919       f.frametype = AST_FRAME_TEXT;
16920       f.subclass.integer = 0;
16921       f.offset = 0;
16922       f.data.ptr = buf;
16923       f.datalen = strlen(buf) + 1;
16924       ast_queue_frame(p->owner, &f);
16925       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
16926       return;
16927    }
16928 
16929    /* Message outside of a call, we do not support that */
16930    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);
16931    transmit_response(p, "405 Method Not Allowed", req);
16932    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16933    return;
16934 }

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

References ao2_ref, and sip_cfg.

Referenced by __sip_ack(), __sip_subscribe_mwi_do(), create_addr(), and create_addr_from_peer().

03068 {
03069    struct sip_proxy *old_obproxy = pvt->outboundproxy;
03070    /* The sip_cfg.outboundproxy is statically allocated, and so
03071     * we don't ever need to adjust refcounts for it
03072     */
03073    if (proxy && proxy != &sip_cfg.outboundproxy) {
03074       ao2_ref(proxy, +1);
03075    }
03076    pvt->outboundproxy = proxy;
03077    if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) {
03078       ao2_ref(old_obproxy, -1);
03079    }
03080 }

static const char * referstatus2str ( enum referstatus  rstatus  )  [static]

Convert transfer status to string.

Definition at line 3189 of file chan_sip.c.

References map_x_s().

Referenced by show_channels_cb().

03190 {
03191    return map_x_s(referstatusstrings, rstatus, "");
03192 }

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

Get registration details from Asterisk DB.

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

14292 {
14293    char data[256];
14294    struct ast_sockaddr sa;
14295    int expire;
14296    char full_addr[128];
14297    AST_DECLARE_APP_ARGS(args,
14298       AST_APP_ARG(addr);
14299       AST_APP_ARG(port);
14300       AST_APP_ARG(expiry_str);
14301       AST_APP_ARG(username);
14302       AST_APP_ARG(contact);
14303    );
14304 
14305    /* If read-only RT backend, then refresh from local DB cache */
14306    if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
14307       return;
14308    }
14309    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) {
14310       return;
14311    }
14312 
14313    AST_NONSTANDARD_RAW_ARGS(args, data, ':');
14314 
14315    snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port);
14316 
14317    if (!ast_sockaddr_parse(&sa, full_addr, 0)) {
14318       return;
14319    }
14320 
14321    if (args.expiry_str) {
14322       expire = atoi(args.expiry_str);
14323    } else {
14324       return;
14325    }
14326 
14327    if (args.username) {
14328       ast_string_field_set(peer, username, args.username);
14329    }
14330    if (args.contact) {
14331       ast_string_field_set(peer, fullcontact, args.contact);
14332    }
14333 
14334    ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n",
14335        peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire);
14336 
14337    ast_sockaddr_copy(&peer->addr, &sa);
14338    if (peer->maxms) {
14339       /* Don't poke peer immediately, just schedule it within qualifyfreq */
14340       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
14341             ast_random() % ((peer->qualifyfreq) ? peer->qualifyfreq : global_qualifyfreq) + 1,
14342             sip_poke_peer_s, peer,
14343             unref_peer(_data, "removing poke peer ref"),
14344             unref_peer(peer, "removing poke peer ref"),
14345             ref_peer(peer, "adding poke peer ref"));
14346    }
14347    AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer,
14348          unref_peer(_data, "remove registration ref"),
14349          unref_peer(peer, "remove registration ref"),
14350          ref_peer(peer, "add registration ref"));
14351    register_peer_exten(peer, TRUE);
14352 }

static void register_peer_exten ( struct sip_peer *  peer,
int  onoff 
) [static]

Automatically add peer extension to dial plan.

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

04770 {
04771    char multi[256];
04772    char *stringp, *ext, *context;
04773    struct pbx_find_info q = { .stacklen = 0 };
04774 
04775    /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and
04776     * the name of the global regexten context, if not specified
04777     * individually.
04778     */
04779    if (ast_strlen_zero(sip_cfg.regcontext))
04780       return;
04781 
04782    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
04783    stringp = multi;
04784    while ((ext = strsep(&stringp, "&"))) {
04785       if ((context = strchr(ext, '@'))) {
04786          *context++ = '\0';   /* split ext@context */
04787          if (!ast_context_find(context)) {
04788             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
04789             continue;
04790          }
04791       } else {
04792          context = sip_cfg.regcontext;
04793       }
04794       if (onoff) {
04795          if (!ast_exists_extension(NULL, context, ext, 1, NULL)) {
04796             ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
04797                 ast_strdup(peer->name), ast_free_ptr, "SIP");
04798          }
04799       } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) {
04800          ast_context_remove_extension(context, ext, 1, NULL);
04801       }
04802    }
04803 }

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

15278 {
15279    enum check_auth_result res = AUTH_NOT_FOUND;
15280    struct sip_peer *peer;
15281    char tmp[256];
15282    char *c, *name, *unused_password, *domain;
15283    char *uri2 = ast_strdupa(uri);
15284    int send_mwi = 0;
15285 
15286    terminate_uri(uri2);
15287 
15288    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
15289 
15290    c = get_in_brackets(tmp);
15291    c = remove_uri_parameters(c);
15292 
15293    if (parse_uri_legacy_check(c, "sip:,sips:", &name, &unused_password, &domain, NULL)) {
15294       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr));
15295       return -1;
15296    }
15297 
15298    SIP_PEDANTIC_DECODE(name);
15299    SIP_PEDANTIC_DECODE(domain);
15300 
15301    extract_host_from_hostport(&domain);
15302 
15303    if (ast_strlen_zero(domain)) {
15304       /* <sip:name@[EMPTY]>, never good */
15305       transmit_response(p, "404 Not found", &p->initreq);
15306       return AUTH_UNKNOWN_DOMAIN;
15307    }
15308 
15309    if (ast_strlen_zero(name)) {
15310       /* <sip:[EMPTY][@]hostport>, unsure whether valid for
15311        * registration. RFC 3261, 10.2 states:
15312        * "The To header field and the Request-URI field typically
15313        * differ, as the former contains a user name."
15314        * But, Asterisk has always treated the domain-only uri as a
15315        * username: we allow admins to create accounts described by
15316        * domain name. */
15317       name = domain;
15318    }
15319 
15320    /* This here differs from 1.4 and 1.6: the domain matching ACLs were
15321     * skipped if it was a domain-only URI (used as username). Here we treat
15322     * <sip:hostport> as <sip:host@hostport> and won't forget to test the
15323     * domain ACLs against host. */
15324    if (!AST_LIST_EMPTY(&domain_list)) {
15325       if (!check_sip_domain(domain, NULL, 0)) {
15326          if (sip_cfg.alwaysauthreject) {
15327             transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
15328          } else {
15329             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
15330          }
15331          return AUTH_UNKNOWN_DOMAIN;
15332       }
15333    }
15334 
15335    ast_string_field_set(p, exten, name);
15336    build_contact(p);
15337    if (req->ignore) {
15338       /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
15339       const char *expires = get_header(req, "Expires");
15340       int expire = atoi(expires);
15341 
15342       if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */
15343          if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) {
15344             expire = atoi(expires + 9);
15345          }
15346       }
15347       if (!ast_strlen_zero(expires) && expire == 0) {
15348          transmit_response_with_date(p, "200 OK", req);
15349          return 0;
15350       }
15351    }
15352    peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
15353 
15354    /* If we don't want username disclosure, use the bogus_peer when a user
15355     * is not found. */
15356    if (!peer && sip_cfg.alwaysauthreject && !sip_cfg.autocreatepeer) {
15357       peer = bogus_peer;
15358       ref_peer(peer, "register_verify: ref the bogus_peer");
15359    }
15360 
15361    if (!(peer && ast_apply_ha(peer->ha, addr))) {
15362       /* Peer fails ACL check */
15363       if (peer) {
15364          unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
15365          peer = NULL;
15366          res = AUTH_ACL_FAILED;
15367       } else {
15368          res = AUTH_NOT_FOUND;
15369       }
15370    }
15371 
15372    if (peer) {
15373       ao2_lock(peer);
15374       if (!peer->host_dynamic) {
15375          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
15376          res = AUTH_PEER_NOT_DYNAMIC;
15377       } else {
15378          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT);
15379          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) {
15380             if (sip_cancel_destroy(p))
15381                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
15382 
15383             if (check_request_transport(peer, req)) {
15384                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
15385                transmit_response_with_date(p, "403 Forbidden", req);
15386                res = AUTH_BAD_TRANSPORT;
15387             } else {
15388 
15389                /* We have a successful registration attempt with proper authentication,
15390                   now, update the peer */
15391                switch (parse_register_contact(p, peer, req)) {
15392                case PARSE_REGISTER_DENIED:
15393                   ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
15394                   transmit_response_with_date(p, "603 Denied", req);
15395                   res = 0;
15396                   break;
15397                case PARSE_REGISTER_FAILED:
15398                   ast_log(LOG_WARNING, "Failed to parse contact info\n");
15399                   transmit_response_with_date(p, "400 Bad Request", req);
15400                   res = 0;
15401                   break;
15402                case PARSE_REGISTER_QUERY:
15403                   ast_string_field_set(p, fullcontact, peer->fullcontact);
15404                   transmit_response_with_date(p, "200 OK", req);
15405                   res = 0;
15406                   break;
15407                case PARSE_REGISTER_UPDATE:
15408                   ast_string_field_set(p, fullcontact, peer->fullcontact);
15409                   /* If expiry is 0, peer has been unregistered already */
15410                   if (p->expiry != 0) {
15411                      update_peer(peer, p->expiry);
15412                   }
15413                   /* Say OK and ask subsystem to retransmit msg counter */
15414                   transmit_response_with_date(p, "200 OK", req);
15415                   send_mwi = 1;
15416                   res = 0;
15417                   break;
15418                }
15419             }
15420 
15421          }
15422       }
15423       ao2_unlock(peer);
15424    }
15425    if (!peer && sip_cfg.autocreatepeer) {
15426       /* Create peer if we have autocreate mode enabled */
15427       peer = temp_peer(name);
15428       if (peer) {
15429          ao2_t_link(peers, peer, "link peer into peer table");
15430          if (!ast_sockaddr_isnull(&peer->addr)) {
15431             ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
15432          }
15433          ao2_lock(peer);
15434          if (sip_cancel_destroy(p))
15435             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
15436          switch (parse_register_contact(p, peer, req)) {
15437          case PARSE_REGISTER_DENIED:
15438             ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
15439             transmit_response_with_date(p, "403 Forbidden", req);
15440             res = 0;
15441             break;
15442          case PARSE_REGISTER_FAILED:
15443             ast_log(LOG_WARNING, "Failed to parse contact info\n");
15444             transmit_response_with_date(p, "400 Bad Request", req);
15445             res = 0;
15446             break;
15447          case PARSE_REGISTER_QUERY:
15448             ast_string_field_set(p, fullcontact, peer->fullcontact);
15449             transmit_response_with_date(p, "200 OK", req);
15450             send_mwi = 1;
15451             res = 0;
15452             break;
15453          case PARSE_REGISTER_UPDATE:
15454             ast_string_field_set(p, fullcontact, peer->fullcontact);
15455             /* Say OK and ask subsystem to retransmit msg counter */
15456             transmit_response_with_date(p, "200 OK", req);
15457             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));
15458             send_mwi = 1;
15459             res = 0;
15460             break;
15461          }
15462          ao2_unlock(peer);
15463       }
15464    }
15465    if (!res) {
15466       if (send_mwi) {
15467          sip_pvt_unlock(p);
15468          sip_send_mwi_to_peer(peer, 0);
15469          sip_pvt_lock(p);
15470       } else {
15471          update_peer_lastmsgssent(peer, -1, 0);
15472       }
15473       ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
15474    }
15475    if (res < 0) {
15476       switch (res) {
15477       case AUTH_SECRET_FAILED:
15478          /* Wrong password in authentication. Go away, don't try again until you fixed it */
15479          transmit_response(p, "403 Forbidden", &p->initreq);
15480          if (global_authfailureevents) {
15481             const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
15482             const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
15483             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
15484                      "ChannelType: SIP\r\n"
15485                      "Peer: SIP/%s\r\n"
15486                      "PeerStatus: Rejected\r\n"
15487                      "Cause: AUTH_SECRET_FAILED\r\n"
15488                      "Address: %s\r\n"
15489                      "Port: %s\r\n",
15490                      name, peer_addr, peer_port);
15491          }
15492          break;
15493       case AUTH_USERNAME_MISMATCH:
15494          /* Username and digest username does not match.
15495             Asterisk uses the From: username for authentication. We need the
15496             devices to use the same authentication user name until we support
15497             proper authentication by digest auth name */
15498       case AUTH_NOT_FOUND:
15499       case AUTH_PEER_NOT_DYNAMIC:
15500       case AUTH_ACL_FAILED:
15501          if (sip_cfg.alwaysauthreject) {
15502             transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
15503             if (global_authfailureevents) {
15504                const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
15505                const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
15506                manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
15507                         "ChannelType: SIP\r\n"
15508                         "Peer: SIP/%s\r\n"
15509                         "PeerStatus: Rejected\r\n"
15510                         "Cause: %s\r\n"
15511                         "Address: %s\r\n"
15512                         "Port: %s\r\n",
15513                         name,
15514                         res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND",
15515                         peer_addr, peer_port);
15516             }
15517          } else {
15518             /* URI not found */
15519             if (res == AUTH_PEER_NOT_DYNAMIC) {
15520                transmit_response(p, "403 Forbidden", &p->initreq);
15521                if (global_authfailureevents) {
15522                   const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
15523                   const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
15524                   manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
15525                      "ChannelType: SIP\r\n"
15526                      "Peer: SIP/%s\r\n"
15527                      "PeerStatus: Rejected\r\n"
15528                      "Cause: AUTH_PEER_NOT_DYNAMIC\r\n"
15529                      "Address: %s\r\n"
15530                      "Port: %s\r\n",
15531                      name, peer_addr, peer_port);
15532                }
15533             } else {
15534                transmit_response(p, "404 Not found", &p->initreq);
15535                if (global_authfailureevents) {
15536                   const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
15537                   const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
15538                   manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
15539                      "ChannelType: SIP\r\n"
15540                      "Peer: SIP/%s\r\n"
15541                      "PeerStatus: Rejected\r\n"
15542                      "Cause: %s\r\n"
15543                      "Address: %s\r\n"
15544                      "Port: %s\r\n",
15545                      name,
15546                      (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND",
15547                      peer_addr, peer_port);
15548                }
15549             }
15550          }
15551          break;
15552       case AUTH_BAD_TRANSPORT:
15553       default:
15554          break;
15555       }
15556    }
15557    if (peer) {
15558       unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func");
15559    }
15560 
15561    return res;
15562 }

static struct sip_registry* registry_addref ( struct sip_registry *  reg,
char *  tag 
) [static, read]

Add object reference to SIP registry.

Definition at line 3171 of file chan_sip.c.

References ast_debug, and ASTOBJ_REF.

Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().

03172 {
03173    ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount + 1);
03174    return ASTOBJ_REF(reg); /* Add pointer to registry in packet */
03175 }

void * registry_unref ( struct sip_registry *  reg,
char *  tag 
) [static]

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

03164 {
03165    ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount - 1);
03166    ASTOBJ_UNREF(reg, sip_registry_destroy);
03167    return NULL;
03168 }

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

References sip_reload().

30646 {
30647    if (sip_reload(0, 0, NULL))
30648       return 0;
30649    return 1;
30650 }

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

28775 {
28776    struct ast_config *cfg, *ucfg;
28777    struct ast_variable *v;
28778    struct sip_peer *peer;
28779    char *cat, *stringp, *context, *oldregcontext;
28780    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
28781    struct ast_flags mask[3] = {{0}};
28782    struct ast_flags setflags[3] = {{0}};
28783    struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED };
28784    int auto_sip_domains = FALSE;
28785    struct ast_sockaddr old_bindaddr = bindaddr;
28786    int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0;
28787    int subscribe_network_change = 1;
28788    time_t run_start, run_end;
28789    int bindport = 0;
28790 
28791    run_start = time(0);
28792    ast_unload_realtime("sipregs");
28793    ast_unload_realtime("sippeers");
28794    cfg = ast_config_load(config, config_flags);
28795 
28796    /* We *must* have a config file otherwise stop immediately */
28797    if (!cfg) {
28798       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
28799       return -1;
28800    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
28801       ucfg = ast_config_load("users.conf", config_flags);
28802       if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
28803          return 1;
28804       } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
28805          ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n");
28806          return 1;
28807       }
28808       /* Must reread both files, because one changed */
28809       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
28810       if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
28811          ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config);
28812          ast_config_destroy(ucfg);
28813          return 1;
28814       }
28815       if (!cfg) {
28816          /* should have been able to reload here */
28817          ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
28818          return -1;
28819       }
28820    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
28821       ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config);
28822       return 1;
28823    } else {
28824       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
28825       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
28826          ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n");
28827          ast_config_destroy(cfg);
28828          return 1;
28829       }
28830    }
28831 
28832    ast_free_ha(sip_cfg.contact_ha);
28833    sip_cfg.contact_ha = NULL;
28834 
28835    default_tls_cfg.enabled = FALSE;    /* Default: Disable TLS */
28836 
28837    if (reason != CHANNEL_MODULE_LOAD) {
28838       ast_debug(4, "--------------- SIP reload started\n");
28839 
28840       clear_sip_domains();
28841       ast_mutex_lock(&authl_lock);
28842       if (authl) {
28843          ao2_t_ref(authl, -1, "Removing old global authentication");
28844          authl = NULL;
28845       }
28846       ast_mutex_unlock(&authl_lock);
28847 
28848 
28849       cleanup_all_regs();
28850       /* Then, actually destroy users and registry */
28851       ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
28852       ast_debug(4, "--------------- Done destroying registry list\n");
28853       ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers");
28854    }
28855 
28856    /* Reset certificate handling for TLS sessions */
28857    if (reason != CHANNEL_MODULE_LOAD) {
28858       ast_free(default_tls_cfg.certfile);
28859       ast_free(default_tls_cfg.pvtfile);
28860       ast_free(default_tls_cfg.cipher);
28861       ast_free(default_tls_cfg.cafile);
28862       ast_free(default_tls_cfg.capath);
28863    }
28864    default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */
28865    default_tls_cfg.pvtfile = ast_strdup("");
28866    default_tls_cfg.cipher = ast_strdup("");
28867    default_tls_cfg.cafile = ast_strdup("");
28868    default_tls_cfg.capath = ast_strdup("");
28869 
28870    /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */
28871    ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts));
28872    oldregcontext = oldcontexts;
28873 
28874    /* Clear all flags before setting default values */
28875    /* Preserve debugging settings for console */
28876    sipdebug &= sip_debug_console;
28877    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
28878    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
28879    ast_clear_flag(&global_flags[2], AST_FLAGS_ALL);
28880 
28881    /* Reset IP addresses  */
28882    ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
28883    memset(&internip, 0, sizeof(internip));
28884 
28885    /* Free memory for local network address mask */
28886    ast_free_ha(localaddr);
28887    memset(&localaddr, 0, sizeof(localaddr));
28888    memset(&externaddr, 0, sizeof(externaddr));
28889    memset(&media_address, 0, sizeof(media_address));
28890    memset(&default_prefs, 0 , sizeof(default_prefs));
28891    memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy));
28892    sip_cfg.outboundproxy.force = FALSE;      /*!< Don't force proxy usage, use route: headers */
28893    default_transports = SIP_TRANSPORT_UDP;
28894    default_primary_transport = SIP_TRANSPORT_UDP;
28895    ourport_tcp = STANDARD_SIP_PORT;
28896    ourport_tls = STANDARD_TLS_PORT;
28897    externtcpport = STANDARD_SIP_PORT;
28898    externtlsport = STANDARD_TLS_PORT;
28899    sip_cfg.srvlookup = DEFAULT_SRVLOOKUP;
28900    global_tos_sip = DEFAULT_TOS_SIP;
28901    global_tos_audio = DEFAULT_TOS_AUDIO;
28902    global_tos_video = DEFAULT_TOS_VIDEO;
28903    global_tos_text = DEFAULT_TOS_TEXT;
28904    global_cos_sip = DEFAULT_COS_SIP;
28905    global_cos_audio = DEFAULT_COS_AUDIO;
28906    global_cos_video = DEFAULT_COS_VIDEO;
28907    global_cos_text = DEFAULT_COS_TEXT;
28908 
28909    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
28910    externexpire = 0;       /* Expiration for DNS re-issuing */
28911    externrefresh = 10;
28912 
28913    /* Reset channel settings to default before re-configuring */
28914    sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM;           /* Allow external invites */
28915    sip_cfg.regcontext[0] = '\0';
28916    sip_cfg.capability = DEFAULT_CAPABILITY;
28917    sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY;
28918    sip_cfg.legacy_useroption_parsing = DEFAULT_LEGACY_USEROPTION_PARSING;
28919    sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING;
28920    sip_cfg.notifycid = DEFAULT_NOTIFYCID;
28921    sip_cfg.notifyhold = FALSE;      /*!< Keep track of hold status for a peer */
28922    sip_cfg.directrtpsetup = FALSE;     /* Experimental feature, disabled by default */
28923    sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT;
28924    sip_cfg.auth_options_requests = DEFAULT_AUTH_OPTIONS;
28925    sip_cfg.allowsubscribe = FALSE;
28926    sip_cfg.disallowed_methods = SIP_UNKNOWN;
28927    sip_cfg.contact_ha = NULL;    /* Reset the contact ACL */
28928    snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version());
28929    snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version());
28930    snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER);
28931    global_prematuremediafilter = TRUE;
28932    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
28933    ast_copy_string(sip_cfg.realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(sip_cfg.realm));
28934    sip_cfg.domainsasrealm = DEFAULT_DOMAINSASREALM;
28935    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
28936    ast_copy_string(default_mwi_from, DEFAULT_MWI_FROM, sizeof(default_mwi_from));
28937    sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS;
28938    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
28939    global_regattempts_max = 0;
28940    global_reg_retry_403 = 0;
28941    sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC;
28942    sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER;
28943    global_autoframing = 0;
28944    sip_cfg.allowguest = DEFAULT_ALLOWGUEST;
28945    global_callcounter = DEFAULT_CALLCOUNTER;
28946    global_match_auth_username = FALSE;    /*!< Match auth username if available instead of From: Default off. */
28947    global_rtptimeout = 0;
28948    global_rtpholdtimeout = 0;
28949    global_rtpkeepalive = DEFAULT_RTPKEEPALIVE;
28950    sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */
28951    sip_cfg.rtautoclear = 120;
28952    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for all devices: TRUE */
28953    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */
28954    sip_cfg.peer_rtupdate = TRUE;
28955    global_dynamic_exclude_static = 0;  /* Exclude static peers */
28956    sip_cfg.tcp_enabled = FALSE;
28957 
28958    /* Session-Timers */
28959    global_st_mode = SESSION_TIMER_MODE_ACCEPT;
28960    global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS;
28961    global_min_se  = DEFAULT_MIN_SE;
28962    global_max_se  = DEFAULT_MAX_SE;
28963 
28964    /* Peer poking settings */
28965    global_qualify_gap = DEFAULT_QUALIFY_GAP;
28966    global_qualify_peers = DEFAULT_QUALIFY_PEERS;
28967 
28968    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */
28969    ast_copy_string(sip_cfg.default_context, DEFAULT_CONTEXT, sizeof(sip_cfg.default_context));
28970    sip_cfg.default_subscribecontext[0] = '\0';
28971    sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS;
28972    default_language[0] = '\0';
28973    default_fromdomain[0] = '\0';
28974    default_fromdomainport = 0;
28975    default_qualify = DEFAULT_QUALIFY;
28976    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
28977    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
28978    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
28979    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
28980    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);    /*!< Default DTMF setting: RFC2833 */
28981    ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA);    /*!< Allow re-invites */
28982    ast_set_flag(&global_flags[0], SIP_NAT_FORCE_RPORT); /*!< Default to nat=force_rport */
28983    ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine));
28984    ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot));
28985 
28986    /* Debugging settings, always default to off */
28987    dumphistory = FALSE;
28988    recordhistory = FALSE;
28989    sipdebug &= ~sip_debug_config;
28990 
28991    /* Misc settings for the channel */
28992    global_relaxdtmf = FALSE;
28993    sip_cfg.callevents = DEFAULT_CALLEVENTS;
28994    global_authfailureevents = FALSE;
28995    global_t1 = DEFAULT_TIMER_T1;
28996    global_timer_b = 64 * DEFAULT_TIMER_T1;
28997    global_t1min = DEFAULT_T1MIN;
28998    global_qualifyfreq = DEFAULT_QUALIFYFREQ;
28999    global_t38_maxdatagram = -1;
29000    global_shrinkcallerid = 1;
29001    authlimit = DEFAULT_AUTHLIMIT;
29002    authtimeout = DEFAULT_AUTHTIMEOUT;
29003    global_store_sip_cause = DEFAULT_STORE_SIP_CAUSE;
29004 
29005    sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY;
29006 
29007    /* Copy the default jb config over global_jbconf */
29008    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
29009 
29010    ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT);
29011    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
29012    ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT);
29013    ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION);
29014 
29015 
29016    /* Read the [general] config section of sip.conf (or from realtime config) */
29017    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
29018       if (handle_common_options(&setflags[0], &mask[0], v)) {
29019          continue;
29020       }
29021       if (handle_t38_options(&setflags[0], &mask[0], v, &global_t38_maxdatagram)) {
29022          continue;
29023       }
29024       /* handle jb conf */
29025       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
29026          continue;
29027 
29028       /* handle tls conf, don't allow setting of tlsverifyclient as it isn't supported by chan_sip */
29029       if (!strcasecmp(v->name, "tlsverifyclient")) {
29030          ast_log(LOG_WARNING, "Ignoring unsupported option 'tlsverifyclient'\n");
29031          continue;
29032       } else if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) {
29033          continue;
29034       }
29035 
29036       if (!strcasecmp(v->name, "context")) {
29037          ast_copy_string(sip_cfg.default_context, v->value, sizeof(sip_cfg.default_context));
29038       } else if (!strcasecmp(v->name, "subscribecontext")) {
29039          ast_copy_string(sip_cfg.default_subscribecontext, v->value, sizeof(sip_cfg.default_subscribecontext));
29040       } else if (!strcasecmp(v->name, "callcounter")) {
29041          global_callcounter = ast_true(v->value) ? 1 : 0;
29042       } else if (!strcasecmp(v->name, "allowguest")) {
29043          sip_cfg.allowguest = ast_true(v->value) ? 1 : 0;
29044       } else if (!strcasecmp(v->name, "realm")) {
29045          ast_copy_string(sip_cfg.realm, v->value, sizeof(sip_cfg.realm));
29046       } else if (!strcasecmp(v->name, "domainsasrealm")) {
29047          sip_cfg.domainsasrealm = ast_true(v->value);
29048       } else if (!strcasecmp(v->name, "useragent")) {
29049          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
29050          ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
29051       } else if (!strcasecmp(v->name, "sdpsession")) {
29052          ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession));
29053       } else if (!strcasecmp(v->name, "sdpowner")) {
29054          /* Field cannot contain spaces */
29055          if (!strstr(v->value, " ")) {
29056             ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner));
29057          } else {
29058             ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d.  Using default.\n", v->value, v->lineno);
29059          }
29060       } else if (!strcasecmp(v->name, "allowtransfer")) {
29061          sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
29062       } else if (!strcasecmp(v->name, "rtcachefriends")) {
29063          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);
29064       } else if (!strcasecmp(v->name, "rtsavesysname")) {
29065          sip_cfg.rtsave_sysname = ast_true(v->value);
29066       } else if (!strcasecmp(v->name, "rtupdate")) {
29067          sip_cfg.peer_rtupdate = ast_true(v->value);
29068       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
29069          sip_cfg.ignore_regexpire = ast_true(v->value);
29070       } else if (!strcasecmp(v->name, "timert1")) {
29071          /* Defaults to 500ms, but RFC 3261 states that it is recommended
29072           * for the value to be set higher, though a lower value is only
29073           * allowed on private networks unconnected to the Internet. */
29074          global_t1 = atoi(v->value);
29075       } else if (!strcasecmp(v->name, "timerb")) {
29076          int tmp = atoi(v->value);
29077          if (tmp < 500) {
29078             global_timer_b = global_t1 * 64;
29079             ast_log(LOG_WARNING, "Invalid value for timerb ('%s').  Setting to default ('%d').\n", v->value, global_timer_b);
29080          }
29081          timerb_set = 1;
29082       } else if (!strcasecmp(v->name, "t1min")) {
29083          global_t1min = atoi(v->value);
29084       } else if (!strcasecmp(v->name, "transport")) {
29085          char *val = ast_strdupa(v->value);
29086          char *trans;
29087 
29088          default_transports = default_primary_transport = 0;
29089          while ((trans = strsep(&val, ","))) {
29090             trans = ast_skip_blanks(trans);
29091 
29092             if (!strncasecmp(trans, "udp", 3)) {
29093                default_transports |= SIP_TRANSPORT_UDP;
29094             } else if (!strncasecmp(trans, "tcp", 3)) {
29095                default_transports |= SIP_TRANSPORT_TCP;
29096             } else if (!strncasecmp(trans, "tls", 3)) {
29097                default_transports |= SIP_TRANSPORT_TLS;
29098             } else {
29099                ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
29100             }
29101             if (default_primary_transport == 0) {
29102                default_primary_transport = default_transports;
29103             }
29104          }
29105       } else if (!strcasecmp(v->name, "tcpenable")) {
29106          if (!ast_false(v->value)) {
29107             ast_debug(2, "Enabling TCP socket for listening\n");
29108             sip_cfg.tcp_enabled = TRUE;
29109          }
29110       } else if (!strcasecmp(v->name, "tcpbindaddr")) {
29111          if (ast_parse_arg(v->value, PARSE_ADDR,
29112                  &sip_tcp_desc.local_address)) {
29113             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
29114                v->name, v->value, v->lineno, config);
29115          }
29116          ast_debug(2, "Setting TCP socket address to %s\n",
29117               ast_sockaddr_stringify(&sip_tcp_desc.local_address));
29118       } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) {
29119          global_dynamic_exclude_static = ast_true(v->value);
29120       } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
29121          int ha_error = 0;
29122          sip_cfg.contact_ha = ast_append_ha(v->name + 7, v->value, sip_cfg.contact_ha, &ha_error);
29123          if (ha_error) {
29124             ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
29125          }
29126       } else if (!strcasecmp(v->name, "rtautoclear")) {
29127          int i = atoi(v->value);
29128          if (i > 0) {
29129             sip_cfg.rtautoclear = i;
29130          } else {
29131             i = 0;
29132          }
29133          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
29134       } else if (!strcasecmp(v->name, "usereqphone")) {
29135          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);
29136       } else if (!strcasecmp(v->name, "prematuremedia")) {
29137          global_prematuremediafilter = ast_true(v->value);
29138       } else if (!strcasecmp(v->name, "relaxdtmf")) {
29139          global_relaxdtmf = ast_true(v->value);
29140       } else if (!strcasecmp(v->name, "vmexten")) {
29141          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
29142       } else if (!strcasecmp(v->name, "rtptimeout")) {
29143          if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
29144             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
29145             global_rtptimeout = 0;
29146          }
29147       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
29148          if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
29149             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
29150             global_rtpholdtimeout = 0;
29151          }
29152       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
29153          if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
29154             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
29155             global_rtpkeepalive = DEFAULT_RTPKEEPALIVE;
29156          }
29157       } else if (!strcasecmp(v->name, "compactheaders")) {
29158          sip_cfg.compactheaders = ast_true(v->value);
29159       } else if (!strcasecmp(v->name, "notifymimetype")) {
29160          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
29161       } else if (!strcasecmp(v->name, "directrtpsetup")) {
29162          sip_cfg.directrtpsetup = ast_true(v->value);
29163       } else if (!strcasecmp(v->name, "notifyringing")) {
29164          sip_cfg.notifyringing = ast_true(v->value);
29165       } else if (!strcasecmp(v->name, "notifyhold")) {
29166          sip_cfg.notifyhold = ast_true(v->value);
29167       } else if (!strcasecmp(v->name, "notifycid")) {
29168          if (!strcasecmp(v->value, "ignore-context")) {
29169             sip_cfg.notifycid = IGNORE_CONTEXT;
29170          } else {
29171             sip_cfg.notifycid = ast_true(v->value) ? ENABLED : DISABLED;
29172          }
29173       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
29174          sip_cfg.alwaysauthreject = ast_true(v->value);
29175       } else if (!strcasecmp(v->name, "auth_options_requests")) {
29176          if (ast_true(v->value)) {
29177             sip_cfg.auth_options_requests = 1;
29178          }
29179       } else if (!strcasecmp(v->name, "mohinterpret")) {
29180          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
29181       } else if (!strcasecmp(v->name, "mohsuggest")) {
29182          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
29183       } else if (!strcasecmp(v->name, "language")) {
29184          ast_copy_string(default_language, v->value, sizeof(default_language));
29185       } else if (!strcasecmp(v->name, "regcontext")) {
29186          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
29187          stringp = newcontexts;
29188          /* Let's remove any contexts that are no longer defined in regcontext */
29189          cleanup_stale_contexts(stringp, oldregcontext);
29190          /* Create contexts if they don't exist already */
29191          while ((context = strsep(&stringp, "&"))) {
29192             ast_copy_string(used_context, context, sizeof(used_context));
29193             ast_context_find_or_create(NULL, NULL, context, "SIP");
29194          }
29195          ast_copy_string(sip_cfg.regcontext, v->value, sizeof(sip_cfg.regcontext));
29196       } else if (!strcasecmp(v->name, "regextenonqualify")) {
29197          sip_cfg.regextenonqualify = ast_true(v->value);
29198       } else if (!strcasecmp(v->name, "legacy_useroption_parsing")) {
29199          sip_cfg.legacy_useroption_parsing = ast_true(v->value);
29200       } else if (!strcasecmp(v->name, "callerid")) {
29201          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
29202       } else if (!strcasecmp(v->name, "mwi_from")) {
29203          ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from));
29204       } else if (!strcasecmp(v->name, "fromdomain")) {
29205          char *fromdomainport;
29206          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
29207          if ((fromdomainport = strchr(default_fromdomain, ':'))) {
29208             *fromdomainport++ = '\0';
29209             if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) {
29210                ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
29211             }
29212          } else {
29213             default_fromdomainport = STANDARD_SIP_PORT;
29214          }
29215       } else if (!strcasecmp(v->name, "outboundproxy")) {
29216          struct sip_proxy *proxy;
29217          if (ast_strlen_zero(v->value)) {
29218             ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno);
29219             continue;
29220          }
29221          proxy = proxy_from_config(v->value, v->lineno, &sip_cfg.outboundproxy);
29222          if (!proxy) {
29223             ast_log(LOG_WARNING, "failure parsing the outbound proxy on line %d of sip.conf.\n", v->lineno);
29224             continue;
29225          }
29226       } else if (!strcasecmp(v->name, "autocreatepeer")) {
29227          sip_cfg.autocreatepeer = ast_true(v->value);
29228       } else if (!strcasecmp(v->name, "match_auth_username")) {
29229          global_match_auth_username = ast_true(v->value);
29230       } else if (!strcasecmp(v->name, "srvlookup")) {
29231          sip_cfg.srvlookup = ast_true(v->value);
29232       } else if (!strcasecmp(v->name, "pedantic")) {
29233          sip_cfg.pedanticsipchecking = ast_true(v->value);
29234       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
29235          max_expiry = atoi(v->value);
29236          if (max_expiry < 1) {
29237             max_expiry = DEFAULT_MAX_EXPIRY;
29238          }
29239       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
29240          min_expiry = atoi(v->value);
29241          if (min_expiry < 1) {
29242             min_expiry = DEFAULT_MIN_EXPIRY;
29243          }
29244       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
29245          default_expiry = atoi(v->value);
29246          if (default_expiry < 1) {
29247             default_expiry = DEFAULT_DEFAULT_EXPIRY;
29248          }
29249       } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) {
29250          mwi_expiry = atoi(v->value);
29251          if (mwi_expiry < 1) {
29252             mwi_expiry = DEFAULT_MWI_EXPIRY;
29253          }
29254       } else if (!strcasecmp(v->name, "tcpauthtimeout")) {
29255          if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
29256                  &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) {
29257             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
29258                v->name, v->value, v->lineno, config);
29259          }
29260       } else if (!strcasecmp(v->name, "tcpauthlimit")) {
29261          if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
29262                  &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) {
29263             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
29264                v->name, v->value, v->lineno, config);
29265          }
29266       } else if (!strcasecmp(v->name, "sipdebug")) {
29267          if (ast_true(v->value))
29268             sipdebug |= sip_debug_config;
29269       } else if (!strcasecmp(v->name, "dumphistory")) {
29270          dumphistory = ast_true(v->value);
29271       } else if (!strcasecmp(v->name, "recordhistory")) {
29272          recordhistory = ast_true(v->value);
29273       } else if (!strcasecmp(v->name, "registertimeout")) {
29274          global_reg_timeout = atoi(v->value);
29275          if (global_reg_timeout < 1) {
29276             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
29277          }
29278       } else if (!strcasecmp(v->name, "registerattempts")) {
29279          global_regattempts_max = atoi(v->value);
29280       } else if (!strcasecmp(v->name, "register_retry_403")) {
29281          global_reg_retry_403 = ast_true(v->value);
29282       } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) {
29283          if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
29284             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
29285          }
29286       } else if (!strcasecmp(v->name, "localnet")) {
29287          struct ast_ha *na;
29288          int ha_error = 0;
29289 
29290          if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) {
29291             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
29292          } else {
29293             localaddr = na;
29294          }
29295          if (ha_error) {
29296             ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value);
29297          }
29298       } else if (!strcasecmp(v->name, "media_address")) {
29299          if (ast_parse_arg(v->value, PARSE_ADDR, &media_address))
29300             ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value);
29301       } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) {
29302          if (ast_parse_arg(v->value, PARSE_ADDR, &externaddr)) {
29303             ast_log(LOG_WARNING,
29304                "Invalid address for externaddr keyword: %s\n",
29305                v->value);
29306          }
29307          externexpire = 0;
29308       } else if (!strcasecmp(v->name, "externhost")) {
29309          ast_copy_string(externhost, v->value, sizeof(externhost));
29310          if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
29311             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
29312          }
29313          externexpire = time(NULL);
29314       } else if (!strcasecmp(v->name, "externrefresh")) {
29315          if (sscanf(v->value, "%30d", &externrefresh) != 1) {
29316             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
29317             externrefresh = 10;
29318          }
29319       } else if (!strcasecmp(v->name, "externtcpport")) {
29320          if (!(externtcpport = port_str2int(v->value, 0))) {
29321             ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
29322             externtcpport = 0;
29323          }
29324       } else if (!strcasecmp(v->name, "externtlsport")) {
29325          if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) {
29326             ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
29327          }
29328       } else if (!strcasecmp(v->name, "allow")) {
29329          int error =  ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE);
29330          if (error) {
29331             ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
29332          }
29333       } else if (!strcasecmp(v->name, "disallow")) {
29334          int error =  ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE);
29335          if (error) {
29336             ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
29337          }
29338       } else if (!strcasecmp(v->name, "preferred_codec_only")) {
29339          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
29340       } else if (!strcasecmp(v->name, "autoframing")) {
29341          global_autoframing = ast_true(v->value);
29342       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
29343          sip_cfg.allow_external_domains = ast_true(v->value);
29344       } else if (!strcasecmp(v->name, "autodomain")) {
29345          auto_sip_domains = ast_true(v->value);
29346       } else if (!strcasecmp(v->name, "domain")) {
29347          char *domain = ast_strdupa(v->value);
29348          char *cntx = strchr(domain, ',');
29349 
29350          if (cntx) {
29351             *cntx++ = '\0';
29352          }
29353 
29354          if (ast_strlen_zero(cntx)) {
29355             ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
29356          }
29357          if (ast_strlen_zero(domain)) {
29358             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
29359          } else {
29360             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : "");
29361          }
29362       } else if (!strcasecmp(v->name, "register")) {
29363          if (sip_register(v->value, v->lineno) == 0) {
29364             registry_count++;
29365          }
29366       } else if (!strcasecmp(v->name, "mwi")) {
29367          sip_subscribe_mwi(v->value, v->lineno);
29368       } else if (!strcasecmp(v->name, "tos_sip")) {
29369          if (ast_str2tos(v->value, &global_tos_sip)) {
29370             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno);
29371          }
29372       } else if (!strcasecmp(v->name, "tos_audio")) {
29373          if (ast_str2tos(v->value, &global_tos_audio)) {
29374             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
29375          }
29376       } else if (!strcasecmp(v->name, "tos_video")) {
29377          if (ast_str2tos(v->value, &global_tos_video)) {
29378             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno);
29379          }
29380       } else if (!strcasecmp(v->name, "tos_text")) {
29381          if (ast_str2tos(v->value, &global_tos_text)) {
29382             ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno);
29383          }
29384       } else if (!strcasecmp(v->name, "cos_sip")) {
29385          if (ast_str2cos(v->value, &global_cos_sip)) {
29386             ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno);
29387          }
29388       } else if (!strcasecmp(v->name, "cos_audio")) {
29389          if (ast_str2cos(v->value, &global_cos_audio)) {
29390             ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
29391          }
29392       } else if (!strcasecmp(v->name, "cos_video")) {
29393          if (ast_str2cos(v->value, &global_cos_video)) {
29394             ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno);
29395          }
29396       } else if (!strcasecmp(v->name, "cos_text")) {
29397          if (ast_str2cos(v->value, &global_cos_text)) {
29398             ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno);
29399          }
29400       } else if (!strcasecmp(v->name, "bindport")) {
29401          if (sscanf(v->value, "%5d", &bindport) != 1) {
29402             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
29403          }
29404       } else if (!strcasecmp(v->name, "qualify")) {
29405          if (!strcasecmp(v->value, "no")) {
29406             default_qualify = 0;
29407          } else if (!strcasecmp(v->value, "yes")) {
29408             default_qualify = DEFAULT_MAXMS;
29409          } else if (sscanf(v->value, "%30d", &default_qualify) != 1) {
29410             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
29411             default_qualify = 0;
29412          }
29413       } else if (!strcasecmp(v->name, "qualifyfreq")) {
29414          int i;
29415          if (sscanf(v->value, "%30d", &i) == 1) {
29416             global_qualifyfreq = i * 1000;
29417          } else {
29418             ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
29419             global_qualifyfreq = DEFAULT_QUALIFYFREQ;
29420          }
29421       } else if (!strcasecmp(v->name, "callevents")) {
29422          sip_cfg.callevents = ast_true(v->value);
29423       } else if (!strcasecmp(v->name, "authfailureevents")) {
29424          global_authfailureevents = ast_true(v->value);
29425       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
29426          default_maxcallbitrate = atoi(v->value);
29427          if (default_maxcallbitrate < 0)
29428             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
29429       } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) {
29430          sip_cfg.matchexternaddrlocally = ast_true(v->value);
29431       } else if (!strcasecmp(v->name, "session-timers")) {
29432          int i = (int) str2stmode(v->value);
29433          if (i < 0) {
29434             ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
29435             global_st_mode = SESSION_TIMER_MODE_ACCEPT;
29436          } else {
29437             global_st_mode = i;
29438          }
29439       } else if (!strcasecmp(v->name, "session-expires")) {
29440          if (sscanf(v->value, "%30d", &global_max_se) != 1) {
29441             ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
29442             global_max_se = DEFAULT_MAX_SE;
29443          }
29444       } else if (!strcasecmp(v->name, "session-minse")) {
29445          if (sscanf(v->value, "%30d", &global_min_se) != 1) {
29446             ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
29447             global_min_se = DEFAULT_MIN_SE;
29448          }
29449          if (global_min_se < DEFAULT_MIN_SE) {
29450             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);
29451             global_min_se = DEFAULT_MIN_SE;
29452          }
29453       } else if (!strcasecmp(v->name, "session-refresher")) {
29454          int i = (int) str2strefresherparam(v->value);
29455          if (i < 0) {
29456             ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
29457             global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS;
29458          } else {
29459             global_st_refresher = i;
29460          }
29461       } else if (!strcasecmp(v->name, "storesipcause")) {
29462          global_store_sip_cause = ast_true(v->value);
29463       } else if (!strcasecmp(v->name, "qualifygap")) {
29464          if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) {
29465             ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config);
29466             global_qualify_gap = DEFAULT_QUALIFY_GAP;
29467          }
29468       } else if (!strcasecmp(v->name, "qualifypeers")) {
29469          if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) {
29470             ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config);
29471             global_qualify_peers = DEFAULT_QUALIFY_PEERS;
29472          }
29473       } else if (!strcasecmp(v->name, "disallowed_methods")) {
29474          char *disallow = ast_strdupa(v->value);
29475          mark_parsed_methods(&sip_cfg.disallowed_methods, disallow);
29476       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
29477          if (ast_true(v->value)) {
29478             global_shrinkcallerid = 1;
29479          } else if (ast_false(v->value)) {
29480             global_shrinkcallerid = 0;
29481          } else {
29482             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
29483          }
29484       } else if (!strcasecmp(v->name, "use_q850_reason")) {
29485          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
29486       } else if (!strcasecmp(v->name, "maxforwards")) {
29487          if (sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1
29488             || sip_cfg.default_max_forwards < 1 || 255 < sip_cfg.default_max_forwards) {
29489             ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d.  Using default.\n", v->value, v->lineno);
29490             sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS;
29491          }
29492       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
29493          if (ast_true(v->value)) {
29494             subscribe_network_change = 1;
29495          } else if (ast_false(v->value)) {
29496             subscribe_network_change = 0;
29497          } else {
29498             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
29499          }
29500       } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
29501          ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
29502       } else if (!strcasecmp(v->name, "parkinglot")) {
29503          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
29504       }
29505    }
29506 
29507    /* Override global defaults if setting found in general section */
29508    ast_copy_flags(&global_flags[0], &setflags[0], mask[0].flags);
29509    ast_copy_flags(&global_flags[1], &setflags[1], mask[1].flags);
29510    ast_copy_flags(&global_flags[2], &setflags[2], mask[2].flags);
29511 
29512    if (subscribe_network_change) {
29513       network_change_event_subscribe();
29514    } else {
29515       network_change_event_unsubscribe();
29516    }
29517 
29518    if (global_t1 < global_t1min) {
29519       ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d).  Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1);
29520       global_t1 = global_t1min;
29521    }
29522 
29523    if (global_timer_b < global_t1 * 64) {
29524       if (timerb_set && timert1_set) {
29525          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);
29526       } else if (timerb_set) {
29527          if ((global_t1 = global_timer_b / 64) < global_t1min) {
29528             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);
29529             global_t1 = global_t1min;
29530             global_timer_b = global_t1 * 64;
29531          }
29532       } else {
29533          global_timer_b = global_t1 * 64;
29534       }
29535    }
29536    if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
29537       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
29538       sip_cfg.allow_external_domains = 1;
29539    }
29540    /* If not or badly configured, set default transports */
29541    if (!sip_cfg.tcp_enabled && (default_transports & SIP_TRANSPORT_TCP)) {
29542       ast_log(LOG_WARNING, "Cannot use 'tcp' transport with tcpenable=no. Removing from available transports.\n");
29543       default_primary_transport &= ~SIP_TRANSPORT_TCP;
29544       default_transports &= ~SIP_TRANSPORT_TCP;
29545    }
29546    if (!default_tls_cfg.enabled && (default_transports & SIP_TRANSPORT_TLS)) {
29547       ast_log(LOG_WARNING, "Cannot use 'tls' transport with tlsenable=no. Removing from available transports.\n");
29548       default_primary_transport &= ~SIP_TRANSPORT_TLS;
29549       default_transports &= ~SIP_TRANSPORT_TLS;
29550    }
29551    if (!default_transports) {
29552       ast_log(LOG_WARNING, "No valid transports available, falling back to 'udp'.\n");
29553       default_transports = default_primary_transport = SIP_TRANSPORT_UDP;
29554    } else if (!default_primary_transport) {
29555       ast_log(LOG_WARNING, "No valid default transport. Selecting 'udp' as default.\n");
29556       default_primary_transport = SIP_TRANSPORT_UDP;
29557    }
29558 
29559    /* Build list of authentication to various SIP realms, i.e. service providers */
29560    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
29561       /* Format for authentication is auth = username:password@realm */
29562       if (!strcasecmp(v->name, "auth")) {
29563          add_realm_authentication(&authl, v->value, v->lineno);
29564       }
29565    }
29566 
29567    if (bindport) {
29568       if (ast_sockaddr_port(&bindaddr)) {
29569          ast_log(LOG_WARNING, "bindport is also specified in bindaddr. "
29570             "Using %d.\n", bindport);
29571       }
29572       ast_sockaddr_set_port(&bindaddr, bindport);
29573    }
29574 
29575    if (!ast_sockaddr_port(&bindaddr)) {
29576       ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT);
29577    }
29578 
29579    /* Set UDP address and open socket */
29580    ast_sockaddr_copy(&internip, &bindaddr);
29581    if (ast_find_ourip(&internip, &bindaddr, 0)) {
29582       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
29583       ast_config_destroy(cfg);
29584       return 0;
29585    }
29586 
29587    ast_mutex_lock(&netlock);
29588    if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) {
29589       close(sipsock);
29590       sipsock = -1;
29591    }
29592    if (sipsock < 0) {
29593       sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ?
29594              AF_INET6 : AF_INET, SOCK_DGRAM, 0);
29595       if (sipsock < 0) {
29596          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
29597          ast_config_destroy(cfg);
29598          ast_mutex_unlock(&netlock);
29599          return -1;
29600       } else {
29601          /* Allow SIP clients on the same host to access us: */
29602          const int reuseFlag = 1;
29603 
29604          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
29605                (const char*)&reuseFlag,
29606                sizeof reuseFlag);
29607 
29608          ast_enable_packet_fragmentation(sipsock);
29609 
29610          if (ast_bind(sipsock, &bindaddr) < 0) {
29611             ast_log(LOG_WARNING, "Failed to bind to %s: %s\n",
29612                ast_sockaddr_stringify(&bindaddr), strerror(errno));
29613             close(sipsock);
29614             sipsock = -1;
29615          } else {
29616             ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr));
29617             ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
29618          }
29619       }
29620    } else {
29621       ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
29622    }
29623    ast_mutex_unlock(&netlock);
29624 
29625    /* Start TCP server */
29626    if (sip_cfg.tcp_enabled) {
29627       if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) {
29628          ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr);
29629       }
29630       if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) {
29631          ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT);
29632       }
29633    } else {
29634       ast_sockaddr_setnull(&sip_tcp_desc.local_address);
29635    }
29636    ast_tcptls_server_start(&sip_tcp_desc);
29637    if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) {
29638       /* TCP server start failed. Tell the admin */
29639       ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n");
29640    } else {
29641       ast_debug(2, "SIP TCP server started\n");
29642    }
29643 
29644    /* Start TLS server if needed */
29645    memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg));
29646 
29647    if (ast_ssl_setup(sip_tls_desc.tls_cfg)) {
29648       if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) {
29649          ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr);
29650          ast_sockaddr_set_port(&sip_tls_desc.local_address,
29651                      STANDARD_TLS_PORT);
29652       }
29653       if (!ast_sockaddr_port(&sip_tls_desc.local_address)) {
29654          ast_sockaddr_set_port(&sip_tls_desc.local_address,
29655                      STANDARD_TLS_PORT);
29656       }
29657       ast_tcptls_server_start(&sip_tls_desc);
29658       if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) {
29659          ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n");
29660          sip_tls_desc.tls_cfg = NULL;
29661       }
29662    } else if (sip_tls_desc.tls_cfg->enabled) {
29663       sip_tls_desc.tls_cfg = NULL;
29664       ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n");
29665    }
29666 
29667    if (ucfg) {
29668       struct ast_variable *gen;
29669       int genhassip, genregistersip;
29670       const char *hassip, *registersip;
29671       
29672       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
29673       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
29674       gen = ast_variable_browse(ucfg, "general");
29675       cat = ast_category_browse(ucfg, NULL);
29676       while (cat) {
29677          if (strcasecmp(cat, "general")) {
29678             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
29679             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
29680             if (ast_true(hassip) || (!hassip && genhassip)) {
29681                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0);
29682                if (peer) {
29683                   /* user.conf entries are always of type friend */
29684                   peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
29685                   ao2_t_link(peers, peer, "link peer into peer table");
29686                   if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
29687                      ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
29688                   }
29689                   
29690                   unref_peer(peer, "unref_peer: from reload_config");
29691                   peer_count++;
29692                }
29693             }
29694             if (ast_true(registersip) || (!registersip && genregistersip)) {
29695                char tmp[256];
29696                const char *host = ast_variable_retrieve(ucfg, cat, "host");
29697                const char *username = ast_variable_retrieve(ucfg, cat, "username");
29698                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
29699                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
29700                const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser");
29701                if (!host) {
29702                   host = ast_variable_retrieve(ucfg, "general", "host");
29703                }
29704                if (!username) {
29705                   username = ast_variable_retrieve(ucfg, "general", "username");
29706                }
29707                if (!secret) {
29708                   secret = ast_variable_retrieve(ucfg, "general", "secret");
29709                }
29710                if (!contact) {
29711                   contact = "s";
29712                }
29713                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
29714                   if (!ast_strlen_zero(secret)) {
29715                      if (!ast_strlen_zero(authuser)) {
29716                         snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact);
29717                      } else {
29718                         snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact);
29719                      }
29720                   } else if (!ast_strlen_zero(authuser)) {
29721                      snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact);
29722                   } else {
29723                      snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact);
29724                   }
29725                   if (sip_register(tmp, 0) == 0) {
29726                      registry_count++;
29727                   }
29728                }
29729             }
29730          }
29731          cat = ast_category_browse(ucfg, cat);
29732       }
29733       ast_config_destroy(ucfg);
29734    }
29735 
29736    /* Load peers, users and friends */
29737    cat = NULL;
29738    while ( (cat = ast_category_browse(cfg, cat)) ) {
29739       const char *utype;
29740       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
29741          continue;
29742       utype = ast_variable_retrieve(cfg, cat, "type");
29743       if (!utype) {
29744          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
29745          continue;
29746       } else {
29747          if (!strcasecmp(utype, "user")) {
29748             ;
29749          } else if (!strcasecmp(utype, "friend")) {
29750             ;
29751          } else if (!strcasecmp(utype, "peer")) {
29752             ;
29753          } else {
29754             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
29755             continue;
29756          }
29757          peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
29758          if (peer) {
29759             display_nat_warning(cat, reason, &peer->flags[0]);
29760             ao2_t_link(peers, peer, "link peer into peers table");
29761             if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
29762                ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
29763             }
29764             unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
29765             peer_count++;
29766          }
29767       }
29768    }
29769 
29770    /* Add default domains - host name, IP address and IP:port
29771     * Only do this if user added any sip domain with "localdomains"
29772     * In order to *not* break backwards compatibility
29773     *    Some phones address us at IP only, some with additional port number
29774     */
29775    if (auto_sip_domains) {
29776       char temp[MAXHOSTNAMELEN];
29777 
29778       /* First our default IP address */
29779       if (!ast_sockaddr_isnull(&bindaddr) && !ast_sockaddr_is_any(&bindaddr)) {
29780          add_sip_domain(ast_sockaddr_stringify_addr(&bindaddr),
29781                    SIP_DOMAIN_AUTO, NULL);
29782       } else if (!ast_sockaddr_isnull(&internip) && !ast_sockaddr_is_any(&internip)) {
29783       /* Our internal IP address, if configured */
29784          add_sip_domain(ast_sockaddr_stringify_addr(&internip),
29785                    SIP_DOMAIN_AUTO, NULL);
29786       } else {
29787          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
29788       }
29789 
29790       /* If TCP is running on a different IP than UDP, then add it too */
29791       if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) &&
29792           !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) {
29793          add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address),
29794                    SIP_DOMAIN_AUTO, NULL);
29795       }
29796 
29797       /* If TLS is running on a different IP than UDP and TCP, then add that too */
29798       if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) &&
29799           !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) &&
29800           !ast_sockaddr_cmp(&sip_tcp_desc.local_address,
29801                   &sip_tls_desc.local_address)) {
29802          add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address),
29803                    SIP_DOMAIN_AUTO, NULL);
29804       }
29805 
29806       /* Our extern IP address, if configured */
29807       if (!ast_sockaddr_isnull(&externaddr)) {
29808          add_sip_domain(ast_sockaddr_stringify_addr(&externaddr),
29809                    SIP_DOMAIN_AUTO, NULL);
29810       }
29811 
29812       /* Extern host name (NAT traversal support) */
29813       if (!ast_strlen_zero(externhost)) {
29814          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
29815       }
29816       
29817       /* Our host name */
29818       if (!gethostname(temp, sizeof(temp))) {
29819          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
29820       }
29821    }
29822 
29823    /* Release configuration from memory */
29824    ast_config_destroy(cfg);
29825 
29826    /* Load the list of manual NOTIFY types to support */
29827    if (notify_types)
29828       ast_config_destroy(notify_types);
29829    if ((notify_types = ast_config_load(notify_config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
29830       ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config);
29831       notify_types = NULL;
29832    }
29833 
29834    /* Done, tell the manager */
29835    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);
29836    run_end = time(0);
29837    ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start));
29838 
29839    return 0;
29840 }

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

19849 {
19850    char tmp[512];
19851    char *c;
19852    char oldnonce[256];
19853 
19854    /* table of recognised keywords, and places where they should be copied */
19855    const struct x {
19856       const char *key;
19857       const ast_string_field *field;
19858    } *i, keys[] = {
19859       { "realm=", &p->realm },
19860       { "nonce=", &p->nonce },
19861       { "opaque=", &p->opaque },
19862       { "qop=", &p->qop },
19863       { "domain=", &p->domain },
19864       { NULL, 0 },
19865    };
19866 
19867    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
19868    if (ast_strlen_zero(tmp))
19869       return -1;
19870    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
19871       ast_log(LOG_WARNING, "missing Digest.\n");
19872       return -1;
19873    }
19874    c = tmp + strlen("Digest ");
19875    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
19876    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
19877       for (i = keys; i->key != NULL; i++) {
19878          char *src, *separator;
19879          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
19880             continue;
19881          /* Found. Skip keyword, take text in quotes or up to the separator. */
19882          c += strlen(i->key);
19883          if (*c == '"') {
19884             src = ++c;
19885             separator = "\"";
19886          } else {
19887             src = c;
19888             separator = ",";
19889          }
19890          strsep(&c, separator); /* clear separator and move ptr */
19891          ast_string_field_ptr_set(p, i->field, src);
19892          break;
19893       }
19894       if (i->key == NULL) /* not found, try ',' */
19895          strsep(&c, ",");
19896    }
19897    /* Reset nonce count */
19898    if (strcmp(p->nonce, oldnonce))
19899       p->noncecount = 0;
19900 
19901    /* Save auth data for following registrations */
19902    if (p->registry) {
19903       struct sip_registry *r = p->registry;
19904 
19905       if (strcmp(r->nonce, p->nonce)) {
19906          ast_string_field_set(r, realm, p->realm);
19907          ast_string_field_set(r, nonce, p->nonce);
19908          ast_string_field_set(r, authdomain, p->domain);
19909          ast_string_field_set(r, opaque, p->opaque);
19910          ast_string_field_set(r, qop, p->qop);
19911          r->noncecount = 0;
19912       }
19913    }
19914    return build_reply_digest(p, sipmethod, digest, digest_len);
19915 }

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

26694 {
26695    /* If we're supposed to be stopped -- stay stopped */
26696    if (monitor_thread == AST_PTHREADT_STOP)
26697       return 0;
26698    ast_mutex_lock(&monlock);
26699    if (monitor_thread == pthread_self()) {
26700       ast_mutex_unlock(&monlock);
26701       ast_log(LOG_WARNING, "Cannot kill myself\n");
26702       return -1;
26703    }
26704    if (monitor_thread != AST_PTHREADT_NULL) {
26705       /* Wake up the thread */
26706       pthread_kill(monitor_thread, SIGURG);
26707    } else {
26708       /* Start a new monitor */
26709       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
26710          ast_mutex_unlock(&monlock);
26711          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
26712          return -1;
26713       }
26714    }
26715    ast_mutex_unlock(&monlock);
26716    return 0;
26717 }

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

Session-Timers: Restart session timer.

Definition at line 26721 of file chan_sip.c.

References ast_debug, AST_SCHED_DEL_UNREF, start_session_timer(), and TRUE.

Referenced by handle_request_invite().

26722 {
26723    if (p->stimer->st_active == TRUE) {
26724       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
26725       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
26726             dialog_unref(p, "Removing session timer ref"));
26727       start_session_timer(p);
26728    }
26729 }

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

Retransmit SIP message if no answer (Called from scheduler).

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

03740 {
03741    struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
03742    int reschedule = DEFAULT_RETRANS;
03743    int xmitres = 0;
03744    /* how many ms until retrans timeout is reached */
03745    int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent);
03746 
03747    /* Do not retransmit if time out is reached. This will be negative if the time between
03748     * the first transmission and now is larger than our timeout period. This is a fail safe
03749     * check in case the scheduler gets behind or the clock is changed. */
03750    if ((diff <= 0) || (diff > pkt->retrans_stop_time)) {
03751       pkt->retrans_stop = 1;
03752    }
03753 
03754    /* Lock channel PVT */
03755    sip_pvt_lock(pkt->owner);
03756 
03757    if (!pkt->retrans_stop) {
03758       pkt->retrans++;
03759       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
03760          if (sipdebug) {
03761             ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n",
03762                pkt->retransid,
03763                sip_methods[pkt->method].text,
03764                pkt->method);
03765          }
03766       } else {
03767          int siptimer_a;
03768 
03769          if (sipdebug) {
03770             ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n",
03771                pkt->retransid,
03772                pkt->retrans,
03773                sip_methods[pkt->method].text,
03774                pkt->method);
03775          }
03776          if (!pkt->timer_a) {
03777             pkt->timer_a = 2 ;
03778          } else {
03779             pkt->timer_a = 2 * pkt->timer_a;
03780          }
03781 
03782          /* For non-invites, a maximum of 4 secs */
03783          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
03784          if (pkt->method != SIP_INVITE && siptimer_a > 4000) {
03785             siptimer_a = 4000;
03786          }
03787 
03788          /* Reschedule re-transmit */
03789          reschedule = siptimer_a;
03790          ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n",
03791             pkt->retrans + 1,
03792             siptimer_a,
03793             pkt->timer_t1,
03794             pkt->retransid);
03795       }
03796 
03797       if (sip_debug_test_pvt(pkt->owner)) {
03798          const struct ast_sockaddr *dst = sip_real_dst(pkt->owner);
03799          ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n",
03800             pkt->retrans, sip_nat_mode(pkt->owner),
03801             ast_sockaddr_stringify(dst),
03802             ast_str_buffer(pkt->data));
03803       }
03804 
03805       append_history(pkt->owner, "ReTx", "%d %s", reschedule, ast_str_buffer(pkt->data));
03806       xmitres = __sip_xmit(pkt->owner, pkt->data);
03807 
03808       /* If there was no error during the network transmission, schedule the next retransmission,
03809        * but if the next retransmission is going to be beyond our timeout period, mark the packet's
03810        * stop_retrans value and set the next retransmit to be the exact time of timeout.  This will
03811        * allow any responses to the packet to be processed before the packet is destroyed on the next
03812        * call to this function by the scheduler. */
03813       if (xmitres != XMIT_ERROR) {
03814          if (reschedule >= diff) {
03815             pkt->retrans_stop = 1;
03816             reschedule = diff;
03817          }
03818          sip_pvt_unlock(pkt->owner);
03819          return  reschedule;
03820       }
03821    }
03822 
03823    /* At this point, either the packet's retransmission timed out, or there was a
03824     * transmission error, either way destroy the scheduler item and this packet. */
03825 
03826    pkt->retransid = -1; /* Kill this scheduler item */
03827 
03828    if (pkt->method != SIP_OPTIONS && xmitres == 0) {
03829       if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */
03830          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"
03831             "Packet timed out after %dms with no response\n",
03832             pkt->owner->callid,
03833             pkt->seqno,
03834             pkt->is_fatal ? "Critical" : "Non-critical",
03835             pkt->is_resp ? "Response" : "Request",
03836             (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent));
03837       }
03838    } else if (pkt->method == SIP_OPTIONS && sipdebug) {
03839       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);
03840    }
03841 
03842    if (xmitres == XMIT_ERROR) {
03843       ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid);
03844       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03845    } else {
03846       append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03847    }
03848 
03849    if (pkt->is_fatal) {
03850       while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
03851          sip_pvt_unlock(pkt->owner);   /* SIP_PVT, not channel */
03852          usleep(1);
03853          sip_pvt_lock(pkt->owner);
03854       }
03855       if (pkt->owner->owner && !pkt->owner->owner->hangupcause) {
03856          pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
03857       }
03858       if (pkt->owner->owner) {
03859          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);
03860 
03861          if (pkt->is_resp &&
03862             (pkt->response_code >= 200) &&
03863             (pkt->response_code < 300) &&
03864             pkt->owner->pendinginvite &&
03865             ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
03866             /* This is a timeout of the 2XX response to a pending INVITE.  In this case terminate the INVITE
03867              * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup
03868              * will send the BYE as long as the dialog is not set as "alreadygone")
03869              * RFC 3261 section 13.3.1.4.
03870              * "If the server retransmits the 2xx response for 64*T1 seconds without receiving
03871              * an ACK, the dialog is confirmed, but the session SHOULD be terminated.  This is
03872              * accomplished with a BYE, as described in Section 15." */
03873             pkt->owner->invitestate = INV_TERMINATED;
03874             pkt->owner->pendinginvite = 0;
03875          } else {
03876             /* there is nothing left to do, mark the dialog as gone */
03877             sip_alreadygone(pkt->owner);
03878          }
03879          ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_NO_USER_RESPONSE);
03880          ast_channel_unlock(pkt->owner->owner);
03881       } else {
03882          /* If no channel owner, destroy now */
03883 
03884          /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
03885          if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) {
03886             pvt_set_needdestroy(pkt->owner, "no response to critical packet");
03887             sip_alreadygone(pkt->owner);
03888             append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
03889          }
03890       }
03891    }
03892 
03893    if (pkt->method == SIP_BYE) {
03894       /* We're not getting answers on SIP BYE's.  Tear down the call anyway. */
03895       sip_alreadygone(pkt->owner);
03896       if (pkt->owner->owner) {
03897          ast_channel_unlock(pkt->owner->owner);
03898       }
03899       append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
03900       pvt_set_needdestroy(pkt->owner, "no response to BYE");
03901    }
03902 
03903    /* Remove the packet */
03904    for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
03905       if (cur == pkt) {
03906          UNLINK(cur, pkt->owner->packets, prev);
03907          sip_pvt_unlock(pkt->owner);
03908          if (pkt->owner) {
03909             pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03910          }
03911          if (pkt->data) {
03912             ast_free(pkt->data);
03913          }
03914          pkt->data = NULL;
03915          ast_free(pkt);
03916          return 0;
03917       }
03918    }
03919    /* error case */
03920    ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
03921    sip_pvt_unlock(pkt->owner);
03922    return 0;
03923 }

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

Definition at line 4331 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

04331                                                         {
04332    struct sip_pvt *pvt = (struct sip_pvt *) data;
04333 
04334    return send_provisional_keepalive_full(pvt, 0);
04335 }

static int send_provisional_keepalive_full ( struct sip_pvt *  pvt,
int  with_sdp 
) [static]

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

04282 {
04283    const char *msg = NULL;
04284    struct ast_channel *chan;
04285    int res = 0;
04286    int old_sched_id = pvt->provisional_keepalive_sched_id;
04287 
04288    chan = sip_pvt_lock_full(pvt);
04289    /* Check that nothing has changed while we were waiting for the lock */
04290    if (old_sched_id != pvt->provisional_keepalive_sched_id) {
04291       /* Keepalive has been cancelled or rescheduled, clean up and leave */
04292       if (chan) {
04293          ast_channel_unlock(chan);
04294          chan = ast_channel_unref(chan);
04295       }
04296       sip_pvt_unlock(pvt);
04297       dialog_unref(pvt, "dialog ref for provisional keepalive");
04298       return 0;
04299    }
04300 
04301    if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) {
04302       msg = "183 Session Progress";
04303    }
04304 
04305    if (pvt->invitestate < INV_COMPLETED) {
04306       if (with_sdp) {
04307          transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE);
04308       } else {
04309          transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq);
04310       }
04311       res = PROVIS_KEEPALIVE_TIMEOUT;
04312    }
04313 
04314    if (chan) {
04315       ast_channel_unlock(chan);
04316       chan = ast_channel_unref(chan);
04317    }
04318 
04319    if (!res) {
04320       pvt->provisional_keepalive_sched_id = -1;
04321    }
04322 
04323    sip_pvt_unlock(pvt);
04324 
04325    if (!res) {
04326       dialog_unref(pvt, "dialog ref for provisional keepalive");
04327    }
04328    return res;
04329 }

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

Definition at line 4337 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

04337                                                                  {
04338    struct sip_pvt *pvt = (void *)data;
04339 
04340    return send_provisional_keepalive_full(pvt, 1);
04341 }

static int send_request ( struct sip_pvt *  p,
struct sip_request *  req,
enum xmittype  reliable,
uint32_t  seqno 
) [static]

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

04423 {
04424    int res;
04425 
04426    /* If we have an outbound proxy, reset peer address
04427       Only do this once.
04428    */
04429    if (p->outboundproxy) {
04430       p->sa = p->outboundproxy->ip;
04431    }
04432 
04433    finalize_content(req);
04434    add_blank(req);
04435    if (sip_debug_test_pvt(p)) {
04436       if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) {
04437          ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), ast_str_buffer(req->data));
04438       } else {
04439          ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), ast_str_buffer(req->data));
04440       }
04441    }
04442    if (p->do_history) {
04443       struct sip_request tmp = { .rlPart1 = 0, };
04444       parse_copy(&tmp, req);
04445       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
04446       deinit_req(&tmp);
04447    }
04448    res = (reliable) ?
04449       __sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) :
04450       __sip_xmit(p, req->data);
04451    deinit_req(req);
04452    return res;
04453 }

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

04381 {
04382    int res;
04383 
04384    finalize_content(req);
04385    add_blank(req);
04386    if (sip_debug_test_pvt(p)) {
04387       const struct ast_sockaddr *dst = sip_real_dst(p);
04388 
04389       ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n",
04390          reliable ? "Reliably " : "", sip_nat_mode(p),
04391          ast_sockaddr_stringify(dst),
04392          ast_str_buffer(req->data));
04393    }
04394    if (p->do_history) {
04395       struct sip_request tmp = { .rlPart1 = 0, };
04396       parse_copy(&tmp, req);
04397       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"),
04398          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text);
04399       deinit_req(&tmp);
04400    }
04401 
04402    /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */
04403    if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) {
04404       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"));
04405    }
04406 
04407    res = (reliable) ?
04408        __sip_reliable_xmit(p, seqno, 1, req->data, (reliable == XMIT_CRITICAL), req->method) :
04409       __sip_xmit(p, req->data);
04410    deinit_req(req);
04411    if (res > 0) {
04412       return 0;
04413    }
04414    return res;
04415 }

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

References __set_address_from_contact(), and ast_test_flag.

Referenced by handle_response_invite().

14449 {
14450    if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) {
14451       /* NAT: Don't trust the contact field.  Just use what they came to us
14452          with. */
14453       /*! \todo We need to save the TRANSPORT here too */
14454       pvt->sa = pvt->recv;
14455       return 0;
14456    }
14457 
14458    return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
14459 }

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

27486 {
27487    if (ast_strlen_zero(value))
27488       return;
27489 
27490    if (!ast_false(value)) {
27491       char buf[64];
27492       char *word, *next;
27493 
27494       ast_copy_string(buf, value, sizeof(buf));
27495       next = buf;
27496       while ((word = strsep(&next, ","))) {
27497          if (!strcasecmp(word, "port"))
27498             ast_set_flag(&flags[0], SIP_INSECURE_PORT);
27499          else if (!strcasecmp(word, "invite"))
27500             ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
27501          else
27502             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
27503       }
27504    }
27505 }

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

14823 {
14824    if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) {
14825       ast_string_field_build(p, randdata, "%08lx", (unsigned long)ast_random()); /* Create nonce for challenge */
14826       p->stalenonce = 0;
14827    }
14828 }

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

Set peer defaults before configuring specific configurations.

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

27920 {
27921    if (peer->expire == 0) {
27922       /* Don't reset expire or port time during reload
27923          if we have an active registration
27924       */
27925       peer->expire = -1;
27926       peer->pokeexpire = -1;
27927       set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP);
27928    }
27929    peer->type = SIP_TYPE_PEER;
27930    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
27931    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
27932    ast_copy_flags(&peer->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY);
27933    ast_string_field_set(peer, context, sip_cfg.default_context);
27934    ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext);
27935    ast_string_field_set(peer, language, default_language);
27936    ast_string_field_set(peer, mohinterpret, default_mohinterpret);
27937    ast_string_field_set(peer, mohsuggest, default_mohsuggest);
27938    ast_string_field_set(peer, engine, default_engine);
27939    ast_sockaddr_setnull(&peer->addr);
27940    ast_sockaddr_setnull(&peer->defaddr);
27941    peer->capability = sip_cfg.capability;
27942    peer->maxcallbitrate = default_maxcallbitrate;
27943    peer->rtptimeout = global_rtptimeout;
27944    peer->rtpholdtimeout = global_rtpholdtimeout;
27945    peer->rtpkeepalive = global_rtpkeepalive;
27946    peer->allowtransfer = sip_cfg.allowtransfer;
27947    peer->autoframing = global_autoframing;
27948    peer->t38_maxdatagram = global_t38_maxdatagram;
27949    peer->qualifyfreq = global_qualifyfreq;
27950    if (global_callcounter)
27951       peer->call_limit=INT_MAX;
27952    ast_string_field_set(peer, vmexten, default_vmexten);
27953    ast_string_field_set(peer, secret, "");
27954    ast_string_field_set(peer, remotesecret, "");
27955    ast_string_field_set(peer, md5secret, "");
27956    ast_string_field_set(peer, cid_num, "");
27957    ast_string_field_set(peer, cid_name, "");
27958    ast_string_field_set(peer, cid_tag, "");
27959    ast_string_field_set(peer, fromdomain, "");
27960    ast_string_field_set(peer, fromuser, "");
27961    ast_string_field_set(peer, regexten, "");
27962    peer->callgroup = 0;
27963    peer->pickupgroup = 0;
27964    peer->maxms = default_qualify;
27965    peer->prefs = default_prefs;
27966    peer->stimer.st_mode_oper = global_st_mode;  /* Session-Timers */
27967    peer->stimer.st_ref = global_st_refresher;
27968    peer->stimer.st_min_se = global_min_se;
27969    peer->stimer.st_max_se = global_max_se;
27970    peer->timer_t1 = global_t1;
27971    peer->timer_b = global_timer_b;
27972    clear_peer_mailboxes(peer);
27973    peer->disallowed_methods = sip_cfg.disallowed_methods;
27974    peer->transports = default_transports;
27975    peer->default_outbound_transport = default_primary_transport;
27976    if (peer->outboundproxy) {
27977       ao2_ref(peer->outboundproxy, -1);
27978       peer->outboundproxy = NULL;
27979    }
27980 }

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

05391 {
05392    if (p->udptl) {
05393       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY) {
05394                         ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
05395       } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_FEC) {
05396          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
05397       } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL) {
05398          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
05399       }
05400    }
05401 }

static int setup_srtp ( struct sip_srtp **  srtp  )  [static]

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

30524 {
30525    if (!ast_rtp_engine_srtp_is_registered()) {
30526       ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n");
30527       return -1;
30528    }
30529 
30530    if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */
30531       return -1;
30532    }
30533 
30534    return 0;
30535 }

static int show_channels_cb ( void *  __cur,
void *  __arg,
int  flags 
) [static]

callback for show channel|subscription

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

18983 {
18984    struct sip_pvt *cur = __cur;
18985    struct __show_chan_arg *arg = __arg;
18986    const struct ast_sockaddr *dst;
18987 
18988    sip_pvt_lock(cur);
18989    dst = sip_real_dst(cur);
18990 
18991    /* XXX indentation preserved to reduce diff. Will be fixed later */
18992    if (cur->subscribed == NONE && !arg->subscriptions) {
18993       /* set if SIP transfer in progress */
18994       const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : "";
18995       char formatbuf[SIPBUFSIZE/2];
18996       
18997       ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst),
18998             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
18999             cur->callid,
19000             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
19001             AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)),
19002             cur->needdestroy ? "(d)" : "",
19003             cur->lastmsg ,
19004             referstatus,
19005             cur->relatedpeer ? cur->relatedpeer->name : "<guest>"
19006          );
19007       arg->numchans++;
19008    }
19009    if (cur->subscribed != NONE && arg->subscriptions) {
19010       struct ast_str *mailbox_str = ast_str_alloca(512);
19011       if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer)
19012          peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer);
19013       ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst),
19014             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
19015                cur->callid,
19016             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
19017             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
19018             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate),
19019             subscription_type2str(cur->subscribed),
19020             cur->subscribed == MWI_NOTIFICATION ? S_OR(ast_str_buffer(mailbox_str), "<none>") : "<none>",
19021             cur->expiry
19022          );
19023       arg->numchans++;
19024    }
19025    sip_pvt_unlock(cur);
19026    return 0;   /* don't care, we scan all channels */
19027 }

static int show_chanstats_cb ( void *  __cur,
void *  __arg,
int  flags 
) [static]

Callback for show_chanstats.

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

18585 {
18586 #define FORMAT2 "%-15.15s  %-11.11s  %-8.8s %-10.10s  %-10.10s (     %%) %-6.6s %-10.10s  %-10.10s (     %%) %-6.6s\n"
18587 #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"
18588    struct sip_pvt *cur = __cur;
18589    struct ast_rtp_instance_stats stats;
18590    char durbuf[10];
18591    int duration;
18592    int durh, durm, durs;
18593    struct ast_channel *c;
18594    struct __show_chan_arg *arg = __arg;
18595    int fd = arg->fd;
18596 
18597    sip_pvt_lock(cur);
18598    c = cur->owner;
18599 
18600    if (cur->subscribed != NONE) {
18601       /* Subscriptions */
18602       sip_pvt_unlock(cur);
18603       return 0;   /* don't care, we scan all channels */
18604    }
18605 
18606    if (!cur->rtp) {
18607       if (sipdebug) {
18608          ast_cli(fd, "%-15.15s  %-11.11s (inv state: %s) -- %s\n",
18609             ast_sockaddr_stringify_addr(&cur->sa), cur->callid,
18610             invitestate2string[cur->invitestate].desc,
18611             "-- No RTP active");
18612       }
18613       sip_pvt_unlock(cur);
18614       return 0;   /* don't care, we scan all channels */
18615    }
18616 
18617    if (ast_rtp_instance_get_stats(cur->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) {
18618       sip_pvt_unlock(cur);
18619       ast_log(LOG_WARNING, "Could not get RTP stats.\n");
18620       return 0;
18621    }
18622 
18623    if (c && c->cdr && !ast_tvzero(c->cdr->start)) {
18624       duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
18625       durh = duration / 3600;
18626       durm = (duration % 3600) / 60;
18627       durs = duration % 60;
18628       snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
18629    } else {
18630       durbuf[0] = '\0';
18631    }
18632 
18633    ast_cli(fd, FORMAT,
18634       ast_sockaddr_stringify_addr(&cur->sa),
18635       cur->callid,
18636       durbuf,
18637       stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount,
18638       stats.rxcount > (unsigned int) 100000 ? "K":" ",
18639       stats.rxploss,
18640       (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0,
18641       stats.rxjitter,
18642       stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount,
18643       stats.txcount > (unsigned int) 100000 ? "K":" ",
18644       stats.txploss,
18645       stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0,
18646       stats.txjitter
18647    );
18648    arg->numchans++;
18649    sip_pvt_unlock(cur);
18650 
18651    return 0;   /* don't care, we scan all channels */
18652 }

static int sip_addheader ( struct ast_channel chan,
const char *  data 
) [static]

Add a SIP header to an outbound INVITE.

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

30311 {
30312    int no = 0;
30313    int ok = FALSE;
30314    char varbuf[30];
30315    const char *inbuf = data;
30316    char *subbuf;
30317    
30318    if (ast_strlen_zero(inbuf)) {
30319       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
30320       return 0;
30321    }
30322    ast_channel_lock(chan);
30323 
30324    /* Check for headers */
30325    while (!ok && no <= 50) {
30326       no++;
30327       snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no);
30328 
30329       /* Compare without the leading underscores */
30330       if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) {
30331          ok = TRUE;
30332       }
30333    }
30334    if (ok) {
30335       size_t len = strlen(inbuf);
30336       subbuf = ast_alloca(len + 1);
30337       ast_get_encoded_str(inbuf, subbuf, len + 1);
30338       pbx_builtin_setvar_helper(chan, varbuf, subbuf);
30339       if (sipdebug) {
30340          ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf);
30341       }
30342    } else {
30343       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
30344    }
30345    ast_channel_unlock(chan);
30346    return 0;
30347 }

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

03223 {
03224    ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
03225    dialog->alreadygone = 1;
03226 }

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

05764 {
05765    int res;
05766    struct sip_pvt *p = ast->tech_pvt;  /* chan is locked, so the reference cannot go away */
05767    struct varshead *headp;
05768    struct ast_var_t *current;
05769    const char *referer = NULL;   /* SIP referrer */
05770    int cc_core_id;
05771    char uri[SIPBUFSIZE] = "";
05772 
05773    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
05774       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
05775       return -1;
05776    }
05777 
05778    if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) {
05779       char device_name[AST_CHANNEL_NAME];
05780       struct ast_cc_monitor *recall_monitor;
05781       struct sip_monitor_instance *monitor_instance;
05782       ast_channel_get_device_name(ast, device_name, sizeof(device_name));
05783       if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) {
05784          monitor_instance = recall_monitor->private_data;
05785          ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri));
05786          ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor");
05787       }
05788    }
05789 
05790    /* Check whether there is vxml_url, distinctive ring variables */
05791    headp=&ast->varshead;
05792    AST_LIST_TRAVERSE(headp, current, entries) {
05793       /* Check whether there is a VXML_URL variable */
05794       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
05795          p->options->vxml_url = ast_var_value(current);
05796       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
05797          p->options->uri_options = ast_var_value(current);
05798       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
05799          /* Check whether there is a variable with a name starting with SIPADDHEADER */
05800          p->options->addsipheaders = 1;
05801       } else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) {
05802          ast_string_field_set(p, fromdomain, ast_var_value(current));
05803       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
05804          /* This is a transferred call */
05805          p->options->transfer = 1;
05806       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
05807          /* This is the referrer */
05808          referer = ast_var_value(current);
05809       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
05810          /* We're replacing a call. */
05811          p->options->replaces = ast_var_value(current);
05812       } else if (!strcasecmp(ast_var_name(current), "SIP_MAX_FORWARDS")) {
05813          if (sscanf(ast_var_value(current), "%d", &(p->maxforwards)) != 1) {
05814             ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer.\n");
05815          }
05816       }
05817    }
05818 
05819    /* Check to see if we should try to force encryption */
05820    if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) {
05821       ast_log(LOG_WARNING, "Encrypted signaling is required\n");
05822       ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05823       return -1;
05824    }
05825 
05826    if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
05827       if (ast_test_flag(&p->flags[0], SIP_REINVITE)) {
05828          ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n");
05829          ast_clear_flag(&p->flags[0], SIP_REINVITE);
05830       }
05831 
05832       if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) {
05833          ast_log(LOG_WARNING, "SRTP audio setup failed\n");
05834          return -1;
05835       }
05836 
05837       if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) {
05838          ast_log(LOG_WARNING, "SRTP video setup failed\n");
05839          return -1;
05840       }
05841 
05842       if (p->trtp && !p->tsrtp && setup_srtp(&p->tsrtp) < 0) {
05843          ast_log(LOG_WARNING, "SRTP text setup failed\n");
05844          return -1;
05845       }
05846    }
05847 
05848    res = 0;
05849    ast_set_flag(&p->flags[0], SIP_OUTGOING);
05850 
05851    /* T.38 re-INVITE FAX detection should never be done for outgoing calls,
05852     * so ensure it is disabled.
05853     */
05854    ast_clear_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38);
05855 
05856    if (p->options->transfer) {
05857       char buf[SIPBUFSIZE/2];
05858 
05859       if (referer) {
05860          if (sipdebug)
05861             ast_debug(3, "Call for %s transferred by %s\n", p->username, referer);
05862          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
05863       } else
05864          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
05865       ast_string_field_set(p, cid_name, buf);
05866    }
05867    ast_debug(1, "Outgoing Call for %s\n", p->username);
05868 
05869    res = update_call_counter(p, INC_CALL_RINGING);
05870 
05871    if (res == -1) {
05872       ast->hangupcause = AST_CAUSE_USER_BUSY;
05873       return res;
05874    }
05875    p->callingpres = ast_party_id_presentation(&ast->caller.id);
05876    p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec);
05877    p->jointnoncodeccapability = p->noncodeccapability;
05878 
05879    /* If there are no audio formats left to offer, punt */
05880    if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
05881       ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
05882       res = -1;
05883    } else {
05884       int xmitres;
05885       struct ast_party_connected_line connected;
05886       struct ast_set_party_connected_line update_connected;
05887 
05888       sip_pvt_lock(p);
05889 
05890       /* Supply initial connected line information if available. */
05891       memset(&update_connected, 0, sizeof(update_connected));
05892       ast_party_connected_line_init(&connected);
05893       if (!ast_strlen_zero(p->cid_num)
05894          || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
05895          update_connected.id.number = 1;
05896          connected.id.number.valid = 1;
05897          connected.id.number.str = (char *) p->cid_num;
05898          connected.id.number.presentation = p->callingpres;
05899       }
05900       if (!ast_strlen_zero(p->cid_name)
05901          || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
05902          update_connected.id.name = 1;
05903          connected.id.name.valid = 1;
05904          connected.id.name.str = (char *) p->cid_name;
05905          connected.id.name.presentation = p->callingpres;
05906       }
05907       if (update_connected.id.number || update_connected.id.name) {
05908          connected.id.tag = (char *) p->cid_tag;
05909          connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
05910          ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
05911       }
05912 
05913       xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri);
05914       if (xmitres == XMIT_ERROR) {
05915          sip_pvt_unlock(p);
05916          return -1;
05917       }
05918       p->invitestate = INV_CALLING;
05919 
05920       /* Initialize auto-congest time */
05921       AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p,
05922                         dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"),
05923                         dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
05924                         dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
05925       sip_pvt_unlock(p);
05926    }
05927    return res;
05928 }

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

04144 {
04145    if (p->final_destruction_scheduled) {
04146       return 0;
04147    }
04148 
04149    if (p->autokillid > -1) {
04150       append_history(p, "CancelDestroy", "");
04151       AST_SCHED_DEL_UNREF(sched, p->autokillid, dialog_unref(p, "remove ref for autokillid"));
04152    }
04153    return 0;
04154 }

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

19681 {
19682    struct ast_variable *varlist;
19683    int i;
19684 
19685    switch (cmd) {
19686    case CLI_INIT:
19687       e->command = "sip notify";
19688       e->usage =
19689          "Usage: sip notify <type> <peer> [<peer>...]\n"
19690          "       Send a NOTIFY message to a SIP peer or peers\n"
19691          "       Message types are defined in sip_notify.conf\n";
19692       return NULL;
19693    case CLI_GENERATE:
19694       return complete_sipnotify(a->line, a->word, a->pos, a->n);
19695    }
19696 
19697    if (a->argc < 4)
19698       return CLI_SHOWUSAGE;
19699 
19700    if (!notify_types) {
19701       ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config);
19702       return CLI_FAILURE;
19703    }
19704 
19705    varlist = ast_variable_browse(notify_types, a->argv[2]);
19706 
19707    if (!varlist) {
19708       ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]);
19709       return CLI_FAILURE;
19710    }
19711 
19712    for (i = 3; i < a->argc; i++) {
19713       struct sip_pvt *p;
19714       char buf[512];
19715       struct ast_variable *header, *var;
19716 
19717       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
19718          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
19719          return CLI_FAILURE;
19720       }
19721 
19722       if (create_addr(p, a->argv[i], NULL, 1)) {
19723          /* Maybe they're not registered, etc. */
19724          dialog_unlink_all(p);
19725          dialog_unref(p, "unref dialog inside for loop" );
19726          /* sip_destroy(p); */
19727          ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]);
19728          continue;
19729       }
19730 
19731       /* Notify is outgoing call */
19732       ast_set_flag(&p->flags[0], SIP_OUTGOING);
19733       sip_notify_allocate(p);
19734       p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
19735 
19736       for (var = varlist; var; var = var->next) {
19737          ast_copy_string(buf, var->value, sizeof(buf));
19738          ast_unescape_semicolon(buf);
19739 
19740          if (!strcasecmp(var->name, "Content")) {
19741             if (ast_str_strlen(p->notify->content))
19742                ast_str_append(&p->notify->content, 0, "\r\n");
19743             ast_str_append(&p->notify->content, 0, "%s", buf);
19744          } else if (!strcasecmp(var->name, "Content-Length")) {
19745             ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring\n");
19746          } else {
19747             header->next = ast_variable_new(var->name, buf, "");
19748             header = header->next;
19749          }
19750       }
19751 
19752       /* Now that we have the peer's address, set our ip and change callid */
19753       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
19754       build_via(p);
19755 
19756       change_callid_pvt(p, NULL);
19757 
19758       ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]);
19759       sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
19760       transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
19761       dialog_unref(p, "bump down the count of p since we're done with it.");
19762    }
19763 
19764    return CLI_SUCCESS;
19765 }

static int sip_debug_test_addr ( const struct ast_sockaddr addr  )  [inline, static]

See if we pass debug IP filter.

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

03373 {
03374    /* Can't debug if sipdebug is not enabled */
03375    if (!sipdebug) {
03376       return 0;
03377    }
03378 
03379    /* A null debug_addr means we'll debug any address */
03380    if (ast_sockaddr_isnull(&debugaddr)) {
03381       return 1;
03382    }
03383 
03384    /* If no port was specified for a debug address, just compare the
03385     * addresses, otherwise compare the address and port
03386     */
03387    if (ast_sockaddr_port(&debugaddr)) {
03388       return !ast_sockaddr_cmp(&debugaddr, addr);
03389    } else {
03390       return !ast_sockaddr_cmp_addr(&debugaddr, addr);
03391    }
03392 }

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

04829 {
04830    ast_debug(3, "Destroying SIP peer %s\n", peer->name);
04831 
04832    /*
04833     * Remove any mailbox event subscriptions for this peer before
04834     * we destroy anything.  An event subscription callback may be
04835     * happening right now.
04836     */
04837    clear_peer_mailboxes(peer);
04838 
04839    if (peer->outboundproxy) {
04840       ao2_ref(peer->outboundproxy, -1);
04841       peer->outboundproxy = NULL;
04842    }
04843 
04844    /* Delete it, it needs to disappear */
04845    if (peer->call) {
04846       dialog_unlink_all(peer->call);
04847       peer->call = dialog_unref(peer->call, "peer->call is being unset");
04848    }
04849 
04850    if (peer->mwipvt) {  /* We have an active subscription, delete it */
04851       dialog_unlink_all(peer->mwipvt);
04852       peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt");
04853    }
04854    
04855    if (peer->chanvars) {
04856       ast_variables_destroy(peer->chanvars);
04857       peer->chanvars = NULL;
04858    }
04859    
04860    register_peer_exten(peer, FALSE);
04861    ast_free_ha(peer->ha);
04862    ast_free_ha(peer->directmediaha);
04863    if (peer->selfdestruct)
04864       ast_atomic_fetchadd_int(&apeerobjs, -1);
04865    else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->is_realtime) {
04866       ast_atomic_fetchadd_int(&rpeerobjs, -1);
04867       ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs);
04868    } else
04869       ast_atomic_fetchadd_int(&speerobjs, -1);
04870    if (peer->auth) {
04871       ao2_t_ref(peer->auth, -1, "Removing peer authentication");
04872       peer->auth = NULL;
04873    }
04874 
04875    if (peer->socket.tcptls_session) {
04876       ao2_ref(peer->socket.tcptls_session, -1);
04877       peer->socket.tcptls_session = NULL;
04878    }
04879 
04880    ast_cc_config_params_destroy(peer->cc_params);
04881 
04882    ast_string_field_free_memory(peer);
04883 }

static void sip_destroy_peer_fn ( void *  peer  )  [static]

Definition at line 4822 of file chan_sip.c.

References sip_destroy_peer().

Referenced by build_peer(), and temp_peer().

04823 {
04824    sip_destroy_peer(peer);
04825 }

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

27210 {
27211    char *host;
27212    char *tmp;
27213    struct sip_peer *p;
27214 
27215    int res = AST_DEVICE_INVALID;
27216 
27217    /* make sure data is not null. Maybe unnecessary, but better be safe */
27218    host = ast_strdupa(data ? data : "");
27219    if ((tmp = strchr(host, '@')))
27220       host = tmp + 1;
27221 
27222    ast_debug(3, "Checking device state for peer %s\n", host);
27223 
27224    /* If find_peer asks for a realtime peer, then this breaks rtautoclear.  This
27225     * is because when a peer tries to autoexpire, the last thing it does is to
27226     * queue up an event telling the system that the devicestate has changed
27227     * (presumably to unavailable).  If we ask for a realtime peer here, this would
27228     * load it BACK into memory, thus defeating the point of trying to clear dead
27229     * hosts out of memory.
27230     */
27231    if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) {
27232       if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) {
27233          /* we have an address for the peer */
27234       
27235          /* Check status in this order
27236             - Hold
27237             - Ringing
27238             - Busy (enforced only by call limit)
27239             - Inuse (we have a call)
27240             - Unreachable (qualify)
27241             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
27242             for registered devices */
27243 
27244          if (p->onHold)
27245             /* First check for hold or ring states */
27246             res = AST_DEVICE_ONHOLD;
27247          else if (p->inRinging) {
27248             if (p->inRinging == p->inUse)
27249                res = AST_DEVICE_RINGING;
27250             else
27251                res = AST_DEVICE_RINGINUSE;
27252          } else if (p->call_limit && (p->inUse == p->call_limit))
27253             /* check call limit */
27254             res = AST_DEVICE_BUSY;
27255          else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level)
27256             /* We're forcing busy before we've reached the call limit */
27257             res = AST_DEVICE_BUSY;
27258          else if (p->call_limit && p->inUse)
27259             /* Not busy, but we do have a call */
27260             res = AST_DEVICE_INUSE;
27261          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0)))
27262             /* We don't have a call. Are we reachable at all? Requires qualify= */
27263             res = AST_DEVICE_UNAVAILABLE;
27264          else  /* Default reply if we're registered and have no other data */
27265             res = AST_DEVICE_NOT_INUSE;
27266       } else {
27267          /* there is no address, it's unavailable */
27268          res = AST_DEVICE_UNAVAILABLE;
27269       }
27270       unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer");
27271    }
27272 
27273    return res;
27274 }

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

19638 {
19639    int oldsipdebug = sipdebug & sip_debug_console;
19640    const char *what;
19641 
19642    if (cmd == CLI_INIT) {
19643       e->command = "sip set debug {on|off|ip|peer}";
19644       e->usage =
19645          "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n"
19646          "       Globally disables dumping of SIP packets,\n"
19647          "       or enables it either globally or for a (single)\n"
19648          "       IP address or registered peer.\n";
19649       return NULL;
19650    } else if (cmd == CLI_GENERATE) {
19651       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
19652          return complete_sip_peer(a->word, a->n, 0);
19653       return NULL;
19654         }
19655 
19656    what = a->argv[e->args-1];      /* guaranteed to exist */
19657    if (a->argc == e->args) {       /* on/off */
19658       if (!strcasecmp(what, "on")) {
19659          sipdebug |= sip_debug_console;
19660          sipdebug_text = 1;   /*! \note this can be a special debug command - "sip debug text" or something */
19661          memset(&debugaddr, 0, sizeof(debugaddr));
19662          ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
19663          return CLI_SUCCESS;
19664       } else if (!strcasecmp(what, "off")) {
19665          sipdebug &= ~sip_debug_console;
19666          sipdebug_text = 0;
19667          ast_cli(a->fd, "SIP Debugging Disabled\n");
19668          return CLI_SUCCESS;
19669       }
19670    } else if (a->argc == e->args +1) {/* ip/peer */
19671       if (!strcasecmp(what, "ip"))
19672          return sip_do_debug_ip(a->fd, a->argv[e->args]);
19673       else if (!strcasecmp(what, "peer"))
19674          return sip_do_debug_peer(a->fd, a->argv[e->args]);
19675    }
19676    return CLI_SHOWUSAGE;   /* default, failure */
19677 }

static char * sip_do_debug_ip ( int  fd,
const char *  arg 
) [static]

Enable SIP Debugging for a single IP.

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

19607 {
19608    if (ast_sockaddr_resolve_first_af(&debugaddr, arg, 0, 0)) {
19609       return CLI_SHOWUSAGE;
19610    }
19611 
19612    ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
19613    sipdebug |= sip_debug_console;
19614 
19615    return CLI_SUCCESS;
19616 }

static char * sip_do_debug_peer ( int  fd,
const char *  arg 
) [static]

Turn on SIP debugging for a given peer.

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

19620 {
19621    struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0);
19622    if (!peer)
19623       ast_cli(fd, "No such peer '%s'\n", arg);
19624    else if (ast_sockaddr_isnull(&peer->addr))
19625       ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg);
19626    else {
19627       ast_sockaddr_copy(&debugaddr, &peer->addr);
19628       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
19629       sipdebug |= sip_debug_console;
19630    }
19631    if (peer)
19632       unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call");
19633    return CLI_SUCCESS;
19634 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

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

30574 {
30575    time_t start_poke, end_poke;
30576    
30577    reload_config(reason);
30578    ast_sched_dump(sched);
30579 
30580    start_poke = time(0);
30581    /* Prune peers who still are supposed to be deleted */
30582    unlink_marked_peers_from_tables();
30583 
30584    ast_debug(4, "--------------- Done destroying pruned peers\n");
30585 
30586    /* Send qualify (OPTIONS) to all peers */
30587    sip_poke_all_peers();
30588 
30589    /* Register with all services */
30590    sip_send_all_registers();
30591 
30592    sip_send_all_mwi_subscriptions();
30593 
30594    end_poke = time(0);
30595    
30596    ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke));
30597 
30598    ast_debug(4, "--------------- SIP reload done\n");
30599 
30600    return 0;
30601 }

static int sip_dtmfmode ( struct ast_channel chan,
const char *  data 
) [static]

Set the DTMFmode for an outbound SIP call (application).

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

30257 {
30258    struct sip_pvt *p;
30259    const char *mode = data;
30260 
30261    if (!data) {
30262       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
30263       return 0;
30264    }
30265    ast_channel_lock(chan);
30266    if (!IS_SIP_TECH(chan->tech)) {
30267       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
30268       ast_channel_unlock(chan);
30269       return 0;
30270    }
30271    p = chan->tech_pvt;
30272    if (!p) {
30273       ast_channel_unlock(chan);
30274       return 0;
30275    }
30276    sip_pvt_lock(p);
30277    if (!strcasecmp(mode, "info")) {
30278       ast_clear_flag(&p->flags[0], SIP_DTMF);
30279       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
30280       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
30281    } else if (!strcasecmp(mode, "shortinfo")) {
30282       ast_clear_flag(&p->flags[0], SIP_DTMF);
30283       ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO);
30284       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
30285    } else if (!strcasecmp(mode, "rfc2833")) {
30286       ast_clear_flag(&p->flags[0], SIP_DTMF);
30287       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
30288       p->jointnoncodeccapability |= AST_RTP_DTMF;
30289    } else if (!strcasecmp(mode, "inband")) {
30290       ast_clear_flag(&p->flags[0], SIP_DTMF);
30291       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
30292       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
30293    } else {
30294       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode);
30295    }
30296    if (p->rtp)
30297       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
30298    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
30299        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
30300       enable_dsp_detect(p);
30301    } else {
30302       disable_dsp_detect(p);
30303    }
30304    sip_pvt_unlock(p);
30305    ast_channel_unlock(chan);
30306    return 0;
30307 }

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

References ast_debug, AST_LIST_TRAVERSE, ast_log(), LOG_NOTICE, and option_debug.

Referenced by __sip_destroy().

19407 {
19408    int x = 0;
19409    struct sip_history *hist;
19410    static int errmsg = 0;
19411 
19412    if (!dialog)
19413       return;
19414 
19415    if (!option_debug && !sipdebug) {
19416       if (!errmsg) {
19417          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
19418          errmsg = 1;
19419       }
19420       return;
19421    }
19422 
19423    ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
19424    if (dialog->subscribed)
19425       ast_debug(1, "  * Subscription\n");
19426    else
19427       ast_debug(1, "  * SIP Call\n");
19428    if (dialog->history)
19429       AST_LIST_TRAVERSE(dialog->history, hist, list)
19430          ast_debug(1, "  %-3.3d. %s\n", ++x, hist->event);
19431    if (!x)
19432       ast_debug(1, "Call '%s' has no history\n", dialog->callid);
19433    ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
19434 }

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

References ast_channel::tech_pvt.

04677 {
04678    return chan->tech_pvt ? ((struct sip_pvt *) chan->tech_pvt)->callid : "";
04679 }

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

References ast_channel::tech_pvt.

30237 {
30238    struct sip_pvt *p = chan->tech_pvt;
30239    return p->peercapability ? p->peercapability : p->capability;
30240 }

static enum ast_rtp_glue_result sip_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 29947 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.

29948 {
29949    struct sip_pvt *p = NULL;
29950    struct ast_channel *opp_chan;
29951    struct sip_pvt *opp = NULL;
29952    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
29953 
29954    if (!(p = chan->tech_pvt)) {
29955       return AST_RTP_GLUE_RESULT_FORBID;
29956    }
29957 
29958    if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
29959                          (!(opp = opp_chan->tech_pvt)))) {
29960       return AST_RTP_GLUE_RESULT_FORBID;
29961    }
29962 
29963    sip_pvt_lock(p);
29964    while (opp && sip_pvt_trylock(opp)) {
29965       sip_pvt_unlock(p);
29966       usleep(1);
29967       sip_pvt_lock(p);
29968    }
29969 
29970    if (!(p->rtp)) {
29971       if (opp) {
29972          sip_pvt_unlock(opp);
29973       }
29974       sip_pvt_unlock(p);
29975       return AST_RTP_GLUE_RESULT_FORBID;
29976    }
29977 
29978    ao2_ref(p->rtp, +1);
29979    *instance = p->rtp;
29980 
29981    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
29982       res = AST_RTP_GLUE_RESULT_REMOTE;
29983       if (opp && !apply_directmedia_ha(p, opp, "audio")) {
29984          res = AST_RTP_GLUE_RESULT_FORBID;
29985       }
29986    } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
29987       res = AST_RTP_GLUE_RESULT_REMOTE;
29988    } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) {
29989       res = AST_RTP_GLUE_RESULT_FORBID;
29990    }
29991 
29992    if (opp) {
29993       sip_pvt_unlock(opp);
29994    }
29995 
29996    if (p->srtp) {
29997       res = AST_RTP_GLUE_RESULT_FORBID;
29998    }
29999 
30000    sip_pvt_unlock(p);
30001 
30002    return res;
30003 }

static enum ast_rtp_glue_result sip_get_trtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 30054 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.

30055 {
30056    struct sip_pvt *p = NULL;
30057    struct ast_channel *opp_chan;
30058    struct sip_pvt *opp = NULL;
30059    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
30060 
30061    if (!(p = chan->tech_pvt)) {
30062       return AST_RTP_GLUE_RESULT_FORBID;
30063    }
30064 
30065    if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
30066                          (!(opp = opp_chan->tech_pvt)))) {
30067       return AST_RTP_GLUE_RESULT_FORBID;
30068    }
30069 
30070    sip_pvt_lock(p);
30071    while (opp && sip_pvt_trylock(opp)) {
30072       sip_pvt_unlock(p);
30073       usleep(1);
30074       sip_pvt_lock(p);
30075    }
30076 
30077    if (!(p->trtp)) {
30078       if (opp) {
30079          sip_pvt_unlock(opp);
30080       }
30081       sip_pvt_unlock(p);
30082       return AST_RTP_GLUE_RESULT_FORBID;
30083    }
30084 
30085    ao2_ref(p->trtp, +1);
30086    *instance = p->trtp;
30087 
30088    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
30089       res = AST_RTP_GLUE_RESULT_REMOTE;
30090       if (opp && !apply_directmedia_ha(p, opp, "text")) {
30091          res = AST_RTP_GLUE_RESULT_FORBID;
30092       }
30093    }
30094 
30095    if (opp) {
30096       sip_pvt_unlock(opp);
30097    }
30098    sip_pvt_unlock(p);
30099 
30100    return res;
30101 }

static struct ast_udptl * sip_get_udptl_peer ( struct ast_channel chan  )  [static, read]

Definition at line 29867 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.

29868 {
29869    struct sip_pvt *p;
29870    struct ast_channel *opp_chan;
29871    struct sip_pvt *opp;
29872    struct ast_udptl *udptl = NULL;
29873 
29874    p = chan->tech_pvt;
29875    if (!p) {
29876       return NULL;
29877    }
29878 
29879    if (!(opp_chan = ast_bridged_channel(chan))) {
29880       return NULL;
29881    } else if (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
29882          (!(opp = opp_chan->tech_pvt))) {
29883       return NULL;
29884    }
29885 
29886    sip_pvt_lock(p);
29887    while (sip_pvt_trylock(opp)) {
29888       sip_pvt_unlock(p);
29889       usleep(1);
29890       sip_pvt_lock(p);
29891    }
29892 
29893    if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
29894       if (apply_directmedia_ha(p, opp, "UDPTL T.38 data")) {
29895          udptl = p->udptl;
29896       }
29897    }
29898 
29899    sip_pvt_unlock(opp);
29900    sip_pvt_unlock(p);
29901    return udptl;
29902 }

static enum ast_rtp_glue_result sip_get_vrtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 30005 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.

30006 {
30007    struct sip_pvt *p = NULL;
30008    struct ast_channel *opp_chan;
30009    struct sip_pvt *opp = NULL;
30010    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
30011 
30012    if (!(p = chan->tech_pvt)) {
30013       return AST_RTP_GLUE_RESULT_FORBID;
30014    }
30015 
30016    if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
30017                          (!(opp = opp_chan->tech_pvt)))) {
30018       return AST_RTP_GLUE_RESULT_FORBID;
30019    }
30020 
30021    sip_pvt_lock(p);
30022    while (opp && sip_pvt_trylock(opp)) {
30023       sip_pvt_unlock(p);
30024       usleep(1);
30025       sip_pvt_lock(p);
30026    }
30027 
30028    if (!(p->vrtp)) {
30029       if (opp) {
30030          sip_pvt_unlock(opp);
30031       }
30032       sip_pvt_unlock(p);
30033       return AST_RTP_GLUE_RESULT_FORBID;
30034    }
30035 
30036    ao2_ref(p->vrtp, +1);
30037    *instance = p->vrtp;
30038 
30039    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
30040       res = AST_RTP_GLUE_RESULT_REMOTE;
30041       if (opp && !apply_directmedia_ha(p, opp, "video")) {
30042          res = AST_RTP_GLUE_RESULT_FORBID;
30043       }
30044    }
30045 
30046    if (opp) {
30047       sip_pvt_unlock(opp);
30048    }
30049    sip_pvt_unlock(p);
30050 
30051    return res;
30052 }

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

References FALSE, and TRUE.

Referenced by load_module().

30442 {
30443 #ifdef HAVE_LIBXML2
30444    return TRUE;
30445 #else
30446    return FALSE;
30447 #endif
30448 }

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

References ast_test_flag.

Referenced by check_via(), retrans_pkt(), and send_response().

03406 {
03407    return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT";
03408 }

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

22203 {
22204    struct sip_dual *d;
22205    struct ast_channel *transferee, *transferer;
22206    pthread_t th;
22207 
22208    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
22209    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name);
22210    d = ast_calloc(1, sizeof(*d));
22211    if (!transferee || !transferer || !d) {
22212       if (transferee) {
22213          ast_hangup(transferee);
22214       }
22215       if (transferer) {
22216          ast_hangup(transferer);
22217       }
22218       ast_free(d);
22219       return -1;
22220    }
22221    d->park_exten = ast_strdup(park_exten);
22222    d->park_context = ast_strdup(park_context);
22223    if (!d->park_exten || !d->park_context) {
22224       ast_hangup(transferee);
22225       ast_hangup(transferer);
22226       ast_free(d->park_exten);
22227       ast_free(d->park_context);
22228       ast_free(d);
22229       return -1;
22230    }
22231 
22232    /* Make formats okay */
22233    transferee->readformat = chan1->readformat;
22234    transferee->writeformat = chan1->writeformat;
22235 
22236    /* Prepare for taking over the channel */
22237    if (ast_channel_masquerade(transferee, chan1)) {
22238       ast_hangup(transferee);
22239       ast_hangup(transferer);
22240       ast_free(d->park_exten);
22241       ast_free(d->park_context);
22242       ast_free(d);
22243       return -1;
22244    }
22245 
22246    /* Setup the extensions and such */
22247    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
22248    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
22249    transferee->priority = chan1->priority;
22250 
22251    ast_do_masquerade(transferee);
22252 
22253    /* We make a clone of the peer channel too, so we can play
22254       back the announcement */
22255 
22256    /* Make formats okay */
22257    transferer->readformat = chan2->readformat;
22258    transferer->writeformat = chan2->writeformat;
22259    ast_string_field_set(transferer, parkinglot, chan2->parkinglot);
22260 
22261    /* Prepare for taking over the channel */
22262    if (ast_channel_masquerade(transferer, chan2)) {
22263       ast_hangup(transferee);
22264       ast_hangup(transferer);
22265       ast_free(d->park_exten);
22266       ast_free(d->park_context);
22267       ast_free(d);
22268       return -1;
22269    }
22270 
22271    /* Setup the extensions and such */
22272    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
22273    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
22274    transferer->priority = chan2->priority;
22275 
22276    ast_do_masquerade(transferer);
22277 
22278    /* Save original request for followup */
22279    copy_request(&d->req, req);
22280    d->chan1 = transferee;  /* Transferee */
22281    d->chan2 = transferer;  /* Transferer */
22282    d->seqno = seqno;
22283    if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) {
22284       /* Could not start thread */
22285       ast_hangup(transferer);
22286       ast_hangup(transferee);
22287       deinit_req(&d->req);
22288       ast_free(d->park_exten);
22289       ast_free(d->park_context);
22290       ast_free(d);   /* We don't need it anymore. If thread is created, d will be free'd
22291                by sip_park_thread() */
22292       return -1;
22293    }
22294    return 0;
22295 }

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

22152 {
22153    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
22154    struct sip_pvt *transferer_pvt;
22155    struct sip_dual *d;
22156    int ext;
22157    int res;
22158 
22159    d = stuff;
22160    transferee = d->chan1;
22161    transferer = d->chan2;
22162    transferer_pvt = transferer->tech_pvt;
22163 
22164    ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
22165 
22166    res = ast_park_call_exten(transferee, transferer, d->park_exten, d->park_context, 0, &ext);
22167 
22168 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
22169    if (res) {
22170       transmit_message_with_text(transferer_pvt, "Unable to park call.\n");
22171    } else {
22172       /* Then tell the transferer what happened */
22173       sprintf(buf, "Call parked on extension '%d'", ext);
22174       transmit_message_with_text(transferer_pvt, buf);
22175    }
22176 #endif
22177 
22178    /* Any way back to the current call??? */
22179    /* Transmit response to the REFER request */
22180    ast_set_flag(&transferer_pvt->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  
22181    if (!res)   {
22182       /* Transfer succeeded */
22183       append_history(transferer_pvt, "SIPpark", "Parked call on %d", ext);
22184       transmit_notify_with_sipfrag(transferer_pvt, d->seqno, "200 OK", TRUE);
22185       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
22186       ast_debug(1, "SIP Call parked on extension '%d'\n", ext);
22187    } else {
22188       transmit_notify_with_sipfrag(transferer_pvt, d->seqno, "503 Service Unavailable", TRUE);
22189       append_history(transferer_pvt, "SIPpark", "Parking failed\n");
22190       ast_log(AST_LOG_NOTICE, "SIP Call parked failed for %s\n", transferee->name);
22191       ast_hangup(transferee);
22192    }
22193    ast_hangup(transferer);
22194    deinit_req(&d->req);
22195    ast_free(d->park_exten);
22196    ast_free(d->park_context);
22197    ast_free(d);
22198    return NULL;
22199 }

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

15032 {
15033    if (!p->relatedpeer) {
15034       return;
15035    }
15036 
15037    /* If they put someone on hold, increment the value... otherwise decrement it */
15038    ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1));
15039 
15040    /* Request device state update */
15041    ast_devstate_changed(AST_DEVICE_UNKNOWN, (p->owner->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE),
15042               "SIP/%s", p->relatedpeer->name);
15043 
15044    return;
15045 }

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

22321 {
22322    pthread_t threadid;
22323 
22324    ast_channel_ref(chan);
22325 
22326    if (ast_pthread_create_detached_background(&threadid, NULL, sip_pickup_thread, chan)) {
22327       ast_debug(1, "Unable to start Group pickup thread on channel %s\n", chan->name);
22328       ast_channel_unref(chan);
22329       return -1;
22330    }
22331    ast_debug(1, "Started Group pickup thread on channel %s\n", chan->name);
22332    return 0;
22333 }

static void * sip_pickup_thread ( void *  stuff  )  [static]

SIP pickup support function Starts in a new thread, then pickup the call.

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

22302 {
22303    struct ast_channel *chan;
22304    chan = stuff;
22305 
22306    if (ast_pickup_call(chan)) {
22307       chan->hangupcause = AST_CAUSE_CALL_REJECTED;
22308    } else {
22309       chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
22310    }
22311    ast_hangup(chan);
22312    ast_channel_unref(chan);
22313    chan = NULL;
22314    return NULL;
22315 }

static void sip_poke_all_peers ( void   )  [static]

Send a poke to all known peers.

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

30452 {
30453    int ms = 0, num = 0;
30454    struct ao2_iterator i;
30455    struct sip_peer *peer;
30456 
30457    if (!speerobjs) { /* No peers, just give up */
30458       return;
30459    }
30460 
30461    i = ao2_iterator_init(peers, 0);
30462    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
30463       ao2_lock(peer);
30464       /* Don't schedule poking on a peer without qualify */
30465       if (peer->maxms) {
30466          if (num == global_qualify_peers) {
30467             ms += global_qualify_gap;
30468             num = 0;
30469          } else {
30470             num++;
30471          }
30472          AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer,
30473                unref_peer(_data, "removing poke peer ref"),
30474                unref_peer(peer, "removing poke peer ref"),
30475                ref_peer(peer, "adding poke peer ref"));
30476       }
30477       ao2_unlock(peer);
30478       unref_peer(peer, "toss iterator peer ptr");
30479    }
30480    ao2_iterator_destroy(&i);
30481 }

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

React to lack of answer to Qualify poke.

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

27041 {
27042    struct sip_peer *peer = (struct sip_peer *)data;
27043 
27044    peer->pokeexpire = -1;
27045 
27046    if (peer->lastms > -1) {
27047       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
27048       if (sip_cfg.peer_rtupdate) {
27049          ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL);
27050       }
27051       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
27052       if (sip_cfg.regextenonqualify) {
27053          register_peer_exten(peer, FALSE);
27054       }
27055    }
27056 
27057    if (peer->call) {
27058       dialog_unlink_all(peer->call);
27059       peer->call = dialog_unref(peer->call, "unref dialog peer->call");
27060       /* peer->call = sip_destroy(peer->call);*/
27061    }
27062 
27063    /* Don't send a devstate change if nothing changed. */
27064    if (peer->lastms > -1) {
27065       peer->lastms = -1;
27066       ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
27067    }
27068 
27069    /* Try again quickly */
27070    AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
27071          DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer,
27072          unref_peer(_data, "removing poke peer ref"),
27073          unref_peer(peer, "removing poke peer ref"),
27074          ref_peer(peer, "adding poke peer ref"));
27075 
27076    /* Release the ref held by the running scheduler entry */
27077    unref_peer(peer, "release peer poke noanswer ref");
27078 
27079    return 0;
27080 }

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 27090 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, ref_peer(), 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().

27091 {
27092    struct sip_pvt *p;
27093    int xmitres = 0;
27094    
27095    if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) {
27096       /* IF we have no IP, or this isn't to be monitored, return
27097         immediately after clearing things out */
27098       AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
27099             unref_peer(peer, "removing poke peer ref"));
27100       
27101       peer->lastms = 0;
27102       if (peer->call) {
27103          peer->call = dialog_unref(peer->call, "unref dialog peer->call");
27104       }
27105       return 0;
27106    }
27107    if (peer->call) {
27108       if (sipdebug) {
27109          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
27110       }
27111       dialog_unlink_all(peer->call);
27112       peer->call = dialog_unref(peer->call, "unref dialog peer->call");
27113       /* peer->call = sip_destroy(peer->call); */
27114    }
27115    if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) {
27116       return -1;
27117    }
27118    peer->call = dialog_ref(p, "copy sip alloc from p to peer->call");
27119 
27120    p->sa = peer->addr;
27121    p->recv = peer->addr;
27122    copy_socket_data(&p->socket, &peer->socket);
27123    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
27124    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
27125    ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
27126 
27127    /* Send OPTIONs to peer's fullcontact */
27128    if (!ast_strlen_zero(peer->fullcontact)) {
27129       ast_string_field_set(p, fullcontact, peer->fullcontact);
27130    }
27131 
27132    if (!ast_strlen_zero(peer->fromuser)) {
27133       ast_string_field_set(p, fromuser, peer->fromuser);
27134    }
27135 
27136    if (!ast_strlen_zero(peer->tohost)) {
27137       ast_string_field_set(p, tohost, peer->tohost);
27138    } else {
27139       ast_string_field_set(p, tohost, ast_sockaddr_stringify_host_remote(&peer->addr));
27140    }
27141 
27142    /* Recalculate our side, and recalculate Call ID */
27143    ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
27144    build_via(p);
27145 
27146    /* Change the dialog callid. */
27147    change_callid_pvt(p, NULL);
27148 
27149    AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
27150          unref_peer(peer, "removing poke peer ref"));
27151    
27152    if (p->relatedpeer)
27153       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
27154    p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog");
27155    ast_set_flag(&p->flags[0], SIP_OUTGOING);
27156 #ifdef VOCAL_DATA_HACK
27157    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
27158    xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */
27159 #else
27160    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */
27161 #endif
27162    peer->ps = ast_tvnow();
27163    if (xmitres == XMIT_ERROR) {
27164       /* Immediately unreachable, network problems */
27165       sip_poke_noanswer(ref_peer(peer, "add ref for peerexpire (fake, for sip_poke_noanswer to remove)"));
27166    } else if (!force) {
27167       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer,
27168             unref_peer(_data, "removing poke peer ref"),
27169             unref_peer(peer, "removing poke peer ref"),
27170             ref_peer(peer, "adding poke peer ref"));
27171    }
27172    dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope");
27173    return 0;
27174 }

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

14267 {
14268    struct sip_peer *peer = (struct sip_peer *)data;
14269    struct sip_peer *foundpeer;
14270 
14271    peer->pokeexpire = -1;
14272 
14273    foundpeer = ao2_find(peers, peer, OBJ_POINTER);
14274    if (!foundpeer) {
14275       unref_peer(peer, "removing poke peer ref");
14276       return 0;
14277    } else if (foundpeer->name != peer->name) {
14278       unref_peer(foundpeer, "removing above peer ref");
14279       unref_peer(peer, "removing poke peer ref");
14280       return 0;
14281    }
14282 
14283    unref_peer(foundpeer, "removing above peer ref");
14284    sip_poke_peer(peer, 0);
14285    unref_peer(peer, "removing poke peer ref");
14286 
14287    return 0;
14288 }

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

26284 {
26285    struct sip_socket *s = &p->socket;
26286    static const char name[] = "SIP socket";
26287    struct sip_threadinfo *th = NULL;
26288    struct ast_tcptls_session_instance *tcptls_session;
26289    struct ast_tcptls_session_args *ca;
26290    struct ast_sockaddr sa_tmp;
26291    pthread_t launched;
26292 
26293    /* check to see if a socket is already active */
26294    if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) {
26295       return s->fd;
26296    }
26297    if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) &&
26298          (s->tcptls_session) &&
26299          (s->tcptls_session->fd != -1)) {
26300       return s->tcptls_session->fd;
26301    }
26302 
26303    /*! \todo Check this... This might be wrong, depending on the proxy configuration
26304       If proxy is in "force" mode its correct.
26305     */
26306    if (p->outboundproxy && p->outboundproxy->transport) {
26307       s->type = p->outboundproxy->transport;
26308    }
26309 
26310    if (s->type == SIP_TRANSPORT_UDP) {
26311       s->fd = sipsock;
26312       return s->fd;
26313    }
26314 
26315    /* At this point we are dealing with a TCP/TLS connection
26316     * 1. We need to check to see if a connection thread exists
26317     *    for this address, if so use that.
26318     * 2. If a thread does not exist for this address, but the tcptls_session
26319     *    exists on the socket, the connection was closed.
26320     * 3. If no tcptls_session thread exists for the address, and no tcptls_session
26321     *    already exists on the socket, create a new one and launch a new thread.
26322     */
26323 
26324    /* 1.  check for existing threads */
26325    ast_sockaddr_copy(&sa_tmp, sip_real_dst(p));
26326    if ((tcptls_session = sip_tcp_locate(&sa_tmp))) {
26327       s->fd = tcptls_session->fd;
26328       if (s->tcptls_session) {
26329          ao2_ref(s->tcptls_session, -1);
26330          s->tcptls_session = NULL;
26331       }
26332       s->tcptls_session = tcptls_session;
26333       return s->fd;
26334    /* 2.  Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */
26335    } else if (s->tcptls_session) {
26336       return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */
26337    }
26338 
26339    /* 3.  Create a new TCP/TLS client connection */
26340    /* create new session arguments for the client connection */
26341    if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) ||
26342       !(ca->name = ast_strdup(name))) {
26343       goto create_tcptls_session_fail;
26344    }
26345    ca->accept_fd = -1;
26346    ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p));
26347    /* if type is TLS, we need to create a tls cfg for this session arg */
26348    if (s->type == SIP_TRANSPORT_TLS) {
26349       if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) {
26350          goto create_tcptls_session_fail;
26351       }
26352       memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg));
26353 
26354       if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) ||
26355          !(ca->tls_cfg->pvtfile = ast_strdup(default_tls_cfg.pvtfile)) ||
26356          !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) ||
26357          !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) ||
26358          !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) {
26359 
26360          goto create_tcptls_session_fail;
26361       }
26362 
26363       /* this host is used as the common name in ssl/tls */
26364       if (!ast_strlen_zero(p->tohost)) {
26365          ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname));
26366       }
26367    }
26368 
26369    /* Create a client connection for address, this does not start the connection, just sets it up. */
26370    if (!(s->tcptls_session = ast_tcptls_client_create(ca))) {
26371       goto create_tcptls_session_fail;
26372    }
26373 
26374    s->fd = s->tcptls_session->fd;
26375 
26376    /* client connections need to have the sip_threadinfo object created before
26377     * the thread is detached.  This ensures the alert_pipe is up before it will
26378     * be used.  Note that this function links the new threadinfo object into the
26379     * threadt container. */
26380    if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) {
26381       goto create_tcptls_session_fail;
26382    }
26383 
26384    /* Give the new thread a reference to the tcptls_session */
26385    ao2_ref(s->tcptls_session, +1);
26386 
26387    if (ast_pthread_create_detached_background(&launched, NULL, sip_tcp_worker_fn, s->tcptls_session)) {
26388       ast_debug(1, "Unable to launch '%s'.", ca->name);
26389       ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */
26390       goto create_tcptls_session_fail;
26391    }
26392 
26393    return s->fd;
26394 
26395 create_tcptls_session_fail:
26396    if (ca) {
26397       ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments");
26398    }
26399    if (s->tcptls_session) {
26400       ast_tcptls_close_session_file(s->tcptls_session);
26401       s->fd = -1;
26402       ao2_ref(s->tcptls_session, -1);
26403       s->tcptls_session = NULL;
26404    }
26405    if (th) {
26406       ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open");
26407    }
26408 
26409    return -1;
26410 }

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

17733 {
17734    struct sip_peer *peer, *pi;
17735    int prunepeer = FALSE;
17736    int multi = FALSE;
17737    const char *name = NULL;
17738    regex_t regexbuf;
17739    int havepattern = 0;
17740    struct ao2_iterator i;
17741    static const char * const choices[] = { "all", "like", NULL };
17742    char *cmplt;
17743    
17744    if (cmd == CLI_INIT) {
17745       e->command = "sip prune realtime [peer|all]";
17746       e->usage =
17747          "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n"
17748          "       Prunes object(s) from the cache.\n"
17749          "       Optional regular expression pattern is used to filter the objects.\n";
17750       return NULL;
17751    } else if (cmd == CLI_GENERATE) {
17752       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) {
17753          cmplt = ast_cli_complete(a->word, choices, a->n);
17754          if (!cmplt)
17755             cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS);
17756          return cmplt;
17757       }
17758       if (a->pos == 5 && !strcasecmp(a->argv[4], "like"))
17759          return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS);
17760       return NULL;
17761    }
17762    switch (a->argc) {
17763    case 4:
17764       name = a->argv[3];
17765       /* we accept a name in position 3, but keywords are not good. */
17766       if (!strcasecmp(name, "peer") || !strcasecmp(name, "like"))
17767          return CLI_SHOWUSAGE;
17768       prunepeer = TRUE;
17769       if (!strcasecmp(name, "all")) {
17770          multi = TRUE;
17771          name = NULL;
17772       }
17773       /* else a single name, already set */
17774       break;
17775    case 5:
17776       /* sip prune realtime {peer|like} name */
17777       name = a->argv[4];
17778       if (!strcasecmp(a->argv[3], "peer"))
17779          prunepeer = TRUE;
17780       else if (!strcasecmp(a->argv[3], "like")) {
17781          prunepeer = TRUE;
17782          multi = TRUE;
17783       } else
17784          return CLI_SHOWUSAGE;
17785       if (!strcasecmp(name, "like"))
17786          return CLI_SHOWUSAGE;
17787       if (!multi && !strcasecmp(name, "all")) {
17788          multi = TRUE;
17789          name = NULL;
17790       }
17791       break;
17792    case 6:
17793       name = a->argv[5];
17794       multi = TRUE;
17795       /* sip prune realtime {peer} like name */
17796       if (strcasecmp(a->argv[4], "like"))
17797          return CLI_SHOWUSAGE;
17798       if (!strcasecmp(a->argv[3], "peer")) {
17799          prunepeer = TRUE;
17800       } else
17801          return CLI_SHOWUSAGE;
17802       break;
17803    default:
17804       return CLI_SHOWUSAGE;
17805    }
17806 
17807    if (multi && name) {
17808       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB)) {
17809          return CLI_SHOWUSAGE;
17810       }
17811       havepattern = 1;
17812    }
17813 
17814    if (multi) {
17815       if (prunepeer) {
17816          int pruned = 0;
17817          
17818          i = ao2_iterator_init(peers, 0);
17819          while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
17820             ao2_lock(pi);
17821             if (name && regexec(&regexbuf, pi->name, 0, NULL, 0)) {
17822                ao2_unlock(pi);
17823                unref_peer(pi, "toss iterator peer ptr before continue");
17824                continue;
17825             };
17826             if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
17827                pi->the_mark = 1;
17828                pruned++;
17829             }
17830             ao2_unlock(pi);
17831             unref_peer(pi, "toss iterator peer ptr");
17832          }
17833          ao2_iterator_destroy(&i);
17834          if (pruned) {
17835             unlink_marked_peers_from_tables();
17836             ast_cli(a->fd, "%d peers pruned.\n", pruned);
17837          } else
17838             ast_cli(a->fd, "No peers found to prune.\n");
17839       }
17840    } else {
17841       if (prunepeer) {
17842          struct sip_peer tmp;
17843          ast_copy_string(tmp.name, name, sizeof(tmp.name));
17844          if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) {
17845             if (!ast_sockaddr_isnull(&peer->addr)) {
17846                ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also");
17847             }
17848             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
17849                ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
17850                /* put it back! */
17851                ao2_t_link(peers, peer, "link peer into peer table");
17852                if (!ast_sockaddr_isnull(&peer->addr)) {
17853                   ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
17854                }
17855             } else
17856                ast_cli(a->fd, "Peer '%s' pruned.\n", name);
17857             unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr");
17858          } else
17859             ast_cli(a->fd, "Peer '%s' not found.\n", name);
17860       }
17861    }
17862 
17863    if (havepattern) {
17864       regfree(&regexbuf);
17865    }
17866 
17867    return CLI_SUCCESS;
17868 }

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

18018 {
18019    switch (cmd) {
18020    case CLI_INIT:
18021       e->command = "sip qualify peer";
18022       e->usage =
18023          "Usage: sip qualify peer <name> [load]\n"
18024          "       Requests a response from one SIP peer and the current status.\n"
18025          "       Option \"load\" forces lookup of peer in realtime storage.\n";
18026       return NULL;
18027    case CLI_GENERATE:
18028       return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
18029    }
18030    return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
18031 }

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

04559 {
04560    int res = -1;
04561    enum ast_t38_state state = T38_STATE_UNAVAILABLE;
04562    struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt;
04563    char *cp;
04564 
04565    sip_pvt_lock(p);
04566 
04567    switch (option) {
04568    case AST_OPTION_T38_STATE:
04569       /* Make sure we got an ast_t38_state enum passed in */
04570       if (*datalen != sizeof(enum ast_t38_state)) {
04571          ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
04572          break;
04573       }
04574 
04575       /* 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 */
04576       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
04577          switch (p->t38.state) {
04578          case T38_LOCAL_REINVITE:
04579          case T38_PEER_REINVITE:
04580             state = T38_STATE_NEGOTIATING;
04581             break;
04582          case T38_ENABLED:
04583             state = T38_STATE_NEGOTIATED;
04584             break;
04585          default:
04586             state = T38_STATE_UNKNOWN;
04587          }
04588       }
04589 
04590       *((enum ast_t38_state *) data) = state;
04591       res = 0;
04592 
04593       break;
04594    case AST_OPTION_DIGIT_DETECT:
04595       cp = (char *) data;
04596       *cp = p->dsp ? 1 : 0;
04597       ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name);
04598       break;
04599    case AST_OPTION_SECURE_SIGNALING:
04600       *((unsigned int *) data) = p->req_secure_signaling;
04601       res = 0;
04602       break;
04603    case AST_OPTION_SECURE_MEDIA:
04604       *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0;
04605       res = 0;
04606       break;
04607    case AST_OPTION_DEVICE_NAME:
04608       if (p && p->outgoing_call) {
04609          cp = (char *) data;
04610          ast_copy_string(cp, p->dialstring, *datalen);
04611          res = 0;
04612       }
04613       /* We purposely break with a return of -1 in the
04614        * implied else case here
04615        */
04616       break;
04617    default:
04618       break;
04619    }
04620 
04621    sip_pvt_unlock(p);
04622 
04623    return res;
04624 }

static void sip_queue_hangup_cause ( struct sip_pvt *  p,
int  cause 
) [static]

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

20667 {
20668    struct ast_channel *owner = p->owner;
20669    const char *name = ast_strdupa(owner->name);
20670 
20671    /* Cannot hold any channel/private locks when calling. */
20672    ast_channel_ref(owner);
20673    ast_channel_unlock(owner);
20674    sip_pvt_unlock(p);
20675    ast_set_hangupsource(owner, name, 0);
20676    if (cause) {
20677       ast_queue_hangup_with_cause(owner, cause);
20678    } else {
20679       ast_queue_hangup(owner);
20680    }
20681    ast_channel_unref(owner);
20682 
20683    /* Relock things. */
20684    owner = sip_pvt_lock_full(p);
20685    if (owner) {
20686       ast_channel_unref(owner);
20687    }
20688 }

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

03396 {
03397    if (p->outboundproxy) {
03398       return &p->outboundproxy->ip;
03399    }
03400 
03401    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;
03402 }

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

05933 {
05934    /* Really delete */
05935    ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
05936 
05937    if (reg->call) {
05938       /* Clear registry before destroying to ensure
05939          we don't get reentered trying to grab the registry lock */
05940       reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry");
05941       ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
05942       dialog_unlink_all(reg->call);
05943       reg->call = dialog_unref(reg->call, "unref reg->call");
05944       /* reg->call = sip_destroy(reg->call); */
05945    }
05946    AST_SCHED_DEL(sched, reg->expire);
05947    AST_SCHED_DEL(sched, reg->timeout);
05948 
05949    ast_string_field_free_memory(reg);
05950    ast_atomic_fetchadd_int(&regobjs, -1);
05951    ast_free(reg);
05952 }

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

20519 {
20520    struct sip_pvt *p = (struct sip_pvt *) data;
20521    struct ast_channel *owner;
20522 
20523    sip_pvt_lock(p); /* called from schedule thread which requires a lock */
20524    while ((owner = p->owner) && ast_channel_trylock(owner)) {
20525       sip_pvt_unlock(p);
20526       usleep(1);
20527       sip_pvt_lock(p);
20528    }
20529    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
20530    p->waitid = -1;
20531    check_pendings(p);
20532    sip_pvt_unlock(p);
20533    if (owner) {
20534       ast_channel_unlock(owner);
20535    }
20536    dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr");
20537    return 0;
20538 }

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

30605 {
30606    static struct sip_peer *tmp_peer, *new_peer;
30607    
30608    switch (cmd) {
30609    case CLI_INIT:
30610       e->command = "sip reload";
30611       e->usage =
30612          "Usage: sip reload\n"
30613          "       Reloads SIP configuration from sip.conf\n";
30614       return NULL;
30615    case CLI_GENERATE:
30616       return NULL;
30617    }
30618 
30619    ast_mutex_lock(&sip_reload_lock);
30620    if (sip_reloading) {
30621       ast_verbose("Previous SIP reload not yet done\n");
30622    } else {
30623       sip_reloading = TRUE;
30624       sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD;
30625    }
30626    ast_mutex_unlock(&sip_reload_lock);
30627    restart_monitor();
30628 
30629    tmp_peer = bogus_peer;
30630    /* Create new bogus peer possibly with new global settings. */
30631    if ((new_peer = temp_peer("(bogus_peer)"))) {
30632       ast_string_field_set(new_peer, md5secret, BOGUS_PEER_MD5SECRET);
30633       ast_clear_flag(&new_peer->flags[0], SIP_INSECURE);
30634       bogus_peer = new_peer;
30635       ao2_t_ref(tmp_peer, -1, "unref the old bogus_peer during reload");
30636    } else {
30637       ast_log(LOG_ERROR, "Could not update the fake authentication peer.\n");
30638       /* You probably have bigger (memory?) issues to worry about though.. */
30639    }
30640 
30641    return CLI_SUCCESS;
30642 }

static int sip_removeheader ( struct ast_channel chan,
const char *  data 
) [static]

Remove SIP headers added previously with SipAddHeader application.

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

30351 {
30352    struct ast_var_t *newvariable;
30353    struct varshead *headp;
30354    int removeall = 0;
30355    char *inbuf = (char *) data;
30356 
30357    if (ast_strlen_zero(inbuf)) {
30358       removeall = 1;
30359    }
30360    ast_channel_lock(chan);
30361 
30362    headp=&chan->varshead;
30363    AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) {
30364       if (strncasecmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) {
30365          if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) {
30366             if (sipdebug)
30367                ast_debug(1,"removing SIP Header \"%s\" as %s\n",
30368                   ast_var_value(newvariable),
30369                   ast_var_name(newvariable));
30370             AST_LIST_REMOVE_CURRENT(entries);
30371             ast_var_delete(newvariable);
30372          }
30373       }
30374    }
30375    AST_LIST_TRAVERSE_SAFE_END;
30376 
30377    ast_channel_unlock(chan);
30378    return 0;
30379 }

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

27292 {
27293    struct sip_pvt *p;
27294    struct ast_channel *tmpc = NULL;
27295    char *ext = NULL, *host;
27296    char tmp[256];
27297    char *dest = data;
27298    char *dnid;
27299    char *secret = NULL;
27300    char *md5secret = NULL;
27301    char *authname = NULL;
27302    char *trans = NULL;
27303    char dialstring[256];
27304    char *remote_address;
27305    enum sip_transport transport = 0;
27306    format_t oldformat = format;
27307    AST_DECLARE_APP_ARGS(args,
27308       AST_APP_ARG(peerorhost);
27309       AST_APP_ARG(exten);
27310       AST_APP_ARG(remote_address);
27311    );
27312 
27313    /* mask request with some set of allowed formats.
27314     * XXX this needs to be fixed.
27315     * The original code uses AST_FORMAT_AUDIO_MASK, but it is
27316     * unclear what to use here. We have global_capabilities, which is
27317     * configured from sip.conf, and sip_tech.capabilities, which is
27318     * hardwired to all audio formats.
27319     */
27320    format &= AST_FORMAT_AUDIO_MASK;
27321    if (!format) {
27322       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));
27323       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
27324       return NULL;
27325    }
27326    ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
27327 
27328    if (ast_strlen_zero(dest)) {
27329       ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
27330       *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
27331       return NULL;
27332    }
27333 
27334    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) {
27335       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest);
27336       *cause = AST_CAUSE_SWITCH_CONGESTION;
27337       return NULL;
27338    }
27339 
27340    p->outgoing_call = TRUE;
27341 
27342    snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest);
27343    ast_string_field_set(p, dialstring, dialstring);
27344 
27345    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
27346       dialog_unlink_all(p);
27347       dialog_unref(p, "unref dialog p from mem fail");
27348       /* sip_destroy(p); */
27349       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
27350       *cause = AST_CAUSE_SWITCH_CONGESTION;
27351       return NULL;
27352    }
27353 
27354    /* Save the destination, the SIP dial string */
27355    ast_copy_string(tmp, dest, sizeof(tmp));
27356 
27357    /* Find DNID and take it away */
27358    dnid = strchr(tmp, '!');
27359    if (dnid != NULL) {
27360       *dnid++ = '\0';
27361       ast_string_field_set(p, todnid, dnid);
27362    }
27363 
27364    /* Divvy up the items separated by slashes */
27365    AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
27366 
27367    /* Find at sign - @ */
27368    host = strchr(args.peerorhost, '@');
27369    if (host) {
27370       *host++ = '\0';
27371       ext = args.peerorhost;
27372       secret = strchr(ext, ':');
27373    }
27374    if (secret) {
27375       *secret++ = '\0';
27376       md5secret = strchr(secret, ':');
27377    }
27378    if (md5secret) {
27379       *md5secret++ = '\0';
27380       authname = strchr(md5secret, ':');
27381    }
27382    if (authname) {
27383       *authname++ = '\0';
27384       trans = strchr(authname, ':');
27385    }
27386    if (trans) {
27387       *trans++ = '\0';
27388       if (!strcasecmp(trans, "tcp"))
27389          transport = SIP_TRANSPORT_TCP;
27390       else if (!strcasecmp(trans, "tls"))
27391          transport = SIP_TRANSPORT_TLS;
27392       else {
27393          if (strcasecmp(trans, "udp"))
27394             ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans);
27395          transport = SIP_TRANSPORT_UDP;
27396       }
27397    } else { /* use default */
27398       transport = SIP_TRANSPORT_UDP;
27399    }
27400 
27401    if (!host) {
27402       ext = args.exten;
27403       host = args.peerorhost;
27404       remote_address = args.remote_address;
27405    } else {
27406       remote_address = args.remote_address;
27407       if (!ast_strlen_zero(args.exten)) {
27408          ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten);
27409       }
27410    }
27411 
27412    if (!ast_strlen_zero(remote_address)) {
27413       p->options->outboundproxy = proxy_from_config(remote_address, 0, NULL);
27414       if (!p->options->outboundproxy) {
27415          ast_log(LOG_WARNING, "Unable to parse outboundproxy %s. We will not use this remote IP address\n", remote_address);
27416       }
27417    }
27418 
27419    set_socket_transport(&p->socket, transport);
27420 
27421    /* We now have
27422       host = peer name, DNS host name or DNS domain (for SRV)
27423       ext = extension (user part of URI)
27424       dnid = destination of the call (applies to the To: header)
27425    */
27426    if (create_addr(p, host, NULL, 1)) {
27427       *cause = AST_CAUSE_UNREGISTERED;
27428       ast_debug(3, "Cant create SIP call - target device not registered\n");
27429       dialog_unlink_all(p);
27430       dialog_unref(p, "unref dialog p UNREGISTERED");
27431       /* sip_destroy(p); */
27432       return NULL;
27433    }
27434    if (ast_strlen_zero(p->peername) && ext)
27435       ast_string_field_set(p, peername, ext);
27436    /* Recalculate our side, and recalculate Call ID */
27437    ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
27438    build_via(p);
27439 
27440    /* Change the dialog callid. */
27441    change_callid_pvt(p, NULL);
27442 
27443    /* We have an extension to call, don't use the full contact here */
27444    /* This to enable dialing registered peers with extension dialling,
27445       like SIP/peername/extension   
27446       SIP/peername will still use the full contact
27447     */
27448    if (ext) {
27449       ast_string_field_set(p, username, ext);
27450       ast_string_field_set(p, fullcontact, NULL);
27451    }
27452    if (secret && !ast_strlen_zero(secret))
27453       ast_string_field_set(p, peersecret, secret);
27454 
27455    if (md5secret && !ast_strlen_zero(md5secret))
27456       ast_string_field_set(p, peermd5secret, md5secret);
27457 
27458    if (authname && !ast_strlen_zero(authname))
27459       ast_string_field_set(p, authname, authname);
27460 #if 0
27461    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
27462 #endif
27463    p->prefcodec = oldformat;           /* Format for this call */
27464    p->jointcapability = oldformat & p->capability;
27465    sip_pvt_lock(p);
27466    tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */
27467    if (sip_cfg.callevents)
27468       manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
27469          "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
27470          p->owner ? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername);
27471    sip_pvt_unlock(p);
27472    if (!tmpc) {
27473       dialog_unlink_all(p);
27474       /* sip_destroy(p); */
27475    } else {
27476       ast_channel_unlock(tmpc);
27477    }
27478    dialog_unref(p, "toss pvt ptr at end of sip_request_call");
27479    ast_update_use_count();
27480    restart_monitor();
27481    return tmpc;
27482 }

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

04108 {
04109    if (p->final_destruction_scheduled) {
04110       return; /* already set final destruction */
04111    }
04112 
04113    if (ms < 0) {
04114       if (p->timer_t1 == 0) {
04115          p->timer_t1 = global_t1;   /* Set timer T1 if not set (RFC 3261) */
04116       }
04117       if (p->timer_b == 0) {
04118          p->timer_b = global_timer_b;  /* Set timer B if not set (RFC 3261) */
04119       }
04120       ms = p->timer_t1 * 64;
04121    }
04122    if (sip_debug_test_pvt(p)) {
04123       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
04124    }
04125    if (sip_cancel_destroy(p)) {
04126       ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
04127    }
04128 
04129    if (p->do_history) {
04130       append_history(p, "SchedDestroy", "%d ms", ms);
04131    }
04132    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct"));
04133 
04134    if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) {
04135       stop_session_timer(p);
04136    }
04137 }

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

References sip_scheddestroy().

Referenced by handle_request_bye().

04095 {
04096    if (p->final_destruction_scheduled) {
04097       return; /* already set final destruction */
04098    }
04099 
04100    sip_scheddestroy(p, ms);
04101    if (p->autokillid != -1) {
04102       p->final_destruction_scheduled = 1;
04103    }
04104 }

static void sip_send_all_mwi_subscriptions ( void   )  [static]

Send all MWI subscriptions.

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

30509 {
30510    ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
30511       struct sip_subscription_mwi *saved;
30512       ASTOBJ_WRLOCK(iterator);
30513       AST_SCHED_DEL(sched, iterator->resub);
30514       saved = ASTOBJ_REF(iterator);
30515       if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, saved)) < 0) {
30516          ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy);
30517       }
30518       ASTOBJ_UNLOCK(iterator);
30519    } while (0));
30520 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

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

30485 {
30486    int ms;
30487    int regspacing;
30488    if (!regobjs)
30489       return;
30490    regspacing = default_expiry * 1000/regobjs;
30491    if (regspacing > 100) {
30492       regspacing = 100;
30493    }
30494    ms = regspacing;
30495    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
30496       ASTOBJ_WRLOCK(iterator);
30497       ms += regspacing;
30498       AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator,
30499                         registry_unref(_data, "REPLACE sched del decs the refcount"),
30500                         registry_unref(iterator, "REPLACE sched add failure decs the refcount"),
30501                         registry_addref(iterator, "REPLACE sched add incs the refcount"));
30502       ASTOBJ_UNLOCK(iterator);
30503    } while (0)
30504    );
30505 }

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

26443 {
26444    /* Called with peer lock, but releases it */
26445    struct sip_pvt *p;
26446    int newmsgs = 0, oldmsgs = 0;
26447    const char *vmexten = NULL;
26448 
26449    ao2_lock(peer);
26450 
26451    if (peer->vmexten) {
26452       vmexten = ast_strdupa(peer->vmexten);
26453    }
26454 
26455    if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) {
26456       update_peer_lastmsgssent(peer, -1, 1);
26457       ao2_unlock(peer);
26458       return 0;
26459    }
26460 
26461    /* Do we have an IP address? If not, skip this peer */
26462    if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) {
26463       update_peer_lastmsgssent(peer, -1, 1);
26464       ao2_unlock(peer);
26465       return 0;
26466    }
26467 
26468    /* Attempt to use cached mwi to get message counts. */
26469    if (!get_cached_mwi(peer, &newmsgs, &oldmsgs) && !cache_only) {
26470       /* Fall back to manually checking the mailbox if not cache_only and get_cached_mwi failed */
26471       struct ast_str *mailbox_str = ast_str_alloca(512);
26472       peer_mailboxes_to_str(&mailbox_str, peer);
26473       ao2_unlock(peer);
26474       /* If there is no mailbox do nothing */
26475       if (!ast_str_strlen(mailbox_str)) {
26476          update_peer_lastmsgssent(peer, -1, 0);
26477          return 0;
26478       }
26479       ast_app_inboxcount(ast_str_buffer(mailbox_str), &newmsgs, &oldmsgs);
26480       ao2_lock(peer);
26481    }
26482 
26483    if (peer->mwipvt) {
26484       /* Base message on subscription */
26485       p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt");
26486       ao2_unlock(peer);
26487    } else {
26488       ao2_unlock(peer);
26489       /* Build temporary dialog for this message */
26490       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
26491          update_peer_lastmsgssent(peer, -1, 0);
26492          return -1;
26493       }
26494 
26495       /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer
26496        * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy
26497        * the peer's socket information to the sip_pvt we just allocated
26498        */
26499       set_socket_transport(&p->socket, 0);
26500       if (create_addr_from_peer(p, peer)) {
26501          /* Maybe they're not registered, etc. */
26502          dialog_unlink_all(p);
26503          dialog_unref(p, "unref dialog p just created via sip_alloc");
26504          update_peer_lastmsgssent(peer, -1, 0);
26505          return 0;
26506       }
26507       /* Recalculate our side, and recalculate Call ID */
26508       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
26509       build_via(p);
26510 
26511       ao2_lock(peer);
26512       if (!ast_strlen_zero(peer->mwi_from)) {
26513          ast_string_field_set(p, mwi_from, peer->mwi_from);
26514       } else if (!ast_strlen_zero(default_mwi_from)) {
26515          ast_string_field_set(p, mwi_from, default_mwi_from);
26516       }
26517       ao2_unlock(peer);
26518 
26519       /* Change the dialog callid. */
26520       change_callid_pvt(p, NULL);
26521 
26522       /* Destroy this session after 32 secs */
26523       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
26524    }
26525 
26526    /* 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,
26527       we really need to have a lock on it */
26528    sip_pvt_lock(p);
26529 
26530    /* Send MWI */
26531    ast_set_flag(&p->flags[0], SIP_OUTGOING);
26532    /* the following will decrement the refcount on p as it finishes */
26533    transmit_notify_with_mwi(p, newmsgs, oldmsgs, vmexten);
26534    sip_pvt_unlock(p);
26535    dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer.");
26536 
26537    update_peer_lastmsgssent(peer, ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)), 0);
26538 
26539    return 0;
26540 }

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

04643 {
04644    struct sip_pvt *p = chan->tech_pvt;
04645 
04646    if (subclass != AST_HTML_URL)
04647       return -1;
04648 
04649    ast_string_field_build(p, url, "<%s>;mode=active", data);
04650 
04651    if (sip_debug_test_pvt(p))
04652       ast_debug(1, "Send URL %s, state = %u!\n", data, chan->_state);
04653 
04654    switch (chan->_state) {
04655    case AST_STATE_RING:
04656       transmit_response(p, "100 Trying", &p->initreq);
04657       break;
04658    case AST_STATE_RINGING:
04659       transmit_response(p, "180 Ringing", &p->initreq);
04660       break;
04661    case AST_STATE_UP:
04662       if (!p->pendinginvite) {      /* We are up, and have no outstanding invite */
04663          transmit_reinvite_with_sdp(p, FALSE, FALSE);
04664       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04665          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
04666       }  
04667       break;
04668    default:
04669       ast_log(LOG_WARNING, "Don't know how to send URI when state is %u!\n", chan->_state);
04670    }
04671 
04672    return 0;
04673 }

static int sip_sendtext ( struct ast_channel ast,
const char *  text 
) [static]

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

04687 {
04688    struct sip_pvt *dialog = ast->tech_pvt;
04689    int debug;
04690 
04691    if (!dialog) {
04692       return -1;
04693    }
04694    /* NOT ast_strlen_zero, because a zero-length message is specifically
04695     * allowed by RFC 3428 (See section 10, Examples) */
04696    if (!text) {
04697       return 0;
04698    }
04699    if(!is_method_allowed(&dialog->allowed_methods, SIP_MESSAGE)) {
04700       ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n");
04701       return(0);
04702    }
04703 
04704    debug = sip_debug_test_pvt(dialog);
04705    if (debug) {
04706       ast_verbose("Sending text %s on %s\n", text, ast->name);
04707    }
04708 
04709    transmit_message_with_text(dialog, text);
04710    return 0;   
04711 }

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

19769 {
19770    switch (cmd) {
19771    case CLI_INIT:
19772       e->command = "sip set history {on|off}";
19773       e->usage =
19774          "Usage: sip set history {on|off}\n"
19775          "       Enables/Disables recording of SIP dialog history for debugging purposes.\n"
19776          "       Use 'sip show history' to view the history of a call number.\n";
19777       return NULL;
19778    case CLI_GENERATE:
19779       return NULL;
19780    }
19781 
19782    if (a->argc != e->args)
19783       return CLI_SHOWUSAGE;
19784 
19785    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
19786       recordhistory = TRUE;
19787       ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n");
19788    } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
19789       recordhistory = FALSE;
19790       ast_cli(a->fd, "SIP History Recording Disabled\n");
19791    } else {
19792       return CLI_SHOWUSAGE;
19793    }
19794    return CLI_SUCCESS;
19795 }

static void sip_set_redirstr ( struct sip_pvt *  p,
char *  reason 
) [static]

Translate referring cause.

Definition at line 15565 of file chan_sip.c.

References ast_string_field_set.

Referenced by get_rdnis().

15565                                                               {
15566 
15567    if (!strcmp(reason, "unknown")) {
15568       ast_string_field_set(p, redircause, "UNKNOWN");
15569    } else if (!strcmp(reason, "user-busy")) {
15570       ast_string_field_set(p, redircause, "BUSY");
15571    } else if (!strcmp(reason, "no-answer")) {
15572       ast_string_field_set(p, redircause, "NOANSWER");
15573    } else if (!strcmp(reason, "unavailable")) {
15574       ast_string_field_set(p, redircause, "UNREACHABLE");
15575    } else if (!strcmp(reason, "unconditional")) {
15576       ast_string_field_set(p, redircause, "UNCONDITIONAL");
15577    } else if (!strcmp(reason, "time-of-day")) {
15578       ast_string_field_set(p, redircause, "UNKNOWN");
15579    } else if (!strcmp(reason, "do-not-disturb")) {
15580       ast_string_field_set(p, redircause, "UNKNOWN");
15581    } else if (!strcmp(reason, "deflection")) {
15582       ast_string_field_set(p, redircause, "UNKNOWN");
15583    } else if (!strcmp(reason, "follow-me")) {
15584       ast_string_field_set(p, redircause, "UNKNOWN");
15585    } else if (!strcmp(reason, "out-of-service")) {
15586       ast_string_field_set(p, redircause, "UNREACHABLE");
15587    } else if (!strcmp(reason, "away")) {
15588       ast_string_field_set(p, redircause, "UNREACHABLE");
15589    } else {
15590       ast_string_field_set(p, redircause, "UNKNOWN");
15591    }
15592 }

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

30104 {
30105    struct sip_pvt *p;
30106    int changed = 0;
30107 
30108    /* Lock the channel and the private safely. */
30109    ast_channel_lock(chan);
30110    p = chan->tech_pvt;
30111    if (!p) {
30112       ast_channel_unlock(chan);
30113       return -1;
30114    }
30115    sip_pvt_lock(p);
30116    if (p->owner != chan) {
30117       /* I suppose it could be argued that if this happens it is a bug. */
30118       ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name);
30119       sip_pvt_unlock(p);
30120       ast_channel_unlock(chan);
30121       return 0;
30122    }
30123 
30124    /* Disable early RTP bridge  */
30125    if ((instance || vinstance || tinstance) &&
30126       !ast_bridged_channel(chan) &&
30127       !sip_cfg.directrtpsetup) {
30128       sip_pvt_unlock(p);
30129       ast_channel_unlock(chan);
30130       return 0;
30131    }
30132 
30133    if (p->alreadygone) {
30134       /* If we're destroyed, don't bother */
30135       sip_pvt_unlock(p);
30136       ast_channel_unlock(chan);
30137       return 0;
30138    }
30139 
30140    /* if this peer cannot handle reinvites of the media stream to devices
30141       that are known to be behind a NAT, then stop the process now
30142    */
30143    if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
30144       sip_pvt_unlock(p);
30145       ast_channel_unlock(chan);
30146       return 0;
30147    }
30148 
30149    if (instance) {
30150       changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip);
30151 
30152       if (p->rtp) {
30153          /* Prevent audio RTCP reads */
30154          ast_channel_set_fd(chan, 1, -1);
30155          /* Silence RTCP while audio RTP is inactive */
30156          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0);
30157       }
30158    } else if (!ast_sockaddr_isnull(&p->redirip)) {
30159       memset(&p->redirip, 0, sizeof(p->redirip));
30160       changed = 1;
30161 
30162       if (p->rtp) {
30163          /* Enable RTCP since it will be inactive if we're coming back
30164           * from a reinvite */
30165          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1);
30166          /* Enable audio RTCP reads */
30167          ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(p->rtp, 1));
30168       }
30169    }
30170 
30171    if (vinstance) {
30172       changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip);
30173 
30174       if (p->vrtp) {
30175          /* Prevent video RTCP reads */
30176          ast_channel_set_fd(chan, 3, -1);
30177          /* Silence RTCP while video RTP is inactive */
30178          ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 0);
30179       }
30180    } else if (!ast_sockaddr_isnull(&p->vredirip)) {
30181       memset(&p->vredirip, 0, sizeof(p->vredirip));
30182       changed = 1;
30183 
30184       if (p->vrtp) {
30185          /* Enable RTCP since it will be inactive if we're coming back
30186           * from a reinvite */
30187          ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_RTCP, 1);
30188          /* Enable video RTCP reads */
30189          ast_channel_set_fd(chan, 3, ast_rtp_instance_fd(p->vrtp, 1));
30190       }
30191    }
30192 
30193    if (tinstance) {
30194       changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip);
30195    } else if (!ast_sockaddr_isnull(&p->tredirip)) {
30196       memset(&p->tredirip, 0, sizeof(p->tredirip));
30197       changed = 1;
30198    }
30199    if (codecs && (p->redircodecs != codecs)) {
30200       p->redircodecs = codecs;
30201       changed = 1;
30202    }
30203 
30204    if (ast_test_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING) && !p->outgoing_call) {
30205       /* We only wish to withhold sending the initial direct media reinvite on the incoming dialog.
30206        * Further direct media reinvites beyond the initial should be sent. In order to allow further
30207        * direct media reinvites to be sent, we clear this flag.
30208        */
30209       ast_clear_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING);
30210       sip_pvt_unlock(p);
30211       ast_channel_unlock(chan);
30212       return 0;
30213    }
30214 
30215    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
30216       if (chan->_state != AST_STATE_UP) {     /* We are in early state */
30217          if (p->do_history)
30218             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
30219          ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
30220       } else if (!p->pendinginvite) {   /* We are up, and have no outstanding invite */
30221          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));
30222          transmit_reinvite_with_sdp(p, FALSE, FALSE);
30223       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
30224          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));
30225          /* We have a pending Invite. Send re-invite when we're done with the invite */
30226          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
30227       }
30228    }
30229    /* Reset lastrtprx timer */
30230    p->lastrtprx = p->lastrtptx = time(NULL);
30231    sip_pvt_unlock(p);
30232    ast_channel_unlock(chan);
30233    return 0;
30234 }

static int sip_set_udptl_peer ( struct ast_channel chan,
struct ast_udptl udptl 
) [static]

Definition at line 29904 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.

29905 {
29906    struct sip_pvt *p;
29907 
29908    /* Lock the channel and the private safely. */
29909    ast_channel_lock(chan);
29910    p = chan->tech_pvt;
29911    if (!p) {
29912       ast_channel_unlock(chan);
29913       return -1;
29914    }
29915    sip_pvt_lock(p);
29916    if (p->owner != chan) {
29917       /* I suppose it could be argued that if this happens it is a bug. */
29918       ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name);
29919       sip_pvt_unlock(p);
29920       ast_channel_unlock(chan);
29921       return 0;
29922    }
29923 
29924    if (udptl) {
29925       ast_udptl_get_peer(udptl, &p->udptlredirip);
29926    } else {
29927       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
29928    }
29929    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
29930       if (!p->pendinginvite) {
29931          ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s\n",
29932                p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip));
29933          transmit_reinvite_with_sdp(p, TRUE, FALSE);
29934       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
29935          ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s\n",
29936                p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip));
29937          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
29938       }
29939    }
29940    /* Reset lastrtprx timer */
29941    p->lastrtprx = p->lastrtptx = time(NULL);
29942    sip_pvt_unlock(p);
29943    ast_channel_unlock(chan);
29944    return 0;
29945 }

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

04499 {
04500    int res = -1;
04501    struct sip_pvt *p = chan->tech_pvt;
04502 
04503         if (!p) {
04504          ast_log(LOG_ERROR, "Attempt to Ref a null pointer.  sip private structure is gone!\n");
04505          return -1;
04506         }
04507 
04508    sip_pvt_lock(p);
04509 
04510    switch (option) {
04511    case AST_OPTION_FORMAT_READ:
04512       if (p->rtp) {
04513          res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data);
04514       }
04515       break;
04516    case AST_OPTION_FORMAT_WRITE:
04517       if (p->rtp) {
04518          res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data);
04519       }
04520       break;
04521    case AST_OPTION_MAKE_COMPATIBLE:
04522       if (p->rtp) {
04523          res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data);
04524       }
04525       break;
04526    case AST_OPTION_DIGIT_DETECT:
04527       if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
04528           (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
04529          char *cp = (char *) data;
04530 
04531          ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name);
04532          if (*cp) {
04533             enable_dsp_detect(p);
04534          } else {
04535             disable_dsp_detect(p);
04536          }
04537          res = 0;
04538       }
04539       break;
04540    case AST_OPTION_SECURE_SIGNALING:
04541       p->req_secure_signaling = *(unsigned int *) data;
04542       res = 0;
04543       break;
04544    case AST_OPTION_SECURE_MEDIA:
04545       ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP);
04546       res = 0;
04547       break;
04548    default:
04549       break;
04550    }
04551 
04552    sip_pvt_unlock(p);
04553 
04554    return res;
04555 }

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

19228 {
19229    struct sip_pvt *cur;
19230    size_t len;
19231    int found = 0;
19232    struct ao2_iterator i;
19233 
19234    switch (cmd) {
19235    case CLI_INIT:
19236       e->command = "sip show channel";
19237       e->usage =
19238          "Usage: sip show channel <call-id>\n"
19239          "       Provides detailed status on a given SIP dialog (identified by SIP call-id).\n";
19240       return NULL;
19241    case CLI_GENERATE:
19242       return complete_sipch(a->line, a->word, a->pos, a->n);
19243    }
19244 
19245    if (a->argc != 4)
19246       return CLI_SHOWUSAGE;
19247    len = strlen(a->argv[3]);
19248    
19249    i = ao2_iterator_init(dialogs, 0);
19250    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
19251       sip_pvt_lock(cur);
19252 
19253       if (!strncasecmp(cur->callid, a->argv[3], len)) {
19254          char formatbuf[SIPBUFSIZE/2];
19255          ast_cli(a->fd, "\n");
19256          if (cur->subscribed != NONE)
19257             ast_cli(a->fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
19258          else
19259             ast_cli(a->fd, "  * SIP Call\n");
19260          ast_cli(a->fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
19261          ast_cli(a->fd, "  Call-ID:                %s\n", cur->callid);
19262          ast_cli(a->fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
19263          ast_cli(a->fd, "  Our Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability));
19264          ast_cli(a->fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
19265          ast_cli(a->fd, "  Their Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability));
19266          ast_cli(a->fd, "  Joint Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability));
19267          ast_cli(a->fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
19268          ast_cli(a->fd, "  T.38 support            %s\n", AST_CLI_YESNO(cur->udptl != NULL));
19269          ast_cli(a->fd, "  Video support           %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
19270          ast_cli(a->fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
19271          ast_cli(a->fd, "  Theoretical Address:    %s\n", ast_sockaddr_stringify(&cur->sa));
19272          ast_cli(a->fd, "  Received Address:       %s\n", ast_sockaddr_stringify(&cur->recv));
19273          ast_cli(a->fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
19274          ast_cli(a->fd, "  Force rport:            %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT)));
19275          if (ast_sockaddr_isnull(&cur->redirip)) {
19276             ast_cli(a->fd,
19277                "  Audio IP:               %s (local)\n",
19278                ast_sockaddr_stringify_addr(&cur->ourip));
19279          } else {
19280             ast_cli(a->fd,
19281                "  Audio IP:               %s (Outside bridge)\n",
19282                ast_sockaddr_stringify_addr(&cur->redirip));
19283          }
19284          ast_cli(a->fd, "  Our Tag:                %s\n", cur->tag);
19285          ast_cli(a->fd, "  Their Tag:              %s\n", cur->theirtag);
19286          ast_cli(a->fd, "  SIP User agent:         %s\n", cur->useragent);
19287          if (!ast_strlen_zero(cur->username))
19288             ast_cli(a->fd, "  Username:               %s\n", cur->username);
19289          if (!ast_strlen_zero(cur->peername))
19290             ast_cli(a->fd, "  Peername:               %s\n", cur->peername);
19291          if (!ast_strlen_zero(cur->uri))
19292             ast_cli(a->fd, "  Original uri:           %s\n", cur->uri);
19293          if (!ast_strlen_zero(cur->cid_num))
19294             ast_cli(a->fd, "  Caller-ID:              %s\n", cur->cid_num);
19295          ast_cli(a->fd, "  Need Destroy:           %s\n", AST_CLI_YESNO(cur->needdestroy));
19296          ast_cli(a->fd, "  Last Message:           %s\n", cur->lastmsg);
19297          ast_cli(a->fd, "  Promiscuous Redir:      %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR)));
19298          ast_cli(a->fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
19299          ast_cli(a->fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
19300          ast_cli(a->fd, "  SIP Options:            ");
19301          if (cur->sipoptions) {
19302             int x;
19303             for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
19304                if (cur->sipoptions & sip_options[x].id)
19305                   ast_cli(a->fd, "%s ", sip_options[x].text);
19306             }
19307             ast_cli(a->fd, "\n");
19308          } else
19309             ast_cli(a->fd, "(none)\n");
19310 
19311          if (!cur->stimer)
19312             ast_cli(a->fd, "  Session-Timer:          Uninitiallized\n");
19313          else {
19314             ast_cli(a->fd, "  Session-Timer:          %s\n", cur->stimer->st_active ? "Active" : "Inactive");
19315             if (cur->stimer->st_active == TRUE) {
19316                ast_cli(a->fd, "  S-Timer Interval:       %d\n", cur->stimer->st_interval);
19317                ast_cli(a->fd, "  S-Timer Refresher:      %s\n", strefresher2str(cur->stimer->st_ref));
19318                ast_cli(a->fd, "  S-Timer Sched Id:       %d\n", cur->stimer->st_schedid);
19319                ast_cli(a->fd, "  S-Timer Peer Sts:       %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive");
19320                ast_cli(a->fd, "  S-Timer Cached Min-SE:  %d\n", cur->stimer->st_cached_min_se);
19321                ast_cli(a->fd, "  S-Timer Cached SE:      %d\n", cur->stimer->st_cached_max_se);
19322                ast_cli(a->fd, "  S-Timer Cached Ref:     %s\n", strefresherparam2str(cur->stimer->st_cached_ref));
19323                ast_cli(a->fd, "  S-Timer Cached Mode:    %s\n", stmode2str(cur->stimer->st_cached_mode));
19324             }
19325          }
19326 
19327          /* add transport and media types */
19328          ast_cli(a->fd, "  Transport:              %s\n", transport2str(cur->socket.type));
19329          ast_cli(a->fd, "  Media:                  %s\n", cur->srtp ? "SRTP" : cur->rtp ? "RTP" : "None");
19330 
19331          ast_cli(a->fd, "\n\n");
19332 
19333          found++;
19334       }
19335 
19336       sip_pvt_unlock(cur);
19337 
19338       ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next");
19339    }
19340    ao2_iterator_destroy(&i);
19341 
19342    if (!found)
19343       ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
19344 
19345    return CLI_SUCCESS;
19346 }

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

19035 {
19036    struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
19037 
19038 
19039    if (cmd == CLI_INIT) {
19040       e->command = "sip show {channels|subscriptions}";
19041       e->usage =
19042          "Usage: sip show channels\n"
19043          "       Lists all currently active SIP calls (dialogs).\n"
19044          "Usage: sip show subscriptions\n"
19045          "       Lists active SIP subscriptions.\n";
19046       return NULL;
19047    } else if (cmd == CLI_GENERATE)
19048       return NULL;
19049 
19050    if (a->argc != e->args)
19051       return CLI_SHOWUSAGE;
19052    arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions");
19053    if (!arg.subscriptions)
19054       ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer");
19055    else
19056       ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
19057 
19058    /* iterate on the container and invoke the callback on each item */
19059    ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels");
19060    
19061    /* print summary information */
19062    ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans,
19063       (arg.subscriptions ? "subscription" : "dialog"),
19064       ESS(arg.numchans));  /* ESS(n) returns an "s" if n>1 */
19065    return CLI_SUCCESS;
19066 #undef FORMAT
19067 #undef FORMAT2
19068 #undef FORMAT3
19069 }

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

18656 {
18657    struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
18658 
18659    switch (cmd) {
18660    case CLI_INIT:
18661       e->command = "sip show channelstats";
18662       e->usage =
18663          "Usage: sip show channelstats\n"
18664          "       Lists all currently active SIP channel's RTCP statistics.\n"
18665          "       Note that calls in the much optimized RTP P2P bridge mode will not show any packets here.";
18666       return NULL;
18667    case CLI_GENERATE:
18668       return NULL;
18669    }
18670 
18671    if (a->argc != 3)
18672       return CLI_SHOWUSAGE;
18673 
18674    ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter");
18675    /* iterate on the container and invoke the callback on each item */
18676    ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats");
18677    ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : "");
18678    return CLI_SUCCESS;
18679 }

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

17904 {
17905    struct domain *d;
17906 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
17907 
17908    switch (cmd) {
17909    case CLI_INIT:
17910       e->command = "sip show domains";
17911       e->usage =
17912          "Usage: sip show domains\n"
17913          "       Lists all configured SIP local domains.\n"
17914          "       Asterisk only responds to SIP messages to local domains.\n";
17915       return NULL;
17916    case CLI_GENERATE:
17917       return NULL;
17918    }
17919 
17920    if (AST_LIST_EMPTY(&domain_list)) {
17921       ast_cli(a->fd, "SIP Domain support not enabled.\n\n");
17922       return CLI_SUCCESS;
17923    } else {
17924       ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
17925       AST_LIST_LOCK(&domain_list);
17926       AST_LIST_TRAVERSE(&domain_list, d, list)
17927          ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
17928             domain_mode_to_text(d->mode));
17929       AST_LIST_UNLOCK(&domain_list);
17930       ast_cli(a->fd, "\n");
17931       return CLI_SUCCESS;
17932    }
17933 }

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

19350 {
19351    struct sip_pvt *cur;
19352    size_t len;
19353    int found = 0;
19354    struct ao2_iterator i;
19355 
19356    switch (cmd) {
19357    case CLI_INIT:
19358       e->command = "sip show history";
19359       e->usage =
19360          "Usage: sip show history <call-id>\n"
19361          "       Provides detailed dialog history on a given SIP call (specified by call-id).\n";
19362       return NULL;
19363    case CLI_GENERATE:
19364       return complete_sip_show_history(a->line, a->word, a->pos, a->n);
19365    }
19366 
19367    if (a->argc != 4)
19368       return CLI_SHOWUSAGE;
19369 
19370    if (!recordhistory)
19371       ast_cli(a->fd, "\n***Note: History recording is currently DISABLED.  Use 'sip set history on' to ENABLE.\n");
19372 
19373    len = strlen(a->argv[3]);
19374 
19375    i = ao2_iterator_init(dialogs, 0);
19376    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
19377       sip_pvt_lock(cur);
19378       if (!strncasecmp(cur->callid, a->argv[3], len)) {
19379          struct sip_history *hist;
19380          int x = 0;
19381 
19382          ast_cli(a->fd, "\n");
19383          if (cur->subscribed != NONE)
19384             ast_cli(a->fd, "  * Subscription\n");
19385          else
19386             ast_cli(a->fd, "  * SIP Call\n");
19387          if (cur->history)
19388             AST_LIST_TRAVERSE(cur->history, hist, list)
19389                ast_cli(a->fd, "%d. %s\n", ++x, hist->event);
19390          if (x == 0)
19391             ast_cli(a->fd, "Call '%s' has no history\n", cur->callid);
19392          found++;
19393       }
19394       sip_pvt_unlock(cur);
19395       ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next");
19396    }
19397    ao2_iterator_destroy(&i);
19398 
19399    if (!found)
19400       ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
19401 
19402    return CLI_SUCCESS;
19403 }

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

16938 {
16939 #define FORMAT "%-25.25s %-15.15s %-15.15s \n"
16940 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
16941    char ilimits[40];
16942    char iused[40];
16943    int showall = FALSE;
16944    struct ao2_iterator i;
16945    struct sip_peer *peer;
16946    
16947    switch (cmd) {
16948    case CLI_INIT:
16949       e->command = "sip show inuse";
16950       e->usage =
16951          "Usage: sip show inuse [all]\n"
16952          "       List all SIP devices usage counters and limits.\n"
16953          "       Add option \"all\" to show all devices, not only those with a limit.\n";
16954       return NULL;
16955    case CLI_GENERATE:
16956       return NULL;
16957    }
16958 
16959    if (a->argc < 3)
16960       return CLI_SHOWUSAGE;
16961 
16962    if (a->argc == 4 && !strcmp(a->argv[3], "all"))
16963       showall = TRUE;
16964    
16965    ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit");
16966 
16967    i = ao2_iterator_init(peers, 0);
16968    while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) {
16969       ao2_lock(peer);
16970       if (peer->call_limit)
16971          snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit);
16972       else
16973          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
16974       snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold);
16975       if (showall || peer->call_limit)
16976          ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits);
16977       ao2_unlock(peer);
16978       unref_peer(peer, "toss iterator pointer");
16979    }
16980    ao2_iterator_destroy(&i);
16981 
16982    return CLI_SUCCESS;
16983 #undef FORMAT
16984 #undef FORMAT2
16985 }

static char * sip_show_mwi ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 18913 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.

18914 {
18915 #define FORMAT  "%-30.30s  %-12.12s  %-10.10s  %-10.10s\n"
18916    char host[80];
18917    
18918    switch (cmd) {
18919    case CLI_INIT:
18920       e->command = "sip show mwi";
18921       e->usage =
18922          "Usage: sip show mwi\n"
18923          "       Provides a list of MWI subscriptions and status.\n";
18924       return NULL;
18925    case CLI_GENERATE:
18926       return NULL;
18927    }
18928    
18929    ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed");
18930    
18931    ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
18932       ASTOBJ_RDLOCK(iterator);
18933       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
18934       ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed));
18935       ASTOBJ_UNLOCK(iterator);
18936    } while(0));
18937 
18938    return CLI_SUCCESS;
18939 #undef FORMAT
18940 }

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

17525 {
17526    char tmp[256];
17527    
17528    switch (cmd) {
17529    case CLI_INIT:
17530       e->command = "sip show objects";
17531       e->usage =
17532          "Usage: sip show objects\n"
17533          "       Lists status of known SIP objects\n";
17534       return NULL;
17535    case CLI_GENERATE:
17536       return NULL;
17537    }  
17538 
17539    if (a->argc != 3)
17540       return CLI_SHOWUSAGE;
17541    ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
17542    ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers");
17543    ast_cli(a->fd, "-= Peer objects by IP =-\n\n"); 
17544    ao2_t_callback(peers_by_ip, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers_by_ip");
17545    ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs);
17546    ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &regl);
17547    ast_cli(a->fd, "-= Dialog objects:\n\n");
17548    ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs");
17549    return CLI_SUCCESS;
17550 }

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

17959 {
17960    switch (cmd) {
17961    case CLI_INIT:
17962       e->command = "sip show peer";
17963       e->usage =
17964          "Usage: sip show peer <name> [load]\n"
17965          "       Shows all details on one SIP peer and the current status.\n"
17966          "       Option \"load\" forces lookup of peer in realtime storage.\n";
17967       return NULL;
17968    case CLI_GENERATE:
17969       return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
17970    }
17971    return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
17972 }

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

17261 {
17262    switch (cmd) {
17263    case CLI_INIT:
17264       e->command = "sip show peers";
17265       e->usage =
17266          "Usage: sip show peers [like <pattern>]\n"
17267          "       Lists all known SIP peers.\n"
17268          "       Optional regular expression pattern is used to filter the peer list.\n";
17269       return NULL;
17270    case CLI_GENERATE:
17271       return NULL;
17272    }
17273 
17274    return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
17275 }

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

18494 {
18495 #define FORMAT2 "%-39.39s %-6.6s %-12.12s  %8.8s %-20.20s %-25.25s\n"
18496 #define FORMAT  "%-39.39s %-6.6s %-12.12s  %8d %-20.20s %-25.25s\n"
18497    char host[80];
18498    char user[80];
18499    char tmpdat[256];
18500    struct ast_tm tm;
18501    int counter = 0;
18502 
18503    switch (cmd) {
18504    case CLI_INIT:
18505       e->command = "sip show registry";
18506       e->usage =
18507          "Usage: sip show registry\n"
18508          "       Lists all registration requests and status.\n";
18509       return NULL;
18510    case CLI_GENERATE:
18511       return NULL;
18512    }
18513 
18514    if (a->argc != 3)
18515       return CLI_SHOWUSAGE;
18516    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time");
18517    
18518    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
18519       ASTOBJ_RDLOCK(iterator);
18520       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
18521       snprintf(user, sizeof(user), "%s", iterator->username);
18522       if (!ast_strlen_zero(iterator->regdomain)) {
18523          snprintf(tmpdat, sizeof(tmpdat), "%s", user);
18524          snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);}
18525       if (iterator->regdomainport) {
18526          snprintf(tmpdat, sizeof(tmpdat), "%s", user);
18527          snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);}
18528       if (iterator->regtime.tv_sec) {
18529          ast_localtime(&iterator->regtime, &tm, NULL);
18530          ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
18531       } else
18532          tmpdat[0] = '\0';
18533       ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
18534       ASTOBJ_UNLOCK(iterator);
18535       counter++;
18536    } while(0));
18537    ast_cli(a->fd, "%d SIP registrations.\n", counter);
18538    return CLI_SUCCESS;
18539 #undef FORMAT
18540 #undef FORMAT2
18541 }

static char * sip_show_sched ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 18450 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.

18451 {
18452    struct ast_str *cbuf;
18453    struct ast_cb_names cbnames = {9, { "retrans_pkt",
18454                                         "__sip_autodestruct",
18455                                         "expire_register",
18456                                         "auto_congest",
18457                                         "sip_reg_timeout",
18458                                         "sip_poke_peer_s",
18459                                         "sip_poke_noanswer",
18460                                         "sip_reregister",
18461                                         "sip_reinvite_retry"},
18462                            { retrans_pkt,
18463                                      __sip_autodestruct,
18464                                      expire_register,
18465                                      auto_congest,
18466                                      sip_reg_timeout,
18467                                      sip_poke_peer_s,
18468                                      sip_poke_noanswer,
18469                                      sip_reregister,
18470                                      sip_reinvite_retry}};
18471    
18472    switch (cmd) {
18473    case CLI_INIT:
18474       e->command = "sip show sched";
18475       e->usage =
18476          "Usage: sip show sched\n"
18477          "       Shows stats on what's in the sched queue at the moment\n";
18478       return NULL;
18479    case CLI_GENERATE:
18480       return NULL;
18481    }
18482 
18483    cbuf = ast_str_alloca(2048);
18484 
18485    ast_cli(a->fd, "\n");
18486    ast_sched_report(sched, &cbuf, &cbnames);
18487    ast_cli(a->fd, "%s", ast_str_buffer(cbuf));
18488 
18489    return CLI_SUCCESS;
18490 }

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

18685 {
18686    int realtimepeers;
18687    int realtimeregs;
18688    char codec_buf[SIPBUFSIZE];
18689    const char *msg;  /* temporary msg pointer */
18690    struct sip_auth_container *credentials;
18691 
18692    switch (cmd) {
18693    case CLI_INIT:
18694       e->command = "sip show settings";
18695       e->usage =
18696          "Usage: sip show settings\n"
18697          "       Provides detailed list of the configuration of the SIP channel.\n";
18698       return NULL;
18699    case CLI_GENERATE:
18700       return NULL;
18701    }
18702 
18703    if (a->argc != 3)
18704       return CLI_SHOWUSAGE;
18705 
18706    realtimepeers = ast_check_realtime("sippeers");
18707    realtimeregs = ast_check_realtime("sipregs");
18708 
18709    ast_mutex_lock(&authl_lock);
18710    credentials = authl;
18711    if (credentials) {
18712       ao2_t_ref(credentials, +1, "Ref global auth for show");
18713    }
18714    ast_mutex_unlock(&authl_lock);
18715 
18716    ast_cli(a->fd, "\n\nGlobal Settings:\n");
18717    ast_cli(a->fd, "----------------\n");
18718    ast_cli(a->fd, "  UDP Bindaddress:        %s\n", ast_sockaddr_stringify(&bindaddr));
18719    if (ast_sockaddr_is_ipv6(&bindaddr) && ast_sockaddr_is_any(&bindaddr)) {
18720       ast_cli(a->fd, "  ** Additional Info:\n");
18721       ast_cli(a->fd, "     [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n");
18722    }
18723    ast_cli(a->fd, "  TCP SIP Bindaddress:    %s\n",
18724       sip_cfg.tcp_enabled != FALSE ?
18725             ast_sockaddr_stringify(&sip_tcp_desc.local_address) :
18726             "Disabled");
18727    ast_cli(a->fd, "  TLS SIP Bindaddress:    %s\n",
18728       default_tls_cfg.enabled != FALSE ?
18729             ast_sockaddr_stringify(&sip_tls_desc.local_address) :
18730             "Disabled");
18731    ast_cli(a->fd, "  Videosupport:           %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT)));
18732    ast_cli(a->fd, "  Textsupport:            %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT)));
18733    ast_cli(a->fd, "  Ignore SDP sess. ver.:  %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION)));
18734    ast_cli(a->fd, "  AutoCreate Peer:        %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer));
18735    ast_cli(a->fd, "  Match Auth Username:    %s\n", AST_CLI_YESNO(global_match_auth_username));
18736    ast_cli(a->fd, "  Allow unknown access:   %s\n", AST_CLI_YESNO(sip_cfg.allowguest));
18737    ast_cli(a->fd, "  Allow subscriptions:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
18738    ast_cli(a->fd, "  Allow overlap dialing:  %s\n", allowoverlap2str(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)));
18739    ast_cli(a->fd, "  Allow promisc. redir:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR)));
18740    ast_cli(a->fd, "  Enable call counters:   %s\n", AST_CLI_YESNO(global_callcounter));
18741    ast_cli(a->fd, "  SIP domain support:     %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list)));
18742    ast_cli(a->fd, "  Realm. auth:            %s\n", AST_CLI_YESNO(credentials != NULL));
18743    if (credentials) {
18744       struct sip_auth *auth;
18745 
18746       AST_LIST_TRAVERSE(&credentials->list, auth, node) {
18747          ast_cli(a->fd, "  Realm. auth entry:      Realm %-15.15s User %-10.20s %s\n",
18748             auth->realm,
18749             auth->username,
18750             !ast_strlen_zero(auth->secret)
18751                ? "<Secret set>"
18752                : (!ast_strlen_zero(auth->md5secret)
18753                   ? "<MD5secret set>" : "<Not set>"));
18754       }
18755       ao2_t_ref(credentials, -1, "Unref global auth for show");
18756    }
18757    ast_cli(a->fd, "  Our auth realm          %s\n", sip_cfg.realm);
18758    ast_cli(a->fd, "  Use domains as realms:  %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm));
18759    ast_cli(a->fd, "  Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains));
18760    ast_cli(a->fd, "  URI user is phone no:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE)));
18761    ast_cli(a->fd, "  Always auth rejects:    %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject));
18762    ast_cli(a->fd, "  Direct RTP setup:       %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup));
18763    ast_cli(a->fd, "  User Agent:             %s\n", global_useragent);
18764    ast_cli(a->fd, "  SDP Session Name:       %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
18765    ast_cli(a->fd, "  SDP Owner Name:         %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner);
18766    ast_cli(a->fd, "  Reg. context:           %s\n", S_OR(sip_cfg.regcontext, "(not set)"));
18767    ast_cli(a->fd, "  Regexten on Qualify:    %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify));
18768    ast_cli(a->fd, "  Legacy userfield parse: %s\n", AST_CLI_YESNO(sip_cfg.legacy_useroption_parsing));
18769    ast_cli(a->fd, "  Caller ID:              %s\n", default_callerid);
18770    if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) {
18771       ast_cli(a->fd, "  From: Domain:           %s:%d\n", default_fromdomain, default_fromdomainport);
18772    } else {
18773       ast_cli(a->fd, "  From: Domain:           %s\n", default_fromdomain);
18774    }
18775    ast_cli(a->fd, "  Record SIP history:     %s\n", AST_CLI_ONOFF(recordhistory));
18776    ast_cli(a->fd, "  Call Events:            %s\n", AST_CLI_ONOFF(sip_cfg.callevents));
18777    ast_cli(a->fd, "  Auth. Failure Events:   %s\n", AST_CLI_ONOFF(global_authfailureevents));
18778 
18779    ast_cli(a->fd, "  T.38 support:           %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
18780    ast_cli(a->fd, "  T.38 EC mode:           %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
18781    ast_cli(a->fd, "  T.38 MaxDtgrm:          %u\n", global_t38_maxdatagram);
18782    if (!realtimepeers && !realtimeregs)
18783       ast_cli(a->fd, "  SIP realtime:           Disabled\n" );
18784    else
18785       ast_cli(a->fd, "  SIP realtime:           Enabled\n" );
18786    ast_cli(a->fd, "  Qualify Freq :          %d ms\n", global_qualifyfreq);
18787    ast_cli(a->fd, "  Q.850 Reason header:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON)));
18788    ast_cli(a->fd, "  Store SIP_CAUSE:        %s\n", AST_CLI_YESNO(global_store_sip_cause));
18789    ast_cli(a->fd, "\nNetwork QoS Settings:\n");
18790    ast_cli(a->fd, "---------------------------\n");
18791    ast_cli(a->fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
18792    ast_cli(a->fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
18793    ast_cli(a->fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
18794    ast_cli(a->fd, "  IP ToS RTP text:        %s\n", ast_tos2str(global_tos_text));
18795    ast_cli(a->fd, "  802.1p CoS SIP:         %u\n", global_cos_sip);
18796    ast_cli(a->fd, "  802.1p CoS RTP audio:   %u\n", global_cos_audio);
18797    ast_cli(a->fd, "  802.1p CoS RTP video:   %u\n", global_cos_video);
18798    ast_cli(a->fd, "  802.1p CoS RTP text:    %u\n", global_cos_text);
18799    ast_cli(a->fd, "  Jitterbuffer enabled:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED)));
18800    if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) {
18801       ast_cli(a->fd, "  Jitterbuffer forced:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED)));
18802       ast_cli(a->fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
18803       ast_cli(a->fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
18804       ast_cli(a->fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
18805       if (!strcasecmp(global_jbconf.impl, "adaptive")) {
18806          ast_cli(a->fd, "  Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra);
18807       }
18808       ast_cli(a->fd, "  Jitterbuffer log:       %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG)));
18809    }
18810 
18811    ast_cli(a->fd, "\nNetwork Settings:\n");
18812    ast_cli(a->fd, "---------------------------\n");
18813    /* determine if/how SIP address can be remapped */
18814    if (localaddr == NULL)
18815       msg = "Disabled, no localnet list";
18816    else if (ast_sockaddr_isnull(&externaddr))
18817       msg = "Disabled";
18818    else if (!ast_strlen_zero(externhost))
18819       msg = "Enabled using externhost";
18820    else
18821       msg = "Enabled using externaddr";
18822    ast_cli(a->fd, "  SIP address remapping:  %s\n", msg);
18823    ast_cli(a->fd, "  Externhost:             %s\n", S_OR(externhost, "<none>"));
18824    ast_cli(a->fd, "  Externaddr:             %s\n", ast_sockaddr_stringify(&externaddr));
18825    ast_cli(a->fd, "  Externrefresh:          %d\n", externrefresh);
18826    {
18827       struct ast_ha *d;
18828       const char *prefix = "Localnet:";
18829 
18830       for (d = localaddr; d ; prefix = "", d = d->next) {
18831          const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr));
18832          const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask));
18833          ast_cli(a->fd, "  %-24s%s/%s\n", prefix, addr, mask);
18834       }
18835    }
18836    ast_cli(a->fd, "\nGlobal Signalling Settings:\n");
18837    ast_cli(a->fd, "---------------------------\n");
18838    ast_cli(a->fd, "  Codecs:                 ");
18839    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability);
18840    ast_cli(a->fd, "%s\n", codec_buf);
18841    ast_cli(a->fd, "  Codec Order:            ");
18842    print_codec_to_cli(a->fd, &default_prefs);
18843    ast_cli(a->fd, "\n");
18844    ast_cli(a->fd, "  Relax DTMF:             %s\n", AST_CLI_YESNO(global_relaxdtmf));
18845    ast_cli(a->fd, "  RFC2833 Compensation:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE)));
18846    ast_cli(a->fd, "  Symmetric RTP:          %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP)));
18847    ast_cli(a->fd, "  Compact SIP headers:    %s\n", AST_CLI_YESNO(sip_cfg.compactheaders));
18848    ast_cli(a->fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
18849    ast_cli(a->fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
18850    ast_cli(a->fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
18851    ast_cli(a->fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
18852    ast_cli(a->fd, "  DNS SRV lookup:         %s\n", AST_CLI_YESNO(sip_cfg.srvlookup));
18853    ast_cli(a->fd, "  Pedantic SIP support:   %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking));
18854    ast_cli(a->fd, "  Reg. min duration       %d secs\n", min_expiry);
18855    ast_cli(a->fd, "  Reg. max duration:      %d secs\n", max_expiry);
18856    ast_cli(a->fd, "  Reg. default duration:  %d secs\n", default_expiry);
18857    ast_cli(a->fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
18858    ast_cli(a->fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
18859    ast_cli(a->fd, "  Outbound reg. retry 403:%d\n", global_reg_retry_403);
18860    ast_cli(a->fd, "  Notify ringing state:   %s\n", AST_CLI_YESNO(sip_cfg.notifyringing));
18861    if (sip_cfg.notifyringing) {
18862       ast_cli(a->fd, "    Include CID:          %s%s\n",
18863             AST_CLI_YESNO(sip_cfg.notifycid),
18864             sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : "");
18865    }
18866    ast_cli(a->fd, "  Notify hold state:      %s\n", AST_CLI_YESNO(sip_cfg.notifyhold));
18867    ast_cli(a->fd, "  SIP Transfer mode:      %s\n", transfermode2str(sip_cfg.allowtransfer));
18868    ast_cli(a->fd, "  Max Call Bitrate:       %d kbps\n", default_maxcallbitrate);
18869    ast_cli(a->fd, "  Auto-Framing:           %s\n", AST_CLI_YESNO(global_autoframing));
18870    ast_cli(a->fd, "  Outb. proxy:            %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name,
18871                      sip_cfg.outboundproxy.force ? "(forced)" : "");
18872    ast_cli(a->fd, "  Session Timers:         %s\n", stmode2str(global_st_mode));
18873    ast_cli(a->fd, "  Session Refresher:      %s\n", strefresherparam2str(global_st_refresher));
18874    ast_cli(a->fd, "  Session Expires:        %d secs\n", global_max_se);
18875    ast_cli(a->fd, "  Session Min-SE:         %d secs\n", global_min_se);
18876    ast_cli(a->fd, "  Timer T1:               %d\n", global_t1);
18877    ast_cli(a->fd, "  Timer T1 minimum:       %d\n", global_t1min);
18878    ast_cli(a->fd, "  Timer B:                %d\n", global_timer_b);
18879    ast_cli(a->fd, "  No premature media:     %s\n", AST_CLI_YESNO(global_prematuremediafilter));
18880    ast_cli(a->fd, "  Max forwards:           %d\n", sip_cfg.default_max_forwards);
18881 
18882    ast_cli(a->fd, "\nDefault Settings:\n");
18883    ast_cli(a->fd, "-----------------\n");
18884    ast_cli(a->fd, "  Allowed transports:     %s\n", get_transport_list(default_transports));
18885    ast_cli(a->fd, "  Outbound transport:    %s\n", get_transport(default_primary_transport));
18886    ast_cli(a->fd, "  Context:                %s\n", sip_cfg.default_context);
18887    ast_cli(a->fd, "  Force rport:            %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT)));
18888    ast_cli(a->fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
18889    ast_cli(a->fd, "  Qualify:                %d\n", default_qualify);
18890    ast_cli(a->fd, "  Use ClientCode:         %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE)));
18891    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)));
18892    ast_cli(a->fd, "  Language:               %s\n", default_language);
18893    ast_cli(a->fd, "  MOH Interpret:          %s\n", default_mohinterpret);
18894    ast_cli(a->fd, "  MOH Suggest:            %s\n", default_mohsuggest);
18895    ast_cli(a->fd, "  Voice Mail Extension:   %s\n", default_vmexten);
18896 
18897    
18898    if (realtimepeers || realtimeregs) {
18899       ast_cli(a->fd, "\nRealtime SIP Settings:\n");
18900       ast_cli(a->fd, "----------------------\n");
18901       ast_cli(a->fd, "  Realtime Peers:         %s\n", AST_CLI_YESNO(realtimepeers));
18902       ast_cli(a->fd, "  Realtime Regs:          %s\n", AST_CLI_YESNO(realtimeregs));
18903       ast_cli(a->fd, "  Cache Friends:          %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)));
18904       ast_cli(a->fd, "  Update:                 %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate));
18905       ast_cli(a->fd, "  Ignore Reg. Expire:     %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire));
18906       ast_cli(a->fd, "  Save sys. name:         %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname));
18907       ast_cli(a->fd, "  Auto Clear:             %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled");
18908    }
18909    ast_cli(a->fd, "\n----\n");
18910    return CLI_SUCCESS;
18911 }

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

17076 {
17077    struct sip_threadinfo *th;
17078    struct ao2_iterator i;
17079 
17080 #define FORMAT2 "%-47.47s %9.9s %6.6s\n"
17081 #define FORMAT  "%-47.47s %-9.9s %-6.6s\n"
17082 
17083    switch (cmd) {
17084    case CLI_INIT:
17085       e->command = "sip show tcp";
17086       e->usage =
17087          "Usage: sip show tcp\n"
17088          "       Lists all active TCP/TLS sessions.\n";
17089       return NULL;
17090    case CLI_GENERATE:
17091       return NULL;
17092    }
17093 
17094    if (a->argc != 3)
17095       return CLI_SHOWUSAGE;
17096 
17097    ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type");
17098 
17099    i = ao2_iterator_init(threadt, 0);
17100    while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
17101       ast_cli(a->fd, FORMAT,
17102          ast_sockaddr_stringify(&th->tcptls_session->remote_address),
17103          get_transport(th->type),
17104          (th->tcptls_session->client ? "Client" : "Server"));
17105       ao2_t_ref(th, -1, "decrement ref from iterator");
17106    }
17107    ao2_iterator_destroy(&i);
17108 
17109    return CLI_SUCCESS;
17110 #undef FORMAT
17111 #undef FORMAT2
17112 }

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

18375 {
18376    char cbuf[256];
18377    struct sip_peer *user;
18378    struct ast_variable *v;
18379    int load_realtime;
18380 
18381    switch (cmd) {
18382    case CLI_INIT:
18383       e->command = "sip show user";
18384       e->usage =
18385          "Usage: sip show user <name> [load]\n"
18386          "       Shows all details on one SIP user and the current status.\n"
18387          "       Option \"load\" forces lookup of peer in realtime storage.\n";
18388       return NULL;
18389    case CLI_GENERATE:
18390       return complete_sip_show_user(a->line, a->word, a->pos, a->n);
18391    }
18392 
18393    if (a->argc < 4)
18394       return CLI_SHOWUSAGE;
18395 
18396    /* Load from realtime storage? */
18397    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE;
18398 
18399    if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) {
18400       ao2_lock(user);
18401       ast_cli(a->fd, "\n\n");
18402       ast_cli(a->fd, "  * Name       : %s\n", user->name);
18403       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
18404       ast_cli(a->fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
18405       ast_cli(a->fd, "  Context      : %s\n", user->context);
18406       ast_cli(a->fd, "  Language     : %s\n", user->language);
18407       if (!ast_strlen_zero(user->accountcode))
18408          ast_cli(a->fd, "  Accountcode  : %s\n", user->accountcode);
18409       ast_cli(a->fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
18410       ast_cli(a->fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
18411       ast_cli(a->fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
18412       ast_cli(a->fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
18413       ast_cli(a->fd, "  Call limit   : %d\n", user->call_limit);
18414       ast_cli(a->fd, "  Callgroup    : ");
18415       print_group(a->fd, user->callgroup, 0);
18416       ast_cli(a->fd, "  Pickupgroup  : ");
18417       print_group(a->fd, user->pickupgroup, 0);
18418       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
18419       ast_cli(a->fd, "  ACL          : %s\n", AST_CLI_YESNO(user->ha != NULL));
18420       ast_cli(a->fd, "  Sess-Timers  : %s\n", stmode2str(user->stimer.st_mode_oper));
18421       ast_cli(a->fd, "  Sess-Refresh : %s\n", strefresherparam2str(user->stimer.st_ref));
18422       ast_cli(a->fd, "  Sess-Expires : %d secs\n", user->stimer.st_max_se);
18423       ast_cli(a->fd, "  Sess-Min-SE  : %d secs\n", user->stimer.st_min_se);
18424       ast_cli(a->fd, "  RTP Engine   : %s\n", user->engine);
18425 
18426       ast_cli(a->fd, "  Codec Order  : (");
18427       print_codec_to_cli(a->fd, &user->prefs);
18428       ast_cli(a->fd, ")\n");
18429 
18430       ast_cli(a->fd, "  Auto-Framing:  %s \n", AST_CLI_YESNO(user->autoframing));
18431       if (user->chanvars) {
18432          ast_cli(a->fd, "  Variables    :\n");
18433          for (v = user->chanvars ; v ; v = v->next)
18434             ast_cli(a->fd, "                 %s = %s\n", v->name, v->value);
18435       }
18436 
18437       ast_cli(a->fd, "\n");
18438 
18439       ao2_unlock(user);
18440       unref_peer(user, "sip show user");
18441    } else {
18442       ast_cli(a->fd, "User %s not found.\n", a->argv[3]);
18443       ast_cli(a->fd, "\n");
18444    }
18445 
18446    return CLI_SUCCESS;
18447 }

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

17116 {
17117    regex_t regexbuf;
17118    int havepattern = FALSE;
17119    struct ao2_iterator user_iter;
17120    struct sip_peer *user;
17121 
17122 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
17123 
17124    switch (cmd) {
17125    case CLI_INIT:
17126       e->command = "sip show users";
17127       e->usage =
17128          "Usage: sip show users [like <pattern>]\n"
17129          "       Lists all known SIP users.\n"
17130          "       Optional regular expression pattern is used to filter the user list.\n";
17131       return NULL;
17132    case CLI_GENERATE:
17133       return NULL;
17134    }
17135 
17136    switch (a->argc) {
17137    case 5:
17138       if (!strcasecmp(a->argv[3], "like")) {
17139          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
17140             return CLI_SHOWUSAGE;
17141          havepattern = TRUE;
17142       } else
17143          return CLI_SHOWUSAGE;
17144    case 3:
17145       break;
17146    default:
17147       return CLI_SHOWUSAGE;
17148    }
17149 
17150    ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "Forcerport");
17151 
17152    user_iter = ao2_iterator_init(peers, 0);
17153    while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) {
17154       ao2_lock(user);
17155       if (!(user->type & SIP_TYPE_USER)) {
17156          ao2_unlock(user);
17157          unref_peer(user, "sip show users");
17158          continue;
17159       }
17160 
17161       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0)) {
17162          ao2_unlock(user);
17163          unref_peer(user, "sip show users");
17164          continue;
17165       }
17166 
17167       ast_cli(a->fd, FORMAT, user->name,
17168          user->secret,
17169          user->accountcode,
17170          user->context,
17171          AST_CLI_YESNO(user->ha != NULL),
17172          AST_CLI_YESNO(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT)));
17173       ao2_unlock(user);
17174       unref_peer(user, "sip show users");
17175    }
17176    ao2_iterator_destroy(&user_iter);
17177 
17178    if (havepattern)
17179       regfree(&regexbuf);
17180 
17181    return CLI_SUCCESS;
17182 #undef FORMAT
17183 }

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

30388 {
30389    char *cdest;
30390    char *extension, *domain;
30391 
30392    cdest = ast_strdupa(dest);
30393 
30394    extension = strsep(&cdest, "@");
30395    domain = cdest;
30396    if (ast_strlen_zero(extension)) {
30397       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
30398       return 0;
30399    }
30400 
30401    /* we'll issue the redirect message here */
30402    if (!domain) {
30403       char *local_to_header;
30404       char to_header[256];
30405 
30406       ast_copy_string(to_header, get_header(&p->initreq, "To"), sizeof(to_header));
30407       if (ast_strlen_zero(to_header)) {
30408          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
30409          return 0;
30410       }
30411       if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:")))
30412          && (local_to_header = strchr(local_to_header, '@'))) {
30413          char ldomain[256];
30414 
30415          memset(ldomain, 0, sizeof(ldomain));
30416          local_to_header++;
30417          /* This is okey because lhost and lport are as big as tmp */
30418          sscanf(local_to_header, "%256[^<>; ]", ldomain);
30419          if (ast_strlen_zero(ldomain)) {
30420             ast_log(LOG_ERROR, "Can't find the host address\n");
30421             return 0;
30422          }
30423          domain = ast_strdupa(ldomain);
30424       }
30425    }
30426 
30427    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain);
30428    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
30429 
30430    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
30431    sip_alreadygone(p);
30432 
30433    if (p->owner) {
30434       enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
30435       ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
30436    }
30437    /* hangup here */
30438    return 0;
30439 }

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

Referenced by initreqprep(), and transmit_notify_with_mwi().

26219 {
26220    if (type & SIP_TRANSPORT_TLS)
26221       return port == STANDARD_TLS_PORT;
26222    else
26223       return port == STANDARD_SIP_PORT;
26224 }

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

05956 {
05957    if (mwi->call) {
05958       mwi->call->mwi = NULL;
05959       mwi->call = dialog_unref(mwi->call, "sip_subscription_mwi destruction");
05960    }
05961 
05962    AST_SCHED_DEL(sched, mwi->resub);
05963    ast_string_field_free_memory(mwi);
05964    ast_free(mwi);
05965 }

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

References change_t38_state(), sip_pvt_lock, sip_pvt_unlock, and transmit_response_reliable().

Referenced by handle_request_invite().

22911 {
22912    struct sip_pvt *p = (struct sip_pvt *) data;
22913 
22914    sip_pvt_lock(p);
22915    /* an application may have taken ownership of the T.38 negotiation on this
22916     * channel while we were waiting to grab the lock... if it did, the scheduler
22917     * id will have been reset to -1, which is our indication that we do *not*
22918     * want to abort the negotiation process
22919     */
22920    if (p->t38id != -1) {
22921       change_t38_state(p, T38_DISABLED);
22922       transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
22923       p->t38id = -1;
22924       dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr");
22925    }
22926    sip_pvt_unlock(p);
22927    return 0;
22928 }

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

References ao2_callback, ao2_ref, ao2_t_ref, and threadinfo_locate_cb().

Referenced by sip_prepare_socket().

26244 {
26245    struct sip_threadinfo *th;
26246    struct ast_tcptls_session_instance *tcptls_instance = NULL;
26247 
26248    if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) {
26249       tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session);
26250       ao2_t_ref(th, -1, "decrement ref from callback");
26251    }
26252 
26253    return tcptls_instance;
26254 }

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

18548 {
18549    struct sip_peer *peer;
18550    int load_realtime = 0;
18551 
18552    switch (cmd) {
18553    case CLI_INIT:
18554       e->command = "sip unregister";
18555       e->usage =
18556          "Usage: sip unregister <peer>\n"
18557          "       Unregister (force expiration) a SIP peer from the registry\n";
18558       return NULL;
18559    case CLI_GENERATE:
18560       return complete_sip_unregister(a->line, a->word, a->pos, a->n);
18561    }
18562    
18563    if (a->argc != 3)
18564       return CLI_SHOWUSAGE;
18565    
18566    if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) {
18567       if (peer->expire > 0) {
18568          AST_SCHED_DEL_UNREF(sched, peer->expire,
18569             unref_peer(peer, "remove register expire ref"));
18570          expire_register(ref_peer(peer, "ref for expire_register"));
18571          ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
18572       } else {
18573          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
18574       }
18575       unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call");
18576    } else {
18577       ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]);
18578    }
18579    
18580    return CLI_SUCCESS;
18581 }

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

26089 {
26090    struct sip_request req;
26091    struct ast_sockaddr addr;
26092    int res;
26093    static char readbuf[65535];
26094 
26095    memset(&req, 0, sizeof(req));
26096    res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr);
26097    if (res < 0) {
26098 #if !defined(__FreeBSD__)
26099       if (errno == EAGAIN)
26100          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
26101       else
26102 #endif
26103       if (errno != ECONNREFUSED)
26104          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
26105       return 1;
26106    }
26107 
26108    readbuf[res] = '\0';
26109 
26110    if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
26111       return 1;
26112    }
26113 
26114    if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) {
26115       return -1;
26116    }
26117 
26118    req.socket.fd = sipsock;
26119    set_socket_transport(&req.socket, SIP_TRANSPORT_UDP);
26120    req.socket.tcptls_session  = NULL;
26121    req.socket.port = htons(ast_sockaddr_port(&bindaddr));
26122 
26123    handle_request_do(&req, &addr);
26124    deinit_req(&req);
26125 
26126    return 1;
26127 }

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

References sip_st_alloc().

Referenced by add_supported_header(), handle_request_invite_st(), handle_response_invite(), and transmit_invite().

27018 {
27019    if (!p->stimer) {
27020       sip_st_alloc(p);
27021       if (!p->stimer) {
27022          return SESSION_TIMER_MODE_INVALID;
27023       }
27024    }
27025 
27026    if (!no_cached && p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID)
27027       return p->stimer->st_cached_mode;
27028 
27029    if (p->relatedpeer) {
27030       p->stimer->st_cached_mode = p->relatedpeer->stimer.st_mode_oper;
27031       return p->stimer->st_cached_mode;
27032    }
27033 
27034    p->stimer->st_cached_mode = global_st_mode;
27035    return global_st_mode;
27036 }

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

Referenced by handle_request_invite_st().

26996 {
26997    if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) {
26998       return p->stimer->st_cached_ref;
26999    }
27000 
27001    if (p->relatedpeer) {
27002       p->stimer->st_cached_ref = (p->relatedpeer->stimer.st_ref == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
27003       return p->stimer->st_cached_ref;
27004    }
27005    
27006    p->stimer->st_cached_ref = (global_st_refresher == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
27007    return p->stimer->st_cached_ref;
27008 }

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

References TRUE.

Referenced by handle_request_invite_st(), handle_response_invite(), reqprep(), and transmit_invite().

26964 {
26965    if (max == TRUE) {
26966       if (p->stimer->st_cached_max_se) {
26967          return  p->stimer->st_cached_max_se;
26968       }
26969       if (p->relatedpeer) {
26970          p->stimer->st_cached_max_se = p->relatedpeer->stimer.st_max_se;
26971          return (p->stimer->st_cached_max_se);
26972       }
26973       p->stimer->st_cached_max_se = global_max_se;
26974       return (p->stimer->st_cached_max_se);
26975    } 
26976    /* Find Min SE timer */
26977    if (p->stimer->st_cached_min_se) {
26978       return p->stimer->st_cached_min_se;
26979    } 
26980    if (p->relatedpeer) {
26981       p->stimer->st_cached_min_se = p->relatedpeer->stimer.st_min_se;
26982       return (p->stimer->st_cached_min_se);
26983    }
26984    p->stimer->st_cached_min_se = global_min_se;
26985    return (p->stimer->st_cached_min_se);
26986 }

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

Session-Timers: Start session timer.

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

26746 {
26747    unsigned int timeout_ms;
26748 
26749    if (p->stimer->st_schedid > -1) {
26750       /* in the event a timer is already going, stop it */
26751       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
26752       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
26753          dialog_unref(p, "unref stimer->st_schedid from dialog"));
26754    }
26755 
26756    /*
26757     * RFC 4028 Section 10
26758     * If the side not performing refreshes does not receive a
26759     * session refresh request before the session expiration, it SHOULD send
26760     * a BYE to terminate the session, slightly before the session
26761     * expiration.  The minimum of 32 seconds and one third of the session
26762     * interval is RECOMMENDED.
26763     */
26764 
26765    timeout_ms = (1000 * p->stimer->st_interval);
26766    if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) {
26767       timeout_ms /= 2;
26768    } else {
26769       timeout_ms -= MIN(timeout_ms / 3, 32000);
26770    }
26771 
26772    p->stimer->st_schedid = ast_sched_add(sched, timeout_ms, proc_session_timer,
26773          dialog_ref(p, "adding session timer ref"));
26774 
26775    if (p->stimer->st_schedid < 0) {
26776       dialog_unref(p, "removing session timer ref");
26777       ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid);
26778    } else {
26779       p->stimer->st_active = TRUE;
26780       ast_debug(2, "Session timer started: %d - %s %ums\n", p->stimer->st_schedid, p->callid, timeout_ms);
26781    }
26782 }

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

References map_x_s().

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

17012 {
17013    return map_x_s(stmodes, m, "Unknown");
17014 }

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

Immediately stop RTP, VRTP and UDPTL as applicable.

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

21693 {
21694    /* Immediately stop RTP, VRTP and UDPTL as applicable */
21695    if (p->rtp)
21696       ast_rtp_instance_stop(p->rtp);
21697    if (p->vrtp)
21698       ast_rtp_instance_stop(p->vrtp);
21699    if (p->trtp)
21700       ast_rtp_instance_stop(p->trtp);
21701    if (p->udptl)
21702       ast_udptl_stop(p->udptl);
21703 }

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

Session-Timers: Stop session timer.

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

26734 {
26735    if (p->stimer->st_active == TRUE) {
26736       p->stimer->st_active = FALSE;
26737       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
26738       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
26739             dialog_unref(p, "removing session timer ref"));
26740    }
26741 }

static int str2dtmfmode ( const char *  str  )  [static]

maps a string to dtmfmode, returns -1 on error

Definition at line 17575 of file chan_sip.c.

References map_s_x().

17576 {
17577    return map_s_x(dtmfstr, str, -1);
17578 }

static enum st_mode str2stmode ( const char *  s  )  [static]

Definition at line 17016 of file chan_sip.c.

References map_s_x().

Referenced by build_peer(), and reload_config().

17017 {
17018    return map_s_x(stmodes, s, -1);
17019 }

static enum st_refresher str2strefresherparam ( const char *  s  )  [static]

Definition at line 17041 of file chan_sip.c.

References map_s_x().

Referenced by build_peer(), and reload_config().

17042 {
17043    return map_s_x(strefresher_params, s, -1);
17044 }

static const char* strefresher2str ( enum st_refresher  r  )  [static]

Definition at line 17046 of file chan_sip.c.

References map_x_s().

Referenced by sip_show_channel().

17047 {
17048    return map_x_s(strefreshers, r, "Unknown");
17049 }

static const char * strefresherparam2str ( enum st_refresher  r  )  [static]

Definition at line 17036 of file chan_sip.c.

References map_x_s().

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

17037 {
17038    return map_x_s(strefresher_params, r, "Unknown");
17039 }

static const char * subscription_type2str ( enum subscriptiontype  subtype  )  [static]

Show subscription type in string format.

Definition at line 18944 of file chan_sip.c.

References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.

Referenced by show_channels_cb(), and sip_show_channel().

18945 {
18946    int i;
18947 
18948    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
18949       if (subscription_types[i].type == subtype) {
18950          return subscription_types[i].text;
18951       }
18952    }
18953    return subscription_types[0].text;
18954 }

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

27984 {
27985    struct sip_peer *peer;
27986 
27987    if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
27988       return NULL;
27989 
27990    if (ast_string_field_init(peer, 512)) {
27991       ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
27992       return NULL;
27993    }
27994    
27995    if (!(peer->cc_params = ast_cc_config_params_init())) {
27996       ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
27997       return NULL;
27998    }
27999 
28000    ast_atomic_fetchadd_int(&apeerobjs, 1);
28001    set_peer_defaults(peer);
28002 
28003    ast_copy_string(peer->name, name, sizeof(peer->name));
28004 
28005    peer->selfdestruct = TRUE;
28006    peer->host_dynamic = TRUE;
28007    peer->prefs = default_prefs;
28008    reg_source_db(peer);
28009 
28010    return peer;
28011 }

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

Referenced by check_user_full(), and register_verify().

15236 {
15237    char *t = uri;
15238    while (*t && *t > ' ' && *t != ';') {
15239       t++;
15240    }
15241    *t = '\0';
15242    return uri;
15243 }

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

Definition at line 26226 of file chan_sip.c.

References ast_sockaddr_cmp(), CMP_MATCH, and CMP_STOP.

Referenced by sip_tcp_locate().

26227 {
26228    struct sip_threadinfo *th = obj;
26229    struct ast_sockaddr *s = arg;
26230 
26231    if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) {
26232       return CMP_MATCH | CMP_STOP;
26233    }
26234 
26235    return 0;
26236 }

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

Definition at line 30790 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

30791 {
30792    struct sip_threadinfo *th = obj, *th2 = arg;
30793 
30794    return (th->tcptls_session == th2->tcptls_session) ? CMP_MATCH | CMP_STOP : 0;
30795 }

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

Definition at line 30783 of file chan_sip.c.

References ast_sockaddr_hash().

Referenced by load_module().

30784 {
30785    const struct sip_threadinfo *th = obj;
30786 
30787    return ast_sockaddr_hash(&th->tcptls_session->remote_address);
30788 }

static char * transfermode2str ( enum transfermodes  mode  )  [static]

Convert transfer mode to text string.

Definition at line 16989 of file chan_sip.c.

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

16990 {
16991    if (mode == TRANSFER_OPENFORALL)
16992       return "open";
16993    else if (mode == TRANSFER_CLOSED)
16994       return "closed";
16995    return "strict";
16996 }

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

15135 {
15136    /* We have to emulate EXACTLY what we'd get with a good peer
15137     * and a bad password, or else we leak information. */
15138    const char *response = "401 Unauthorized";
15139    const char *reqheader = "Authorization";
15140    const char *respheader = "WWW-Authenticate";
15141    const char *authtoken;
15142    struct ast_str *buf;
15143    char *c;
15144 
15145    /* table of recognised keywords, and their value in the digest */
15146    enum keys { K_NONCE, K_LAST };
15147    struct x {
15148       const char *key;
15149       const char *s;
15150    } *i, keys[] = {
15151       [K_NONCE] = { "nonce=", "" },
15152       [K_LAST] = { NULL, NULL}
15153    };
15154 
15155    authtoken = get_header(req, reqheader);
15156    if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
15157       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
15158        * information */
15159       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
15160       /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
15161       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15162       return;
15163    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
15164       /* We have no auth, so issue challenge and request authentication */
15165       set_nonce_randdata(p, 1);
15166       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
15167       /* Schedule auto destroy in 32 seconds */
15168       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15169       return;
15170    }
15171 
15172    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
15173       __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
15174       return;
15175    }
15176 
15177    /* Make a copy of the response and parse it */
15178    if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
15179       __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
15180       return;
15181    }
15182 
15183    c = buf->str;
15184 
15185    while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
15186       for (i = keys; i->key != NULL; i++) {
15187          const char *separator = ",";  /* default */
15188 
15189          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
15190             continue;
15191          }
15192          /* Found. Skip keyword, take text in quotes or up to the separator. */
15193          c += strlen(i->key);
15194          if (*c == '"') { /* in quotes. Skip first and look for last */
15195             c++;
15196             separator = "\"";
15197          }
15198          i->s = c;
15199          strsep(&c, separator);
15200          break;
15201       }
15202       if (i->key == NULL) { /* not found, jump after space or comma */
15203          strsep(&c, " ,");
15204       }
15205    }
15206 
15207    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
15208    if (strcasecmp(p->randdata, keys[K_NONCE].s)) {
15209       if (!req->ignore) {
15210          set_nonce_randdata(p, 1);
15211       }
15212       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
15213 
15214       /* Schedule auto destroy in 32 seconds */
15215       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15216    } else {
15217       __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
15218    }
15219 }

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

Referenced by sip_show_channel().

19213 {
19214    switch (transport) {
19215    case SIP_TRANSPORT_TLS:
19216       return "TLS";
19217    case SIP_TRANSPORT_UDP:
19218       return "UDP";
19219    case SIP_TRANSPORT_TCP:
19220       return "TCP";
19221    }
19222 
19223    return "Undefined";
19224 }

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

Definition at line 17614 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer().

17615 {
17616    return map_x_s(trust_id_outboundstr, mode, "<error>");
17617 }

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_peer_from_tables ( struct sip_peer *  peer  )  [static]

Definition at line 3048 of file chan_sip.c.

References ao2_t_unlink, and ast_sockaddr_isnull().

Referenced by expire_register().

03049 {
03050    ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
03051    if (!ast_sockaddr_isnull(&peer->addr)) {
03052       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
03053    }
03054 }

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

31940 {
31941    struct sip_pvt *p;
31942    struct sip_threadinfo *th;
31943    struct ast_context *con;
31944    struct ao2_iterator i;
31945    int wait_count;
31946 
31947    network_change_event_unsubscribe();
31948 
31949    ast_sched_dump(sched);
31950    
31951    /* First, take us out of the channel type list */
31952    ast_channel_unregister(&sip_tech);
31953 
31954    /* Unregister dial plan functions */
31955    ast_custom_function_unregister(&sipchaninfo_function);
31956    ast_custom_function_unregister(&sippeer_function);
31957    ast_custom_function_unregister(&sip_header_function);
31958    ast_custom_function_unregister(&checksipdomain_function);
31959 
31960    /* Unregister dial plan applications */
31961    ast_unregister_application(app_dtmfmode);
31962    ast_unregister_application(app_sipaddheader);
31963    ast_unregister_application(app_sipremoveheader);
31964 
31965 #ifdef TEST_FRAMEWORK
31966    AST_TEST_UNREGISTER(test_sip_peers_get);
31967    AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse);
31968    AST_TEST_UNREGISTER(test_tcp_message_fragmentation);
31969    AST_TEST_UNREGISTER(get_in_brackets_const_test);
31970 #endif
31971    /* Unregister all the AstData providers */
31972    ast_data_unregister(NULL);
31973 
31974    /* Unregister CLI commands */
31975    ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip));
31976 
31977    /* Disconnect from UDPTL */
31978    ast_udptl_proto_unregister(&sip_udptl);
31979 
31980    /* Disconnect from RTP engine */
31981    ast_rtp_glue_unregister(&sip_rtp_glue);
31982 
31983    /* Unregister AMI actions */
31984    ast_manager_unregister("SIPpeers");
31985    ast_manager_unregister("SIPshowpeer");
31986    ast_manager_unregister("SIPqualifypeer");
31987    ast_manager_unregister("SIPshowregistry");
31988    ast_manager_unregister("SIPnotify");
31989    
31990    /* Kill TCP/TLS server threads */
31991    if (sip_tcp_desc.master) {
31992       ast_tcptls_server_stop(&sip_tcp_desc);
31993    }
31994    if (sip_tls_desc.master) {
31995       ast_tcptls_server_stop(&sip_tls_desc);
31996    }
31997    ast_ssl_teardown(sip_tls_desc.tls_cfg);
31998 
31999    /* Kill all existing TCP/TLS threads */
32000    i = ao2_iterator_init(threadt, 0);
32001    while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
32002       pthread_t thread = th->threadid;
32003       th->stop = 1;
32004       pthread_kill(thread, SIGURG);
32005       ao2_t_ref(th, -1, "decrement ref from iterator");
32006    }
32007    ao2_iterator_destroy(&i);
32008 
32009    /* Hangup all dialogs if they have an owner */
32010    i = ao2_iterator_init(dialogs, 0);
32011    while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
32012       if (p->owner)
32013          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
32014       ao2_t_ref(p, -1, "toss dialog ptr from iterator_next");
32015    }
32016    ao2_iterator_destroy(&i);
32017 
32018    unlink_all_peers_from_tables();
32019 
32020    ast_mutex_lock(&monlock);
32021    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
32022       pthread_t th = monitor_thread;
32023       monitor_thread = AST_PTHREADT_STOP;
32024       pthread_cancel(th);
32025       pthread_kill(th, SIGURG);
32026       ast_mutex_unlock(&monlock);
32027       pthread_join(th, NULL);
32028    } else {
32029       monitor_thread = AST_PTHREADT_STOP;
32030       ast_mutex_unlock(&monlock);
32031    }
32032 
32033    /* Destroy all the dialogs and free their memory */
32034    i = ao2_iterator_init(dialogs, 0);
32035    while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
32036       dialog_unlink_all(p);
32037       ao2_t_ref(p, -1, "throw away iterator result");
32038    }
32039    ao2_iterator_destroy(&i);
32040 
32041    /* Free memory for local network address mask */
32042    ast_free_ha(localaddr);
32043 
32044    ast_mutex_lock(&authl_lock);
32045    if (authl) {
32046       ao2_t_ref(authl, -1, "Removing global authentication");
32047       authl = NULL;
32048    }
32049    ast_mutex_unlock(&authl_lock);
32050 
32051    sip_epa_unregister_all();
32052    destroy_escs();
32053 
32054    ast_free(default_tls_cfg.certfile);
32055    ast_free(default_tls_cfg.pvtfile);
32056    ast_free(default_tls_cfg.cipher);
32057    ast_free(default_tls_cfg.cafile);
32058    ast_free(default_tls_cfg.capath);
32059 
32060    cleanup_all_regs();
32061    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
32062    ASTOBJ_CONTAINER_DESTROY(&regl);
32063 
32064    ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
32065       ASTOBJ_WRLOCK(iterator);
32066       if (iterator->dnsmgr) {
32067          ast_dnsmgr_release(iterator->dnsmgr);
32068          iterator->dnsmgr = NULL;
32069          ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy);
32070       }
32071       ASTOBJ_UNLOCK(iterator);
32072    } while(0));
32073    ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy);
32074    ASTOBJ_CONTAINER_DESTROY(&submwil);
32075 
32076    /*
32077     * Wait awhile for the TCP/TLS thread container to become empty.
32078     *
32079     * XXX This is a hack, but the worker threads cannot be created
32080     * joinable.  They can die on their own and remove themselves
32081     * from the container thus resulting in a huge memory leak.
32082     */
32083    wait_count = 1000;
32084    while (ao2_container_count(threadt) && --wait_count) {
32085       sched_yield();
32086    }
32087    if (!wait_count) {
32088       ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
32089    }
32090 
32091    ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
32092 
32093    ao2_t_ref(peers, -1, "unref the peers table");
32094    ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table");
32095    ao2_t_ref(dialogs, -1, "unref the dialogs table");
32096    ao2_t_ref(dialogs_to_destroy, -1, "unref dialogs_to_destroy");
32097    ao2_t_ref(threadt, -1, "unref the thread table");
32098    ao2_t_ref(sip_monitor_instances, -1, "unref the sip_monitor_instances table");
32099 
32100    clear_sip_domains();
32101    ast_free_ha(sip_cfg.contact_ha);
32102    if (sipsock_read_id) {
32103       ast_io_remove(io, sipsock_read_id);
32104       sipsock_read_id = NULL;
32105    }
32106    close(sipsock);
32107    io_context_destroy(io);
32108    sched_context_destroy(sched);
32109    con = ast_context_find(used_context);
32110    if (con) {
32111       ast_context_destroy(con, "SIP");
32112    }
32113    ast_unload_realtime("sipregs");
32114    ast_unload_realtime("sippeers");
32115    ast_cc_monitor_unregister(&sip_cc_monitor_callbacks);
32116    ast_cc_agent_unregister(&sip_cc_agent_callbacks);
32117 
32118    sip_reqresp_parser_exit();
32119    sip_unregister_tests();
32120 
32121    if (notify_types) {
32122       ast_config_destroy(notify_types);
32123       notify_types = NULL;
32124    }
32125 
32126    return 0;
32127 }

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

References ast_test_flag, realtime_update_peer(), and sip_cfg.

Referenced by register_verify().

04887 {
04888    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
04889    if (sip_cfg.peer_rtupdate &&
04890        (p->is_realtime || rtcachefriends)) {
04891       realtime_update_peer(p->name, &p->addr, p->username, p->fullcontact, p->useragent, expire, p->deprecated_username, p->lastms);
04892    }
04893 }

static void update_peer_lastmsgssent ( struct sip_peer *  peer,
int  value,
int  locked 
) [static]

Definition at line 15259 of file chan_sip.c.

References ao2_lock, and ao2_unlock.

Referenced by register_verify(), and sip_send_mwi_to_peer().

15260 {
15261    if (!locked) {
15262       ao2_lock(peer);
15263    }
15264    peer->lastmsgssent = value;
15265    if (!locked) {
15266       ao2_unlock(peer);
15267    }
15268 }

static void update_provisional_keepalive ( struct sip_pvt *  pvt,
int  with_sdp 
) [static]

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

04344 {
04345    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"));
04346 
04347    pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT,
04348       with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback"));
04349 }

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

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 30252 of file chan_sip.c.

char* app_sipremoveheader = "SIPRemoveHeader" [static]

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

struct ast_cli_entry cli_sip[] [static]

SIP Cli commands definition.

Definition at line 30828 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 17559 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 18047 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 17580 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 31777 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 31782 of file chan_sip.c.

Initial value:
 {
   .name = "SIP_HEADER",
   .read = func_header_read,
}

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

Initial value:
 {
   .name = "SIPCHANINFO",
   .read = function_sipchaninfo_read,
}

Structure to declare a dialplan function: SIPCHANINFO.

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

struct _map_x_s strefresher_params[] [static]

Definition at line 17022 of file chan_sip.c.

struct _map_x_s strefreshers[] [static]

Definition at line 17029 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 17607 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 29 Oct 2014 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1