Thu Sep 9 06:27:39 2010

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  domain_list
struct  epa_static_data_list
struct  event_state_compositor
 The Event State Compositors. More...
struct  invstate2stringtable
 Readable descriptions of device states. More...
struct  match_req_args
struct  sip_history_head
struct  sip_reasons
 Diversion header reasons. More...

Object counters @{

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


#define append_history(p, event, fmt, args...)   append_history_full(p, "%-15s " fmt, event, ## args)
 Append to SIP dialog history.
#define CHECK_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 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 %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
#define FORMAT   "%-47.47s %-9.9s %-6.6s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT2   "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n"
#define FORMAT2   "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"
#define FORMAT2   "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"
#define FORMAT2   "%-47.47s %9.9s %6.6s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n"
#define FORMAT4   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n"
#define sip_pvt_lock(x)   ao2_lock(x)
#define sip_pvt_trylock(x)   ao2_trylock(x)
#define sip_pvt_unlock(x)   ao2_unlock(x)
#define UNLINK(element, head, prev)
enum  match_req_res { SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_REQ_LOOP_DETECTED }
static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto,chan_local", }
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static char * app_sipremoveheader = "SIPRemoveHeader"
static struct ast_module_infoast_module_info = &__mod_info
static struct sip_auth * authl = NULL
 Authentication list for realm authentication.
struct ast_sockaddr bindaddr
static struct epa_static_data cc_epa_static_data
static struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_check_auth_buf , .custom_init = NULL , }
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.
static struct _map_x_s dtmfstr []
 mapping between dtmf flags and strings
static int esc_etag_counter
static const int ESC_MAX_BUCKETS = 37
static struct
event_state_compositor 
event_state_compositors []
 The Event State Compositors.
static struct ast_sockaddr externaddr
 our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:
static time_t externexpire
static char externhost [MAXHOSTNAMELEN]
static int externrefresh = 10
static uint16_t externtcpport
static uint16_t externtlsport
static struct _map_x_s faxecmodes []
static struct ast_flags global_flags [3] = {{0}}
static int global_t38_maxdatagram
static const int HASH_DIALOG_SIZE = 563
static const int HASH_PEER_SIZE = 563
static struct _map_x_s insecurestr []
static struct ast_sockaddr internip
 our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages.
static struct io_contextio
static struct ast_halocaladdr
 List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
static struct ast_sockaddr media_address
static pthread_t monitor_thread = AST_PTHREADT_NULL
 This is the thread for the monitor which checks for input on the channels which are not currently in use.
static ast_mutex_t monlock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } , 1, PTHREAD_MUTEX_INITIALIZER }
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
static ast_mutex_t netlock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } , 1, PTHREAD_MUTEX_INITIALIZER }
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 ast_mutex_t sip_reload_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } , 1, PTHREAD_MUTEX_INITIALIZER }
static int sip_reloading = FALSE
static enum channelreloadreason sip_reloadreason
static struct ast_rtp_glue sip_rtp_glue
static struct
ast_tcptls_session_args 
sip_tcp_desc
 The TCP server definition.
struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
struct ast_channel_tech sip_tech_info
 This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF.
static struct ast_tls_config sip_tls_cfg
 Working TLS connection configuration.
static struct
ast_tcptls_session_args 
sip_tls_desc
 The TCP/TLS server definition.
static struct ast_udptl_protocol sip_udptl
 Interface structure with callbacks used to connect to UDPTL module.
static struct ast_custom_function sipchaninfo_function
 Structure to declare a dialplan function: SIPCHANINFO.
static enum sip_debug_e sipdebug
static int sipdebug_text
 extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.
static struct ast_custom_function sippeer_function
 Structure to declare a dialplan function: SIPPEER.
static int sipsock = -1
 Main socket for UDP SIP communication.
static int * sipsock_read_id
static int speerobjs = 0
static struct _map_x_s stmodes []
 Report Peer status in character string.
static struct _map_x_s strefreshers []
static struct
ast_subscription_mwi_list 
submwil
 The MWI subscription list.
static struct ao2_containerthreadt
 The table of TCP threads.
static struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , }
static char used_context [AST_MAX_CONTEXT]
static const char * __get_header (const struct sip_request *req, const char *name, int *start)
static void __init_check_auth_buf (void)
static void __init_ts_temp_pvt (void)
 A per-thread temporary pvt structure.
static void __reg_module (void)
static int __set_address_from_contact (const char *fullcontact, struct ast_sockaddr *addr, int tcp)
int __sip_ack (struct sip_pvt *p, int 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, int seqno, int resp, struct ast_str *data, int len, int fatal, int sipmethod)
 Transmit packet with retransmits.
int __sip_semi_ack (struct sip_pvt *p, int 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, int len)
 Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit.
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function.
static void __unreg_module (void)
static char * _sip_qualify_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Send qualify message to peer from cli or manager. Mostly for debugging.
static char * _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Show one peer in detail (main function).
static char * _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Execute sip show peers command.
static void * _sip_tcp_helper_thread (struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
 SIP TCP thread management function This function reads from the socket, parses the packet into a request.
static void add_blank (struct sip_request *req)
 add a blank line if no body
static void add_cc_call_info_to_response (struct sip_pvt *p, struct sip_request *resp)
static void add_codec_to_sdp (const struct sip_pvt *p, 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 struct sip_auth * add_realm_authentication (struct sip_auth *authlist, const char *configuration, int lineno)
 Add realm authentication in list.
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 void append_date (struct sip_request *req)
 Append date to SIP message.
static void append_history_full (struct sip_pvt *p, const char *fmt,...)
 Append to SIP dialog history with arg list.
static void append_history_va (struct sip_pvt *p, const char *fmt, va_list ap)
 Append to SIP dialog history with arg list.
static int apply_directmedia_ha (struct sip_pvt *p, const char *op)
 AST_DATA_STRUCTURE (sip_peer, DATA_EXPORT_SIP_PEER)
static void ast_quiet_chan (struct ast_channel *chan)
 Turn off generator data XXX Does this function belong in the SIP channel?
static void ast_sip_ouraddrfor (const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p)
 NAT fix - decide which IP address to use for Asterisk server?
static int ast_sockaddr_resolve_first (struct ast_sockaddr *addr, const char *name, int flag)
 Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
static int ast_sockaddr_resolve_first_af (struct ast_sockaddr *addr, const char *name, int flag, int family)
 Return the first entry from ast_sockaddr_resolve filtered by address family.
static int attempt_transfer (struct sip_dual *transferer, struct sip_dual *target)
 Attempt transfer of SIP call This fix for attended transfers on a local PBX.
static void auth_headers (enum sip_auth_type code, char **header, char **respheader)
 return the request and response heade 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 struct sip_peer * build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
 Build peer from configuration (file or realtime static/dynamic).
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest.
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 Build route list from Record-Route header.
static void build_via (struct sip_pvt *p)
 Build a Via header for a request.
static int cb_extensionstate (char *context, char *exten, int state, void *data)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem.
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_redirecting_information (struct sip_pvt *p, struct sip_request *req, struct ast_party_redirecting *redirecting, struct ast_set_party_redirecting *update_redirecting, int set_call_forward)
 update redirecting information for a channel based on headers
static void change_t38_state (struct sip_pvt *p, int state)
 Change the T38 state on a SIP dialog.
static enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, const char *uri, enum xmittype reliable, int ignore)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
static enum check_auth_result check_peer_ok (struct sip_pvt *p, char *of, struct sip_request *req, int sipmethod, struct ast_sockaddr *addr, struct sip_peer **authpeer, enum xmittype reliable, char *calleridname, char *uri2)
 Validate device authentication.
static void check_pendings (struct sip_pvt *p)
 Check pending actions on SIP call.
static 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, 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_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 int clear_realm_authentication (struct sip_auth *authlist)
 Clear realm authentication list (at reload).
static void clear_sip_domains (void)
 Clear our domain list (at reload).
static char * complete_sip_peer (const char *word, int state, int flags2)
 Do completion on peer name.
static char * complete_sip_registered_peer (const char *word, int state, int flags2)
 Do completion on registered peer name.
static char * complete_sip_show_history (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show history' CLI.
static char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show peer' CLI.
static char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show user' CLI.
static char * complete_sip_unregister (const char *line, const char *word, int pos, int state)
 Support routine for 'sip unregister' CLI.
static char * complete_sip_user (const char *word, int state)
 Do completion on user name.
static char * complete_sipch (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.
static char * complete_sipnotify (const char *line, const char *word, int pos, int state)
 Support routine for 'sip notify' CLI.
static int construct_pidf_body (enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity)
static int copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy all headers from one request to another.
static int copy_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy one header field from one request to another.
static void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses)
static void copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock)
static struct ast_variablecopy_vars (struct ast_variable *src)
 duplicate a list of channel variables,
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy SIP VIA Headers from the request to the response.
static int create_addr (struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog, struct ast_sockaddr *remote_address)
 create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
static int create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer)
 Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.
static struct sip_epa_entry * create_epa_entry (const char *const event_package, const char *const destination)
static struct sip_esc_entry * create_esc_entry (struct event_state_compositor *esc, struct sip_request *req, const int expires)
static void create_new_sip_etag (struct sip_esc_entry *esc_entry, int is_linked)
static 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 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, int lockowner, int lockdialoglist)
 Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.
struct sip_pvt * dialog_unref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func)
static void disable_dsp_detect (struct sip_pvt *p)
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_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_incoming(), sipsock_read
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 *authlist, const char *realm)
 Find authentication for a specific 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 (const struct ast_sockaddr *addr)
 Helper for dns resolution to filter by address family.
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 Call transfer support (old way, deprecated by the IETF).
static char * get_body (struct sip_request *req, char *name, char delimiter)
 Get a specific line from the message body.
static char * get_body_by_line (const char *line, const char *name, int nameLen, char delimiter)
 Reads one line of SIP message body.
static int get_cached_mwi (struct sip_peer *peer, int *new, int *old)
 Get cached MWI info.
static void get_crypto_attrib (struct sip_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. 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.
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 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, int addnewline)
 Get text out of a SIP MESSAGE packet.
static const char * get_name_from_variable (struct ast_variable *var, const char *newpeername)
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, int 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, int seqno, struct ast_sockaddr *addr, int *recount, const char *e, int *nounlock)
 Handle incoming INVITE request.
static int handle_request_message (struct sip_pvt *p, struct sip_request *req)
 Handle incoming MESSAGE request.
static int handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int 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 int seqno, const char *uri)
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int 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, int 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, int seqno)
 Handle SIP response in dialogue.
static void handle_response_invite (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 Handle SIP response to INVITE dialogue.
static void handle_response_notify (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int 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, int seqno)
static void handle_response_refer (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
static int handle_response_register (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int 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, int seqno)
static void handle_response_update (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 Handle authentication challenge for SIP UPDATE.
static int handle_sip_publish_initial (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const int expires)
static int handle_sip_publish_modify (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires)
static int handle_sip_publish_refresh (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires)
static int handle_sip_publish_remove (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag)
static int handle_t38_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v, int *maxdatagram)
 Handle T.38 configuration options common to users and peers.
const char * hangup_cause2sip (int cause)
 Convert Asterisk hangup causes to SIP codes.
int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes.
static int init_req (struct sip_request *req, int sipmethod, const char *recip)
 Initialize SIP request.
static int init_resp (struct sip_request *resp, const char *msg)
 Initialize SIP response, based on SIP request.
static int initialize_escs (void)
static void initialize_initreq (struct sip_pvt *p, struct sip_request *req)
 Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
static 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, int seqno, int *nounlock)
 Find all call legs and bridge transferee with target called from handle_request_refer.
static int lws2sws (char *msgbuf, int len)
 Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
static void make_our_tag (char *tagbuf, size_t len)
 Make our SIP dialog tag.
static int manager_show_registry (struct mansession *s, const struct message *m)
 Show SIP registrations in the manager API.
static int manager_sip_qualify_peer (struct mansession *s, const struct message *m)
 Qualify SIP peers in the manager API.
static int manager_sip_show_peer (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sip_show_peers (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sipnotify (struct mansession *s, const struct message *m)
static int map_s_x (const struct _map_x_s *table, const char *s, int errorvalue)
 map from a string to an integer value, case insensitive. If no match is found, return errorvalue.
static const char * map_x_s (const struct _map_x_s *table, int x, const char *errorstring)
 map from an integer value to a string. If no match is found, return errorstring
static void mark_method_allowed (unsigned int *allowed_methods, enum sipmethod method)
static void mark_method_unallowed (unsigned int *allowed_methods, enum sipmethod method)
static void mark_parsed_methods (unsigned int *methods, char *methods_str)
static 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 unsigned int parse_allowed_methods (struct sip_request *req)
 parse the Allow header to see what methods the endpoint we are communicating with allows.
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, parse it.
static int parse_minse (const char *p_hdrval, int *const p_interval)
 Session-Timers: Function for parsing Min-SE header.
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req, char **name, char **number, int set_call_forward)
 Parse 302 Moved temporalily response.
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 Save contact header for 200 OK on INVITE.
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
 Parse contact header and save registration (peer registration).
static int parse_request (struct sip_request *req)
 Parse a SIP message.
static int parse_session_expires (const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref)
 Session-Timers: Function for parsing Session-Expires header.
static int 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 int peer_is_marked (void *peerobj, void *arg, 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 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 void process_request_queue (struct sip_pvt *p, int *recount, int *nounlock)
static int process_sdp (struct sip_pvt *p, struct sip_request *req, int t38action)
 Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
static int process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec)
static int process_sdp_a_image (const char *a, struct sip_pvt *p)
static int process_sdp_a_sendonly (const char *a, int *sendonly)
static int process_sdp_a_text (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec)
static int process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec)
static int process_sdp_c (const char *c, struct ast_sockaddr *addr)
static int process_sdp_o (const char *o, struct sip_pvt *p)
static int 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 queue_request (struct sip_pvt *p, const struct sip_request *req)
static struct sip_peer * realtime_peer (const char *newpeername, struct ast_sockaddr *addr, int devstate_only)
 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 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 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, int 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 scheduler_process_request_queue (const void *data)
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, int seqno)
 Send SIP Request to the other part of the dialogue.
static int send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int 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_ack (struct ast_cc_agent *agent)
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 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 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 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 called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
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, int seqno)
 Park a call using the subsystem in res_features.c This is executed in a separate thread.
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 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 char * sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Send an OPTIONS packet to a SIP peer.
static int sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen)
 Query an option on a SIP dialog.
static struct ast_framesip_read (struct ast_channel *ast)
 Read SIP RTP from channel.
static struct ast_sockaddrsip_real_dst (const struct sip_pvt *p)
 The real destination address for a write.
static const char * sip_reason_code_to_str (enum AST_REDIRECTING_REASON code)
static enum AST_REDIRECTING_REASON sip_reason_str_to_code (const char *text)
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.
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, const struct ast_event *event, 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)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
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_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 enum st_mode st_get_mode (struct sip_pvt *p)
 Get the session-timer mode.
static enum st_refresher st_get_refresher (struct sip_pvt *p)
 Get the entity (UAC or UAS) that's acting as the session-timer refresher.
static int st_get_se (struct sip_pvt *p, int max)
 Get Max or Min SE (session timer expiry).
static void start_session_timer (struct sip_pvt *p)
 Session-Timers: Start session timer.
static void state_notify_build_xml (int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto)
 Builds XML portion of NOTIFY messages for presence or dialog updates.
static const char * stmode2str (enum st_mode m)
static void stop_media_flows (struct sip_pvt *p)
 Immediately stop RTP, VRTP and UDPTL as applicable.
static void stop_session_timer (struct sip_pvt *p)
 Session-Timers: Stop session timer.
static int str2dtmfmode (const char *str)
 maps a string to dtmfmode, returns -1 on error
static enum st_mode str2stmode (const char *s)
static enum st_refresher str2strefresher (const char *s)
static const char * strefresher2str (enum st_refresher r)
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
static unsigned int t38_get_rate (enum ast_control_t38_rate rate)
 Get Max T.38 Transmission rate from T38 capabilities.
static void tcptls_packet_destructor (void *obj)
static struct sip_peer * temp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode).
static void temp_pvt_cleanup (void *)
static int temp_pvt_init (void *)
static char * terminate_uri (char *uri)
static int threadinfo_locate_cb (void *obj, void *arg, int flags)
static int threadt_cmp_cb (void *obj, void *arg, int flags)
static int threadt_hash_cb (const void *obj, const int flags)
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static int transmit_cc_notify (struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state)
static void transmit_fake_auth_response (struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.
static int transmit_info_with_aoc (struct sip_pvt *p, struct ast_aoc_decoded *decoded)
 Send SIP INFO advice of charge message.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init, const char *const explicit_uri)
 Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.
static int transmit_message_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, int 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, int 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_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp, int rpid)
 Used for 200 OK and 183 early media.
static int transmit_response_with_sip_etag (struct sip_pvt *p, const char *msg, const struct sip_request *req, struct sip_esc_entry *esc_entry, int need_new_etag)
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem (RFC3265).
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static void unlink_marked_peers_from_tables (void)
static void unlink_peer_from_tables (struct sip_peer *peer)
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_provisional_keepalive (struct sip_pvt *pvt, int with_sdp)
static void update_redirecting (struct sip_pvt *p, const void *data, size_t datalen)
 Send a provisional response indicating that a call was redirected.

Defines

#define SIP_PEDANTIC_DECODE(str)

Variables

static int can_parse_xml
static unsigned int chan_idx
static const char config [] = "sip.conf"
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static unsigned int dumphistory
static int global_authfailureevents
static unsigned int global_autoframing
static int global_callcounter
static unsigned int global_cos_audio
static unsigned int global_cos_sip
static unsigned int global_cos_text
static unsigned int global_cos_video
static int global_dynamic_exclude_static = 0
static struct ast_jb_conf global_jbconf
static int global_match_auth_username
static int global_max_se
static int global_min_se
static int global_prematuremediafilter
static int global_qualify_gap
static int global_qualify_peers
static int global_qualifyfreq
static int global_reg_timeout
static int global_regattempts_max
static int global_relaxdtmf
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static char global_sdpowner [AST_MAX_EXTENSION]
static char global_sdpsession [AST_MAX_EXTENSION]
static int global_shrinkcallerid
static enum st_mode global_st_mode
static enum st_refresher global_st_refresher
static int global_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.

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]


Detailed Description

Implementation of Session Initiation Protocol.

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

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

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

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

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

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

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

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

Definition in file chan_sip.c.


Define Documentation

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

#define CHECK_AUTH_BUF_INITLEN   256

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

Referenced by create_addr_from_peer(), and register_verify().

#define DATA_EXPORT_SIP_PEER ( MEMBER   ) 

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

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

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

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

Definition at line 17056 of file chan_sip.c.

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

Definition at line 17056 of file chan_sip.c.

#define FORMAT   "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"

Definition at line 17056 of file chan_sip.c.

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

Definition at line 17056 of file chan_sip.c.

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

Definition at line 17056 of file chan_sip.c.

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

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

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

Definition at line 17055 of file chan_sip.c.

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

Definition at line 17055 of file chan_sip.c.

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

Definition at line 17055 of file chan_sip.c.

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

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

Referenced by show_channels_cb().

#define SIP_PEDANTIC_DECODE ( str   ) 

Value:

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

Definition at line 696 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)

Definition at line 1078 of file chan_sip.c.

Referenced by dialog_needdestroy(), and sip_hangup().

#define sip_pvt_unlock (  )     ao2_unlock(x)

#define UNLINK ( element,
head,
prev   ) 

some list management macros.

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

07193                    {
07194    SIP_REQ_MATCH,
07195    SIP_REQ_NOT_MATCH,
07196    SIP_REQ_LOOP_DETECTED,
07197 };


Function Documentation

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

Definition at line 6778 of file chan_sip.c.

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

06779 {
06780    int pass;
06781 
06782    /*
06783     * Technically you can place arbitrary whitespace both before and after the ':' in
06784     * a header, although RFC3261 clearly says you shouldn't before, and place just
06785     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was
06786     * a good idea to say you can do it, and if you can do it, why in the hell would.
06787     * you say you shouldn't.
06788     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
06789     * and we always allow spaces after that for compatibility.
06790     */
06791    for (pass = 0; name && pass < 2;pass++) {
06792       int x, len = strlen(name);
06793       for (x = *start; x < req->headers; x++) {
06794          const char *header = REQ_OFFSET_TO_STR(req, header[x]);
06795          if (!strncasecmp(header, name, len)) {
06796             const char *r = header + len; /* skip name */
06797             if (sip_cfg.pedanticsipchecking)
06798                r = ast_skip_blanks(r);
06799 
06800             if (*r == ':') {
06801                *start = x+1;
06802                return ast_skip_blanks(r+1);
06803             }
06804          }
06805       }
06806       if (pass == 0) /* Try aliases */
06807          name = find_alias(name, NULL);
06808    }
06809 
06810    /* Don't return NULL, so get_header is always a valid pointer */
06811    return "";
06812 }

static void __init_check_auth_buf ( void   )  [static]

Definition at line 13244 of file chan_sip.c.

13255 {

static void __init_ts_temp_pvt ( void   )  [static]

A per-thread temporary pvt structure.

Definition at line 1102 of file chan_sip.c.

01126 : The address we bind to */

static void __reg_module ( void   )  [static]

Definition at line 28645 of file chan_sip.c.

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

Definition at line 12835 of file chan_sip.c.

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

Referenced by build_peer(), and set_address_from_contact().

12836 {
12837    char *domain, *transport;
12838    char contact_buf[256];
12839    char *contact;
12840 
12841    /* Work on a copy */
12842    ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
12843    contact = contact_buf;
12844 
12845    /* 
12846     * We have only the part in <brackets> here so we just need to parse a SIP URI.
12847     *
12848     * Note: The outbound proxy could be using UDP between the proxy and Asterisk.
12849     * We still need to be able to send to the remote agent through the proxy.
12850     */
12851 
12852    if (parse_uri(contact, "sip:,sips:", &contact, NULL, &domain,
12853             &transport)) {
12854       ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact);
12855    }
12856 
12857    /* XXX This could block for a long time XXX */
12858    /* We should only do this if it's a name, not an IP */
12859    /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records
12860       to find transport, port address and hostname. If there's a port number, we have to
12861       assume that the domain part is a host name and only look for an A/AAAA record in DNS.
12862    */
12863 
12864    if (ast_sockaddr_resolve_first(addr, domain, 0)) {
12865       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't "
12866          "resolve in DNS) : '%s'\n", domain);
12867       return -1;
12868    }
12869 
12870    /* set port */
12871    if (!ast_sockaddr_port(addr)) {
12872       ast_sockaddr_set_port(addr,
12873                   (get_transport_str2enum(transport) ==
12874                    SIP_TRANSPORT_TLS ||
12875                    !strncasecmp(fullcontact, "sips", 4)) ?
12876                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
12877    }
12878 
12879    return 0;
12880 }

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

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

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

03701 {
03702    struct sip_pkt *cur, *prev = NULL;
03703    const char *msg = "Not Found";   /* used only for debugging */
03704    int res = FALSE;
03705 
03706    /* If we have an outbound proxy for this dialog, then delete it now since
03707      the rest of the requests in this dialog needs to follow the routing.
03708      If obforcing is set, we will keep the outbound proxy during the whole
03709      dialog, regardless of what the SIP rfc says
03710    */
03711    if (p->outboundproxy && !p->outboundproxy->force){
03712       ref_proxy(p, NULL);
03713    }
03714 
03715    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
03716       if (cur->seqno != seqno || cur->is_resp != resp) {
03717          continue;
03718       }
03719       if (cur->is_resp || cur->method == sipmethod) {
03720          res = TRUE;
03721          msg = "Found";
03722          if (!resp && (seqno == p->pendinginvite)) {
03723             ast_debug(1, "Acked pending invite %d\n", p->pendinginvite);
03724             p->pendinginvite = 0;
03725          }
03726          if (cur->retransid > -1) {
03727             if (sipdebug)
03728                ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
03729          }
03730          /* This odd section is designed to thwart a
03731           * race condition in the packet scheduler. There are
03732           * two conditions under which deleting the packet from the
03733           * scheduler can fail.
03734           *
03735           * 1. The packet has been removed from the scheduler because retransmission
03736           * is being attempted. The problem is that if the packet is currently attempting
03737           * retransmission and we are at this point in the code, then that MUST mean
03738           * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
03739           * lock temporarily to allow retransmission.
03740           *
03741           * 2. The packet has reached its maximum number of retransmissions and has
03742           * been permanently removed from the packet scheduler. If this is the case, then
03743           * the packet's retransid will be set to -1. The atomicity of the setting and checking
03744           * of the retransid to -1 is ensured since in both cases p's lock is held.
03745           */
03746          while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
03747             sip_pvt_unlock(p);
03748             usleep(1);
03749             sip_pvt_lock(p);
03750          }
03751          UNLINK(cur, p->packets, prev);
03752          dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt");
03753          if (cur->data) {
03754             ast_free(cur->data);
03755          }
03756          ast_free(cur);
03757          break;
03758       }
03759    }
03760    ast_debug(1, "Stopping retransmission on '%s' of %s %d: Match %s\n",
03761       p->callid, resp ? "Response" : "Request", seqno, msg);
03762    return res;
03763 }

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

References __sip_pretend_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, 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_scheddestroy(), cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), and TRUE.

Referenced by sip_scheddestroy(), and sip_show_sched().

03573 {
03574    struct sip_pvt *p = (struct sip_pvt *)data;
03575 
03576    /* If this is a subscription, tell the phone that we got a timeout */
03577    if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) {
03578       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
03579       p->subscribed = NONE;
03580       append_history(p, "Subscribestatus", "timeout");
03581       ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>");
03582       return 10000;  /* Reschedule this destruction so that we know that it's gone */
03583    }
03584 
03585    /* If there are packets still waiting for delivery, delay the destruction */
03586    if (p->packets) {
03587       if (!p->needdestroy) {
03588          char method_str[31];
03589          ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
03590          append_history(p, "ReliableXmit", "timeout");
03591          if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
03592             if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
03593                pvt_set_needdestroy(p, "autodestruct");
03594             }
03595          }
03596          return 10000;
03597       } else {
03598          /* They've had their chance to respond. Time to bail */
03599          __sip_pretend_ack(p);
03600       }
03601    }
03602 
03603    /* Reset schedule ID */
03604    p->autokillid = -1;
03605 
03606    if (p->owner) {
03607       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
03608       ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
03609    } else if (p->refer && !p->alreadygone) {
03610       ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
03611       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
03612       append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid);
03613       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03614    } else {
03615       append_history(p, "AutoDestroy", "%s", p->callid);
03616       ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid);
03617       dialog_unlink_all(p, TRUE, TRUE); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */
03618       /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */
03619       /* sip_destroy(p); */      /* Go ahead and destroy dialog. All attempts to recover is done */
03620       /* sip_destroy also absorbs the reference */
03621    }
03622    dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
03623    return 0;
03624 }

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 5249 of file chan_sip.c.

References ao2_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_SCHED_DEL_UNREF, 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, cfsip_methods::text, TRUE, unref_peer(), and update_call_counter().

Referenced by sip_destroy().

05250 {
05251    struct sip_request *req;
05252 
05253    if (p->stimer) {
05254       ast_free(p->stimer);
05255       p->stimer = NULL;
05256    }
05257 
05258    if (sip_debug_test_pvt(p))
05259       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
05260 
05261    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05262       update_call_counter(p, DEC_CALL_LIMIT);
05263       ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
05264    }
05265 
05266    /* Unlink us from the owner if we have one */
05267    if (p->owner) {
05268       if (lockowner)
05269          ast_channel_lock(p->owner);
05270       ast_debug(1, "Detaching from %s\n", p->owner->name);
05271       p->owner->tech_pvt = NULL;
05272       /* Make sure that the channel knows its backend is going away */
05273       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05274       if (lockowner)
05275          ast_channel_unlock(p->owner);
05276       /* Give the channel a chance to react before deallocation */
05277       usleep(1);
05278    }
05279 
05280    /* Remove link from peer to subscription of MWI */
05281    if (p->relatedpeer && p->relatedpeer->mwipvt)
05282       p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
05283    if (p->relatedpeer && p->relatedpeer->call == p)
05284       p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
05285    
05286    if (p->relatedpeer)
05287       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy");
05288    
05289    if (p->registry) {
05290       if (p->registry->call == p)
05291          p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all");
05292       p->registry = registry_unref(p->registry, "delete p->registry");
05293    }
05294    
05295    if (p->mwi) {
05296       p->mwi->call = NULL;
05297    }
05298 
05299    if (dumphistory)
05300       sip_dump_history(p);
05301 
05302    if (p->options)
05303       ast_free(p->options);
05304 
05305    if (p->notify) {
05306       ast_variables_destroy(p->notify->headers);
05307       ast_free(p->notify->content);
05308       ast_free(p->notify);
05309    }
05310    if (p->rtp) {
05311       ast_rtp_instance_destroy(p->rtp);
05312    }
05313    if (p->vrtp) {
05314       ast_rtp_instance_destroy(p->vrtp);
05315    }
05316    if (p->trtp) {
05317       ast_rtp_instance_destroy(p->trtp);
05318    }
05319    if (p->udptl)
05320       ast_udptl_destroy(p->udptl);
05321    if (p->refer)
05322       ast_free(p->refer);
05323    if (p->route) {
05324       free_old_route(p->route);
05325       p->route = NULL;
05326    }
05327    deinit_req(&p->initreq);
05328 
05329    /* Destroy Session-Timers if allocated */
05330    if (p->stimer) {
05331       p->stimer->quit_flag = 1;
05332       if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) {
05333          AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
05334                dialog_unref(p, "removing session timer ref"));
05335       }
05336       ast_free(p->stimer);
05337       p->stimer = NULL;
05338    }
05339 
05340    /* Clear history */
05341    if (p->history) {
05342       struct sip_history *hist;
05343       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
05344          ast_free(hist);
05345          p->history_entries--;
05346       }
05347       ast_free(p->history);
05348       p->history = NULL;
05349    }
05350 
05351    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
05352       ast_free(req);
05353    }
05354 
05355    if (p->chanvars) {
05356       ast_variables_destroy(p->chanvars);
05357       p->chanvars = NULL;
05358    }
05359 
05360    if (p->srtp) {
05361       sip_srtp_destroy(p->srtp);
05362       p->srtp = NULL;
05363    }
05364 
05365    if (p->vsrtp) {
05366       sip_srtp_destroy(p->vsrtp);
05367       p->vsrtp = NULL;
05368    }
05369 
05370    if (p->tsrtp) {
05371       sip_srtp_destroy(p->tsrtp);
05372       p->tsrtp = NULL;
05373    }
05374 
05375    if (p->directmediaha) {
05376       ast_free_ha(p->directmediaha);
05377       p->directmediaha = NULL;
05378    }
05379 
05380    ast_string_field_free_memory(p);
05381 
05382    ast_cc_config_params_destroy(p->cc_params);
05383 
05384    if (p->epa_entry) {
05385       ao2_ref(p->epa_entry, -1);
05386       p->epa_entry = NULL;
05387    }
05388 
05389    if (p->socket.tcptls_session) {
05390       ao2_ref(p->socket.tcptls_session, -1);
05391       p->socket.tcptls_session = NULL;
05392    }
05393 }

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

Register with SIP proxy.

Returns:
see __sip_xmit

Definition at line 12111 of file chan_sip.c.

References transmit_register().

Referenced by sip_reregister().

12112 {
12113    int res;
12114 
12115    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
12116    return res;
12117 }

void __sip_pretend_ack ( struct sip_pvt *  p  ) 

Pretend to ack all packets called with p locked.

Definition at line 3767 of file chan_sip.c.

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

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

03768 {
03769    struct sip_pkt *cur = NULL;
03770 
03771    while (p->packets) {
03772       int method;
03773       if (cur == p->packets) {
03774          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
03775          return;
03776       }
03777       cur = p->packets;
03778       method = (cur->method) ? cur->method : find_sip_method(cur->data->str);
03779       __sip_ack(p, cur->seqno, cur->is_resp, method);
03780    }
03781 }

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

Transmit packet with retransmits.

Returns:
0 on success, -1 on failure to allocate packet

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

Definition at line 3480 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_tvnow(), DEFAULT_RETRANS, LOG_ERROR, and retrans_pkt().

Referenced by send_request(), and send_response().

03481 {
03482    struct sip_pkt *pkt = NULL;
03483    int siptimer_a = DEFAULT_RETRANS;
03484    int xmitres = 0;
03485    int respid;
03486 
03487    if (sipmethod == SIP_INVITE) {
03488       /* Note this is a pending invite */
03489       p->pendinginvite = seqno;
03490    }
03491 
03492    /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */
03493    /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */
03494    /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */
03495    if (!(p->socket.type & SIP_TRANSPORT_UDP)) {
03496       xmitres = __sip_xmit(p, data, len); /* Send packet */
03497       if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03498          append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)");
03499          return AST_FAILURE;
03500       } else {
03501          return AST_SUCCESS;
03502       }
03503    }
03504 
03505    if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) {
03506       return AST_FAILURE;
03507    }
03508    /* copy data, add a terminator and save length */
03509    if (!(pkt->data = ast_str_create(len))) {
03510       ast_free(pkt);
03511       return AST_FAILURE;
03512    }
03513    ast_str_set(&pkt->data, 0, "%s%s", data->str, "\0");
03514    pkt->packetlen = len;
03515    /* copy other parameters from the caller */
03516    pkt->method = sipmethod;
03517    pkt->seqno = seqno;
03518    pkt->is_resp = resp;
03519    pkt->is_fatal = fatal;
03520    pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner");
03521    pkt->next = p->packets;
03522    p->packets = pkt; /* Add it to the queue */
03523    if (resp) {
03524       /* Parse out the response code */
03525       if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) {
03526          pkt->response_code = respid;
03527       }
03528    }
03529    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
03530    pkt->retransid = -1;
03531    if (pkt->timer_t1) {
03532       siptimer_a = pkt->timer_t1;
03533    }
03534 
03535    pkt->time_sent = ast_tvnow(); /* time packet was sent */
03536    pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */
03537 
03538    /* Schedule retransmission */
03539    AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1);
03540    if (sipdebug) {
03541       ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
03542    }
03543 
03544    xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);   /* Send packet */
03545 
03546    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03547       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03548       ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n");
03549       AST_SCHED_DEL(sched, pkt->retransid);
03550       p->packets = pkt->next;
03551       pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03552       ast_free(pkt->data);
03553       ast_free(pkt);
03554       return AST_FAILURE;
03555    } else {
03556       /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread
03557        * only wakes up every 1000ms by default, we have to poke the thread here to make
03558        * sure it successfully detects this must be retransmitted in less time than
03559        * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */
03560       if (monitor_thread != AST_PTHREADT_NULL) {
03561          pthread_kill(monitor_thread, SIGURG);
03562       }
03563       return AST_SUCCESS;
03564    }
03565 }

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

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

Definition at line 3784 of file chan_sip.c.

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

Referenced by handle_response(), and sip_hangup().

03785 {
03786    struct sip_pkt *cur;
03787    int res = FALSE;
03788 
03789    for (cur = p->packets; cur; cur = cur->next) {
03790       if (cur->seqno == seqno && cur->is_resp == resp &&
03791          (cur->is_resp || method_match(sipmethod, cur->data->str))) {
03792          /* this is our baby */
03793          if (cur->retransid > -1) {
03794             if (sipdebug)
03795                ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
03796          }
03797          AST_SCHED_DEL(sched, cur->retransid);
03798          res = TRUE;
03799          break;
03800       }
03801    }
03802    ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found");
03803    return res;
03804 }

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

Actually setup an MWI subscription or resubscribe.

Definition at line 11460 of file chan_sip.c.

References ast_dnsmgr_lookup(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, bindaddr, build_callid_pvt(), build_contact(), build_via(), create_addr(), dialog_unlink_all(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), MAXHOSTNAMELEN, obproxy_get(), ref_proxy(), set_socket_transport(), sip_alloc(), sip_cfg, transmit_invite(), and TRUE.

Referenced by sip_subscribe_mwi_do().

11461 {
11462    /* If we have no DNS manager let's do a lookup */
11463    if (!mwi->dnsmgr) {
11464       char transport[MAXHOSTNAMELEN];
11465       snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport));
11466 
11467       mwi->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
11468       ast_dnsmgr_lookup(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL);
11469    }
11470 
11471    /* If we already have a subscription up simply send a resubscription */
11472    if (mwi->call) {
11473       transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL);
11474       return 0;
11475    }
11476    
11477    /* Create a dialog that we will use for the subscription */
11478    if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) {
11479       return -1;
11480    }
11481 
11482    ref_proxy(mwi->call, obproxy_get(mwi->call, NULL));
11483 
11484    if (!ast_sockaddr_port(&mwi->us) && mwi->portno) {
11485       ast_sockaddr_set_port(&mwi->us, mwi->portno);
11486    }
11487    
11488    /* Setup the destination of our subscription */
11489    if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0, NULL)) {
11490       dialog_unlink_all(mwi->call, TRUE, TRUE);
11491       mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all");
11492       return 0;
11493    }
11494 
11495    mwi->call->expiry = mwi_expiry;
11496    
11497    if (!mwi->dnsmgr && mwi->portno) {
11498       ast_sockaddr_set_port(&mwi->call->sa, mwi->portno);
11499       ast_sockaddr_set_port(&mwi->call->recv, mwi->portno);
11500    } else {
11501       mwi->portno = ast_sockaddr_port(&mwi->call->sa);
11502    }
11503    
11504    /* Set various other information */
11505    if (!ast_strlen_zero(mwi->authuser)) {
11506       ast_string_field_set(mwi->call, peername, mwi->authuser);
11507       ast_string_field_set(mwi->call, authname, mwi->authuser);
11508       ast_string_field_set(mwi->call, fromuser, mwi->authuser);
11509    } else {
11510       ast_string_field_set(mwi->call, peername, mwi->username);
11511       ast_string_field_set(mwi->call, authname, mwi->username);
11512       ast_string_field_set(mwi->call, fromuser, mwi->username);
11513    }
11514    ast_string_field_set(mwi->call, username, mwi->username);
11515    if (!ast_strlen_zero(mwi->secret)) {
11516       ast_string_field_set(mwi->call, peersecret, mwi->secret);
11517    }
11518    set_socket_transport(&mwi->call->socket, mwi->transport);
11519    mwi->call->socket.port = htons(mwi->portno);
11520    ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call);
11521    build_contact(mwi->call);
11522    build_via(mwi->call);
11523    build_callid_pvt(mwi->call);
11524    ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING);
11525    
11526    /* Associate the call with us */
11527    mwi->call->mwi = ASTOBJ_REF(mwi);
11528    
11529    /* Actually send the packet */
11530    transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL);
11531 
11532    return 0;
11533 }

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

Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit.

Returns:
length of transmitted message, XMIT_ERROR on known network failures -1 on other failures.

Definition at line 3081 of file chan_sip.c.

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

03082 {
03083    int res = 0;
03084    const struct ast_sockaddr *dst = sip_real_dst(p);
03085 
03086    ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", data->str, get_transport_pvt(p), ast_sockaddr_stringify(dst));
03087 
03088    if (sip_prepare_socket(p) < 0) {
03089       return XMIT_ERROR;
03090    }
03091 
03092    if (p->socket.type == SIP_TRANSPORT_UDP) {
03093       res = ast_sendto(p->socket.fd, data->str, len, 0, dst);
03094    } else if (p->socket.tcptls_session) {
03095       res = sip_tcptls_write(p->socket.tcptls_session, data->str, len);
03096    } else {
03097       ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n");
03098       return XMIT_ERROR;
03099    }
03100 
03101    if (res == -1) {
03102       switch (errno) {
03103       case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
03104       case EHOSTUNREACH:   /* Host can't be reached */
03105       case ENETDOWN:       /* Interface down */
03106       case ENETUNREACH: /* Network failure */
03107       case ECONNREFUSED:      /* ICMP port unreachable */
03108          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
03109       }
03110    }
03111    if (res != len) {
03112       ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s returned %d: %s\n", data, len, ast_sockaddr_stringify(dst), res, strerror(errno));
03113    }
03114 
03115    return res;
03116 }

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

References add_cc_call_info_to_response(), 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_response(), transmit_response_reliable(), and transmit_response_using_temp().

09643 {
09644    struct sip_request resp;
09645    int seqno = 0;
09646 
09647    if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) {
09648       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
09649       return -1;
09650    }
09651    respprep(&resp, p, msg, req);
09652 
09653    if (ast_test_flag(&p->flags[0], SIP_SENDRPID)
09654          && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND)
09655          && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) {
09656       ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND);
09657       add_rpid(&resp, p);
09658    }
09659    if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) {
09660       add_cc_call_info_to_response(p, &resp);
09661    }
09662 
09663    /* If we are cancelling an incoming invite for some reason, add information
09664       about the reason why we are doing this in clear text */
09665    if (p->method == SIP_INVITE && msg[0] != '1') {
09666       char buf[20];
09667 
09668       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) {
09669          int hangupcause = 0;
09670 
09671          if (p->owner && p->owner->hangupcause) {
09672             hangupcause = p->owner->hangupcause;
09673          } else if (p->hangupcause) {
09674             hangupcause = p->hangupcause;
09675          } else {
09676             int respcode;
09677             if (sscanf(msg, "%30d ", &respcode))
09678                hangupcause = hangup_sip2cause(respcode);
09679          }
09680 
09681          if (hangupcause) {
09682             sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f);
09683             add_header(&resp, "Reason", buf);
09684          }
09685       }
09686 
09687       if (p->owner && p->owner->hangupcause) {
09688          add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
09689          snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
09690          add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
09691       }
09692    }
09693    return send_response(p, &resp, reliable, seqno);
09694 }

static void __unreg_module ( void   )  [static]

Definition at line 28645 of file chan_sip.c.

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

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

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

16113 {
16114    struct sip_peer *peer;
16115    int load_realtime;
16116 
16117    if (argc < 4)
16118       return CLI_SHOWUSAGE;
16119 
16120    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
16121    if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) {
16122       sip_poke_peer(peer, 1);
16123       unref_peer(peer, "qualify: done with peer");
16124    } else if (type == 0) {
16125       ast_cli(fd, "Peer '%s' not found\n", argv[3]);
16126    } else {
16127       astman_send_error(s, m, "Peer not found");
16128    }
16129    return CLI_SUCCESS;
16130 }

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

References 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_print_group(), ast_sched_when(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, 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(), strefresher2str(), text, transfermode2str(), TRUE, unref_peer(), and ast_variable::value.

Referenced by manager_sip_show_peer(), and sip_show_peer().

16198 {
16199    char status[30] = "";
16200    char cbuf[256];
16201    struct sip_peer *peer;
16202    char codec_buf[512];
16203    struct ast_codec_pref *pref;
16204    struct ast_variable *v;
16205    struct sip_auth *auth;
16206    int x = 0, load_realtime;
16207    format_t codec = 0;
16208    int realtimepeers;
16209 
16210    realtimepeers = ast_check_realtime("sippeers");
16211 
16212    if (argc < 4)
16213       return CLI_SHOWUSAGE;
16214 
16215    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
16216    peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0);
16217 
16218    if (s) {    /* Manager */
16219       if (peer) {
16220          const char *id = astman_get_header(m, "ActionID");
16221 
16222          astman_append(s, "Response: Success\r\n");
16223          if (!ast_strlen_zero(id))
16224             astman_append(s, "ActionID: %s\r\n", id);
16225       } else {
16226          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]);
16227          astman_send_error(s, m, cbuf);
16228          return CLI_SUCCESS;
16229       }
16230    }
16231    if (peer && type==0 ) { /* Normal listing */
16232       struct ast_str *mailbox_str = ast_str_alloca(512);
16233       ast_cli(fd, "\n\n");
16234       ast_cli(fd, "  * Name       : %s\n", peer->name);
16235       if (realtimepeers) { /* Realtime is enabled */
16236          ast_cli(fd, "  Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No");
16237       }
16238       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
16239       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
16240       ast_cli(fd, "  Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>");
16241       for (auth = peer->auth; auth; auth = auth->next) {
16242          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
16243          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
16244       }
16245       ast_cli(fd, "  Context      : %s\n", peer->context);
16246       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
16247       ast_cli(fd, "  Language     : %s\n", peer->language);
16248       if (!ast_strlen_zero(peer->accountcode))
16249          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
16250       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
16251       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
16252       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
16253       if (!ast_strlen_zero(peer->fromuser))
16254          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
16255       if (!ast_strlen_zero(peer->fromdomain))
16256          ast_cli(fd, "  FromDomain   : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
16257       ast_cli(fd, "  Callgroup    : ");
16258       print_group(fd, peer->callgroup, 0);
16259       ast_cli(fd, "  Pickupgroup  : ");
16260       print_group(fd, peer->pickupgroup, 0);
16261       peer_mailboxes_to_str(&mailbox_str, peer);
16262       ast_cli(fd, "  MOH Suggest  : %s\n", peer->mohsuggest);
16263       ast_cli(fd, "  Mailbox      : %s\n", mailbox_str->str);
16264       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
16265       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
16266       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
16267       ast_cli(fd, "  Max forwards : %d\n", peer->maxforwards);
16268       if (peer->busy_level)
16269          ast_cli(fd, "  Busy level   : %d\n", peer->busy_level);
16270       ast_cli(fd, "  Dynamic      : %s\n", AST_CLI_YESNO(peer->host_dynamic));
16271       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
16272       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
16273       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
16274       ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
16275       ast_cli(fd, "  Force rport  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)));
16276       ast_cli(fd, "  ACL          : %s\n", AST_CLI_YESNO(peer->ha != NULL));
16277       ast_cli(fd, "  DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL));
16278       ast_cli(fd, "  T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
16279       ast_cli(fd, "  T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
16280       ast_cli(fd, "  T.38 MaxDtgrm: %d\n", peer->t38_maxdatagram);
16281       ast_cli(fd, "  DirectMedia  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)));
16282       ast_cli(fd, "  PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)));
16283       ast_cli(fd, "  User=Phone   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)));
16284       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)));
16285       ast_cli(fd, "  Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)));
16286       ast_cli(fd, "  Ign SDP ver  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION)));
16287       ast_cli(fd, "  Trust RPID   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID)));
16288       ast_cli(fd, "  Send RPID    : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID)));
16289       ast_cli(fd, "  Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
16290       ast_cli(fd, "  Overlap dial : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP)));
16291       if (peer->outboundproxy)
16292          ast_cli(fd, "  Outb. proxy  : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name,
16293                      peer->outboundproxy->force ? "(forced)" : "");
16294 
16295       /* - is enumerated */
16296       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
16297       ast_cli(fd, "  Timer T1     : %d\n", peer->timer_t1);
16298       ast_cli(fd, "  Timer B      : %d\n", peer->timer_b);
16299       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
16300       ast_cli(fd, "  Addr->IP     : %s\n", ast_sockaddr_stringify(&peer->addr));
16301       ast_cli(fd, "  Defaddr->IP  : %s\n", ast_sockaddr_stringify(&peer->defaddr));
16302       ast_cli(fd, "  Prim.Transp. : %s\n", get_transport(peer->socket.type));
16303       ast_cli(fd, "  Allowed.Trsp : %s\n", get_transport_list(peer->transports));
16304       if (!ast_strlen_zero(sip_cfg.regcontext))
16305          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
16306       ast_cli(fd, "  Def. Username: %s\n", peer->username);
16307       ast_cli(fd, "  SIP Options  : ");
16308       if (peer->sipoptions) {
16309          int lastoption = -1;
16310          for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
16311             if (sip_options[x].id != lastoption) {
16312                if (peer->sipoptions & sip_options[x].id)
16313                   ast_cli(fd, "%s ", sip_options[x].text);
16314                lastoption = x;
16315             }
16316          }
16317       } else
16318          ast_cli(fd, "(none)");
16319 
16320       ast_cli(fd, "\n");
16321       ast_cli(fd, "  Codecs       : ");
16322       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
16323       ast_cli(fd, "%s\n", codec_buf);
16324       ast_cli(fd, "  Codec Order  : (");
16325       print_codec_to_cli(fd, &peer->prefs);
16326       ast_cli(fd, ")\n");
16327 
16328       ast_cli(fd, "  Auto-Framing :  %s \n", AST_CLI_YESNO(peer->autoframing));
16329       ast_cli(fd, "  100 on REG   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_REGISTERTRYING)));
16330       ast_cli(fd, "  Status       : ");
16331       peer_status(peer, status, sizeof(status));
16332       ast_cli(fd, "%s\n", status);
16333       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
16334       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
16335       ast_cli(fd, "  Qualify Freq : %d ms\n", peer->qualifyfreq);
16336       if (peer->chanvars) {
16337          ast_cli(fd, "  Variables    :\n");
16338          for (v = peer->chanvars ; v ; v = v->next)
16339             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
16340       }
16341 
16342       ast_cli(fd, "  Sess-Timers  : %s\n", stmode2str(peer->stimer.st_mode_oper));
16343       ast_cli(fd, "  Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref));
16344       ast_cli(fd, "  Sess-Expires : %d secs\n", peer->stimer.st_max_se);
16345       ast_cli(fd, "  Min-Sess     : %d secs\n", peer->stimer.st_min_se);
16346       ast_cli(fd, "  RTP Engine   : %s\n", peer->engine);
16347       ast_cli(fd, "  Parkinglot   : %s\n", peer->parkinglot);
16348       ast_cli(fd, "  Use Reason   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)));
16349       ast_cli(fd, "\n");
16350       peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer ptr");
16351    } else  if (peer && type == 1) { /* manager listing */
16352       char buffer[256];
16353       struct ast_str *mailbox_str = ast_str_alloca(512);
16354       astman_append(s, "Channeltype: SIP\r\n");
16355       astman_append(s, "ObjectName: %s\r\n", peer->name);
16356       astman_append(s, "ChanObjectType: peer\r\n");
16357       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
16358       astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y");
16359       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
16360       astman_append(s, "Context: %s\r\n", peer->context);
16361       astman_append(s, "Language: %s\r\n", peer->language);
16362       if (!ast_strlen_zero(peer->accountcode))
16363          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
16364       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
16365       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
16366       if (!ast_strlen_zero(peer->fromuser))
16367          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
16368       if (!ast_strlen_zero(peer->fromdomain))
16369          astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
16370       astman_append(s, "Callgroup: ");
16371       astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup));
16372       astman_append(s, "Pickupgroup: ");
16373       astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup));
16374       astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest);
16375       peer_mailboxes_to_str(&mailbox_str, peer);
16376       astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str);
16377       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
16378       astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards);
16379       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
16380       astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards);
16381       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
16382       astman_append(s, "Busy-level: %d\r\n", peer->busy_level);
16383       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
16384       astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N");
16385       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
16386       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire));
16387       astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
16388       astman_append(s, "SIP-Forcerport: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)?"Y":"N"));
16389       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
16390       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N"));
16391       astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N"));
16392       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
16393       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
16394       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
16395       astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N"));
16396       astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N"));
16397       astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
16398       astman_append(s, "SIP-T.38MaxDtgrm: %d\r\n", peer->t38_maxdatagram);
16399       astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper));
16400       astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref));
16401       astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se);
16402       astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se);
16403       astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine);
16404 
16405       /* - is enumerated */
16406       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
16407       astman_append(s, "ToHost: %s\r\n", peer->tohost);
16408       astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr));
16409       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));
16410       astman_append(s, "Default-Username: %s\r\n", peer->username);
16411       if (!ast_strlen_zero(sip_cfg.regcontext))
16412          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
16413       astman_append(s, "Codecs: ");
16414       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
16415       astman_append(s, "%s\r\n", codec_buf);
16416       astman_append(s, "CodecOrder: ");
16417       pref = &peer->prefs;
16418       for(x = 0; x < 64 ; x++) {
16419          codec = ast_codec_pref_index(pref, x);
16420          if (!codec)
16421             break;
16422          astman_append(s, "%s", ast_getformatname(codec));
16423          if (x < 63 && ast_codec_pref_index(pref, x+1))
16424             astman_append(s, ",");
16425       }
16426 
16427       astman_append(s, "\r\n");
16428       astman_append(s, "Status: ");
16429       peer_status(peer, status, sizeof(status));
16430       astman_append(s, "%s\r\n", status);
16431       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
16432       astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact);
16433       astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq);
16434       astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot);
16435       if (peer->chanvars) {
16436          for (v = peer->chanvars ; v ; v = v->next) {
16437             astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value);
16438          }
16439       }
16440       astman_append(s, "SIP-Use-Reason-Header : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N");
16441 
16442       peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer");
16443 
16444    } else {
16445       ast_cli(fd, "Peer %s not found.\n", argv[3]);
16446       ast_cli(fd, "\n");
16447    }
16448 
16449    return CLI_SUCCESS;
16450 }

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

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

Referenced by manager_sip_show_peers(), and sip_show_peers().

15516 {
15517    regex_t regexbuf;
15518    int havepattern = FALSE;
15519    struct sip_peer *peer;
15520    struct ao2_iterator i;
15521    
15522 /* the last argument is left-aligned, so we don't need a size anyways */
15523 #define FORMAT2 "%-25.25s  %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"
15524 #define FORMAT  "%-25.25s  %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
15525 
15526    char name[256];
15527    int total_peers = 0;
15528    int peers_mon_online = 0;
15529    int peers_mon_offline = 0;
15530    int peers_unmon_offline = 0;
15531    int peers_unmon_online = 0;
15532    const char *id;
15533    char idtext[256] = "";
15534    int realtimepeers;
15535    int objcount = ao2_container_count(peers);
15536    struct sip_peer **peerarray;
15537    int k;
15538    
15539    
15540    realtimepeers = ast_check_realtime("sippeers");
15541    peerarray = ast_calloc(sizeof(struct sip_peer *), objcount);
15542 
15543    if (s) { /* Manager - get ActionID */
15544       id = astman_get_header(m, "ActionID");
15545       if (!ast_strlen_zero(id))
15546          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
15547    }
15548 
15549    switch (argc) {
15550    case 5:
15551       if (!strcasecmp(argv[3], "like")) {
15552          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
15553             return CLI_SHOWUSAGE;
15554          havepattern = TRUE;
15555       } else
15556          return CLI_SHOWUSAGE;
15557    case 3:
15558       break;
15559    default:
15560       return CLI_SHOWUSAGE;
15561    }
15562 
15563    if (!s) /* Normal list */
15564       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
15565    
15566 
15567    i = ao2_iterator_init(peers, 0);
15568    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {  
15569       ao2_lock(peer);
15570 
15571       if (!(peer->type & SIP_TYPE_PEER)) {
15572          ao2_unlock(peer);
15573          unref_peer(peer, "unref peer because it's actually a user");
15574          continue;
15575       }
15576 
15577       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
15578          objcount--;
15579          ao2_unlock(peer);
15580          unref_peer(peer, "toss iterator peer ptr before continue");
15581          continue;
15582       }
15583 
15584       peerarray[total_peers++] = peer;
15585       ao2_unlock(peer);
15586    }
15587    ao2_iterator_destroy(&i);
15588    
15589    qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc);
15590 
15591    for(k=0; k < total_peers; k++) {
15592       char status[20] = "";
15593       char srch[2000];
15594       char pstatus;
15595       peer = peerarray[k];
15596       
15597       ao2_lock(peer);
15598       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
15599          ao2_unlock(peer);
15600          unref_peer(peer, "toss iterator peer ptr before continue");
15601          continue;
15602       }
15603 
15604       if (!ast_strlen_zero(peer->username) && !s)
15605          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
15606       else
15607          ast_copy_string(name, peer->name, sizeof(name));
15608       
15609       pstatus = peer_status(peer, status, sizeof(status));
15610       if (pstatus == 1)
15611          peers_mon_online++;
15612       else if (pstatus == 0)
15613          peers_mon_offline++;
15614       else {
15615          if (ast_sockaddr_isnull(&peer->addr) ||
15616              !ast_sockaddr_port(&peer->addr)) {
15617             peers_unmon_offline++;
15618          } else {
15619             peers_unmon_online++;
15620          }
15621       }
15622 
15623       snprintf(srch, sizeof(srch), FORMAT, name,
15624          ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr),
15625          peer->host_dynamic ? " D " : "   ",    /* Dynamic or not? */
15626          ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : "   ", /* NAT=yes? */
15627          peer->ha ? " A " : "   ",  /* permit/deny */
15628          ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status,
15629          realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
15630 
15631       if (!s)  {/* Normal CLI list */
15632          ast_cli(fd, FORMAT, name,
15633          ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr),
15634          peer->host_dynamic ? " D " : "   ",    /* Dynamic or not? */
15635          ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : "   ", /* NAT=yes? */
15636          peer->ha ? " A " : "   ",       /* permit/deny */
15637          ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status,
15638          realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
15639       } else { /* Manager format */
15640          /* The names here need to be the same as other channels */
15641          astman_append(s,
15642          "Event: PeerEntry\r\n%s"
15643          "Channeltype: SIP\r\n"
15644          "ObjectName: %s\r\n"
15645          "ChanObjectType: peer\r\n" /* "peer" or "user" */
15646          "IPaddress: %s\r\n"
15647          "IPport: %d\r\n"
15648          "Dynamic: %s\r\n"
15649          "Forcerport: %s\r\n"
15650          "VideoSupport: %s\r\n"
15651          "TextSupport: %s\r\n"
15652          "ACL: %s\r\n"
15653          "Status: %s\r\n"
15654          "RealtimeDevice: %s\r\n\r\n",
15655          idtext,
15656          peer->name,
15657          ast_sockaddr_isnull(&peer->addr) ? "-none-" : ast_sockaddr_stringify(&peer->addr),
15658          ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr),
15659          peer->host_dynamic ? "yes" : "no",  /* Dynamic or not? */
15660          ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no",  /* NAT=yes? */
15661          ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no",  /* VIDEOSUPPORT=yes? */
15662          ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no",   /* TEXTSUPPORT=yes? */
15663          peer->ha ? "yes" : "no",       /* permit/deny */
15664          status,
15665          realtimepeers ? (peer->is_realtime ? "yes":"no") : "no");
15666       }
15667       ao2_unlock(peer);
15668       unref_peer(peer, "toss iterator peer ptr");
15669    }
15670    
15671    if (!s)
15672       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
15673               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
15674 
15675    if (havepattern)
15676       regfree(&regexbuf);
15677 
15678    if (total)
15679       *total = total_peers;
15680    
15681    ast_free(peerarray);
15682    
15683    return CLI_SUCCESS;
15684 #undef FORMAT
15685 #undef FORMAT2
15686 }

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

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

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

Definition at line 2428 of file chan_sip.c.

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

Referenced by sip_tcp_worker_fn().

02429 {
02430    int res, cl;
02431    struct sip_request req = { 0, } , reqcpy = { 0, };
02432    struct sip_threadinfo *me = NULL;
02433    char buf[1024] = "";
02434    struct pollfd fds[2] = { { 0 }, { 0 }, };
02435    struct ast_tcptls_session_args *ca = NULL;
02436 
02437    /* If this is a server session, then the connection has already been setup,
02438     * simply create the threadinfo object so we can access this thread for writing.
02439     * 
02440     * if this is a client connection more work must be done.
02441     * 1. We own the parent session args for a client connection.  This pointer needs
02442     *    to be held on to so we can decrement it's ref count on thread destruction.
02443     * 2. The threadinfo object was created before this thread was launched, however
02444     *    it must be found within the threadt table.
02445     * 3. Last, the tcptls_session must be started.
02446     */
02447    if (!tcptls_session->client) {
02448       if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) {
02449          goto cleanup;
02450       }
02451       ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread");
02452    } else {
02453       struct sip_threadinfo tmp = {
02454          .tcptls_session = tcptls_session,
02455       };
02456 
02457       if ((!(ca = tcptls_session->parent)) ||
02458          (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) ||
02459          (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) {
02460          goto cleanup;
02461       }
02462    }
02463 
02464    me->threadid = pthread_self();
02465    ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
02466 
02467    /* set up pollfd to watch for reads on both the socket and the alert_pipe */
02468    fds[0].fd = tcptls_session->fd;
02469    fds[1].fd = me->alert_pipe[0];
02470    fds[0].events = fds[1].events = POLLIN | POLLPRI;
02471 
02472    if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
02473       goto cleanup;
02474    }
02475    if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) {
02476       goto cleanup;
02477    }
02478 
02479    for (;;) {
02480       struct ast_str *str_save;
02481 
02482       res = ast_poll(fds, 2, -1); /* polls for both socket and alert_pipe */
02483       if (res < 0) {
02484          ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
02485          goto cleanup;
02486       }
02487 
02488       /* handle the socket event, check for both reads from the socket fd,
02489        * and writes from alert_pipe fd */
02490       if (fds[0].revents) { /* there is data on the socket to be read */
02491 
02492          fds[0].revents = 0;
02493 
02494          /* clear request structure */
02495          str_save = req.data;
02496          memset(&req, 0, sizeof(req));
02497          req.data = str_save;
02498          ast_str_reset(req.data);
02499 
02500          str_save = reqcpy.data;
02501          memset(&reqcpy, 0, sizeof(reqcpy));
02502          reqcpy.data = str_save;
02503          ast_str_reset(reqcpy.data);
02504 
02505          memset(buf, 0, sizeof(buf));
02506 
02507          if (tcptls_session->ssl) {
02508             set_socket_transport(&req.socket, SIP_TRANSPORT_TLS);
02509             req.socket.port = htons(ourport_tls);
02510          } else {
02511             set_socket_transport(&req.socket, SIP_TRANSPORT_TCP);
02512             req.socket.port = htons(ourport_tcp);
02513          }
02514          req.socket.fd = tcptls_session->fd;
02515 
02516          /* Read in headers one line at a time */
02517          while (req.len < 4 || strncmp(REQ_OFFSET_TO_STR(&req, len - 4), "\r\n\r\n", 4)) {
02518             ast_mutex_lock(&tcptls_session->lock);
02519             if (!fgets(buf, sizeof(buf), tcptls_session->f)) {
02520                ast_mutex_unlock(&tcptls_session->lock);
02521                goto cleanup;
02522             }
02523             ast_mutex_unlock(&tcptls_session->lock);
02524             if (me->stop) {
02525                 goto cleanup;
02526             }
02527             ast_str_append(&req.data, 0, "%s", buf);
02528             req.len = req.data->used;
02529          }
02530          copy_request(&reqcpy, &req);
02531          parse_request(&reqcpy);
02532          /* In order to know how much to read, we need the content-length header */
02533          if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
02534             while (cl > 0) {
02535                size_t bytes_read;
02536                ast_mutex_lock(&tcptls_session->lock);
02537                if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
02538                   ast_mutex_unlock(&tcptls_session->lock);
02539                   goto cleanup;
02540                }
02541                buf[bytes_read] = '\0';
02542                ast_mutex_unlock(&tcptls_session->lock);
02543                if (me->stop) {
02544                   goto cleanup;
02545                }
02546                cl -= strlen(buf);
02547                ast_str_append(&req.data, 0, "%s", buf);
02548                req.len = req.data->used;
02549             }
02550          }
02551          /*! \todo XXX If there's no Content-Length or if the content-length and what
02552                we receive is not the same - we should generate an error */
02553 
02554          req.socket.tcptls_session = tcptls_session;
02555          handle_request_do(&req, &tcptls_session->remote_address);
02556       }
02557 
02558       if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */
02559          enum sip_tcptls_alert alert;
02560          struct tcptls_packet *packet;
02561 
02562          fds[1].revents = 0;
02563 
02564          if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) {
02565             ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02566             continue;
02567          }
02568 
02569          switch (alert) {
02570          case TCPTLS_ALERT_STOP:
02571             goto cleanup;
02572          case TCPTLS_ALERT_DATA:
02573             ao2_lock(me);
02574             if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) {
02575                ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty");
02576             } else if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) {
02577                ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n");
02578             }
02579 
02580             if (packet) {
02581                ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed");
02582             }
02583             ao2_unlock(me);
02584             break;
02585          default:
02586             ast_log(LOG_ERROR, "Unknown tcptls thread alert '%d'\n", alert);
02587          }
02588       }
02589    }
02590 
02591    ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
02592 
02593 cleanup:
02594    if (me) {
02595       ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
02596       ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
02597    }
02598    deinit_req(&reqcpy);
02599    deinit_req(&req);
02600 
02601    /* if client, we own the parent session arguments and must decrement ref */
02602    if (ca) {
02603       ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments");
02604    }
02605 
02606    if (tcptls_session) {
02607       ast_mutex_lock(&tcptls_session->lock);
02608       if (tcptls_session->f) {
02609          fclose(tcptls_session->f);
02610          tcptls_session->f = NULL;
02611       }
02612       if (tcptls_session->fd != -1) {
02613          close(tcptls_session->fd);
02614          tcptls_session->fd = -1;
02615       }
02616       tcptls_session->parent = NULL;
02617       ast_mutex_unlock(&tcptls_session->lock);
02618 
02619       ao2_ref(tcptls_session, -1);
02620       tcptls_session = NULL;
02621    }
02622    return NULL;
02623 }

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

add a blank line if no body

Definition at line 3815 of file chan_sip.c.

References ast_str_append(), and ast_str_strlen().

Referenced by send_request(), and send_response().

03816 {
03817    if (!req->lines) {
03818       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
03819       ast_str_append(&req->data, 0, "\r\n");
03820       req->len = ast_str_strlen(req->data);
03821    }
03822 }

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

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

10820 {
10821    char uri[SIPBUFSIZE];
10822    struct ast_str *header = ast_str_alloca(SIPBUFSIZE);
10823    struct ast_cc_agent *agent = find_sip_cc_agent_by_original_callid(p);
10824    struct sip_cc_agent_pvt *agent_pvt;
10825 
10826    if (!agent) {
10827       /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an
10828        * agent? Oh well, we'll just warn and return without adding the header.
10829        */
10830       ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid);
10831       return;
10832    }
10833 
10834    agent_pvt = agent->private_data;
10835 
10836    if (!ast_strlen_zero(agent_pvt->subscribe_uri)) {
10837       ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri));
10838    } else {
10839       generate_uri(p, uri, sizeof(uri));
10840       ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri));
10841    }
10842    /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed
10843     * to be more accurate. This parameter has no bearing on the actual operation
10844     * of the feature; it's just there for informational purposes.
10845     */
10846    ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR");
10847    add_header(resp, "Call-Info", ast_str_buffer(header));
10848    ao2_ref(agent, -1);
10849 }

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

10132 {
10133    int rtp_code;
10134    struct ast_format_list fmt;
10135 
10136 
10137    if (debug)
10138       ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec));
10139    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1)
10140       return;
10141 
10142    if (p->rtp) {
10143       struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
10144       fmt = ast_codec_pref_getsize(pref, codec);
10145    } 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 */
10146       return;
10147    ast_str_append(m_buf, 0, " %d", rtp_code);
10148    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
10149              ast_rtp_lookup_mime_subtype2(1, codec,
10150                      ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
10151              ast_rtp_lookup_sample_rate2(1, codec));
10152 
10153    switch (codec) {
10154    case AST_FORMAT_G729A:
10155       /* Indicate that we don't support VAD (G.729 annex B) */
10156       ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
10157       break;
10158    case AST_FORMAT_G723_1:
10159       /* Indicate that we don't support VAD (G.723.1 annex A) */
10160       ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
10161       break;
10162    case AST_FORMAT_ILBC:
10163       /* Add information about us using only 20/30 ms packetization */
10164       ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
10165       break;
10166    case AST_FORMAT_SIREN7:
10167       /* Indicate that we only expect 32Kbps */
10168       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code);
10169       break;
10170    case AST_FORMAT_SIREN14:
10171       /* Indicate that we only expect 48Kbps */
10172       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code);
10173       break;
10174    case AST_FORMAT_G719:
10175       /* Indicate that we only expect 64Kbps */
10176       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code);
10177       break;
10178    }
10179 
10180    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
10181       *min_packet_size = fmt.cur_ms;
10182 
10183    /* Our first codec packetization processed cannot be zero */
10184    if ((*min_packet_size)==0 && fmt.cur_ms)
10185       *min_packet_size = fmt.cur_ms;
10186 }

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

Add content (not header) to SIP message.

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

09105 {
09106    if (req->lines) {
09107       ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n");
09108       return -1;
09109    }
09110 
09111    ast_str_append(&req->content, 0, "%s", line);
09112    return 0;
09113 }

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

References add_content(), and add_header().

Referenced by transmit_info_with_digit().

09994 {
09995    char tmp[256];
09996    int event;
09997    if (mode) {
09998       /* Application/dtmf short version used by some implementations */
09999       if (digit == '*')
10000          event = 10;
10001       else if (digit == '#')
10002          event = 11;
10003       else if ((digit >= 'A') && (digit <= 'D'))
10004          event = 12 + digit - 'A';
10005       else
10006          event = atoi(&digit);
10007       snprintf(tmp, sizeof(tmp), "%d\r\n", event);
10008       add_header(req, "Content-Type", "application/dtmf");
10009       add_content(req, tmp);
10010    } else {
10011       /* Application/dtmf-relay as documented by Cisco */
10012       snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
10013       add_header(req, "Content-Type", "application/dtmf-relay");
10014       add_content(req, tmp);
10015    }
10016    return 0;
10017 }

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

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

Referenced by transmit_invite(), and update_redirecting().

11202 {
11203    const char *diverting_number;
11204    const char *diverting_name;
11205    const char *reason;
11206    char header_text[256];
11207 
11208    if (!pvt->owner) {
11209       return;
11210    }
11211 
11212    diverting_number = pvt->owner->redirecting.from.number.str;
11213    if (!pvt->owner->redirecting.from.number.valid
11214       || ast_strlen_zero(diverting_number)) {
11215       return;
11216    }
11217 
11218    reason = sip_reason_code_to_str(pvt->owner->redirecting.reason);
11219 
11220    /* We at least have a number to place in the Diversion header, which is enough */
11221    diverting_name = pvt->owner->redirecting.from.name.str;
11222    if (!pvt->owner->redirecting.from.name.valid
11223       || ast_strlen_zero(diverting_name)) {
11224       snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number,
11225             ast_sockaddr_stringify_host(&pvt->ourip), reason);
11226    } else {
11227       snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s",
11228             diverting_name, diverting_number,
11229             ast_sockaddr_stringify_host(&pvt->ourip), reason);
11230    }
11231 
11232    add_header(req, "Diversion", header_text);
11233 }

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

Add header to SIP message.

Definition at line 9032 of file chan_sip.c.

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

09033 {
09034    if (req->headers == SIP_MAX_HEADERS) {
09035       ast_log(LOG_WARNING, "Out of SIP header space\n");
09036       return -1;
09037    }
09038 
09039    if (req->lines) {
09040       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
09041       return -1;
09042    }
09043 
09044    if (sip_cfg.compactheaders) {
09045       var = find_alias(var, var);
09046    }
09047 
09048    ast_str_append(&req->data, 0, "%s: %s\r\n", var, value);
09049    req->header[req->headers] = req->len;
09050 
09051    req->len = ast_str_strlen(req->data);
09052    req->headers++;
09053 
09054    return 0;   
09055 }

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

Add 'Max-Forwards' header to SIP message.

Definition at line 9058 of file chan_sip.c.

References add_header(), ast_channel_trylock, ast_channel_unlock, pbx_builtin_getvar_helper(), sip_pvt_lock, and sip_pvt_unlock.

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

09059 {
09060    char clen[10];
09061    const char *max = NULL;
09062 
09063    /* deadlock avoidance */
09064    while (dialog->owner && ast_channel_trylock(dialog->owner)) {
09065       sip_pvt_unlock(dialog);
09066       usleep(1);
09067       sip_pvt_lock(dialog);
09068    }
09069 
09070    if (dialog->owner) {
09071       max = pbx_builtin_getvar_helper(dialog->owner, "SIP_MAX_FORWARDS");
09072       ast_channel_unlock(dialog->owner);
09073    }
09074 
09075    /* The channel variable overrides the peer/channel value */
09076    if (max == NULL) {
09077       snprintf(clen, sizeof(clen), "%d", dialog->maxforwards);
09078    }
09079    return add_header(req, "Max-Forwards", max != NULL ? max : clen);
09080 }

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

10270 {
10271    int rtp_code;
10272 
10273    if (debug)
10274       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, format, 0));
10275    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1)
10276       return;
10277 
10278    ast_str_append(m_buf, 0, " %d", rtp_code);
10279    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
10280              ast_rtp_lookup_mime_subtype2(0, format, 0),
10281              ast_rtp_lookup_sample_rate2(0, format));
10282    if (format == AST_RTP_DTMF)   /* Indicate we support DTMF and FLASH... */
10283       ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
10284 }

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

Todo:
document this function

Definition at line 25536 of file chan_sip.c.

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

Referenced by build_peer().

25537 {
25538    char *next, *mbox, *context;
25539 
25540    next = ast_strdupa(value);
25541 
25542    while ((mbox = context = strsep(&next, ","))) {
25543       struct sip_mailbox *mailbox;
25544       int duplicate = 0;
25545 
25546       strsep(&context, "@");
25547 
25548       if (ast_strlen_zero(mbox)) {
25549          continue;
25550       }
25551 
25552       /* Check whether the mailbox is already in the list */
25553       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
25554          if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) {
25555             duplicate = 1;
25556             mailbox->delme = 0;
25557             break;
25558          }
25559       }
25560       if (duplicate) {
25561          continue;
25562       }
25563 
25564       if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) {
25565          continue;
25566       }
25567 
25568       if (!ast_strlen_zero(context)) {
25569          mailbox->context = mailbox->mailbox + strlen(mbox) + 1;
25570          strcpy(mailbox->context, context); /* SAFE */
25571       }
25572       strcpy(mailbox->mailbox, mbox); /* SAFE */
25573 
25574       AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
25575    }
25576 }

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

Definition at line 22883 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_LIST_TRAVERSE, mailbox, mwi_event_cb(), and S_OR.

Referenced by build_peer(), and handle_request_subscribe().

22884 {
22885    struct sip_mailbox *mailbox;
22886 
22887    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
22888       mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer,
22889          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
22890          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
22891          AST_EVENT_IE_END);
22892    }
22893 }

static struct sip_auth * add_realm_authentication ( struct sip_auth *  authlist,
const char *  configuration,
int  lineno 
) [static, read]

Add realm authentication in list.

Definition at line 25349 of file chan_sip.c.

References ast_calloc, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), ast_verb, LOG_WARNING, and secret.

Referenced by build_peer(), and reload_config().

25350 {
25351    char authcopy[256];
25352    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
25353    struct sip_auth *a, *b, *auth;
25354 
25355    if (ast_strlen_zero(configuration))
25356       return authlist;
25357 
25358    ast_debug(1, "Auth config ::  %s\n", configuration);
25359 
25360    ast_copy_string(authcopy, configuration, sizeof(authcopy));
25361    username = authcopy;
25362 
25363    /* split user[:secret] and relm */
25364    realm = strrchr(username, '@');
25365    if (realm)
25366       *realm++ = '\0';
25367    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
25368       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
25369       return authlist;
25370    }
25371 
25372    /* parse username at ':' for secret, or '#" for md5secret */
25373    if ((secret = strchr(username, ':'))) {
25374       *secret++ = '\0';
25375    } else if ((md5secret = strchr(username, '#'))) {
25376       *md5secret++ = '\0';
25377    }
25378 
25379    if (!(auth = ast_calloc(1, sizeof(*auth))))
25380       return authlist;
25381 
25382    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
25383    ast_copy_string(auth->username, username, sizeof(auth->username));
25384    if (secret)
25385       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
25386    if (md5secret)
25387       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
25388 
25389    /* find the end of the list */
25390    for (b = NULL, a = authlist; a ; b = a, a = a->next)
25391       ;
25392    if (b)
25393       b->next = auth;   /* Add structure add end of list */
25394    else
25395       authlist = auth;
25396 
25397    ast_verb(3, "Added authentication for realm %s\n", realm);
25398 
25399    return authlist;
25400 
25401 }

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

Add route header into request per learned route.

Definition at line 9215 of file chan_sip.c.

References add_header(), and ast_copy_string().

Referenced by initreqprep(), and reqprep().

09216 {
09217    char r[SIPBUFSIZE*2], *p;
09218    int n, rem = sizeof(r);
09219 
09220    if (!route)
09221       return;
09222 
09223    p = r;
09224    for (;route ; route = route->next) {
09225       n = strlen(route->hop);
09226       if (rem < n+3) /* we need room for ",<route>" */
09227          break;
09228       if (p != r) {  /* add a separator after fist route */
09229          *p++ = ',';
09230          --rem;
09231       }
09232       *p++ = '<';
09233       ast_copy_string(p, route->hop, rem); /* cannot fail */
09234       p += n;
09235       *p++ = '>';
09236       rem -= (n+2);
09237    }
09238    *p = '\0';
09239    add_header(req, "Route", r);
09240 }

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

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

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

10024 {
10025    struct ast_str *tmp = ast_str_alloca(256);
10026    char tmp2[256];
10027    char *lid_num = NULL;
10028    char *lid_name = NULL;
10029    int lid_pres;
10030    const char *fromdomain;
10031    const char *privacy = NULL;
10032    const char *screen = NULL;
10033    const char *anonymous_string = "\"Anonymous\" <anonymous@anonymous.invalid>";
10034 
10035    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
10036       return 0;
10037    }
10038 
10039    if (p->owner && p->owner->connected.id.number.valid
10040       && p->owner->connected.id.number.str) {
10041       lid_num = p->owner->connected.id.number.str;
10042    }
10043    if (p->owner && p->owner->connected.id.name.valid
10044       && p->owner->connected.id.name.str) {
10045       lid_name = p->owner->connected.id.name.str;
10046    }
10047    lid_pres = (p->owner) ? ast_party_id_presentation(&p->owner->connected.id) : AST_PRES_NUMBER_NOT_AVAILABLE;
10048 
10049    if (ast_strlen_zero(lid_num))
10050       return 0;
10051    if (ast_strlen_zero(lid_name))
10052       lid_name = lid_num;
10053    fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
10054 
10055    lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 1);
10056 
10057    if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) {
10058       if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
10059          ast_str_set(&tmp, -1, "%s", anonymous_string);
10060       } else {
10061          ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name, lid_num, fromdomain);
10062       }
10063       add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp));
10064    } else {
10065       ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name, lid_num, fromdomain, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "calling" : "called");
10066 
10067       switch (lid_pres) {
10068       case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
10069       case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
10070          privacy = "off";
10071          screen = "no";
10072          break;
10073       case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
10074       case AST_PRES_ALLOWED_NETWORK_NUMBER:
10075          privacy = "off";
10076          screen = "yes";
10077          break;
10078       case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
10079       case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
10080          privacy = "full";
10081          screen = "no";
10082          break;
10083       case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
10084       case AST_PRES_PROHIB_NETWORK_NUMBER:
10085          privacy = "full";
10086          screen = "yes";
10087          break;
10088       case AST_PRES_NUMBER_NOT_AVAILABLE:
10089          break;
10090       default:
10091          if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
10092             privacy = "full";
10093          }
10094          else
10095             privacy = "off";
10096          screen = "no";
10097          break;
10098       }
10099 
10100       if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) {
10101          ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen);
10102       }
10103 
10104       add_header(req, "Remote-Party-ID", ast_str_buffer(tmp));
10105    }
10106    return 0;
10107 }

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 10405 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_internal_timing_enabled(), ast_log(), ast_random(), AST_RTP_MAX, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_append(), ast_strlen_zero(), AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose, capability, debug, 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.

10406 {
10407    format_t alreadysent = 0;
10408 
10409    struct ast_sockaddr addr = { {0,} };
10410    struct ast_sockaddr vaddr = { {0,} };
10411    struct ast_sockaddr taddr = { {0,} };
10412    struct ast_sockaddr udptladdr = { {0,} };
10413    struct ast_sockaddr dest = { {0,} };
10414    struct ast_sockaddr vdest = { {0,} };
10415    struct ast_sockaddr tdest = { {0,} };
10416    struct ast_sockaddr udptldest = { {0,} };
10417 
10418    /* SDP fields */
10419    char *version =   "v=0\r\n";     /* Protocol version */
10420    char subject[256];            /* Subject of the session */
10421    char owner[256];           /* Session owner/creator */
10422    char connection[256];            /* Connection data */
10423    char *session_time = "t=0 0\r\n";         /* Time the session is active */
10424    char bandwidth[256] = "";        /* Max bitrate */
10425    char *hold = "";
10426    struct ast_str *m_audio = ast_str_alloca(256);  /* Media declaration line for audio */
10427    struct ast_str *m_video = ast_str_alloca(256);  /* Media declaration line for video */
10428    struct ast_str *m_text = ast_str_alloca(256);   /* Media declaration line for text */
10429    struct ast_str *m_modem = ast_str_alloca(256);  /* Media declaration line for modem */
10430    struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */
10431    struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */
10432    struct ast_str *a_text = ast_str_alloca(1024);  /* Attributes for text */
10433    struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */
10434    const char *a_crypto = NULL;
10435    const char *v_a_crypto = NULL;
10436    const char *t_a_crypto = NULL;
10437 
10438    format_t x;
10439    format_t capability = 0;
10440    int needaudio = FALSE;
10441    int needvideo = FALSE;
10442    int needtext = FALSE;
10443    int debug = sip_debug_test_pvt(p);
10444    int min_audio_packet_size = 0;
10445    int min_video_packet_size = 0;
10446    int min_text_packet_size = 0;
10447 
10448    char codecbuf[SIPBUFSIZE];
10449    char buf[SIPBUFSIZE];
10450    char dummy_answer[256];
10451 
10452    /* Set the SDP session name */
10453    snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
10454 
10455    if (!p->rtp) {
10456       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
10457       return AST_FAILURE;
10458    }
10459    /* XXX We should not change properties in the SIP dialog until
10460       we have acceptance of the offer if this is a re-invite */
10461 
10462    /* Set RTP Session ID and version */
10463    if (!p->sessionid) {
10464       p->sessionid = (int)ast_random();
10465       p->sessionversion = p->sessionid;
10466    } else {
10467       if (oldsdp == FALSE)
10468          p->sessionversion++;
10469    }
10470 
10471    if (add_audio) {
10472       /* Check if we need video in this call */
10473       if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) {
10474          if (p->vrtp) {
10475             needvideo = TRUE;
10476             ast_debug(2, "This call needs video offers!\n");
10477          } else
10478             ast_debug(2, "This call needs video offers, but there's no video support enabled!\n");
10479       }
10480       /* Check if we need text in this call */
10481       if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) {
10482          if (sipdebug_text)
10483             ast_verbose("We think we can do text\n");
10484          if (p->trtp) {
10485             if (sipdebug_text) {
10486                ast_verbose("And we have a text rtp object\n");
10487             }
10488             needtext = TRUE;
10489             ast_debug(2, "This call needs text offers! \n");
10490          } else {
10491             ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n");
10492          }
10493       }
10494    }
10495 
10496    get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest);
10497 
10498    snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n",
10499        ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner,
10500        p->sessionid, p->sessionversion,
10501        (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
10502          "IP6" : "IP4",
10503        ast_sockaddr_stringify_addr(&dest));
10504 
10505    snprintf(connection, sizeof(connection), "c=IN %s %s\r\n",
10506        (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
10507          "IP6" : "IP4",
10508        ast_sockaddr_stringify_addr(&dest));
10509 
10510    if (add_audio) {
10511       capability = p->jointcapability;
10512 
10513       /* XXX note, Video and Text are negated - 'true' means 'no' */
10514       ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability),
10515            p->novideo ? "True" : "False", p->notext ? "True" : "False");
10516       ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
10517 
10518       /* Check if we need audio */
10519       if (capability & AST_FORMAT_AUDIO_MASK)
10520          needaudio = TRUE;
10521 
10522       if (debug) {
10523          ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&p->ourip));
10524       }
10525 
10526       /* Ok, we need video. Let's add what we need for video and set codecs.
10527          Video is handled differently than audio since we can not transcode. */
10528       if (needvideo) {
10529          get_crypto_attrib(p->vsrtp, &v_a_crypto);
10530          ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest),
10531             v_a_crypto ? "SAVP" : "AVP");
10532 
10533          /* Build max bitrate string */
10534          if (p->maxcallbitrate)
10535             snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
10536          if (debug) {
10537             ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&p->ourip));
10538          }
10539       }
10540 
10541       /* Ok, we need text. Let's add what we need for text and set codecs.
10542          Text is handled differently than audio since we can not transcode. */
10543       if (needtext) {
10544          if (sipdebug_text)
10545             ast_verbose("Lets set up the text sdp\n");
10546          get_crypto_attrib(p->tsrtp, &t_a_crypto);
10547          ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest),
10548             t_a_crypto ? "SAVP" : "AVP");
10549          if (debug) {  /* XXX should I use tdest below ? */
10550             ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&p->ourip));
10551          }
10552       }
10553 
10554       /* Start building generic SDP headers */
10555 
10556       /* We break with the "recommendation" and send our IP, in order that our
10557          peer doesn't have to ast_gethostbyname() us */
10558 
10559       get_crypto_attrib(p->srtp, &a_crypto);
10560       ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest),
10561          a_crypto ? "SAVP" : "AVP");
10562 
10563       if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
10564          hold = "a=recvonly\r\n";
10565       else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
10566          hold = "a=inactive\r\n";
10567       else
10568          hold = "a=sendrecv\r\n";
10569 
10570       /* Now, start adding audio codecs. These are added in this order:
10571          - First what was requested by the calling channel
10572          - Then preferences in order from sip.conf device config for this peer/user
10573          - Then other codecs in capabilities, including video
10574       */
10575 
10576       /* Prefer the audio codec we were requested to use, first, no matter what
10577          Note that p->prefcodec can include video codecs, so mask them out
10578       */
10579       if (capability & p->prefcodec) {
10580          format_t codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
10581 
10582          add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size);
10583          alreadysent |= codec;
10584       }
10585 
10586       /* Start by sending our preferred audio/video codecs */
10587       for (x = 0; x < 64; x++) {
10588          format_t codec;
10589 
10590          if (!(codec = ast_codec_pref_index(&p->prefs, x)))
10591             break;
10592 
10593          if (!(capability & codec))
10594             continue;
10595 
10596          if (alreadysent & codec)
10597             continue;
10598 
10599          add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size);
10600          alreadysent |= codec;
10601       }
10602 
10603       /* Now send any other common audio and video codecs, and non-codec formats: */
10604       for (x = 1ULL; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) {
10605          if (!(capability & x))  /* Codec not requested */
10606             continue;
10607 
10608          if (alreadysent & x) /* Already added to SDP */
10609             continue;
10610 
10611          if (x & AST_FORMAT_AUDIO_MASK)
10612             add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size);
10613          else if (x & AST_FORMAT_VIDEO_MASK)
10614             add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size);
10615          else if (x & AST_FORMAT_TEXT_MASK)
10616             add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size);
10617       }
10618 
10619       /* Now add DTMF RFC2833 telephony-event as a codec */
10620       for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
10621          if (!(p->jointnoncodeccapability & x))
10622             continue;
10623 
10624          add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug);
10625       }
10626 
10627       ast_debug(3, "-- Done with adding codecs to SDP\n");
10628 
10629       if (!p->owner || !ast_internal_timing_enabled(p->owner))
10630          ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n");
10631 
10632       if (min_audio_packet_size)
10633          ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size);
10634 
10635       /* XXX don't think you can have ptime for video */
10636       if (min_video_packet_size)
10637          ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size);
10638 
10639       /* XXX don't think you can have ptime for text */
10640       if (min_text_packet_size)
10641          ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size);
10642 
10643       if (m_audio->len - m_audio->used < 2 || m_video->len - m_video->used < 2 ||
10644           m_text->len - m_text->used < 2 || a_text->len - a_text->used < 2 ||
10645           a_audio->len - a_audio->used < 2 || a_video->len - a_video->used < 2)
10646          ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
10647    }
10648 
10649    if (add_t38) {
10650       /* Our T.38 end is */
10651       ast_udptl_get_us(p->udptl, &udptladdr);
10652 
10653       /* Determine T.38 UDPTL destination */
10654       if (!ast_sockaddr_isnull(&p->udptlredirip)) {
10655          ast_sockaddr_copy(&udptldest, &p->udptlredirip);
10656       } else {
10657          ast_sockaddr_copy(&udptldest, &p->ourip);
10658          ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr));
10659       }
10660 
10661       if (debug) {
10662          ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr));
10663       }
10664 
10665       /* We break with the "recommendation" and send our IP, in order that our
10666          peer doesn't have to ast_gethostbyname() us */
10667 
10668       ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest));
10669 
10670       if (!ast_sockaddr_cmp(&udptldest, &dest)) {
10671          ast_str_append(&m_modem, 0, "c=IN %s %s\r\n",
10672                (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
10673                "IP6" : "IP4", ast_sockaddr_stringify_addr(&udptldest));
10674       }
10675 
10676       ast_str_append(&a_modem, 0, "a=T38FaxVersion:%d\r\n", p->t38.our_parms.version);
10677       ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", t38_get_rate(p->t38.our_parms.rate));
10678       if (p->t38.our_parms.fill_bit_removal) {
10679          ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n");
10680       }
10681       if (p->t38.our_parms.transcoding_mmr) {
10682          ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n");
10683       }
10684       if (p->t38.our_parms.transcoding_jbig) {
10685          ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n");
10686       }
10687       switch (p->t38.our_parms.rate_management) {
10688       case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF:
10689          ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n");
10690          break;
10691       case AST_T38_RATE_MANAGEMENT_LOCAL_TCF:
10692          ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n");
10693          break;
10694       }
10695       ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl));
10696       switch (ast_udptl_get_error_correction_scheme(p->udptl)) {
10697       case UDPTL_ERROR_CORRECTION_NONE:
10698          break;
10699       case UDPTL_ERROR_CORRECTION_FEC:
10700          ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n");
10701          break;
10702       case UDPTL_ERROR_CORRECTION_REDUNDANCY:
10703          ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n");
10704          break;
10705       }
10706    }
10707 
10708    if (needaudio)
10709       ast_str_append(&m_audio, 0, "\r\n");
10710    if (needvideo)
10711       ast_str_append(&m_video, 0, "\r\n");
10712    if (needtext)
10713       ast_str_append(&m_text, 0, "\r\n");
10714 
10715    add_header(resp, "Content-Type", "application/sdp");
10716    add_content(resp, version);
10717    add_content(resp, owner);
10718    add_content(resp, subject);
10719    add_content(resp, connection);
10720    if (needvideo)    /* only if video response is appropriate */
10721       add_content(resp, bandwidth);
10722    add_content(resp, session_time);
10723    if (needaudio) {
10724       add_content(resp, m_audio->str);
10725       add_content(resp, a_audio->str);
10726       add_content(resp, hold);
10727       if (a_crypto) {
10728          add_content(resp, a_crypto);
10729       }
10730    } else if (p->offered_media[SDP_AUDIO].offered) {
10731       snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs);
10732       add_content(resp, dummy_answer);
10733    }
10734    if (needvideo) { /* only if video response is appropriate */
10735       add_content(resp, m_video->str);
10736       add_content(resp, a_video->str);
10737       add_content(resp, hold);   /* Repeat hold for the video stream */
10738       if (v_a_crypto) {
10739          add_content(resp, v_a_crypto);
10740       }
10741    } else if (p->offered_media[SDP_VIDEO].offered) {
10742       snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs);
10743       add_content(resp, dummy_answer);
10744    }
10745    if (needtext) { /* only if text response is appropriate */
10746       add_content(resp, m_text->str);
10747       add_content(resp, a_text->str);
10748       add_content(resp, hold);   /* Repeat hold for the text stream */
10749       if (t_a_crypto) {
10750          add_content(resp, t_a_crypto);
10751       }
10752    } else if (p->offered_media[SDP_TEXT].offered) {
10753       snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs);
10754       add_content(resp, dummy_answer);
10755    }
10756    if (add_t38) {
10757       add_content(resp, m_modem->str);
10758       add_content(resp, a_modem->str);
10759    } else if (p->offered_media[SDP_IMAGE].offered) {
10760       add_content(resp, "m=image 0 udptl t38\r\n");
10761    }
10762 
10763    /* Update lastrtprx when we send our SDP */
10764    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
10765 
10766    ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
10767 
10768    return AST_SUCCESS;
10769 }

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

25286 {
25287    struct domain *d;
25288 
25289    if (ast_strlen_zero(domain)) {
25290       ast_log(LOG_WARNING, "Zero length domain.\n");
25291       return 1;
25292    }
25293 
25294    if (!(d = ast_calloc(1, sizeof(*d))))
25295       return 0;
25296 
25297    ast_copy_string(d->domain, domain, sizeof(d->domain));
25298 
25299    if (!ast_strlen_zero(context))
25300       ast_copy_string(d->context, context, sizeof(d->context));
25301 
25302    d->mode = mode;
25303 
25304    AST_LIST_LOCK(&domain_list);
25305    AST_LIST_INSERT_TAIL(&domain_list, d, list);
25306    AST_LIST_UNLOCK(&domain_list);
25307 
25308    if (sipdebug)  
25309       ast_debug(1, "Added local SIP domain '%s'\n", domain);
25310 
25311    return 1;
25312 }

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

09021 {
09022    int res;
09023    if (st_get_mode(pvt) != SESSION_TIMER_MODE_REFUSE) {
09024       res = add_header(req, "Supported", "replaces, timer");
09025    } else {
09026       res = add_header(req, "Supported", "replaces");
09027    }
09028    return res;
09029 }

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

10216 {
10217    int rtp_code;
10218 
10219    if (!p->trtp)
10220       return;
10221 
10222    if (debug)
10223       ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
10224 
10225    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1)
10226       return;
10227 
10228    ast_str_append(m_buf, 0, " %d", rtp_code);
10229    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
10230              ast_rtp_lookup_mime_subtype2(1, codec, 0),
10231              ast_rtp_lookup_sample_rate2(1, codec));
10232    /* Add fmtp code here */
10233 
10234    if (codec == AST_FORMAT_T140RED) {
10235       int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140);
10236       ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
10237           t140code,
10238           t140code,
10239           t140code);
10240 
10241    }
10242 }

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

Add text body to SIP message.

Definition at line 9981 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_message_with_text().

09982 {
09983    /* XXX Convert \n's to \r\n's XXX */
09984    add_header(req, "Content-Type", "text/plain;charset=UTF-8");
09985    add_content(req, text);
09986    return 0;
09987 }

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

implement the setvar config line

Definition at line 25434 of file chan_sip.c.

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

25435 {
25436    struct ast_variable *tmpvar = NULL;
25437    char *varname = ast_strdupa(buf), *varval = NULL;
25438    
25439    if ((varval = strchr(varname, '='))) {
25440       *varval++ = '\0';
25441       if ((tmpvar = ast_variable_new(varname, varval, ""))) {
25442          tmpvar->next = list;
25443          list = tmpvar;
25444       }
25445    }
25446    return list;
25447 }

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

10193 {
10194    int rtp_code;
10195 
10196    if (!p->vrtp)
10197       return;
10198 
10199    if (debug)
10200       ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec));
10201 
10202    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1)
10203       return;
10204 
10205    ast_str_append(m_buf, 0, " %d", rtp_code);
10206    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
10207              ast_rtp_lookup_mime_subtype2(1, codec, 0),
10208              ast_rtp_lookup_sample_rate2(1, codec));
10209    /* Add fmtp code here */
10210 }

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

References add_content(), and add_header().

Referenced by transmit_info_with_vidupdate().

10112 {
10113    const char *xml_is_a_huge_waste_of_space =
10114       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
10115       " <media_control>\r\n"
10116       "  <vc_primitive>\r\n"
10117       "   <to_encoder>\r\n"
10118       "    <picture_fast_update>\r\n"
10119       "    </picture_fast_update>\r\n"
10120       "   </to_encoder>\r\n"
10121       "  </vc_primitive>\r\n"
10122       " </media_control>\r\n";
10123    add_header(req, "Content-Type", "application/media_control+xml");
10124    add_content(req, xml_is_a_huge_waste_of_space);
10125    return 0;
10126 }

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

Append date to SIP message.

Definition at line 9819 of file chan_sip.c.

References add_header().

09820 {
09821    char tmpdat[256];
09822    struct tm tm;
09823    time_t t = time(NULL);
09824 
09825    gmtime_r(&t, &tm);
09826    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
09827    add_header(req, "Date", tmpdat);
09828 }

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

Append to SIP dialog history with arg list.

Definition at line 3272 of file chan_sip.c.

References append_history_va().

03273 {
03274    va_list ap;
03275 
03276    if (!p) {
03277       return;
03278    }
03279 
03280    if (!p->do_history && !recordhistory && !dumphistory) {
03281       return;
03282    }
03283 
03284    va_start(ap, fmt);
03285    append_history_va(p, fmt, ap);
03286    va_end(ap);
03287 
03288    return;
03289 }

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

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

Referenced by append_history_full().

03245 {
03246    char buf[80], *c = buf; /* max history length */
03247    struct sip_history *hist;
03248    int l;
03249 
03250    vsnprintf(buf, sizeof(buf), fmt, ap);
03251    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
03252    l = strlen(buf) + 1;
03253    if (!(hist = ast_calloc(1, sizeof(*hist) + l))) {
03254       return;
03255    }
03256    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
03257       ast_free(hist);
03258       return;
03259    }
03260    memcpy(hist->event, buf, l);
03261    if (p->history_entries == MAX_HISTORY_ENTRIES) {
03262       struct sip_history *oldest;
03263       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
03264       p->history_entries--;
03265       ast_free(oldest);
03266    }
03267    AST_LIST_INSERT_TAIL(p->history, hist, list);
03268    p->history_entries++;
03269 }

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

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

27294 {
27295    struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
27296    int res = AST_SENSE_ALLOW;
27297 
27298    ast_rtp_instance_get_remote_address(p->rtp, &them);
27299    ast_rtp_instance_get_local_address(p->rtp, &us);
27300 
27301    if ((res = ast_apply_ha(p->directmediaha, &them)) == AST_SENSE_DENY) {
27302       ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
27303          op, ast_strdupa(ast_sockaddr_stringify(&them)), ast_strdupa(ast_sockaddr_stringify(&us)));
27304    }
27305 
27306    return res;
27307 }

AST_DATA_STRUCTURE ( sip_peer  ,
DATA_EXPORT_SIP_PEER   
)

static void ast_quiet_chan ( struct ast_channel chan  )  [static]

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

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

20167 {
20168    if (chan && chan->_state == AST_STATE_UP) {
20169       if (ast_test_flag(chan, AST_FLAG_MOH))
20170          ast_moh_stop(chan);
20171       else if (chan->generatordata)
20172          ast_deactivate_generator(chan);
20173    }
20174 }

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 3138 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_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and transmit_response_using_temp().

03139 {
03140    struct ast_sockaddr theirs;
03141 
03142    /* Set want_remap to non-zero if we want to remap 'us' to an externally
03143     * reachable IP address and port. This is done if:
03144     * 1. we have a localaddr list (containing 'internal' addresses marked
03145     *    as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them,
03146     *    and AST_SENSE_ALLOW on 'external' ones);
03147     * 2. externaddr is set, so we know what to use as the
03148     *    externally visible address;
03149     * 3. the remote address, 'them', is external;
03150     * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY
03151     *    when passed to ast_apply_ha() so it does need to be remapped.
03152     *    This fourth condition is checked later.
03153     */
03154    int want_remap = 0;
03155 
03156    ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */
03157    /* now ask the system what would it use to talk to 'them' */
03158    ast_ouraddrfor(them, us);
03159    ast_sockaddr_copy(&theirs, them);
03160 
03161    if (ast_sockaddr_is_ipv6(&theirs)) {
03162       if (localaddr && !ast_sockaddr_isnull(&externaddr)) {
03163          ast_log(LOG_WARNING, "Address remapping activated in sip.conf "
03164             "but we're using IPv6, which doesn't need it. Please "
03165             "remove \"localnet\" and/or \"externaddr\" settings.\n");
03166       }
03167    } else {
03168       want_remap = localaddr &&
03169          !ast_sockaddr_isnull(&externaddr) &&
03170          ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
03171    }
03172 
03173    if (want_remap &&
03174        (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) {
03175       /* if we used externhost, see if it is time to refresh the info */
03176       if (externexpire && time(NULL) >= externexpire) {
03177          if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
03178             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
03179          }
03180          externexpire = time(NULL) + externrefresh;
03181       }
03182       if (!ast_sockaddr_isnull(&externaddr)) {
03183          ast_sockaddr_copy(us, &externaddr);
03184          switch (p->socket.type) {
03185          case SIP_TRANSPORT_TCP:
03186             if (!externtcpport && ast_sockaddr_port(&externaddr)) {
03187                /* for consistency, default to the externaddr port */
03188                externtcpport = ast_sockaddr_port(&externaddr);
03189             }
03190             ast_sockaddr_set_port(us, externtcpport);
03191             break;
03192          case SIP_TRANSPORT_TLS:
03193             ast_sockaddr_set_port(us, externtlsport);
03194             break;
03195          case SIP_TRANSPORT_UDP:
03196             if (!ast_sockaddr_port(&externaddr)) {
03197                ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
03198             }
03199             break;
03200          default:
03201             break;
03202          }
03203       }
03204       ast_debug(1, "Target address %s is not local, substituting externaddr\n",
03205            ast_sockaddr_stringify(them));
03206    } else if (p) {
03207       /* no remapping, but we bind to a specific address, so use it. */
03208       switch (p->socket.type) {
03209       case SIP_TRANSPORT_TCP:
03210          if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) {
03211             ast_sockaddr_copy(us,
03212                     &sip_tcp_desc.local_address);
03213          } else {
03214             ast_sockaddr_set_port(us,
03215                         ast_sockaddr_port(&sip_tcp_desc.local_address));
03216          }
03217          break;
03218       case SIP_TRANSPORT_TLS:
03219          if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) {
03220             ast_sockaddr_copy(us,
03221                     &sip_tls_desc.local_address);
03222          } else {
03223             ast_sockaddr_set_port(us,
03224                         ast_sockaddr_port(&sip_tls_desc.local_address));
03225          }
03226          break;
03227       case SIP_TRANSPORT_UDP:
03228          /* fall through on purpose */
03229       default:
03230          if (!ast_sockaddr_is_any(&bindaddr)) {
03231             ast_sockaddr_copy(us, &bindaddr);
03232          }
03233          if (!ast_sockaddr_port(us)) {
03234             ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
03235          }
03236       }
03237    } else if (!ast_sockaddr_is_any(&bindaddr)) {
03238       ast_sockaddr_copy(us, &bindaddr);
03239    }
03240    ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us));
03241 }

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

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

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

27957 {
27958    return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(&bindaddr));
27959 }

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

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

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

27933 {
27934    struct ast_sockaddr *addrs;
27935    int addrs_cnt;
27936 
27937    addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
27938    if (addrs_cnt <= 0) {
27939       return 1;
27940    }
27941    if (addrs_cnt > 1) {
27942       ast_debug(1, "Multiple addresses, using the first one only\n");
27943    }
27944 
27945    ast_sockaddr_copy(addr, &addrs[0]);
27946 
27947    ast_free(addrs);
27948    return 0;
27949 }

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

20179 {
20180    int res = 0;
20181    struct ast_channel *peera = NULL,   
20182       *peerb = NULL,
20183       *peerc = NULL,
20184       *peerd = NULL;
20185 
20186 
20187    /* We will try to connect the transferee with the target and hangup
20188       all channels to the transferer */   
20189    ast_debug(4, "Sip transfer:--------------------\n");
20190    if (transferer->chan1)
20191       ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
20192    else
20193       ast_debug(4, "-- No transferer first channel - odd??? \n");
20194    if (target->chan1)
20195       ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
20196    else
20197       ast_debug(4, "-- No target first channel ---\n");
20198    if (transferer->chan2)
20199       ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
20200    else
20201       ast_debug(4, "-- No bridged call to transferee\n");
20202    if (target->chan2)
20203       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)");
20204    else
20205       ast_debug(4, "-- No target second channel ---\n");
20206    ast_debug(4, "-- END Sip transfer:--------------------\n");
20207    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
20208       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
20209       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
20210       peerc = transferer->chan2; /* Asterisk to Transferee */
20211       peerd = target->chan2;     /* Asterisk to Target */
20212       ast_debug(3, "SIP transfer: Four channels to handle\n");
20213    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
20214       peera = target->chan1;     /* Transferer to PBX -> target channel */
20215       peerb = transferer->chan1; /* Transferer to IVR*/
20216       peerc = target->chan2;     /* Asterisk to Target */
20217       peerd = transferer->chan2; /* Nothing */
20218       ast_debug(3, "SIP transfer: Three channels to handle\n");
20219    }
20220 
20221    if (peera && peerb && peerc && (peerb != peerc)) {
20222       ast_quiet_chan(peera);     /* Stop generators */
20223       ast_quiet_chan(peerb);  
20224       ast_quiet_chan(peerc);
20225       if (peerd)
20226          ast_quiet_chan(peerd);
20227 
20228       ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
20229       if (ast_channel_masquerade(peerb, peerc)) {
20230          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
20231          res = -1;
20232       } else
20233          ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n");
20234       return res;
20235    } else {
20236       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
20237       if (transferer->chan1)
20238          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
20239       if (target->chan1)
20240          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
20241       return -1;
20242    }
20243    return 0;
20244 }

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

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

Definition at line 12612 of file chan_sip.c.

References ast_verbose.

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

12613 {
12614    if (code == WWW_AUTH) {       /* 401 */
12615       *header = "WWW-Authenticate";
12616       *respheader = "Authorization";
12617    } else if (code == PROXY_AUTH) { /* 407 */
12618       *header = "Proxy-Authenticate";
12619       *respheader = "Proxy-Authorization";
12620    } else {
12621       ast_verbose("-- wrong response code %d\n", code);
12622       *header = *respheader = "Invalid";
12623    }
12624 }

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

05050 {
05051    struct sip_pvt *p = (struct sip_pvt *)arg;
05052 
05053    sip_pvt_lock(p);
05054    p->initid = -1;   /* event gone, will not be rescheduled */
05055    if (p->owner) {
05056       /* XXX fails on possible deadlock */
05057       if (!ast_channel_trylock(p->owner)) {
05058          append_history(p, "Cong", "Auto-congesting (timer)");
05059          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
05060          ast_channel_unlock(p->owner);
05061       }
05062 
05063       /* Give the channel a chance to act before we proceed with destruction */
05064       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05065    }
05066    sip_pvt_unlock(p);
05067    dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)");
05068    return 0;
05069 }

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

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

Definition at line 6983 of file chan_sip.c.

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

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

06984 {
06985    char buf[33];
06986 
06987    const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify(&pvt->ourip));
06988    
06989    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
06990 
06991 }

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

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

Referenced by transmit_register().

06995 {
06996    char buf[33];
06997 
06998    const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host(ourip));
06999 
07000    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
07001 }

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

Build contact header - the contact header we send out.

Definition at line 11013 of file chan_sip.c.

References ast_sockaddr_stringify(), ast_string_field_build, ast_strlen_zero(), 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().

11014 {
11015    if (p->socket.type == SIP_TRANSPORT_UDP) {
11016       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten,
11017          ast_strlen_zero(p->exten) ? "" : "@", ast_sockaddr_stringify(&p->ourip));
11018    } else {
11019       ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", p->exten,
11020          ast_strlen_zero(p->exten) ? "" : "@", ast_sockaddr_stringify(&p->ourip),
11021          get_transport(p->socket.type));
11022    }
11023 }

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

References __set_address_from_contact(), accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), ao2_alloc, ao2_t_alloc, ao2_t_find, ao2_t_ref, asprintf, ast_append_ha(), ast_atomic_fetchadd_int(), ast_callerid_split(), AST_CC_AGENT_NATIVE, AST_CC_AGENT_NEVER, ast_cc_config_params_init, ast_cc_is_config_param(), ast_cc_set_param(), ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_debug, ast_dnsmgr_lookup(), 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_sockaddr_stringify_host(), 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(), bindaddr, cid_name, cid_num, clear_realm_authentication(), context, DEFAULT_MAXMS, destroy_association(), destroy_mailbox(), errno, FALSE, ast_flags::flags, format, get_address_family_filter(), get_srv_protocol(), get_srv_service(), handle_common_options(), handle_t38_options(), language, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, mark_parsed_methods(), MAXHOSTNAMELEN, mohinterpret, mohsuggest, ast_variable::name, ast_variable::next, OBJ_POINTER, OBJ_UNLINK, parkinglot, PARSE_PORT_FORBID, port_str2int(), proxy_update(), 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(), str2strefresher(), strsep(), TRUE, unref_peer(), and ast_variable::value.

25580 {
25581    struct sip_peer *peer = NULL;
25582    struct ast_ha *oldha = NULL;
25583    struct ast_ha *olddirectmediaha = NULL;
25584    int found = 0;
25585    int firstpass = 1;
25586    uint16_t port = 0;
25587    int format = 0;      /* Ama flags */
25588    int timerb_set = 0, timert1_set = 0;
25589    time_t regseconds = 0;
25590    struct ast_flags peerflags[3] = {{(0)}};
25591    struct ast_flags mask[3] = {{(0)}};
25592    char callback[256] = "";
25593    struct sip_peer tmp_peer;
25594    const char *srvlookup = NULL;
25595    static int deprecation_warning = 1;
25596    int alt_fullcontact = alt ? 1 : 0, headercount = 0;
25597    struct ast_str *fullcontact = ast_str_alloca(512);
25598 
25599    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
25600       /* Note we do NOT use find_peer here, to avoid realtime recursion */
25601       /* We also use a case-sensitive comparison (unlike find_peer) so
25602          that case changes made to the peer name will be properly handled
25603          during reload
25604       */
25605       ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name));
25606       peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table");
25607    }
25608 
25609    if (peer) {
25610       /* Already in the list, remove it and it will be added back (or FREE'd)  */
25611       found++;
25612       if (!(peer->the_mark))
25613          firstpass = 0;
25614    } else {
25615       if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
25616          return NULL;
25617 
25618       if (ast_string_field_init(peer, 512)) {
25619          ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
25620          return NULL;
25621       }
25622 
25623       if (!(peer->cc_params = ast_cc_config_params_init())) {
25624          ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
25625          return NULL;
25626       }
25627 
25628       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
25629          ast_atomic_fetchadd_int(&rpeerobjs, 1);
25630          ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs);
25631       } else
25632          ast_atomic_fetchadd_int(&speerobjs, 1);
25633    }
25634 
25635    /* Note that our peer HAS had its reference count increased */
25636    if (firstpass) {
25637       peer->lastmsgssent = -1;
25638       oldha = peer->ha;
25639       peer->ha = NULL;
25640       olddirectmediaha = peer->directmediaha;
25641       peer->directmediaha = NULL;
25642       set_peer_defaults(peer);   /* Set peer defaults */
25643       peer->type = 0;
25644    }
25645    if (!found && name)
25646       ast_copy_string(peer->name, name, sizeof(peer->name));
25647 
25648    /* If we have channel variables, remove them (reload) */
25649    if (peer->chanvars) {
25650       ast_variables_destroy(peer->chanvars);
25651       peer->chanvars = NULL;
25652       /* XXX should unregister ? */
25653    }
25654 
25655    if (found)
25656       peer->portinuri = 0;
25657 
25658    /* If we have realm authentication information, remove them (reload) */
25659    clear_realm_authentication(peer->auth);
25660    peer->auth = NULL;
25661    /* clear the transport information.  We will detect if a default value is required after parsing the config */
25662    peer->default_outbound_transport = 0;
25663    peer->transports = 0;
25664 
25665    if (!devstate_only) {
25666       struct sip_mailbox *mailbox;
25667       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
25668          mailbox->delme = 1;
25669       }
25670    }
25671 
25672    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
25673       if (!devstate_only) {
25674          if (handle_common_options(&peerflags[0], &mask[0], v)) {
25675             continue;
25676          }
25677          if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) {
25678             continue;
25679          }
25680          if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) {
25681             char *val = ast_strdupa(v->value);
25682             char *trans;
25683 
25684             while ((trans = strsep(&val, ","))) {
25685                trans = ast_skip_blanks(trans);
25686 
25687                if (!strncasecmp(trans, "udp", 3)) {
25688                   peer->transports |= SIP_TRANSPORT_UDP;
25689                } else if (!strncasecmp(trans, "tcp", 3)) {
25690                   peer->transports |= SIP_TRANSPORT_TCP;
25691                } else if (!strncasecmp(trans, "tls", 3)) {
25692                   peer->transports |= SIP_TRANSPORT_TLS;
25693                } else {
25694                   ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
25695                }
25696 
25697                if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */
25698                   peer->default_outbound_transport = peer->transports;
25699                }
25700             }
25701          } else if (realtime && !strcasecmp(v->name, "regseconds")) {
25702             ast_get_time_t(v->value, &regseconds, 0, NULL);
25703          } else if (realtime && !strcasecmp(v->name, "name")) {
25704             ast_copy_string(peer->name, v->value, sizeof(peer->name));
25705          } else if (realtime && !strcasecmp(v->name, "useragent")) {
25706             ast_string_field_set(peer, useragent, v->value);
25707          } else if (!strcasecmp(v->name, "type")) {
25708             if (!strcasecmp(v->value, "peer")) {
25709                peer->type |= SIP_TYPE_PEER;
25710             } else if (!strcasecmp(v->value, "user")) {
25711                peer->type |= SIP_TYPE_USER;
25712             } else if (!strcasecmp(v->value, "friend")) {
25713                peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
25714             }
25715          } else if (!strcasecmp(v->name, "remotesecret")) {
25716             ast_string_field_set(peer, remotesecret, v->value);
25717          } else if (!strcasecmp(v->name, "secret")) {
25718             ast_string_field_set(peer, secret, v->value);
25719          } else if (!strcasecmp(v->name, "md5secret")) {
25720             ast_string_field_set(peer, md5secret, v->value);
25721          } else if (!strcasecmp(v->name, "auth")) {
25722             peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
25723          } else if (!strcasecmp(v->name, "callerid")) {
25724             char cid_name[80] = { '\0' }, cid_num[80] = { '\0' };
25725 
25726             ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
25727             ast_string_field_set(peer, cid_name, cid_name);
25728             ast_string_field_set(peer, cid_num, cid_num);
25729          } else if (!strcasecmp(v->name, "mwi_from")) {
25730             ast_string_field_set(peer, mwi_from, v->value);
25731          } else if (!strcasecmp(v->name, "fullname")) {
25732             ast_string_field_set(peer, cid_name, v->value);
25733          } else if (!strcasecmp(v->name, "trunkname")) {
25734             /* This is actually for a trunk, so we don't want to override callerid */
25735             ast_string_field_set(peer, cid_name, "");
25736          } else if (!strcasecmp(v->name, "cid_number")) {
25737             ast_string_field_set(peer, cid_num, v->value);
25738          } else if (!strcasecmp(v->name, "cid_tag")) {
25739             ast_string_field_set(peer, cid_tag, v->value);
25740          } else if (!strcasecmp(v->name, "context")) {
25741             ast_string_field_set(peer, context, v->value);
25742             ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT);
25743          } else if (!strcasecmp(v->name, "subscribecontext")) {
25744             ast_string_field_set(peer, subscribecontext, v->value);
25745          } else if (!strcasecmp(v->name, "fromdomain")) {
25746             char *fromdomainport;
25747             ast_string_field_set(peer, fromdomain, v->value);
25748             if ((fromdomainport = strchr(peer->fromdomain, ':'))) {
25749                *fromdomainport++ = '\0';
25750                if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) {
25751                   ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
25752                }
25753             } else {
25754                peer->fromdomainport = STANDARD_SIP_PORT;
25755             }
25756          } else if (!strcasecmp(v->name, "usereqphone")) {
25757             ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
25758          } else if (!strcasecmp(v->name, "fromuser")) {
25759             ast_string_field_set(peer, fromuser, v->value);
25760          } else if (!strcasecmp(v->name, "outboundproxy")) {
25761             char *tok, *proxyname;
25762 
25763             if (ast_strlen_zero(v->value)) {
25764                ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno);
25765                continue;
25766             }
25767 
25768             peer->outboundproxy =
25769                 ao2_alloc(sizeof(*peer->outboundproxy), NULL);
25770 
25771             tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
25772 
25773             sip_parse_host(tok, v->lineno, &proxyname,
25774                       &peer->outboundproxy->port,
25775                       &peer->outboundproxy->transport);
25776 
25777             tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
25778 
25779             if ((tok = strtok(NULL, ","))) {
25780                peer->outboundproxy->force = !strncasecmp(ast_skip_blanks(tok), "force", 5);
25781             } else {
25782                peer->outboundproxy->force = FALSE;
25783             }
25784 
25785             if (ast_strlen_zero(proxyname)) {
25786                ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno);
25787                sip_cfg.outboundproxy.name[0] = '\0';
25788                continue;
25789             }
25790 
25791             ast_copy_string(peer->outboundproxy->name, proxyname, sizeof(peer->outboundproxy->name));
25792 
25793             proxy_update(peer->outboundproxy);
25794          } else if (!strcasecmp(v->name, "host")) {
25795             if (!strcasecmp(v->value, "dynamic")) {
25796                /* They'll register with us */
25797                if (!found || !peer->host_dynamic) {
25798                   /* Initialize stuff if this is a new peer, or if it used to
25799                    * not be dynamic before the reload. */
25800                   ast_sockaddr_setnull(&peer->addr);
25801                }
25802                peer->host_dynamic = TRUE;
25803             } else {
25804                /* Non-dynamic.  Make sure we become that way if we're not */
25805                AST_SCHED_DEL_UNREF(sched, peer->expire,
25806                      unref_peer(peer, "removing register expire ref"));
25807                peer->host_dynamic = FALSE;
25808                srvlookup = v->value;
25809             }
25810          } else if (!strcasecmp(v->name, "defaultip")) {
25811             if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) {
25812                unref_peer(peer, "unref_peer: from build_peer defaultip");
25813                return NULL;
25814             }
25815          } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
25816             int ha_error = 0;
25817             if (!ast_strlen_zero(v->value)) {
25818                peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
25819             }
25820             if (ha_error) {
25821                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
25822             }
25823          } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
25824             int ha_error = 0;
25825             if (!ast_strlen_zero(v->value)) {
25826                peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error);
25827             }
25828             if (ha_error) {
25829                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
25830             }
25831          } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) {
25832             int ha_error = 0;
25833             peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error);
25834             if (ha_error) {
25835                ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value);
25836             }
25837          } else if (!strcasecmp(v->name, "port")) {
25838             peer->portinuri = 1;
25839             if (!(port = port_str2int(v->value, 0))) {
25840                if (realtime) {
25841                   /* If stored as integer, could be 0 for some DBs (notably MySQL) */
25842                   peer->portinuri = 0;
25843                } else {
25844                   ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value);
25845                }
25846             }
25847          } else if (!strcasecmp(v->name, "callingpres")) {
25848             peer->callingpres = ast_parse_caller_presentation(v->value);
25849             if (peer->callingpres == -1) {
25850                peer->callingpres = atoi(v->value);
25851             }
25852          } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) {   /* "username" is deprecated */
25853             ast_string_field_set(peer, username, v->value);
25854             if (!strcasecmp(v->name, "username")) {
25855                if (deprecation_warning) {
25856                   ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n");
25857                   deprecation_warning = 0;
25858                }
25859                peer->deprecated_username = 1;
25860             }
25861          } else if (!strcasecmp(v->name, "language")) {
25862             ast_string_field_set(peer, language, v->value);
25863          } else if (!strcasecmp(v->name, "regexten")) {
25864             ast_string_field_set(peer, regexten, v->value);
25865          } else if (!strcasecmp(v->name, "callbackextension")) {
25866             ast_copy_string(callback, v->value, sizeof(callback));
25867          } else if (!strcasecmp(v->name, "amaflags")) {
25868             format = ast_cdr_amaflags2int(v->value);
25869             if (format < 0) {
25870                ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
25871             } else {
25872                peer->amaflags = format;
25873             }
25874          } else if (!strcasecmp(v->name, "maxforwards")) {
25875             if ((sscanf(v->value, "%30d", &peer->maxforwards) != 1) || (peer->maxforwards < 1)) {
25876                ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d.  Using default.\n", v->value, v->lineno);
25877                peer->maxforwards = sip_cfg.default_max_forwards;
25878             }
25879          } else if (!strcasecmp(v->name, "accountcode")) {
25880             ast_string_field_set(peer, accountcode, v->value);
25881          } else if (!strcasecmp(v->name, "mohinterpret")) {
25882             ast_string_field_set(peer, mohinterpret, v->value);
25883          } else if (!strcasecmp(v->name, "mohsuggest")) {
25884             ast_string_field_set(peer, mohsuggest, v->value);
25885          } else if (!strcasecmp(v->name, "parkinglot")) {
25886             ast_string_field_set(peer, parkinglot, v->value);
25887          } else if (!strcasecmp(v->name, "rtp_engine")) {
25888             ast_string_field_set(peer, engine, v->value);
25889          } else if (!strcasecmp(v->name, "mailbox")) {
25890             add_peer_mailboxes(peer, v->value);
25891          } else if (!strcasecmp(v->name, "hasvoicemail")) {
25892             /* People expect that if 'hasvoicemail' is set, that the mailbox will
25893              * be also set, even if not explicitly specified. */
25894             if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) {
25895                add_peer_mailboxes(peer, name);
25896             }
25897          } else if (!strcasecmp(v->name, "subscribemwi")) {
25898             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
25899          } else if (!strcasecmp(v->name, "vmexten")) {
25900             ast_string_field_set(peer, vmexten, v->value);
25901          } else if (!strcasecmp(v->name, "callgroup")) {
25902             peer->callgroup = ast_get_group(v->value);
25903          } else if (!strcasecmp(v->name, "allowtransfer")) {
25904             peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
25905          } else if (!strcasecmp(v->name, "pickupgroup")) {
25906             peer->pickupgroup = ast_get_group(v->value);
25907          } else if (!strcasecmp(v->name, "allow")) {
25908             int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE);
25909             if (error) {
25910                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
25911             }
25912          } else if (!strcasecmp(v->name, "disallow")) {
25913             int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE);
25914             if (error) {
25915                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
25916             }
25917          } else if (!strcasecmp(v->name, "preferred_codec_only")) {
25918             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
25919          } else if (!strcasecmp(v->name, "registertrying")) {
25920             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_REGISTERTRYING);
25921          } else if (!strcasecmp(v->name, "autoframing")) {
25922             peer->autoframing = ast_true(v->value);
25923          } else if (!strcasecmp(v->name, "rtptimeout")) {
25924             if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
25925                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
25926                peer->rtptimeout = global_rtptimeout;
25927             }
25928          } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
25929             if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
25930                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
25931                peer->rtpholdtimeout = global_rtpholdtimeout;
25932             }
25933          } else if (!strcasecmp(v->name, "rtpkeepalive")) {
25934             if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
25935                ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
25936                peer->rtpkeepalive = global_rtpkeepalive;
25937             }
25938          } else if (!strcasecmp(v->name, "timert1")) {
25939             if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) {
25940                ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d.  Using default.\n", v->value, v->lineno);
25941                peer->timer_t1 = global_t1min;
25942             }
25943             timert1_set = 1;
25944          } else if (!strcasecmp(v->name, "timerb")) {
25945             if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) {
25946                ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d.  Using default.\n", v->value, v->lineno);
25947                peer->timer_b = global_timer_b;
25948             }
25949             timerb_set = 1;
25950          } else if (!strcasecmp(v->name, "setvar")) {
25951             peer->chanvars = add_var(v->value, peer->chanvars);
25952          } else if (!strcasecmp(v->name, "header")) {
25953             char tmp[4096];
25954             snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value);
25955             peer->chanvars = add_var(tmp, peer->chanvars);
25956          } else if (!strcasecmp(v->name, "qualifyfreq")) {
25957             int i;
25958             if (sscanf(v->value, "%30d", &i) == 1) {
25959                peer->qualifyfreq = i * 1000;
25960             } else {
25961                ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
25962                peer->qualifyfreq = global_qualifyfreq;
25963             }
25964          } else if (!strcasecmp(v->name, "maxcallbitrate")) {
25965             peer->maxcallbitrate = atoi(v->value);
25966             if (peer->maxcallbitrate < 0) {
25967                peer->maxcallbitrate = default_maxcallbitrate;
25968             }
25969          } else if (!strcasecmp(v->name, "session-timers")) {
25970             int i = (int) str2stmode(v->value);
25971             if (i < 0) {
25972                ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
25973                peer->stimer.st_mode_oper = global_st_mode;
25974             } else {
25975                peer->stimer.st_mode_oper = i;
25976             }
25977          } else if (!strcasecmp(v->name, "session-expires")) {
25978             if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) {
25979                ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
25980                peer->stimer.st_max_se = global_max_se;
25981             }
25982          } else if (!strcasecmp(v->name, "session-minse")) {
25983             if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) {
25984                ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
25985                peer->stimer.st_min_se = global_min_se;
25986             }
25987             if (peer->stimer.st_min_se < 90) {
25988                ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config);
25989                peer->stimer.st_min_se = global_min_se;
25990             }
25991          } else if (!strcasecmp(v->name, "session-refresher")) {
25992             int i = (int) str2strefresher(v->value);
25993             if (i < 0) {
25994                ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
25995                peer->stimer.st_ref = global_st_refresher;
25996             } else {
25997                peer->stimer.st_ref = i;
25998             }
25999          } else if (!strcasecmp(v->name, "disallowed_methods")) {
26000             char *disallow = ast_strdupa(v->value);
26001             mark_parsed_methods(&peer->disallowed_methods, disallow);
26002          } else if (!strcasecmp(v->name, "unsolicited_mailbox")) {
26003             ast_string_field_set(peer, unsolicited_mailbox, v->value);
26004          } else if (!strcasecmp(v->name, "use_q850_reason")) {
26005             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
26006          } else if (!strcasecmp(v->name, "encryption")) {
26007             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP);
26008          } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
26009             ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
26010          }
26011       }
26012 
26013       /* These apply to devstate lookups */
26014       if (realtime && !strcasecmp(v->name, "lastms")) {
26015          sscanf(v->value, "%30d", &peer->lastms);
26016       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
26017          ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID);
26018       } else if (realtime && !strcasecmp(v->name, "fullcontact")) {
26019          if (alt_fullcontact && !alt) {
26020             /* Reset, because the alternate also has a fullcontact and we
26021              * do NOT want the field value to be doubled. It might be
26022              * tempting to skip this, but the first table might not have
26023              * fullcontact and since we're here, we know that the alternate
26024              * absolutely does. */
26025             alt_fullcontact = 0;
26026             ast_str_reset(fullcontact);
26027          }
26028          /* Reconstruct field, because realtime separates our value at the ';' */
26029          if (fullcontact->used > 0) {
26030             ast_str_append(&fullcontact, 0, ";%s", v->value);
26031          } else {
26032             ast_str_set(&fullcontact, 0, "%s", v->value);
26033          }
26034       } else if (!strcasecmp(v->name, "qualify")) {
26035          if (!strcasecmp(v->value, "no")) {
26036             peer->maxms = 0;
26037          } else if (!strcasecmp(v->value, "yes")) {
26038             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
26039          } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
26040             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);
26041             peer->maxms = 0;
26042          }
26043          if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
26044             /* This would otherwise cause a network storm, where the
26045              * qualify response refreshes the peer from the database,
26046              * which in turn causes another qualify to be sent, ad
26047              * infinitum. */
26048             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);
26049             peer->maxms = 0;
26050          }
26051       } else if (!strcasecmp(v->name, "callcounter")) {
26052          peer->call_limit = ast_true(v->value) ? INT_MAX : 0;
26053       } else if (!strcasecmp(v->name, "call-limit")) {
26054          peer->call_limit = atoi(v->value);
26055          if (peer->call_limit < 0) {
26056             peer->call_limit = 0;
26057          }
26058       } else if (!strcasecmp(v->name, "busylevel")) {
26059          peer->busy_level = atoi(v->value);
26060          if (peer->busy_level < 0) {
26061             peer->busy_level = 0;
26062          }
26063       } else if (ast_cc_is_config_param(v->name)) {
26064          ast_cc_set_param(peer->cc_params, v->name, v->value);
26065       }
26066    }
26067 
26068    if (!devstate_only) {
26069       struct sip_mailbox *mailbox;
26070       AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) {
26071          if (mailbox->delme) {
26072             AST_LIST_REMOVE_CURRENT(entry);
26073             destroy_mailbox(mailbox);
26074          }
26075       }
26076       AST_LIST_TRAVERSE_SAFE_END;
26077    }
26078 
26079    if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) {
26080       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);
26081       ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER);
26082    }
26083 
26084    /* Note that Timer B is dependent upon T1 and MUST NOT be lower
26085     * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */
26086    if (peer->timer_b < peer->timer_t1 * 64) {
26087       if (timerb_set && timert1_set) {
26088          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);
26089       } else if (timerb_set) {
26090          if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) {
26091             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);
26092             peer->timer_t1 = global_t1min;
26093             peer->timer_b = peer->timer_t1 * 64;
26094          }
26095          peer->timer_t1 = peer->timer_b / 64;
26096       } else {
26097          peer->timer_b = peer->timer_t1 * 64;
26098       }
26099    }
26100 
26101    if (!peer->default_outbound_transport) {
26102       /* Set default set of transports */
26103       peer->transports = default_transports;
26104       /* Set default primary transport */
26105       peer->default_outbound_transport = default_primary_transport;
26106    }
26107 
26108    /* The default transport type set during build_peer should only replace the socket.type when...
26109     * 1. Registration is not present and the socket.type and default transport types are different.
26110     * 2. The socket.type is not an acceptable transport type after rebuilding peer.
26111     * 3. The socket.type is not set yet. */
26112    if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) ||
26113       !(peer->socket.type & peer->transports) || !(peer->socket.type)) {
26114 
26115       set_socket_transport(&peer->socket, peer->default_outbound_transport);
26116    }
26117 
26118    if (ast_str_strlen(fullcontact)) {
26119       ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact));
26120       peer->rt_fromcontact = TRUE;
26121       /* We have a hostname in the fullcontact, but if we don't have an
26122        * address listed on the entry (or if it's 'dynamic'), then we need to
26123        * parse the entry to obtain the IP address, so a dynamic host can be
26124        * contacted immediately after reload (as opposed to waiting for it to
26125        * register once again). But if we have an address for this peer and NAT was
26126        * specified, use that address instead. */
26127       /* XXX May need to revisit the final argument; does the realtime DB store whether
26128        * the original contact was over TLS or not? XXX */
26129       if (!ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT) || ast_sockaddr_isnull(&peer->addr)) {
26130          __set_address_from_contact(fullcontact->str, &peer->addr, 0);
26131       }
26132    }
26133 
26134    if (srvlookup && peer->dnsmgr == NULL) {
26135       char transport[MAXHOSTNAMELEN];
26136       char _srvlookup[MAXHOSTNAMELEN];
26137       char *params;
26138 
26139       ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup));
26140       if ((params = strchr(_srvlookup, ';'))) {
26141          *params++ = '\0';
26142       }
26143 
26144       snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type));
26145 
26146       peer->addr.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
26147       if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL)) {
26148          ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
26149          unref_peer(peer, "getting rid of a peer pointer");
26150          return NULL;
26151       }
26152 
26153       ast_string_field_set(peer, tohost, peer->dnsmgr ? srvlookup :
26154                  ast_sockaddr_stringify_host(&peer->addr));
26155       
26156       if (global_dynamic_exclude_static) {
26157          int err = 0;
26158          sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 
26159                      sip_cfg.contact_ha, &err);
26160          if (err) {
26161             ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
26162          }
26163       }
26164    }
26165 
26166    if (port && !realtime && peer->host_dynamic) {
26167       ast_sockaddr_set_port(&peer->defaddr, port);
26168    } else if (port) {
26169       ast_sockaddr_set_port(&peer->addr, port);
26170    }
26171 
26172    if (ast_sockaddr_port(&peer->addr) == 0) {
26173       ast_sockaddr_set_port(&peer->addr,
26174                   (peer->socket.type & SIP_TRANSPORT_TLS) ?
26175                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
26176    }
26177    if (ast_sockaddr_port(&peer->defaddr) == 0) {
26178       ast_sockaddr_set_port(&peer->defaddr,
26179                   (peer->socket.type & SIP_TRANSPORT_TLS) ?
26180                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
26181    }
26182    if (!peer->socket.port) {
26183       peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
26184    }
26185 
26186    if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) {
26187       time_t nowtime = time(NULL);
26188 
26189       if ((nowtime - regseconds) > 0) {
26190          destroy_association(peer);
26191          memset(&peer->addr, 0, sizeof(peer->addr));
26192          peer->lastms = -1;
26193          ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
26194       }
26195    }
26196 
26197    /* Startup regular pokes */
26198    if (!devstate_only && realtime && peer->lastms > 0) {
26199       ref_peer(peer, "schedule qualify");
26200       sip_poke_peer(peer, 0);
26201    }
26202 
26203    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
26204    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
26205    ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags);
26206    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
26207       sip_cfg.allowsubscribe = TRUE;   /* No global ban any more */
26208    }
26209    if (peer->host_dynamic && !peer->is_realtime) {
26210       reg_source_db(peer);
26211    }
26212 
26213    /* If they didn't request that MWI is sent *only* on subscribe, go ahead and
26214     * subscribe to it now. */
26215    if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
26216       !AST_LIST_EMPTY(&peer->mailboxes)) {
26217       add_peer_mwi_subs(peer);
26218       /* Send MWI from the event cache only.  This is so we can send initial
26219        * MWI if app_voicemail got loaded before chan_sip.  If it is the other
26220        * way, then we will get events when app_voicemail gets loaded. */
26221       sip_send_mwi_to_peer(peer, NULL, 1);
26222    }
26223 
26224    peer->the_mark = 0;
26225 
26226    ast_free_ha(oldha);
26227    ast_free_ha(olddirectmediaha);
26228    if (!ast_strlen_zero(callback)) { /* build string from peer info */
26229       char *reg_string;
26230       if (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) {
26231          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
26232       } else if (reg_string) {
26233          sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
26234          ast_free(reg_string);
26235       }
26236    }
26237    return peer;
26238 }

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

References append_history, ast_copy_string(), ast_debug, ast_md5_hash(), ast_random(), ast_sockaddr_stringify_host(), ast_strlen_zero(), find_realm_authentication(), secret, sip_methods, and text.

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

18018 {
18019    char a1[256];
18020    char a2[256];
18021    char a1_hash[256];
18022    char a2_hash[256];
18023    char resp[256];
18024    char resp_hash[256];
18025    char uri[256];
18026    char opaque[256] = "";
18027    char cnonce[80];
18028    const char *username;
18029    const char *secret;
18030    const char *md5secret;
18031    struct sip_auth *auth = NULL; /* Realm authentication */
18032 
18033    if (!ast_strlen_zero(p->domain))
18034       ast_copy_string(uri, p->domain, sizeof(uri));
18035    else if (!ast_strlen_zero(p->uri))
18036       ast_copy_string(uri, p->uri, sizeof(uri));
18037    else
18038       snprintf(uri, sizeof(uri), "sip:%s@%s", p->username, ast_sockaddr_stringify_host(&p->sa));
18039 
18040    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
18041 
18042    /* Check if we have separate auth credentials */
18043    if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */
18044       auth = find_realm_authentication(authl, p->realm); /* If not, global list */
18045 
18046    if (auth) {
18047       ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
18048       username = auth->username;
18049       secret = auth->secret;
18050       md5secret = auth->md5secret;
18051       if (sipdebug)
18052          ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid);
18053    } else {
18054       /* No authentication, use peer or register= config */
18055       username = p->authname;
18056       secret =  p->peersecret;
18057       md5secret = p->peermd5secret;
18058    }
18059    if (ast_strlen_zero(username))   /* We have no authentication */
18060       return -1;
18061 
18062    /* Calculate SIP digest response */
18063    snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
18064    snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri);
18065    if (!ast_strlen_zero(md5secret))
18066       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
18067    else
18068       ast_md5_hash(a1_hash, a1);
18069    ast_md5_hash(a2_hash, a2);
18070 
18071    p->noncecount++;
18072    if (!ast_strlen_zero(p->qop))
18073       snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
18074    else
18075       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash);
18076    ast_md5_hash(resp_hash, resp);
18077 
18078    /* only include the opaque string if it's set */
18079    if (!ast_strlen_zero(p->opaque)) {
18080      snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
18081    }
18082 
18083    /* XXX We hard code our qop to "auth" for now.  XXX */
18084    if (!ast_strlen_zero(p->qop))
18085       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount);
18086    else
18087       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);
18088 
18089    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
18090 
18091    return 0;
18092 }

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

Build route list from Record-Route header.

Definition at line 13123 of file chan_sip.c.

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

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

13124 {
13125    struct sip_route *thishop, *head, *tail;
13126    int start = 0;
13127    int len;
13128    const char *rr, *contact, *c;
13129 
13130    /* Once a persistent route is set, don't fool with it */
13131    if (p->route && p->route_persistent) {
13132       ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop);
13133       return;
13134    }
13135 
13136    if (p->route) {
13137       free_old_route(p->route);
13138       p->route = NULL;
13139    }
13140 
13141    /* We only want to create the route set the first time this is called */
13142    p->route_persistent = 1;
13143    
13144    /* Build a tailq, then assign it to p->route when done.
13145     * If backwards, we add entries from the head so they end up
13146     * in reverse order. However, we do need to maintain a correct
13147     * tail pointer because the contact is always at the end.
13148     */
13149    head = NULL;
13150    tail = head;
13151    /* 1st we pass through all the hops in any Record-Route headers */
13152    for (;;) {
13153       /* Each Record-Route header */
13154       rr = __get_header(req, "Record-Route", &start);
13155       if (*rr == '\0') {
13156          break;
13157       }
13158       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
13159          ++rr;
13160          len = strcspn(rr, ">") + 1;
13161          /* Make a struct route */
13162          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
13163             /* ast_calloc is not needed because all fields are initialized in this block */
13164             ast_copy_string(thishop->hop, rr, len);
13165             ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop);
13166             /* Link in */
13167             if (backwards) {
13168                /* Link in at head so they end up in reverse order */
13169                thishop->next = head;
13170                head = thishop;
13171                /* If this was the first then it'll be the tail */
13172                if (!tail) {
13173                   tail = thishop;
13174                }
13175             } else {
13176                thishop->next = NULL;
13177                /* Link in at the end */
13178                if (tail) {
13179                   tail->next = thishop;
13180                } else {
13181                   head = thishop;
13182                }
13183                tail = thishop;
13184             }
13185          }
13186       }
13187    }
13188 
13189    /* Only append the contact if we are dealing with a strict router */
13190    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) {
13191       /* 2nd append the Contact: if there is one */
13192       /* Can be multiple Contact headers, comma separated values - we just take the first */
13193       contact = get_header(req, "Contact");
13194       if (!ast_strlen_zero(contact)) {
13195          ast_debug(2, "build_route: Contact hop: %s\n", contact);
13196          /* Look for <: delimited address */
13197          c = strchr(contact, '<');
13198          if (c) {
13199             /* Take to > */
13200             ++c;
13201             len = strcspn(c, ">") + 1;
13202          } else {
13203             /* No <> - just take the lot */
13204             c = contact;
13205             len = strlen(contact) + 1;
13206          }
13207          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
13208             /* ast_calloc is not needed because all fields are initialized in this block */
13209             ast_copy_string(thishop->hop, c, len);
13210             thishop->next = NULL;
13211             /* Goes at the end */
13212             if (tail) {
13213                tail->next = thishop;
13214             } else {
13215                head = thishop;
13216             }
13217          }
13218       }
13219    }
13220 
13221    /* Store as new route */
13222    p->route = head;
13223 
13224    /* For debugging dump what we ended up with */
13225    if (sip_debug_test_pvt(p)) {
13226       list_route(p->route);
13227    }
13228 }

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

Build a Via header for a request.

Definition at line 3119 of file chan_sip.c.

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

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

03120 {
03121    /* Work around buggy UNIDEN UIP200 firmware */
03122    const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : "";
03123 
03124    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
03125    snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s",
03126        get_transport_pvt(p),
03127        ast_sockaddr_stringify(&p->ourip),
03128        (int) p->branch, rport);
03129 }

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 13498 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 handle_request_subscribe(), handle_response(), and handle_response_notify().

13499 {
13500    struct sip_pvt *p = data;
13501 
13502    sip_pvt_lock(p);
13503 
13504    switch(state) {
13505    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
13506    case AST_EXTENSION_REMOVED:   /* Extension is gone */
13507       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
13508       ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
13509       p->stateid = -1;
13510       p->subscribed = NONE;
13511       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
13512       break;
13513    default: /* Tell user */
13514       p->laststate = state;
13515       break;
13516    }
13517    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
13518       if (!p->pendinginvite) {
13519          transmit_state_notify(p, state, 1, FALSE);
13520       } else {
13521          /* We already have a NOTIFY sent that is not answered. Queue the state up.
13522             if many state changes happen meanwhile, we will only send a notification of the last one */
13523          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
13524       }
13525    }
13526    ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
13527          ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
13528 
13529    sip_pvt_unlock(p);
13530 
13531    return 0;
13532 }

static void cc_epa_destructor ( void *  data  )  [static]

Definition at line 872 of file chan_sip.c.

References ast_free.

00873 {
00874    struct sip_epa_entry *epa_entry = data;
00875    struct cc_epa_entry *cc_entry = epa_entry->instance_data;
00876    ast_free(cc_entry);
00877 }

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

18603 {
18604    struct cc_epa_entry *cc_entry = epa_entry->instance_data;
18605    struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
18606          find_sip_monitor_instance_by_suspension_entry, epa_entry);
18607    const char *min_expires;
18608 
18609    if (!monitor_instance) {
18610       ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry);
18611       return;
18612    }
18613 
18614    if (resp != 423) {
18615       ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
18616             "Received error response to our PUBLISH");
18617       ao2_ref(monitor_instance, -1);
18618       return;
18619    }
18620 
18621    /* Allrighty, the other end doesn't like our Expires value. They think it's
18622     * too small, so let's see if they've provided a more sensible value. If they
18623     * haven't, then we'll just double our Expires value and see if they like that
18624     * instead.
18625     *
18626     * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE,
18627     * PUBLISH, and REGISTER could all benefit from the same shared code.
18628     */
18629    min_expires = get_header(req, "Min-Expires");
18630    if (ast_strlen_zero(min_expires)) {
18631       pvt->expiry *= 2;
18632       if (pvt->expiry < 0) {
18633          /* You dork! You overflowed! */
18634          ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
18635                "PUBLISH expiry overflowed");
18636          ao2_ref(monitor_instance, -1);
18637          return;
18638       }
18639    } else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) {
18640       ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
18641             "Min-Expires has non-numeric value");
18642       ao2_ref(monitor_instance, -1);
18643       return;
18644    }
18645    /* At this point, we have most certainly changed pvt->expiry, so try transmitting
18646     * again
18647     */
18648    transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL);
18649    ao2_ref(monitor_instance, -1);
18650 }

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

18343 {
18344    char *redirecting_from_name = NULL;
18345    char *redirecting_from_number = NULL;
18346    char *redirecting_to_name = NULL;
18347    char *redirecting_to_number = NULL;
18348    int reason = AST_REDIRECTING_REASON_UNCONDITIONAL;
18349    int is_response = req->method == SIP_RESPONSE;
18350    int res = 0;
18351 
18352    res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason);
18353    if (res == -1) {
18354       if (is_response) {
18355          get_name_and_number(get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number);
18356       } else {
18357          return;
18358       }
18359    }
18360 
18361    /* At this point, all redirecting "from" info should be filled in appropriately
18362     * on to the "to" info
18363     */
18364 
18365    if (is_response) {
18366       parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward);
18367    } else {
18368       get_name_and_number(get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number);
18369    }
18370 
18371    if (!ast_strlen_zero(redirecting_from_number)) {
18372       ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number);
18373       update_redirecting->from.number = 1;
18374       redirecting->from.number.valid = 1;
18375       ast_free(redirecting->from.number.str);
18376       redirecting->from.number.str = redirecting_from_number;
18377    }
18378    if (!ast_strlen_zero(redirecting_from_name)) {
18379       ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name);
18380       update_redirecting->from.name = 1;
18381       redirecting->from.name.valid = 1;
18382       ast_free(redirecting->from.name.str);
18383       redirecting->from.name.str = redirecting_from_name;
18384    }
18385    if (!ast_strlen_zero(p->cid_tag)) {
18386       ast_free(redirecting->from.tag);
18387       redirecting->from.tag = ast_strdup(p->cid_tag);
18388       ast_free(redirecting->to.tag);
18389       redirecting->to.tag = ast_strdup(p->cid_tag);
18390    }
18391    if (!ast_strlen_zero(redirecting_to_number)) {
18392       ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number);
18393       update_redirecting->to.number = 1;
18394       redirecting->to.number.valid = 1;
18395       ast_free(redirecting->to.number.str);
18396       redirecting->to.number.str = redirecting_to_number;
18397    }
18398    if (!ast_strlen_zero(redirecting_to_name)) {
18399       ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number);
18400       update_redirecting->to.name = 1;
18401       redirecting->to.name.valid = 1;
18402       ast_free(redirecting->to.name.str);
18403       redirecting->to.name.str = redirecting_to_name;
18404    }
18405    redirecting->reason = reason;
18406 }

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

Change the T38 state on a SIP dialog.

Definition at line 4669 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, ast_channel::name, and ast_control_t38_parameters::request_response.

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

04670 {
04671    int old = p->t38.state;
04672    struct ast_channel *chan = p->owner;
04673    struct ast_control_t38_parameters parameters = { .request_response = 0 };
04674 
04675    /* Don't bother changing if we are already in the state wanted */
04676    if (old == state)
04677       return;
04678 
04679    p->t38.state = state;
04680    ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
04681 
04682    /* If no channel was provided we can't send off a control frame */
04683    if (!chan)
04684       return;
04685 
04686    /* Given the state requested and old state determine what control frame we want to queue up */
04687    switch (state) {
04688    case T38_PEER_REINVITE:
04689       parameters = p->t38.their_parms;
04690       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
04691       parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
04692       ast_udptl_set_tag(p->udptl, "SIP/%s", p->username);
04693       break;
04694    case T38_ENABLED:
04695       parameters = p->t38.their_parms;
04696       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
04697       parameters.request_response = AST_T38_NEGOTIATED;
04698       ast_udptl_set_tag(p->udptl, "SIP/%s", p->username);
04699       break;
04700    case T38_DISABLED:
04701       if (old == T38_ENABLED) {
04702          parameters.request_response = AST_T38_TERMINATED;
04703       } else if (old == T38_LOCAL_REINVITE) {
04704          parameters.request_response = AST_T38_REFUSED;
04705       }
04706       break;
04707    case T38_LOCAL_REINVITE:
04708       /* wait until we get a peer response before responding to local reinvite */
04709       break;
04710    }
04711 
04712    /* Woot we got a message, create a control frame and send it on! */
04713    if (parameters.request_response)
04714       ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
04715 }

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 13252 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(), check_auth_buf, CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), LOG_NOTICE, LOG_WARNING, S_OR, set_nonce_randdata(), sip_methods, sip_scheddestroy(), strsep(), text, transmit_response_with_auth(), and TRUE.

Referenced by check_peer_ok(), and register_verify().

13255 {
13256    const char *response;
13257    char *reqheader, *respheader;
13258    const char *authtoken;
13259    char a1_hash[256];
13260    char resp_hash[256]="";
13261    char *c;
13262    int  wrongnonce = FALSE;
13263    int  good_response;
13264    const char *usednonce = p->randdata;
13265    struct ast_str *buf;
13266    int res;
13267 
13268    /* table of recognised keywords, and their value in the digest */
13269    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
13270    struct x {
13271       const char *key;
13272       const char *s;
13273    } *i, keys[] = {
13274       [K_RESP] = { "response=", "" },
13275       [K_URI] = { "uri=", "" },
13276       [K_USER] = { "username=", "" },
13277       [K_NONCE] = { "nonce=", "" },
13278       [K_LAST] = { NULL, NULL}
13279    };
13280 
13281    /* Always OK if no secret */
13282    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
13283       return AUTH_SUCCESSFUL;
13284 
13285    /* Always auth with WWW-auth since we're NOT a proxy */
13286    /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */
13287    response = "401 Unauthorized";
13288 
13289    /*
13290     * Note the apparent swap of arguments below, compared to other
13291     * usages of auth_headers().
13292     */
13293    auth_headers(WWW_AUTH, &respheader, &reqheader);
13294 
13295    authtoken =  get_header(req, reqheader);  
13296    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
13297       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
13298          information */
13299       if (!reliable) {
13300          /* Resend message if this was NOT a reliable delivery.   Otherwise the
13301             retransmission should get it */
13302          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
13303          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
13304          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13305       }
13306       return AUTH_CHALLENGE_SENT;
13307    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
13308       /* We have no auth, so issue challenge and request authentication */
13309       set_nonce_randdata(p, 1); /* Create nonce for challenge */
13310       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
13311       /* Schedule auto destroy in 32 seconds */
13312       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13313       return AUTH_CHALLENGE_SENT;
13314    }
13315 
13316    /* --- We have auth, so check it */
13317 
13318    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
13319       an example in the spec of just what it is you're doing a hash on. */
13320 
13321    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
13322       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
13323    }
13324 
13325    /* Make a copy of the response and parse it */
13326    res = ast_str_set(&buf, 0, "%s", authtoken);
13327 
13328    if (res == AST_DYNSTR_BUILD_FAILED) {
13329       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
13330    }
13331 
13332    c = buf->str;
13333 
13334    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
13335       for (i = keys; i->key != NULL; i++) {
13336          const char *separator = ",";  /* default */
13337 
13338          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
13339             continue;
13340          }
13341          /* Found. Skip keyword, take text in quotes or up to the separator. */
13342          c += strlen(i->key);
13343          if (*c == '"') { /* in quotes. Skip first and look for last */
13344             c++;
13345             separator = "\"";
13346          }
13347          i->s = c;
13348          strsep(&c, separator);
13349          break;
13350       }
13351       if (i->key == NULL) { /* not found, jump after space or comma */
13352          strsep(&c, " ,");
13353       }
13354    }
13355 
13356    /* Verify that digest username matches  the username we auth as */
13357    if (strcmp(username, keys[K_USER].s)) {
13358       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
13359          username, keys[K_USER].s);
13360       /* Oops, we're trying something here */
13361       return AUTH_USERNAME_MISMATCH;
13362    }
13363 
13364    /* Verify nonce from request matches our nonce, and the nonce has not already been responded to.
13365     * If this check fails, send 401 with new nonce */
13366    if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */
13367       wrongnonce = TRUE;
13368       usednonce = keys[K_NONCE].s;
13369    } else {
13370       p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */
13371    }
13372 
13373    if (!ast_strlen_zero(md5secret)) {
13374       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
13375    } else {
13376       char a1[256];
13377 
13378       snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
13379       ast_md5_hash(a1_hash, a1);
13380    }
13381 
13382    /* compute the expected response to compare with what we received */
13383    {
13384       char a2[256];
13385       char a2_hash[256];
13386       char resp[256];
13387 
13388       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
13389             S_OR(keys[K_URI].s, uri));
13390       ast_md5_hash(a2_hash, a2);
13391       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
13392       ast_md5_hash(resp_hash, resp);
13393    }
13394 
13395    good_response = keys[K_RESP].s &&
13396          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
13397    if (wrongnonce) {
13398       if (good_response) {
13399          if (sipdebug)
13400             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From"));
13401          /* We got working auth token, based on stale nonce . */
13402          set_nonce_randdata(p, 0);
13403          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
13404       } else {
13405          /* Everything was wrong, so give the device one more try with a new challenge */
13406          if (!req->ignore) {
13407             if (sipdebug) {
13408                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
13409             }
13410             set_nonce_randdata(p, 1);
13411          } else {
13412             if (sipdebug) {
13413                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
13414             }
13415          }
13416          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
13417       }
13418 
13419       /* Schedule auto destroy in 32 seconds */
13420       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13421       return AUTH_CHALLENGE_SENT;
13422    }
13423    if (good_response) {
13424       append_history(p, "AuthOK", "Auth challenge successful for %s", username);
13425       return AUTH_SUCCESSFUL;
13426    }
13427 
13428    /* Ok, we have a bad username/secret pair */
13429    /* Tell the UAS not to re-send this authentication data, because
13430       it will continue to fail
13431    */
13432 
13433    return AUTH_SECRET_FAILED;
13434 }

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 14800 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_verbose, check_auth(), cid_name, cid_num, context, copy_vars(), debug, dialog_initialize_rtp(), do_setnat(), FALSE, find_peer(), get_rpid(), language, mohinterpret, mohsuggest, parkinglot, set_pvt_allowed_methods(), set_t38_capabilities(), sip_debug_test_addr(), TRUE, and unref_peer().

Referenced by check_user_full().

14804 {
14805    enum check_auth_result res;
14806    int debug = sip_debug_test_addr(addr);
14807    struct sip_peer *peer;
14808 
14809    if (sipmethod == SIP_SUBSCRIBE) {
14810       /* For subscribes, match on device name only; for other methods,
14811       * match on IP address-port of the incoming request.
14812       */
14813       peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0);
14814    } else {
14815       /* First find devices based on username (avoid all type=peer's) */
14816       peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0);
14817 
14818       /* Then find devices based on IP */
14819       if (!peer) {
14820          peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
14821       }
14822    }
14823 
14824    if (!peer) {
14825       if (debug) {
14826          ast_verbose("No matching peer for '%s' from '%s'\n",
14827             of, ast_sockaddr_stringify(&p->recv));
14828       }
14829       return AUTH_DONT_KNOW;
14830    }
14831 
14832    if (!ast_apply_ha(peer->ha, addr)) {
14833       ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
14834       unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
14835       return AUTH_ACL_FAILED;
14836    }
14837    if (debug)
14838       ast_verbose("Found peer '%s' for '%s' from %s\n",
14839          peer->name, of, ast_sockaddr_stringify(&p->recv));
14840 
14841    /* XXX what about p->prefs = peer->prefs; ? */
14842    /* Set Frame packetization */
14843    if (p->rtp) {
14844       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
14845       p->autoframing = peer->autoframing;
14846    }
14847 
14848    /* Take the peer */
14849    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
14850    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
14851    ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
14852 
14853    if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) {
14854       p->t38_maxdatagram = peer->t38_maxdatagram;
14855       set_t38_capabilities(p);
14856    }
14857 
14858    /* Copy SIP extensions profile to peer */
14859    /* XXX is this correct before a successful auth ? */
14860    if (p->sipoptions)
14861       peer->sipoptions = p->sipoptions;
14862 
14863    do_setnat(p);
14864 
14865    ast_string_field_set(p, peersecret, peer->secret);
14866    ast_string_field_set(p, peermd5secret, peer->md5secret);
14867    ast_string_field_set(p, subscribecontext, peer->subscribecontext);
14868    ast_string_field_set(p, mohinterpret, peer->mohinterpret);
14869    ast_string_field_set(p, mohsuggest, peer->mohsuggest);
14870    ast_string_field_set(p, parkinglot, peer->parkinglot);
14871    ast_string_field_set(p, engine, peer->engine);
14872    p->disallowed_methods = peer->disallowed_methods;
14873    set_pvt_allowed_methods(p, req);
14874    ast_cc_copy_config_params(p->cc_params, peer->cc_params);
14875    if (peer->callingpres)  /* Peer calling pres setting will override RPID */
14876       p->callingpres = peer->callingpres;
14877    if (peer->maxms && peer->lastms)
14878       p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
14879    else
14880       p->timer_t1 = peer->timer_t1;
14881 
14882    /* Set timer B to control transaction timeouts */
14883    if (peer->timer_b)
14884       p->timer_b = peer->timer_b;
14885    else
14886       p->timer_b = 64 * p->timer_t1;
14887 
14888    if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
14889       /* Pretend there is no required authentication */
14890       ast_string_field_set(p, peersecret, NULL);
14891       ast_string_field_set(p, peermd5secret, NULL);
14892    }
14893    if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) {
14894       ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
14895       ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
14896       ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
14897       /* If we have a call limit, set flag */
14898       if (peer->call_limit)
14899          ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
14900       ast_string_field_set(p, peername, peer->name);
14901       ast_string_field_set(p, authname, peer->name);
14902 
14903       if (sipmethod == SIP_INVITE) {
14904          /* copy channel vars */
14905          p->chanvars = copy_vars(peer->chanvars);
14906       }
14907 
14908       if (authpeer) {
14909          ao2_t_ref(peer, 1, "copy pointer into (*authpeer)");
14910          (*authpeer) = peer;  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
14911       }
14912 
14913       if (!ast_strlen_zero(peer->username)) {
14914          ast_string_field_set(p, username, peer->username);
14915          /* Use the default username for authentication on outbound calls */
14916          /* XXX this takes the name from the caller... can we override ? */
14917          ast_string_field_set(p, authname, peer->username);
14918       }
14919       if (!get_rpid(p, req)) {
14920          if (!ast_strlen_zero(peer->cid_num)) {
14921             char *tmp = ast_strdupa(peer->cid_num);
14922             if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
14923                ast_shrink_phone_number(tmp);
14924             ast_string_field_set(p, cid_num, tmp);
14925          }
14926          if (!ast_strlen_zero(peer->cid_name))
14927             ast_string_field_set(p, cid_name, peer->cid_name);
14928          if (!ast_strlen_zero(peer->cid_tag))
14929             ast_string_field_set(p, cid_tag, peer->cid_tag);
14930          if (peer->callingpres)
14931             p->callingpres = peer->callingpres;
14932       }
14933       ast_string_field_set(p, fullcontact, peer->fullcontact);
14934       if (!ast_strlen_zero(peer->context))
14935          ast_string_field_set(p, context, peer->context);
14936       ast_string_field_set(p, peersecret, peer->secret);
14937       ast_string_field_set(p, peermd5secret, peer->md5secret);
14938       ast_string_field_set(p, language, peer->language);
14939       ast_string_field_set(p, accountcode, peer->accountcode);
14940       p->amaflags = peer->amaflags;
14941       p->callgroup = peer->callgroup;
14942       p->pickupgroup = peer->pickupgroup;
14943       p->capability = peer->capability;
14944       p->prefs = peer->prefs;
14945       p->jointcapability = peer->capability;
14946       if (peer->maxforwards > 0) {
14947          p->maxforwards = peer->maxforwards;
14948       }
14949       if (p->peercapability)
14950          p->jointcapability &= p->peercapability;
14951       p->maxcallbitrate = peer->maxcallbitrate;
14952       if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
14953           (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
14954          p->noncodeccapability |= AST_RTP_DTMF;
14955       else
14956          p->noncodeccapability &= ~AST_RTP_DTMF;
14957       p->jointnoncodeccapability = p->noncodeccapability;
14958       if (!dialog_initialize_rtp(p)) {
14959          if (p->rtp) {
14960             ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
14961             p->autoframing = peer->autoframing;
14962          }
14963       } else {
14964          res = AUTH_RTP_FAILED;
14965       }
14966    }
14967    unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer");
14968    return res;
14969 }

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

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

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

18527 {
18528    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18529       /* if we can't BYE, then this is really a pending CANCEL */
18530       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
18531          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
18532          /* Actually don't destroy us yet, wait for the 487 on our original
18533             INVITE, but do set an autodestruct just in case we never get it. */
18534       else {
18535          /* We have a pending outbound invite, don't send something
18536             new in-transaction */
18537          if (p->pendinginvite)
18538             return;
18539 
18540          if (p->owner) {
18541             ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
18542          }
18543          /* Perhaps there is an SD change INVITE outstanding */
18544          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
18545       }
18546       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
18547       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18548    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
18549       /* if we can't REINVITE, hold it for later */
18550       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
18551          ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
18552       } else {
18553          ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid);
18554          /* Didn't get to reinvite yet, so do it now */
18555          transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE);
18556          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
18557       }
18558    }
18559 }

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

References ast_channel_trylock, ast_channel_unlock, ast_log(), ast_rtp_instance_get_hold_timeout(), ast_rtp_instance_get_timeout(), 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, LOG_NOTICE, sip_pvt_lock, and sip_pvt_unlock.

Referenced by dialog_needdestroy().

24170 {
24171    /* If we have no RTP or no active owner, no need to check timers */
24172    if (!dialog->rtp || !dialog->owner)
24173       return;
24174    /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */
24175 
24176    if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip))
24177       return;
24178 
24179    /* If the call is involved in a T38 fax session do not check RTP timeout */
24180    if (dialog->t38.state == T38_ENABLED)
24181       return;
24182 
24183    /* If we have no timers set, return now */
24184    if (!ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) {
24185       return;
24186    }
24187 
24188    /*! \todo Check video RTP keepalives
24189 
24190       Do we need to move the lastrtptx to the RTP structure to have one for audio and one
24191       for video? It really does belong to the RTP structure.
24192    */
24193 
24194    /* Check AUDIO RTP timers */
24195    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))) {
24196       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)))) {
24197          /* Needs a hangup */
24198          if (ast_rtp_instance_get_timeout(dialog->rtp)) {
24199             while (dialog->owner && ast_channel_trylock(dialog->owner)) {
24200                sip_pvt_unlock(dialog);
24201                usleep(1);
24202                sip_pvt_lock(dialog);
24203             }
24204             if (!dialog->owner) {
24205                return; /* channel hangup can occur during deadlock avoidance. */
24206             }
24207             ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
24208                dialog->owner->name, (long) (t - dialog->lastrtprx));
24209             /* Issue a softhangup */
24210             ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV);
24211             ast_channel_unlock(dialog->owner);
24212             /* forget the timeouts for this call, since a hangup
24213                has already been requested and we don't want to
24214                repeatedly request hangups
24215             */
24216             ast_rtp_instance_set_timeout(dialog->rtp, 0);
24217             ast_rtp_instance_set_hold_timeout(dialog->rtp, 0);
24218             if (dialog->vrtp) {
24219                ast_rtp_instance_set_timeout(dialog->vrtp, 0);
24220                ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0);
24221             }
24222          }
24223       }
24224    }
24225 }

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

25316 {
25317    struct domain *d;
25318    int result = 0;
25319 
25320    AST_LIST_LOCK(&domain_list);
25321    AST_LIST_TRAVERSE(&domain_list, d, list) {
25322       if (strcasecmp(d->domain, domain))
25323          continue;
25324 
25325       if (len && !ast_strlen_zero(d->context))
25326          ast_copy_string(context, d->context, len);
25327       
25328       result = 1;
25329       break;
25330    }
25331    AST_LIST_UNLOCK(&domain_list);
25332 
25333    return result;
25334 }

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

References check_user_full().

Referenced by handle_request_options(), and handle_request_publish().

15101 {
15102    return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL);
15103 }

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

References ast_copy_string(), ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), dummy(), exten, get_header(), get_rpid(), LOG_ERROR, LOG_NOTICE, sip_cfg, SIP_PEDANTIC_DECODE, strsep(), and terminate_uri().

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

14980 {
14981    char from[256] = { 0, };
14982    char *dummy = NULL;  /* dummy return value for parse_uri */
14983    char *domain = NULL; /* dummy return value for parse_uri */
14984    char *of;
14985    enum check_auth_result res = AUTH_DONT_KNOW;
14986    char calleridname[50];
14987    char *uri2 = ast_strdupa(uri);
14988 
14989    terminate_uri(uri2); /* trim extra stuff */
14990 
14991    ast_copy_string(from, get_header(req, "From"), sizeof(from));
14992    /* XXX here tries to map the username for invite things */
14993    memset(calleridname, 0, sizeof(calleridname));
14994 
14995    /* strip the display-name portion off the beginning of the FROM header. */
14996    if (!(of = (char *) get_calleridname(from, calleridname, sizeof(calleridname)))) {
14997       ast_log(LOG_ERROR, "FROM header can not be parsed \n");
14998       return res;
14999    }
15000 
15001    if (calleridname[0])
15002       ast_string_field_set(p, cid_name, calleridname);
15003 
15004    if (ast_strlen_zero(p->exten)) {
15005       char *t = uri2;
15006       if (!strncasecmp(t, "sip:", 4))
15007          t+= 4;
15008       else if (!strncasecmp(t, "sips:", 5))
15009          t += 5;
15010       ast_string_field_set(p, exten, t);
15011       t = strchr(p->exten, '@');
15012       if (t)
15013          *t = '\0';
15014 
15015       if (ast_strlen_zero(p->our_contact))
15016          build_contact(p);
15017    }
15018 
15019    of = get_in_brackets(of);
15020 
15021    /* save the URI part of the From header */
15022    ast_string_field_set(p, from, of);
15023 
15024    /* ignore all fields but name */
15025    if (parse_uri(of, "sip:,sips:", &of, &dummy, &domain, NULL)) {
15026       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
15027    }
15028 
15029    SIP_PEDANTIC_DECODE(of);
15030    SIP_PEDANTIC_DECODE(domain);
15031 
15032    if (ast_strlen_zero(of)) {
15033       /* XXX note: the original code considered a missing @host
15034        * as a username-only URI. The SIP RFC (19.1.1) says that
15035        * this is wrong, and it should be considered as a domain-only URI.
15036        * For backward compatibility, we keep this block, but it is
15037        * really a mistake and should go away.
15038        */
15039       of = domain;
15040    } else {
15041       char *tmp = ast_strdupa(of);
15042       /* We need to be able to handle auth-headers looking like
15043          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
15044       */
15045       tmp = strsep(&tmp, ";");
15046       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
15047          ast_shrink_phone_number(tmp);
15048       ast_string_field_set(p, cid_num, tmp);
15049    }
15050 
15051    if (global_match_auth_username) {
15052       /*
15053        * XXX This is experimental code to grab the search key from the
15054        * Auth header's username instead of the 'From' name, if available.
15055        * Do not enable this block unless you understand the side effects (if any!)
15056        * Note, the search for "username" should be done in a more robust way.
15057        * Note2, at the moment we check both fields, though maybe we should
15058        * pick one or another depending on the request ? XXX
15059        */
15060       const char *hdr = get_header(req, "Authorization");
15061       if (ast_strlen_zero(hdr))
15062          hdr = get_header(req, "Proxy-Authorization");
15063 
15064       if ( !ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\"")) ) {
15065          ast_copy_string(from, hdr + strlen("username=\""), sizeof(from));
15066          of = from;
15067          of = strsep(&of, "\"");
15068       }
15069    }
15070 
15071    res = check_peer_ok(p, of, req, sipmethod, addr,
15072          authpeer, reliable, calleridname, uri2);
15073    if (res != AUTH_DONT_KNOW)
15074       return res;
15075 
15076    /* Finally, apply the guest policy */
15077    if (sip_cfg.allowguest) {
15078       get_rpid(p, req);
15079       if (!dialog_initialize_rtp(p)) {
15080          res = AUTH_SUCCESSFUL;
15081       } else {
15082          res = AUTH_RTP_FAILED;
15083       }
15084    } else if (sip_cfg.alwaysauthreject)
15085       res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
15086    else
15087       res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
15088 
15089 
15090    if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) {
15091       ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
15092    }
15093 
15094    return res;
15095 }

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

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

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

14740 {
14741    char via[512];
14742    char *c, *maddr;
14743    struct ast_sockaddr tmp;
14744    uint16_t port;
14745 
14746    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
14747 
14748    /* Work on the leftmost value of the topmost Via header */
14749    c = strchr(via, ',');
14750    if (c)
14751       *c = '\0';
14752 
14753    /* Check for rport */
14754    c = strstr(via, ";rport");
14755    if (c && (c[6] != '=')) { /* rport query, not answer */
14756       ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT);
14757       ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
14758    }
14759 
14760    /* Check for maddr */
14761    maddr = strstr(via, "maddr=");
14762    if (maddr) {
14763       maddr += 6;
14764       c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz"
14765                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]");
14766       *c = '\0';
14767    }
14768 
14769    c = strchr(via, ';');
14770    if (c)
14771       *c = '\0';
14772 
14773    c = strchr(via, ' ');
14774    if (c) {
14775       *c = '\0';
14776       c = ast_skip_blanks(c+1);
14777       if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) {
14778          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
14779          return;
14780       }
14781 
14782       if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) {
14783          p->sa = p->recv;
14784       }
14785 
14786       ast_sockaddr_resolve_first(&tmp, c, 0);
14787       port = ast_sockaddr_port(&tmp);
14788       ast_sockaddr_set_port(&p->sa,
14789                   port != 0 ? port : STANDARD_SIP_PORT);
14790 
14791       if (sip_debug_test_pvt(p)) {
14792          ast_verbose("Sending to %s (%s)\n",
14793                 ast_sockaddr_stringify(sip_real_dst(p)),
14794                 sip_nat_mode(p));
14795       }
14796    }
14797 }

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

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

14710 {
14711    char via[256];
14712    char *cur, *opts;
14713 
14714    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
14715 
14716    /* Work on the leftmost value of the topmost Via header */
14717    opts = strchr(via, ',');
14718    if (opts)
14719       *opts = '\0';
14720 
14721    /* parse all relevant options */
14722    opts = strchr(via, ';');
14723    if (!opts)
14724       return;  /* no options to parse */
14725    *opts++ = '\0';
14726    while ( (cur = strsep(&opts, ";")) ) {
14727       if (!strncmp(cur, "rport=", 6)) {
14728          int port = strtol(cur+6, NULL, 10);
14729          /* XXX add error checking */
14730          ast_sockaddr_set_port(&p->ourip, port);
14731       } else if (!strncmp(cur, "received=", 9)) {
14732          if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip))
14733             ;  /* XXX add error checking */
14734       }
14735    }
14736 }

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

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

Referenced by config_parse_variables(), and reload_config().

15784 {
15785    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
15786 
15787    while ((oldcontext = strsep(&old, "&"))) {
15788       stalecontext = '\0';
15789       ast_copy_string(newlist, new, sizeof(newlist));
15790       stringp = newlist;
15791       while ((newcontext = strsep(&stringp, "&"))) {
15792          if (!strcmp(newcontext, oldcontext)) {
15793             /* This is not the context you're looking for */
15794             stalecontext = '\0';
15795             break;
15796          } else if (strcmp(newcontext, oldcontext)) {
15797             stalecontext = oldcontext;
15798          }
15799          
15800       }
15801       if (stalecontext)
15802          ast_context_destroy(ast_context_find(stalecontext), "SIP");
15803    }
15804 }

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

Destroy all peer-related mailbox subscriptions

Definition at line 4267 of file chan_sip.c.

References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.

Referenced by set_peer_defaults(), and sip_destroy_peer().

04268 {
04269    struct sip_mailbox *mailbox;
04270 
04271    while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry)))
04272       destroy_mailbox(mailbox);
04273 }

static int clear_realm_authentication ( struct sip_auth *  authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 25404 of file chan_sip.c.

References ast_free.

Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().

25405 {
25406    struct sip_auth *a = authlist;
25407    struct sip_auth *b;
25408 
25409    while (a) {
25410       b = a;
25411       a = a->next;
25412       ast_free(b);
25413    }
25414 
25415    return 1;
25416 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

25338 {
25339    struct domain *d;
25340 
25341    AST_LIST_LOCK(&domain_list);
25342    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
25343       ast_free(d);
25344    AST_LIST_UNLOCK(&domain_list);
25345 }

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

Do completion on peer name.

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

17180 {
17181    char *result = NULL;
17182    int wordlen = strlen(word);
17183    int which = 0;
17184    struct ao2_iterator i = ao2_iterator_init(peers, 0);
17185    struct sip_peer *peer;
17186 
17187    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
17188       /* locking of the object is not required because only the name and flags are being compared */
17189       if (!strncasecmp(word, peer->name, wordlen) &&
17190             (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
17191             ++which > state)
17192          result = ast_strdup(peer->name);
17193       unref_peer(peer, "toss iterator peer ptr before break");
17194       if (result) {
17195          break;
17196       }
17197    }
17198    ao2_iterator_destroy(&i);
17199    return result;
17200 }

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

Do completion on registered peer name.

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

17204 {
17205        char *result = NULL;
17206        int wordlen = strlen(word);
17207        int which = 0;
17208        struct ao2_iterator i;
17209        struct sip_peer *peer;
17210        
17211        i = ao2_iterator_init(peers, 0);
17212        while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
17213           if (!strncasecmp(word, peer->name, wordlen) &&
17214          (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
17215          ++which > state && peer->expire > 0)
17216              result = ast_strdup(peer->name);
17217           if (result) {
17218              unref_peer(peer, "toss iterator peer ptr before break");
17219              break;
17220           }
17221           unref_peer(peer, "toss iterator peer ptr");
17222        }
17223        ao2_iterator_destroy(&i);
17224        return result;
17225 }

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

References complete_sipch().

Referenced by sip_show_history().

17229 {
17230    if (pos == 3)
17231       return complete_sipch(line, word, pos, state);
17232 
17233    return NULL;
17234 }

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

References complete_sip_peer().

Referenced by sip_qualify_peer(), and sip_show_peer().

17238 {
17239    if (pos == 3) {
17240       return complete_sip_peer(word, state, 0);
17241    }
17242 
17243    return NULL;
17244 }

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

References complete_sip_user().

Referenced by sip_show_user().

16481 {
16482    if (pos == 3)
16483       return complete_sip_user(word, state);
16484 
16485    return NULL;
16486 }

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

References complete_sip_registered_peer().

Referenced by sip_unregister().

17248 {
17249        if (pos == 2)
17250                return complete_sip_registered_peer(word, state, 0);
17251 
17252        return NULL;
17253 }

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

Do completion on user name.

Definition at line 16453 of file chan_sip.c.

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

Referenced by complete_sip_show_user().

16454 {
16455    char *result = NULL;
16456    int wordlen = strlen(word);
16457    int which = 0;
16458    struct ao2_iterator user_iter;
16459    struct sip_peer *user;
16460 
16461    user_iter = ao2_iterator_init(peers, 0);
16462    while ((user = ao2_iterator_next(&user_iter))) {
16463       ao2_lock(user);
16464       if (!(user->type & SIP_TYPE_USER)) {
16465          ao2_unlock(user);
16466          unref_peer(user, "complete sip user");
16467          continue;
16468       }
16469       /* locking of the object is not required because only the name and flags are being compared */
16470       if (!strncasecmp(word, user->name, wordlen) && ++which > state) {
16471          result = ast_strdup(user->name);
16472       }
16473       ao2_unlock(user);
16474       unref_peer(user, "complete sip user");
16475    }
16476    ao2_iterator_destroy(&user_iter);
16477    return result;
16478 }

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

17150 {
17151    int which=0;
17152    struct sip_pvt *cur;
17153    char *c = NULL;
17154    int wordlen = strlen(word);
17155    struct ao2_iterator i;
17156 
17157    if (pos != 3) {
17158       return NULL;
17159    }
17160 
17161    i = ao2_iterator_init(dialogs, 0);
17162    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
17163       sip_pvt_lock(cur);
17164       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
17165          c = ast_strdup(cur->callid);
17166          sip_pvt_unlock(cur);
17167          dialog_unref(cur, "drop ref in iterator loop break");
17168          break;
17169       }
17170       sip_pvt_unlock(cur);
17171       dialog_unref(cur, "drop ref in iterator loop");
17172    }
17173    ao2_iterator_destroy(&i);
17174    return c;
17175 }

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

Support routine for 'sip notify' CLI.

Definition at line 17256 of file chan_sip.c.

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

Referenced by sip_cli_notify().

17257 {
17258    char *c = NULL;
17259 
17260    if (pos == 2) {
17261       int which = 0;
17262       char *cat = NULL;
17263       int wordlen = strlen(word);
17264 
17265       /* do completion for notify type */
17266 
17267       if (!notify_types)
17268          return NULL;
17269       
17270       while ( (cat = ast_category_browse(notify_types, cat)) ) {
17271          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
17272             c = ast_strdup(cat);
17273             break;
17274          }
17275       }
17276       return c;
17277    }
17278 
17279    if (pos > 2)
17280       return complete_sip_peer(word, state, 0);
17281 
17282    return NULL;
17283 }

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

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

01902 {
01903    struct ast_str *body = ast_str_alloca(size);
01904    char tuple_id[32];
01905 
01906    generate_random_string(tuple_id, sizeof(tuple_id));
01907 
01908    /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF
01909     * body gets a lot more extra junk that isn't necessary, so we'll leave it out here.
01910     */
01911    ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
01912    /* XXX The entity attribute is currently set to the peer name associated with the
01913     * dialog. This is because we currently only call this function for call-completion
01914     * PUBLISH bodies. In such cases, the entity is completely disregarded. For other
01915     * event packages, it may be crucial to have a proper URI as the presentity so this
01916     * should be revisited as support is expanded.
01917     */
01918    ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity);
01919    ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id);
01920    ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed");
01921    ast_str_append(&body, 0, "</tuple>\n");
01922    ast_str_append(&body, 0, "</presence>\n");
01923    ast_copy_string(pidf_body, ast_str_buffer(body), size);
01924    return 0;
01925 }

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

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

Referenced by respprep().

09128 {
09129    int start = 0;
09130    int copied = 0;
09131    for (;;) {
09132       const char *tmp = __get_header(orig, field, &start);
09133 
09134       if (ast_strlen_zero(tmp))
09135          break;
09136       /* Add what we're responding to */
09137       add_header(req, field, tmp);
09138       copied++;
09139    }
09140    return copied ? 0 : -1;
09141 }

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

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

Referenced by reqprep(), and respprep().

09117 {
09118    const char *tmp = get_header(orig, field);
09119 
09120    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
09121       return add_header(req, field, tmp);
09122    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
09123    return -1;
09124 }

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

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

Referenced by _sip_tcp_helper_thread(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), queue_request(), sip_park(), and sip_park_thread().

10793 {
10794    /* XXX this function can encounter memory allocation errors, perhaps it
10795     * should return a value */
10796 
10797    struct ast_str *duplicate = dst->data;
10798    struct ast_str *duplicate_content = dst->content;
10799 
10800    /* copy the entire request then restore the original data and content
10801     * members from the dst request */
10802    memcpy(dst, src, sizeof(*dst));
10803    dst->data = duplicate;
10804    dst->content = duplicate_content;
10805 
10806    /* copy the data into the dst request */
10807    if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1)))
10808       return;
10809    ast_str_copy_string(&dst->data, src->data);
10810 
10811    /* copy the content into the dst request (if it exists) */
10812    if (src->content) {
10813       if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1)))
10814          return;
10815       ast_str_copy_string(&dst->content, src->content);
10816    }
10817 }

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

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

04732 {
04733    if (to_sock->tcptls_session) {
04734       ao2_ref(to_sock->tcptls_session, -1);
04735       to_sock->tcptls_session = NULL;
04736    }
04737 
04738    if (from_sock->tcptls_session) {
04739       ao2_ref(from_sock->tcptls_session, +1);
04740    }
04741 
04742    *to_sock = *from_sock;
04743 }

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

duplicate a list of channel variables,

Returns:
the copy.

Definition at line 2280 of file chan_sip.c.

References ast_variable_new(), and ast_variable::next.

02281 {
02282    struct ast_variable *res = NULL, *tmp, *v = NULL;
02283 
02284    for (v = src ; v ; v = v->next) {
02285       if ((tmp = ast_variable_new(v->name, v->value, v->file))) {
02286          tmp->next = res;
02287          res = tmp;
02288       }
02289    }
02290    return res;
02291 }

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

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

Referenced by respprep().

09152 {
09153    int copied = 0;
09154    int start = 0;
09155 
09156    for (;;) {
09157       char new[512];
09158       const char *oh = __get_header(orig, field, &start);
09159 
09160       if (ast_strlen_zero(oh))
09161          break;
09162 
09163       if (!copied) { /* Only check for empty rport in topmost via header */
09164          char leftmost[512], *others, *rport;
09165 
09166          /* Only work on leftmost value */
09167          ast_copy_string(leftmost, oh, sizeof(leftmost));
09168          others = strchr(leftmost, ',');
09169          if (others)
09170              *others++ = '\0';
09171 
09172          /* Find ;rport;  (empty request) */
09173          rport = strstr(leftmost, ";rport");
09174          if (rport && *(rport+6) == '=')
09175             rport = NULL;     /* We already have a parameter to rport */
09176 
09177          if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) {
09178             /* We need to add received port - rport */
09179             char *end;
09180 
09181             rport = strstr(leftmost, ";rport");
09182 
09183             if (rport) {
09184                end = strchr(rport + 1, ';');
09185                if (end)
09186                   memmove(rport, end, strlen(end) + 1);
09187                else
09188                   *rport = '\0';
09189             }
09190 
09191             /* Add rport to first VIA header if requested */
09192             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
09193                leftmost, ast_sockaddr_stringify_addr(&p->recv),
09194                ast_sockaddr_port(&p->recv),
09195                others ? "," : "", others ? others : "");
09196          } else {
09197             /* We should *always* add a received to the topmost via */
09198             snprintf(new, sizeof(new), "%s;received=%s%s%s",
09199                leftmost, ast_sockaddr_stringify_addr(&p->recv),
09200                others ? "," : "", others ? others : "");
09201          }
09202          oh = new;   /* the header to copy */
09203       }  /* else add the following via headers untouched */
09204       add_header(req, field, oh);
09205       copied++;
09206    }
09207    if (!copied) {
09208       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
09209       return -1;
09210    }
09211    return 0;
09212 }

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

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

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

Definition at line 4949 of file chan_sip.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_srv(), ast_log(), AST_NONSTANDARD_RAW_ARGS, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_strdupa, ast_string_field_set, bindaddr, create_addr_from_peer(), 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().

04950 {
04951    struct sip_peer *peer;
04952    char *peername, *peername2, *hostn;
04953    char host[MAXHOSTNAMELEN];
04954    char service[MAXHOSTNAMELEN];
04955    int srv_ret = 0;
04956    int tportno;
04957 
04958    AST_DECLARE_APP_ARGS(hostport,
04959       AST_APP_ARG(host);
04960       AST_APP_ARG(port);
04961    );
04962 
04963    peername = ast_strdupa(opeer);
04964    peername2 = ast_strdupa(opeer);
04965    AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':');
04966 
04967    if (hostport.port)
04968       dialog->portinuri = 1;
04969 
04970    dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
04971    dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
04972    peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
04973 
04974    if (peer) {
04975       int res;
04976       if (newdialog) {
04977          set_socket_transport(&dialog->socket, 0);
04978       }
04979       res = create_addr_from_peer(dialog, peer);
04980       if (!ast_sockaddr_isnull(remote_address)) {
04981          ast_sockaddr_copy(&dialog->sa, remote_address);
04982       }
04983       dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer");
04984       unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup");
04985       return res;
04986    }
04987 
04988    if (dialog_initialize_rtp(dialog)) {
04989       return -1;
04990    }
04991 
04992    ast_string_field_set(dialog, tohost, hostport.host);
04993    dialog->allowed_methods &= ~sip_cfg.disallowed_methods;
04994 
04995    /* Get the outbound proxy information */
04996    ref_proxy(dialog, obproxy_get(dialog, NULL));
04997 
04998    if (addr) {
04999       /* This address should be updated using dnsmgr */
05000       ast_sockaddr_copy(&dialog->sa, addr);
05001    } else {
05002 
05003       /* Let's see if we can find the host in DNS. First try DNS SRV records,
05004          then hostname lookup */
05005       /*! \todo Fix this function. When we ask for SRV, we should check all transports
05006            In the future, we should first check NAPTR to find out transport preference
05007        */
05008       hostn = peername;
05009       /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then
05010        * an A record lookup should be used instead of SRV.
05011        */
05012       if (!hostport.port && sip_cfg.srvlookup) {
05013          snprintf(service, sizeof(service), "_%s._%s.%s", 
05014              get_srv_service(dialog->socket.type),
05015              get_srv_protocol(dialog->socket.type), peername);
05016          if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno,
05017                      service)) > 0) {
05018             hostn = host;
05019          }
05020       }
05021 
05022       if (ast_sockaddr_resolve_first(&dialog->sa, hostn, 0)) {
05023          ast_log(LOG_WARNING, "No such host: %s\n", peername);
05024       }
05025 
05026       if (srv_ret > 0) {
05027          ast_sockaddr_set_port(&dialog->sa, tportno);
05028       }
05029    }
05030 
05031    if (!dialog->socket.type)
05032       set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP);
05033    if (!dialog->socket.port) {
05034       dialog->socket.port = htons(ast_sockaddr_port(&bindaddr));
05035    }
05036 
05037    if (!ast_sockaddr_port(&dialog->sa)) {
05038       ast_sockaddr_set_port(&dialog->sa,
05039                   (dialog->socket.type == SIP_TRANSPORT_TLS) ?
05040                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
05041    }
05042    ast_sockaddr_copy(&dialog->recv, &dialog->sa);
05043    return 0;
05044 }

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

References accountcode, ao2_t_link, ao2_t_unlink, ast_cc_copy_config_params(), ast_clear_flag, ast_copy_flags, ast_debug, ast_duplicate_ha_list(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify_host(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_new_with_bindaddr(), bindaddr, check_request_transport, cid_name, cid_num, context, copy_socket_data(), copy_vars(), dialog_initialize_rtp(), language, mohinterpret, mohsuggest, obproxy_get(), parkinglot, ref_proxy(), and set_t38_capabilities().

Referenced by create_addr(), and sip_send_mwi_to_peer().

04804 {
04805    /* this checks that the dialog is contacting the peer on a valid
04806     * transport type based on the peers transport configuration,
04807     * otherwise, this function bails out */
04808    if (dialog->socket.type && check_request_transport(peer, dialog))
04809       return -1;
04810    copy_socket_data(&dialog->socket, &peer->socket);
04811 
04812    if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) &&
04813        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
04814       dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr;
04815       dialog->recv = dialog->sa;
04816    } else
04817       return -1;
04818 
04819    /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */
04820    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
04821    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
04822    ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
04823    dialog->capability = peer->capability;
04824    dialog->prefs = peer->prefs;
04825    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
04826       /* t38pt_udptl was enabled in the peer and not in [general] */
04827       if (dialog->udptl || (!dialog->udptl && (dialog->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr)))) {
04828          dialog->t38_maxdatagram = peer->t38_maxdatagram;
04829          set_t38_capabilities(dialog);
04830       } else {
04831          /* It is impossible to support T38 without udptl */
04832          ast_debug(1, "UDPTL creation failed on dialog.\n");
04833          ast_clear_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT);
04834       }
04835    } else if (dialog->udptl) {
04836       ast_udptl_destroy(dialog->udptl);
04837       dialog->udptl = NULL;
04838    }
04839 
04840    ast_string_field_set(dialog, engine, peer->engine);
04841 
04842    if (dialog_initialize_rtp(dialog)) {
04843       return -1;
04844    }
04845 
04846    if (dialog->rtp) { /* Audio */
04847       ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04848       ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04849       ast_rtp_instance_set_timeout(dialog->rtp, peer->rtptimeout);
04850       ast_rtp_instance_set_hold_timeout(dialog->rtp, peer->rtpholdtimeout);
04851       /* Set Frame packetization */
04852       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs);
04853       dialog->autoframing = peer->autoframing;
04854    }
04855    if (dialog->vrtp) { /* Video */
04856       ast_rtp_instance_set_timeout(dialog->vrtp, peer->rtptimeout);
04857       ast_rtp_instance_set_hold_timeout(dialog->vrtp, peer->rtpholdtimeout);
04858    }
04859    if (dialog->trtp) { /* Realtime text */
04860       ast_rtp_instance_set_timeout(dialog->trtp, peer->rtptimeout);
04861       ast_rtp_instance_set_hold_timeout(dialog->trtp, peer->rtpholdtimeout);
04862    }
04863 
04864    /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */
04865    ast_string_field_set(dialog, peername, peer->name);
04866    ast_string_field_set(dialog, authname, peer->username);
04867    ast_string_field_set(dialog, username, peer->username);
04868    ast_string_field_set(dialog, peersecret, peer->secret);
04869    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
04870    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
04871    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
04872    ast_string_field_set(dialog, tohost, peer->tohost);
04873    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
04874    ast_string_field_set(dialog, accountcode, peer->accountcode);
04875    ast_string_field_set(dialog, context, peer->context);
04876    ast_string_field_set(dialog, cid_num, peer->cid_num);
04877    ast_string_field_set(dialog, cid_name, peer->cid_name);
04878    ast_string_field_set(dialog, cid_tag, peer->cid_tag);
04879    ast_string_field_set(dialog, mwi_from, peer->mwi_from);
04880    ast_string_field_set(dialog, parkinglot, peer->parkinglot);
04881    ast_string_field_set(dialog, engine, peer->engine);
04882    ref_proxy(dialog, obproxy_get(dialog, peer));
04883    dialog->callgroup = peer->callgroup;
04884    dialog->pickupgroup = peer->pickupgroup;
04885    dialog->allowtransfer = peer->allowtransfer;
04886    dialog->jointnoncodeccapability = dialog->noncodeccapability;
04887    dialog->rtptimeout = peer->rtptimeout;
04888    dialog->peerauth = peer->auth;
04889    dialog->maxcallbitrate = peer->maxcallbitrate;
04890    dialog->disallowed_methods = peer->disallowed_methods;
04891    ast_cc_copy_config_params(dialog->cc_params, peer->cc_params);
04892    if (ast_strlen_zero(dialog->tohost))
04893       ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host(&dialog->sa));
04894    if (!ast_strlen_zero(peer->fromdomain)) {
04895       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
04896       if (!dialog->initreq.headers) {
04897          char *c;
04898          char *tmpcall = ast_strdupa(dialog->callid);
04899          /* this sure looks to me like we are going to change the callid on this dialog!! */
04900          c = strchr(tmpcall, '@');
04901          if (c) {
04902             *c = '\0';
04903             ao2_t_unlink(dialogs, dialog, "About to change the callid -- remove the old name");
04904             ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
04905             ao2_t_link(dialogs, dialog, "New dialog callid -- inserted back into table");
04906          }
04907       }
04908    }
04909    if (!ast_strlen_zero(peer->fromuser))
04910       ast_string_field_set(dialog, fromuser, peer->fromuser);
04911    if (!ast_strlen_zero(peer->language))
04912       ast_string_field_set(dialog, language, peer->language);
04913    /* Set timer T1 to RTT for this peer (if known by qualify=) */
04914    /* Minimum is settable or default to 100 ms */
04915    /* If there is a maxms and lastms from a qualify use that over a manual T1
04916       value. Otherwise, use the peer's T1 value. */
04917    if (peer->maxms && peer->lastms)
04918       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
04919    else
04920       dialog->timer_t1 = peer->timer_t1;
04921 
04922    /* Set timer B to control transaction timeouts, the peer setting is the default and overrides
04923       the known timer */
04924    if (peer->timer_b)
04925       dialog->timer_b = peer->timer_b;
04926    else
04927       dialog->timer_b = 64 * dialog->timer_t1;
04928 
04929    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
04930        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
04931       dialog->noncodeccapability |= AST_RTP_DTMF;
04932    else
04933       dialog->noncodeccapability &= ~AST_RTP_DTMF;
04934    dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha);
04935    if (peer->call_limit)
04936       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
04937    if (!dialog->portinuri)
04938       dialog->portinuri = peer->portinuri;
04939    dialog->chanvars = copy_vars(peer->chanvars);
04940    if (peer->fromdomainport)
04941       dialog->fromdomainport = peer->fromdomainport;
04942 
04943    return 0;
04944 }

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

Definition at line 900 of file chan_sip.c.

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

Referenced by sip_cc_monitor_suspend().

00901 {
00902    struct sip_epa_entry *epa_entry;
00903    const struct epa_static_data *static_data;
00904 
00905    if (!(static_data = find_static_data(event_package))) {
00906       return NULL;
00907    }
00908 
00909    if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) {
00910       return NULL;
00911    }
00912 
00913    epa_entry->static_data = static_data;
00914    ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination));
00915    return epa_entry;
00916 }

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

01027 {
01028    struct sip_esc_entry *esc_entry;
01029    int expires_ms;
01030 
01031    if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) {
01032       return NULL;
01033    }
01034 
01035    esc_entry->event = esc->name;
01036 
01037    expires_ms = expires * 1000;
01038    /* Bump refcount for scheduler */
01039    ao2_ref(esc_entry, +1);
01040    esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry);
01041 
01042    /* Note: This links the esc_entry into the ESC properly */
01043    create_new_sip_etag(esc_entry, 0);
01044 
01045    return esc_entry;
01046 }

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

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

01014 {
01015    int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1);
01016    struct event_state_compositor *esc = get_esc(esc_entry->event);
01017 
01018    ast_assert(esc != NULL);
01019    if (is_linked) {
01020       ao2_unlink(esc->compositor, esc_entry);
01021    }
01022    snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag);
01023    ao2_link(esc->compositor, esc_entry);
01024 }

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

Deinitialize SIP response/request.

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

09371 {
09372    if (req->data) {
09373       ast_free(req->data);
09374       req->data = NULL;
09375    }
09376    if (req->content) {
09377       ast_free(req->content);
09378       req->content = NULL;
09379    }
09380 }

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

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

Definition at line 12664 of file chan_sip.c.

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

Referenced by build_peer(), expire_register(), and parse_register_contact().

12665 {
12666    int realtimeregs = ast_check_realtime("sipregs");
12667    char *tablename = (realtimeregs) ? "sipregs" : "sippeers";
12668 
12669    if (!sip_cfg.ignore_regexpire) {
12670       if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
12671          ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", peer->deprecated_username ? "username" : "defaultuser", "", "regserver", "", "useragent", "", "lastms", "", SENTINEL);
12672       } else {
12673          ast_db_del("SIP/Registry", peer->name);
12674          ast_db_del("SIP/PeerMethods", peer->name);
12675       }
12676    }
12677 }

static void destroy_escs ( void   )  [static]

Definition at line 1060 of file chan_sip.c.

References ao2_ref, ARRAY_LEN, and event_state_compositors.

Referenced by unload_module().

01061 {
01062    int i;
01063    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01064       ao2_ref(event_state_compositors[i].compositor, -1);
01065    }
01066 }

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

Destroy mailbox subscriptions

Definition at line 4259 of file chan_sip.c.

References ast_event_unsubscribe(), and ast_free.

Referenced by build_peer(), and clear_peer_mailboxes().

04260 {
04261    if (mailbox->event_sub)
04262       ast_event_unsubscribe(mailbox->event_sub);
04263    ast_free(mailbox);
04264 }

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

Parse first line of incoming SIP request.

Definition at line 10889 of file chan_sip.c.

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

Referenced by parse_request().

10890 {
10891    char *e = ast_skip_blanks(req->data->str);   /* there shouldn't be any */
10892    char *local_rlPart1;
10893 
10894    if (!*e)
10895       return -1;
10896    req->rlPart1 = e - req->data->str;  /* method or protocol */
10897    local_rlPart1 = e;
10898    e = ast_skip_nonblanks(e);
10899    if (*e)
10900       *e++ = '\0';
10901    /* Get URI or status code */
10902    e = ast_skip_blanks(e);
10903    if ( !*e )
10904       return -1;
10905    ast_trim_blanks(e);
10906 
10907    if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */
10908       if (strlen(e) < 3)   /* status code is 3 digits */
10909          return -1;
10910       req->rlPart2 = e - req->data->str;
10911    } else { /* We have a request */
10912       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
10913          ast_debug(3, "Oops. Bogus uri in <> %s\n", e);
10914          e++;
10915          if (!*e)
10916             return -1;
10917       }
10918       req->rlPart2 = e - req->data->str;  /* URI */
10919       e = ast_skip_nonblanks(e);
10920       if (*e)
10921          *e++ = '\0';
10922       e = ast_skip_blanks(e);
10923       if (strcasecmp(e, "SIP/2.0") ) {
10924          ast_debug(3, "Skipping packet - Bad request protocol %s\n", e);
10925          return -1;
10926       }
10927    }
10928    return 1;
10929 }

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

References ast_assert, and ast_strlen_zero().

Referenced by handle_request_publish().

22394 {
22395    int etag_present = !ast_strlen_zero(etag);
22396    int body_present = req->lines > 0;
22397 
22398    ast_assert(expires_int != NULL);
22399 
22400    if (ast_strlen_zero(expires)) {
22401       /* Section 6, item 4, second bullet point of RFC 3903 says to
22402        * use a locally-configured default expiration if none is provided
22403        * in the request
22404        */
22405       *expires_int = DEFAULT_PUBLISH_EXPIRES;
22406    } else if (sscanf(expires, "%30d", expires_int) != 1) {
22407       return SIP_PUBLISH_UNKNOWN;
22408    }
22409 
22410    if (*expires_int == 0) {
22411       return SIP_PUBLISH_REMOVE;
22412    } else if (!etag_present && body_present) {
22413       return SIP_PUBLISH_INITIAL;
22414    } else if (etag_present && !body_present) {
22415       return SIP_PUBLISH_REFRESH;
22416    } else if (etag_present && body_present) {
22417       return SIP_PUBLISH_MODIFY;
22418    }
22419 
22420    return SIP_PUBLISH_UNKNOWN;
22421 }

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

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

28086 {
28087    struct sip_pvt *pvt = obj, *pvt2 = arg;
28088 
28089    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0;
28090 }

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

Definition at line 15699 of file chan_sip.c.

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

Referenced by sip_show_objects().

15700 {
15701    struct sip_pvt *pvt = userobj;
15702    int refc = ao2_t_ref(userobj, 0, "");
15703    struct ast_cli_args *a = (struct ast_cli_args *) arg;
15704    
15705    ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n",
15706       pvt->callid, 0, refc);
15707    return 0;
15708 }

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

References CMP_MATCH.

Referenced by find_call().

28076 {
28077    struct sip_pvt *pvt = obj, *pvt2 = arg;
28078 
28079    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0;
28080 }

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

References ast_str_case_hash().

Referenced by load_module().

28066 {
28067    const struct sip_pvt *pvt = obj;
28068 
28069    return ast_str_case_hash(pvt->callid);
28070 }

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

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

04749 {
04750    struct ast_sockaddr bindaddr_tmp;
04751 
04752    if (!sip_methods[dialog->method].need_rtp) {
04753       return 0;
04754    }
04755 
04756    ast_sockaddr_copy(&bindaddr_tmp, &bindaddr);
04757    if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
04758       return -1;
04759    }
04760 
04761    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
04762          (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) {
04763       if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
04764          return -1;
04765       }
04766       ast_rtp_instance_set_timeout(dialog->vrtp, global_rtptimeout);
04767       ast_rtp_instance_set_hold_timeout(dialog->vrtp, global_rtpholdtimeout);
04768 
04769       ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1);
04770    }
04771 
04772    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) {
04773       if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
04774          return -1;
04775       }
04776       ast_rtp_instance_set_timeout(dialog->trtp, global_rtptimeout);
04777       ast_rtp_instance_set_hold_timeout(dialog->trtp, global_rtpholdtimeout);
04778 
04779       ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1);
04780    }
04781 
04782    ast_rtp_instance_set_timeout(dialog->rtp, global_rtptimeout);
04783    ast_rtp_instance_set_hold_timeout(dialog->rtp, global_rtpholdtimeout);
04784 
04785    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1);
04786    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04787    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04788 
04789    ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP");
04790 
04791    do_setnat(dialog);
04792 
04793    return 0;
04794 }

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. It will return CMP_MATCH for candidates, and they will be unlinked.

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

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

Referenced by do_monitor().

15819 {
15820    struct sip_pvt *dialog = dialogobj;
15821    time_t *t = arg;
15822 
15823    if (sip_pvt_trylock(dialog)) {
15824       /* Don't block the monitor thread.  This function is called often enough
15825        * that we can wait for the next time around. */
15826       return 0;
15827    }
15828 
15829    /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
15830    if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
15831       ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
15832       sip_pvt_unlock(dialog);
15833       return 0;
15834    }
15835 
15836    if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) {
15837       ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
15838       sip_pvt_unlock(dialog);
15839       return 0;
15840    }
15841 
15842    /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
15843    check_rtp_timeout(dialog, *t);
15844 
15845    /* If we have sessions that needs to be destroyed, do it now */
15846    /* Check if we have outstanding requests not responsed to or an active call
15847       - if that's the case, wait with destruction */
15848    if (dialog->needdestroy && !dialog->packets && !dialog->owner) {
15849       /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
15850       if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
15851          ast_debug(2, "Bridge still active.  Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
15852          sip_pvt_unlock(dialog);
15853          return 0;
15854       }
15855       
15856       if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) {
15857          ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
15858          sip_pvt_unlock(dialog);
15859          return 0;
15860       }
15861 
15862       sip_pvt_unlock(dialog);
15863       /* no, the unlink should handle this: dialog_unref(dialog, "needdestroy: one more refcount decrement to allow dialog to be destroyed"); */
15864       /* the CMP_MATCH will unlink this dialog from the dialog hash table */
15865       dialog_unlink_all(dialog, TRUE, FALSE);
15866       return 0; /* the unlink_all should unlink this from the table, so.... no need to return a match */
15867    }
15868 
15869    sip_pvt_unlock(dialog);
15870 
15871    return 0;
15872 }

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

Definition at line 2172 of file chan_sip.c.

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

02173 {
02174    if (p)
02175 #ifdef REF_DEBUG
02176       __ao2_ref_debug(p, 1, tag, file, line, func);
02177 #else
02178       ao2_ref(p, 1);
02179 #endif
02180    else
02181       ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
02182    return p;
02183 }

void* dialog_unlink_all ( struct sip_pvt *  dialog,
int  lockowner,
int  lockdialoglist 
)

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

References ao2_t_unlink, ast_channel_lock, ast_channel_unlock, ast_debug, ast_extension_state_del(), ast_free, AST_SCHED_DEL, AST_SCHED_DEL_UNREF, and registry_unref().

Referenced by __sip_autodestruct(), __sip_subscribe_mwi_do(), dialog_needdestroy(), handle_request_subscribe(), manager_sipnotify(), reload_config(), 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().

02703 {
02704    struct sip_pkt *cp;
02705 
02706    dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done");
02707 
02708    ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
02709 
02710    /* Unlink us from the owner (channel) if we have one */
02711    if (dialog->owner) {
02712       if (lockowner)
02713          ast_channel_lock(dialog->owner);
02714       ast_debug(1, "Detaching from channel %s\n", dialog->owner->name);
02715       dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
02716       if (lockowner) {
02717          ast_channel_unlock(dialog->owner);
02718       }
02719    }
02720    if (dialog->registry) {
02721       if (dialog->registry->call == dialog) {
02722          dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
02723       }
02724       dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
02725    }
02726    if (dialog->stateid > -1) {
02727       ast_extension_state_del(dialog->stateid, NULL);
02728       dialog_unref(dialog, "removing extension_state, should unref the associated dialog ptr that was stored there.");
02729       dialog->stateid = -1; /* shouldn't we 'zero' this out? */
02730    }
02731    /* Remove link from peer to subscription of MWI */
02732    if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) {
02733       dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
02734    }
02735    if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) {
02736       dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
02737    }
02738 
02739    /* remove all current packets in this dialog */
02740    while((cp = dialog->packets)) {
02741       dialog->packets = dialog->packets->next;
02742       AST_SCHED_DEL(sched, cp->retransid);
02743       dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy");
02744       if (cp->data) {
02745          ast_free(cp->data);
02746       }
02747       ast_free(cp);
02748    }
02749 
02750    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"));
02751 
02752    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"));
02753    
02754    if (dialog->autokillid > -1) {
02755       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"));
02756    }
02757 
02758    if (dialog->request_queue_sched_id > -1) {
02759       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"));
02760    }
02761 
02762    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"));
02763 
02764    if (dialog->t38id > -1) {
02765       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"));
02766    }
02767 
02768    dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
02769    return NULL;
02770 }

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

Definition at line 2185 of file chan_sip.c.

References __ao2_ref_debug(), and ao2_ref.

02186 {
02187    if (p)
02188 #ifdef REF_DEBUG
02189       __ao2_ref_debug(p, -1, tag, file, line, func);
02190 #else
02191       ao2_ref(p, -1);
02192 #endif
02193    return NULL;
02194 }

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

Definition at line 3971 of file chan_sip.c.

References ast_dsp_free().

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

03972 {
03973    if (p->dsp) {
03974       ast_dsp_free(p->dsp);
03975       p->dsp = NULL;
03976    }
03977 }

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

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

Referenced by handle_request_invite().

20698 {
20699    struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2);
20700    struct ast_app *pickup = pbx_findapp("Pickup");
20701 
20702    if (!pickup) {
20703       ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n");
20704       return -1;
20705    }
20706 
20707    ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context);
20708 
20709    ast_debug(2, "About to call Pickup(%s)\n", str->str);
20710 
20711    /* There is no point in capturing the return value since pickup_exec
20712       doesn't return anything meaningful unless the passed data is an empty
20713       string (which in our case it will not be) */
20714    pbx_exec(channel, pickup, str->str);
20715 
20716    return 0;
20717 }

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

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

24232 {
24233    int res;
24234    time_t t;
24235    int reloading;
24236 
24237    /* Add an I/O event to our SIP UDP socket */
24238    if (sipsock > -1)
24239       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
24240 
24241    /* From here on out, we die whenever asked */
24242    for(;;) {
24243       /* Check for a reload request */
24244       ast_mutex_lock(&sip_reload_lock);
24245       reloading = sip_reloading;
24246       sip_reloading = FALSE;
24247       ast_mutex_unlock(&sip_reload_lock);
24248       if (reloading) {
24249          ast_verb(1, "Reloading SIP\n");
24250          sip_do_reload(sip_reloadreason);
24251 
24252          /* Change the I/O fd of our UDP socket */
24253          if (sipsock > -1) {
24254             if (sipsock_read_id)
24255                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
24256             else
24257                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
24258          } else if (sipsock_read_id) {
24259             ast_io_remove(io, sipsock_read_id);
24260             sipsock_read_id = NULL;
24261          }
24262       }
24263 
24264       /* Check for dialogs needing to be killed */
24265       t = time(NULL);
24266       /* don't scan the dialogs list if it hasn't been a reasonable period
24267          of time since the last time we did it (when MWI is being sent, we can
24268          get back to this point every millisecond or less)
24269       */
24270       ao2_t_callback(dialogs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t,
24271             "callback to remove dialogs w/needdestroy");
24272 
24273       /* the old methodology would be to restart the search for dialogs to delete with every
24274          dialog that was found and destroyed, probably because the list contents would change,
24275          so we'd need to restart. This isn't the best thing to do with callbacks. */
24276 
24277       /* XXX TODO The scheduler usage in this module does not have sufficient
24278        * synchronization being done between running the scheduler and places
24279        * scheduling tasks.  As it is written, any scheduled item may not run
24280        * any sooner than about  1 second, regardless of whether a sooner time
24281        * was asked for. */
24282 
24283       pthread_testcancel();
24284       /* Wait for sched or io */
24285       res = ast_sched_wait(sched);
24286       if ((res < 0) || (res > 1000))
24287          res = 1000;
24288       res = ast_io_wait(io, res);
24289       if (res > 20)
24290          ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res);
24291       ast_mutex_lock(&monlock);
24292       res = ast_sched_runq(sched);
24293       if (res >= 20)
24294          ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res);
24295       ast_mutex_unlock(&monlock);
24296    }
24297 
24298    /* Never reached */
24299    return NULL;
24300 }

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

17918 {
17919    char *header, *respheader;
17920    char digest[1024];
17921 
17922    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
17923       return -2;
17924 
17925    p->authtries++;
17926    auth_headers(code, &header, &respheader);
17927    ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
17928    memset(digest, 0, sizeof(digest));
17929    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
17930       /* No way to authenticate */
17931       return -1;
17932    }
17933    /* Now we have a reply digest */
17934    p->options->auth = digest;
17935    p->options->authheader = respheader;
17936    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL);
17937 }

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

17894 {
17895    char *header, *respheader;
17896    char digest[1024];
17897 
17898    p->authtries++;
17899    auth_headers(code, &header, &respheader);
17900    memset(digest, 0, sizeof(digest));
17901    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
17902       /* There's nothing to use for authentication */
17903       /* No digest challenge in request */
17904       if (sip_debug_test_pvt(p) && p->registry)
17905          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
17906          /* No old challenge */
17907       return -1;
17908    }
17909    if (p->do_history)
17910       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
17911    if (sip_debug_test_pvt(p) && p->registry)
17912       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
17913    return transmit_register(p->registry, SIP_REGISTER, digest, respheader);
17914 }

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

Set nat mode on the various data sockets.

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

04643 {
04644    const char *mode;
04645    int natflags;
04646 
04647    natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
04648    mode = natflags ? "On" : "Off";
04649 
04650    if (p->rtp) {
04651       ast_debug(1, "Setting NAT on RTP to %s\n", mode);
04652       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags);
04653    }
04654    if (p->vrtp) {
04655       ast_debug(1, "Setting NAT on VRTP to %s\n", mode);
04656       ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags);
04657    }
04658    if (p->udptl) {
04659       ast_debug(1, "Setting NAT on UDPTL to %s\n", mode);
04660       ast_udptl_setnat(p->udptl, natflags);
04661    }
04662    if (p->trtp) {
04663       ast_debug(1, "Setting NAT on TRTP to %s\n", mode);
04664       ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags);
04665    }
04666 }

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

Print domain mode to cli.

Definition at line 16027 of file chan_sip.c.

Referenced by sip_show_domains().

16028 {
16029    switch (mode) {
16030    case SIP_DOMAIN_AUTO:
16031       return "[Automatic]";
16032    case SIP_DOMAIN_CONFIG:
16033       return "[Configured]";
16034    }
16035 
16036    return "";
16037 }

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

Convert DTMF mode to printable string.

Definition at line 15755 of file chan_sip.c.

References map_x_s().

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

15756 {
15757    return map_x_s(dtmfstr, mode, "<error>");
15758 }

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

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

03939 {
03940    int features = 0;
03941 
03942    if (p->dsp) {
03943       return;
03944    }
03945 
03946    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
03947             (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
03948       if (!p->rtp || ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND)) {
03949          features |= DSP_FEATURE_DIGIT_DETECT;
03950                 }
03951    }
03952 
03953    if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) {
03954       features |= DSP_FEATURE_FAX_DETECT;
03955    }
03956 
03957    if (!features) {
03958       return;
03959    }
03960 
03961    if (!(p->dsp = ast_dsp_new())) {
03962       return;
03963    }
03964 
03965    ast_dsp_set_features(p->dsp, features);
03966    if (global_relaxdtmf) {
03967       ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
03968    }
03969 }

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

Definition at line 972 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by initialize_escs().

00973 {
00974    struct sip_esc_entry *entry1 = obj;
00975    struct sip_esc_entry *entry2 = arg;
00976 
00977    return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0;
00978 }

static void esc_entry_destructor ( void *  obj  )  [static]

Definition at line 958 of file chan_sip.c.

References AST_SCHED_DEL.

Referenced by create_esc_entry().

00959 {
00960    struct sip_esc_entry *esc_entry = obj;
00961    if (esc_entry->sched_id > -1) {
00962       AST_SCHED_DEL(sched, esc_entry->sched_id);
00963    }
00964 }

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

Definition at line 966 of file chan_sip.c.

References ast_str_hash().

Referenced by initialize_escs().

00967 {
00968    const struct sip_esc_entry *entry = obj;
00969    return ast_str_hash(entry->entity_tag);
00970 }

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

Expire registration of SIP peer.

Definition at line 12693 of file chan_sip.c.

References ao2_ref, ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), 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().

12694 {
12695    struct sip_peer *peer = (struct sip_peer *)data;
12696 
12697    if (!peer) {      /* Hmmm. We have no peer. Weird. */
12698       return 0;
12699    }
12700 
12701    peer->expire = -1;
12702    peer->portinuri = 0;
12703 
12704    destroy_association(peer); /* remove registration data from storage */
12705    set_socket_transport(&peer->socket, peer->default_outbound_transport);
12706 
12707    if (peer->socket.tcptls_session) {
12708       ao2_ref(peer->socket.tcptls_session, -1);
12709       peer->socket.tcptls_session = NULL;
12710    }
12711 
12712    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
12713    register_peer_exten(peer, FALSE);   /* Remove regexten */
12714    ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
12715 
12716    /* Do we need to release this peer from memory?
12717       Only for realtime peers and autocreated peers
12718    */
12719    if (peer->is_realtime) {
12720       ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
12721    }
12722 
12723    if (peer->selfdestruct ||
12724        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
12725       unlink_peer_from_tables(peer);
12726    }
12727 
12728    /* Only clear the addr after we check for destruction.  The addr must remain
12729     * in order to unlink from the peers_by_ip container correctly */
12730    memset(&peer->addr, 0, sizeof(peer->addr));
12731 
12732    unref_peer(peer, "removing peer ref for expire_register");
12733 
12734    return 0;
12735 }

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

Check Contact: URI of SIP message.

Definition at line 10997 of file chan_sip.c.

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

Referenced by handle_incoming(), and handle_request_invite().

10998 {
10999    char stripped[SIPBUFSIZE];
11000    char *c;
11001 
11002    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
11003    c = get_in_brackets(stripped);
11004    /* Cut the URI at the at sign after the @, not in the username part */
11005    c = remove_uri_parameters(c);
11006    if (!ast_strlen_zero(c)) {
11007       ast_string_field_set(p, uri, c);
11008    }
11009 
11010 }

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

Definition at line 16191 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

16192 {
16193    return map_x_s(faxecmodes, faxec, "Unknown");
16194 }

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

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

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

09084 {
09085    char clen[10];
09086 
09087    if (req->lines) {
09088       ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n");
09089       return -1;
09090    }
09091 
09092    snprintf(clen, sizeof(clen), "%zd", ast_str_strlen(req->content));
09093    add_header(req, "Content-Length", clen);
09094 
09095    if (ast_str_strlen(req->content)) {
09096       ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content));
09097       req->len = ast_str_strlen(req->data);
09098    }
09099    req->lines = ast_str_strlen(req->content) ? 1 : 0;
09100    return 0;
09101 }

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

References aliases, and ARRAY_LEN.

06741 {
06742    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
06743    static const struct cfalias {
06744       char * const fullname;
06745       char * const shortname;
06746    } aliases[] = {
06747       { "Content-Type",  "c" },
06748       { "Content-Encoding",    "e" },
06749       { "From",       "f" },
06750       { "Call-ID",       "i" },
06751       { "Contact",       "m" },
06752       { "Content-Length",   "l" },
06753       { "Subject",       "s" },
06754       { "To",         "t" },
06755       { "Supported",     "k" },
06756       { "Refer-To",      "r" },
06757       { "Referred-By",   "b" },
06758       { "Allow-Events",  "u" },
06759       { "Event",      "o" },
06760       { "Via",     "v" },
06761       { "Accept-Contact",      "a" },
06762       { "Reject-Contact",      "j" },
06763       { "Request-Disposition", "d" },
06764       { "Session-Expires",     "x" },
06765       { "Identity",            "y" },
06766       { "Identity-Info",       "n" },
06767    };
06768    int x;
06769 
06770    for (x = 0; x < ARRAY_LEN(aliases); x++) {
06771       if (!strcasecmp(aliases[x].fullname, name))
06772          return aliases[x].shortname;
06773    }
06774 
06775    return _default;
06776 }

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

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

01653 {
01654    struct ast_cc_agent *agent = obj;
01655    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01656    struct sip_pvt *call_pvt = arg;
01657 
01658    return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0;
01659 }

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

Definition at line 4553 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by find_peer().

04554 {
04555    struct sip_peer *search = obj, *match = arg;
04556    int *which_objects = data;
04557 
04558    /* Usernames in SIP uri's are case sensitive. Domains are not */
04559    if (strcmp(search->name, match->name)) {
04560       return 0;
04561    }
04562 
04563    switch (*which_objects) {
04564    case FINDUSERS:
04565       if (!(search->type & SIP_TYPE_USER)) {
04566          return 0;
04567       }
04568       break;
04569    case FINDPEERS:
04570       if (!(search->type & SIP_TYPE_PEER)) {
04571          return 0;
04572       }
04573       break;
04574    case FINDALLDEVICES:
04575       break;
04576    }
04577 
04578    return CMP_MATCH | CMP_STOP;
04579 }

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

Definition at line 1622 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.

Referenced by find_sip_cc_agent_by_notify_uri().

01623 {
01624    struct ast_cc_agent *agent = obj;
01625    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01626    const char *uri = arg;
01627 
01628    return !strcmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
01629 }

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

Definition at line 1637 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.

Referenced by find_sip_cc_agent_by_subscribe_uri().

01638 {
01639    struct ast_cc_agent *agent = obj;
01640    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01641    const char *uri = arg;
01642 
01643    return !strcmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
01644 }

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_incoming(), sipsock_read

Definition at line 7334 of file chan_sip.c.

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

07335 {
07336    struct sip_pvt *p = NULL;
07337    char totag[128];
07338    char fromtag[128];
07339    const char *callid = get_header(req, "Call-ID");
07340    const char *from = get_header(req, "From");
07341    const char *to = get_header(req, "To");
07342    const char *cseq = get_header(req, "Cseq");
07343    struct sip_pvt *sip_pvt_ptr;
07344    unsigned int seqno;
07345    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
07346    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
07347    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
07348          ast_strlen_zero(from) || ast_strlen_zero(cseq) ||
07349          (sscanf(cseq, "%30u", &seqno) != 1)) {
07350 
07351       /* RFC 3261 section 24.4.1.   Send a 400 Bad Request if the request is malformed. */
07352       if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
07353          transmit_response_using_temp(callid, addr, 1, intended_method,
07354                        req, "400 Bad Request");
07355       }
07356       return NULL;   /* Invalid packet */
07357    }
07358 
07359    if (sip_cfg.pedanticsipchecking) {
07360       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
07361          we need more to identify a branch - so we have to check branch, from
07362          and to tags to identify a call leg.
07363          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
07364          in sip.conf
07365          */
07366       if (gettag(req, "To", totag, sizeof(totag)))
07367          req->has_to_tag = 1; /* Used in handle_request/response */
07368       gettag(req, "From", fromtag, sizeof(fromtag));
07369 
07370       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);
07371 
07372       /* All messages must always have From: tag */
07373       if (ast_strlen_zero(fromtag)) {
07374          ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
07375          return NULL;
07376       }
07377       /* reject requests that must always have a To: tag */
07378       if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) {
07379          if (req->method != SIP_ACK) {
07380             transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
07381          }
07382          ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
07383          return NULL;
07384       }
07385    }
07386 
07387    if (!sip_cfg.pedanticsipchecking) {
07388       struct sip_pvt tmp_dialog = {
07389          .callid = callid,
07390       };
07391       sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs");
07392       if (sip_pvt_ptr) {  /* well, if we don't find it-- what IS in there? */
07393          /* Found the call */
07394          sip_pvt_lock(sip_pvt_ptr);
07395          return sip_pvt_ptr;
07396       }
07397    } else { /* in pedantic mode! -- do the fancy search */
07398       struct sip_pvt tmp_dialog = {
07399          .callid = callid,
07400       };
07401       struct match_req_args args = { 0, };
07402       int found;
07403       struct ao2_iterator *iterator = ao2_t_callback(dialogs,
07404          OBJ_POINTER | OBJ_MULTIPLE,
07405          dialog_find_multiple,
07406          &tmp_dialog,
07407          "pedantic ao2_find in dialogs");
07408 
07409       args.method = req->method;
07410       args.callid = NULL; /* we already matched this. */
07411       args.totag = totag;
07412       args.fromtag = fromtag;
07413       args.seqno = seqno;
07414 
07415       /* If this is a Request, set the Via and Authorization header arguments */
07416       if (req->method != SIP_RESPONSE) {
07417          args.ruri = REQ_OFFSET_TO_STR(req, rlPart2);
07418          get_viabranch(ast_strdupa(get_header(req, "Via")), (char **) &args.viasentby, (char **) &args.viabranch);
07419          if (!ast_strlen_zero(get_header(req, "Authorization")) ||
07420             !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) {
07421             args.authentication_present = 1;
07422          }
07423       }
07424 
07425       /* Iterate a list of dialogs already matched by Call-id */
07426       while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) {
07427          found = match_req_to_dialog(sip_pvt_ptr, &args);
07428 
07429          switch (found) {
07430          case SIP_REQ_MATCH:
07431             sip_pvt_lock(sip_pvt_ptr);
07432             ao2_iterator_destroy(iterator);
07433             return sip_pvt_ptr; /* return pvt with ref */
07434          case SIP_REQ_LOOP_DETECTED:
07435             /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
07436             * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
07437             transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
07438             dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search.");
07439             ao2_iterator_destroy(iterator);
07440             return NULL;
07441          case SIP_REQ_NOT_MATCH:
07442          default:
07443             dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search");
07444          }
07445       }
07446       if (iterator) {
07447          ao2_iterator_destroy(iterator);
07448       }
07449    } /* end of pedantic mode Request/Reponse to Dialog matching */
07450 
07451    /* See if the method is capable of creating a dialog */
07452    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
07453       if (intended_method == SIP_REFER) {
07454          /* We do support REFER, but not outside of a dialog yet */
07455          transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)");
07456       } else {
07457          /* Ok, time to create a new SIP dialog object, a pvt */
07458          if ((p = sip_alloc(callid, addr, 1, intended_method, req)))  {
07459             /* Ok, we've created a dialog, let's go and process it */
07460             sip_pvt_lock(p);
07461          } else {
07462             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
07463                getting a dialog from sip_alloc.
07464    
07465                Without a dialog we can't retransmit and handle ACKs and all that, but at least
07466                send an error message.
07467    
07468                Sorry, we apologize for the inconvienience
07469             */
07470             transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error");
07471             ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
07472          }
07473       }
07474       return p; /* can be NULL */
07475    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
07476       /* A method we do not support, let's take it on the volley */
07477       transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented");
07478       ast_debug(2, "Got a request with unsupported SIP method.\n");
07479    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
07480       /* This is a request outside of a dialog that we don't know about */
07481       transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
07482       ast_debug(2, "That's odd...  Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
07483    }
07484    /* We do not respond to responses for dialogs that we don't know about, we just drop
07485       the session quickly */
07486    if (intended_method == SIP_RESPONSE)
07487       ast_debug(2, "That's odd...  Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>");
07488 
07489    return NULL;
07490 }

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

11537 {
11538    struct ast_channel *c = obj;
11539    struct sip_pvt *p = data;
11540    int res;
11541 
11542    ast_channel_lock(c);
11543 
11544    res = (c->pbx &&
11545          (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) &&
11546          (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context)));
11547 
11548    ast_channel_unlock(c);
11549 
11550    return res ? CMP_MATCH | CMP_STOP : 0;
11551 }

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

Referenced by parse_moved_contact().

04099 {
04100    char last_char = '\0';
04101    const char *s;
04102    for (s = start; *s && s != lim; last_char = *s++) {
04103       if (*s == '"' && last_char != '\\')
04104          break;
04105    }
04106    return s;
04107 }

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

04595 {
04596    struct sip_peer *p = NULL;
04597    struct sip_peer tmp_peer;
04598 
04599    if (peer) {
04600       ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
04601       p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table");
04602    } else if (addr) { /* search by addr? */
04603       ast_sockaddr_copy(&tmp_peer.addr, addr);
04604       tmp_peer.flags[0].flags = 0;
04605       tmp_peer.transports = transport;
04606       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); */
04607       if (!p) {
04608          ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT);
04609          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); */
04610          if (p) {
04611             return p;
04612          }
04613       }
04614    }
04615 
04616    if (!p && (realtime || devstate_only)) {
04617       p = realtime_peer(peer, addr, devstate_only);
04618       if (p) {
04619          switch (which_objects) {
04620          case FINDUSERS:
04621             if (!(p->type & SIP_TYPE_USER)) {
04622                unref_peer(p, "Wrong type of realtime SIP endpoint");
04623                return NULL;
04624             }
04625             break;
04626          case FINDPEERS:
04627             if (!(p->type & SIP_TYPE_PEER)) {
04628                unref_peer(p, "Wrong type of realtime SIP endpoint");
04629                return NULL;
04630             }
04631             break;
04632          case FINDALLDEVICES:
04633             break;
04634          }
04635       }
04636    }
04637 
04638    return p;
04639 }

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

Find authentication for a specific realm.

Definition at line 25419 of file chan_sip.c.

Referenced by build_reply_digest().

25420 {
25421    struct sip_auth *a;
25422 
25423    for (a = authlist; a; a = a->next) {
25424       if (!strcasecmp(a->realm, realm))
25425          break;
25426    }
25427 
25428    return a;
25429 }

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

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

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

07839 {
07840    const char *content_type;
07841    const char *content_length;
07842    const char *search;
07843    char *boundary;
07844    unsigned int x;
07845    int boundaryisquoted = FALSE;
07846    int found_application_sdp = FALSE;
07847    int found_end_of_headers = FALSE;
07848 
07849    content_length = get_header(req, "Content-Length");
07850 
07851    if (!ast_strlen_zero(content_length)) {
07852       if (sscanf(content_length, "%30u", &x) != 1) {
07853          ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
07854          return 0;
07855       }
07856 
07857       /* Content-Length of zero means there can't possibly be an
07858          SDP here, even if the Content-Type says there is */
07859       if (x == 0)
07860          return 0;
07861    }
07862 
07863    content_type = get_header(req, "Content-Type");
07864 
07865    /* if the body contains only SDP, this is easy */
07866    if (!strncasecmp(content_type, "application/sdp", 15)) {
07867       req->sdp_start = 0;
07868       req->sdp_count = req->lines;
07869       return req->lines ? 1 : 0;
07870    }
07871 
07872    /* if it's not multipart/mixed, there cannot be an SDP */
07873    if (strncasecmp(content_type, "multipart/mixed", 15))
07874       return 0;
07875 
07876    /* if there is no boundary marker, it's invalid */
07877    if ((search = strcasestr(content_type, ";boundary=")))
07878       search += 10;
07879    else if ((search = strcasestr(content_type, "; boundary=")))
07880       search += 11;
07881    else
07882       return 0;
07883 
07884    if (ast_strlen_zero(search))
07885       return 0;
07886 
07887    /* If the boundary is quoted with ", remove quote */
07888    if (*search == '\"')  {
07889       search++;
07890       boundaryisquoted = TRUE;
07891    }
07892 
07893    /* make a duplicate of the string, with two extra characters
07894       at the beginning */
07895    boundary = ast_strdupa(search - 2);
07896    boundary[0] = boundary[1] = '-';
07897    /* Remove final quote */
07898    if (boundaryisquoted)
07899       boundary[strlen(boundary) - 1] = '\0';
07900 
07901    /* search for the boundary marker, the empty line delimiting headers from
07902       sdp part and the end boundry if it exists */
07903 
07904    for (x = 0; x < (req->lines); x++) {
07905       const char *line = REQ_OFFSET_TO_STR(req, line[x]);
07906       if (!strncasecmp(line, boundary, strlen(boundary))){
07907          if (found_application_sdp && found_end_of_headers) {
07908             req->sdp_count = (x - 1) - req->sdp_start;
07909             return 1;
07910          }
07911          found_application_sdp = FALSE;
07912       }
07913       if (!strcasecmp(line, "Content-Type: application/sdp"))
07914          found_application_sdp = TRUE;
07915       
07916       if (ast_strlen_zero(line)) {
07917          if (found_application_sdp && !found_end_of_headers){
07918             req->sdp_start = x;
07919             found_end_of_headers = TRUE;
07920          }
07921       }
07922    }
07923    if (found_application_sdp && found_end_of_headers) {
07924       req->sdp_count = x - req->sdp_start;
07925       return TRUE;
07926    }
07927    return FALSE;
07928 }

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

Definition at line 1631 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_notify_uri_helper().

Referenced by get_destination().

01632 {
01633    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP");
01634    return agent;
01635 }

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

Definition at line 1661 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_callid_helper().

Referenced by add_cc_call_info_to_response().

01662 {
01663    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP");
01664    return agent;
01665 }

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

Definition at line 1646 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().

Referenced by handle_cc_subscribe().

01647 {
01648    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP");
01649    return agent;
01650 }

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

find_sip_method: Find SIP method from header

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

02913 {
02914    int i, res = 0;
02915    
02916    if (ast_strlen_zero(msg)) {
02917       return 0;
02918    }
02919    for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) {
02920       if (method_match(i, msg)) {
02921          res = sip_methods[i].id;
02922       }
02923    }
02924    return res;
02925 }

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

Definition at line 1843 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by handle_cc_notify(), and handle_response().

01844 {
01845    struct sip_monitor_instance *monitor_instance = obj;
01846    return monitor_instance->subscription_pvt == arg ? CMP_MATCH | CMP_STOP : 0;
01847 }

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

Definition at line 1849 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by cc_handle_publish_error().

01850 {
01851    struct sip_monitor_instance *monitor_instance = obj;
01852    return monitor_instance->suspension_entry == arg ? CMP_MATCH | CMP_STOP : 0;
01853 }

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

Definition at line 886 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by create_epa_entry().

00887 {
00888    const struct epa_backend *backend = NULL;
00889 
00890    AST_LIST_LOCK(&epa_static_data_list);
00891    AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) {
00892       if (!strcmp(backend->static_data->name, event_package)) {
00893          break;
00894       }
00895    }
00896    AST_LIST_UNLOCK(&epa_static_data_list);
00897    return backend ? backend->static_data : NULL;
00898 }

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

Find subscription type in array.

Definition at line 17034 of file chan_sip.c.

References ARRAY_LEN, subscription_types, and type.

Referenced by transmit_state_notify().

17035 {
17036    int i;
17037 
17038    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
17039       if (subscription_types[i].type == subtype) {
17040          return &subscription_types[i];
17041       }
17042    }
17043    return &subscription_types[0];
17044 }

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

Remove route from route list.

Definition at line 13100 of file chan_sip.c.

References ast_free.

Referenced by __sip_destroy(), and build_route().

13101 {
13102    struct sip_route *next;
13103 
13104    while (route) {
13105       next = route->next;
13106       ast_free(route);
13107       route = next;
13108    }
13109 }

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

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

18155 {
18156    if (ast_strlen_zero(data)) {
18157       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
18158       return -1;
18159    }
18160    if (check_sip_domain(data, NULL, 0))
18161       ast_copy_string(buf, data, len);
18162    else
18163       buf[0] = '\0';
18164    return 0;
18165 }

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

18096 {
18097    struct sip_pvt *p;
18098    const char *content = NULL;
18099    AST_DECLARE_APP_ARGS(args,
18100       AST_APP_ARG(header);
18101       AST_APP_ARG(number);
18102    );
18103    int i, number, start = 0;
18104 
18105    if (ast_strlen_zero(data)) {
18106       ast_log(LOG_WARNING, "This function requires a header name.\n");
18107       return -1;
18108    }
18109 
18110    ast_channel_lock(chan);
18111    if (!IS_SIP_TECH(chan->tech)) {
18112       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
18113       ast_channel_unlock(chan);
18114       return -1;
18115    }
18116 
18117    AST_STANDARD_APP_ARGS(args, data);
18118    if (!args.number) {
18119       number = 1;
18120    } else {
18121       sscanf(args.number, "%30d", &number);
18122       if (number < 1)
18123          number = 1;
18124    }
18125 
18126    p = chan->tech_pvt;
18127 
18128    /* If there is no private structure, this channel is no longer alive */
18129    if (!p) {
18130       ast_channel_unlock(chan);
18131       return -1;
18132    }
18133 
18134    for (i = 0; i < number; i++)
18135       content = __get_header(&p->initreq, args.header, &start);
18136 
18137    if (ast_strlen_zero(content)) {
18138       ast_channel_unlock(chan);
18139       return -1;
18140    }
18141 
18142    ast_copy_string(buf, content, len);
18143    ast_channel_unlock(chan);
18144 
18145    return 0;
18146 }

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

18273 {
18274    struct sip_pvt *p;
18275    static int deprecated = 0;
18276 
18277    *buf = 0;
18278    
18279    if (!data) {
18280       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
18281       return -1;
18282    }
18283 
18284    ast_channel_lock(chan);
18285    if (!IS_SIP_TECH(chan->tech)) {
18286       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
18287       ast_channel_unlock(chan);
18288       return -1;
18289    }
18290 
18291    if (deprecated++ % 20 == 0) {
18292       /* Deprecated in 1.6.1 */
18293       ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated.  Please transition to using CHANNEL().\n");
18294    }
18295 
18296    p = chan->tech_pvt;
18297 
18298    /* If there is no private structure, this channel is no longer alive */
18299    if (!p) {
18300       ast_channel_unlock(chan);
18301       return -1;
18302    }
18303 
18304    if (!strcasecmp(data, "peerip")) {
18305       ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len);
18306    } else  if (!strcasecmp(data, "recvip")) {
18307       ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len);
18308    } else  if (!strcasecmp(data, "from")) {
18309       ast_copy_string(buf, p->from, len);
18310    } else  if (!strcasecmp(data, "uri")) {
18311       ast_copy_string(buf, p->uri, len);
18312    } else  if (!strcasecmp(data, "useragent")) {
18313       ast_copy_string(buf, p->useragent, len);
18314    } else  if (!strcasecmp(data, "peername")) {
18315       ast_copy_string(buf, p->peername, len);
18316    } else if (!strcasecmp(data, "t38passthrough")) {
18317       if (p->t38.state == T38_DISABLED) {
18318          ast_copy_string(buf, "0", len);
18319       } else { /* T38 is offered or enabled in this call */
18320          ast_copy_string(buf, "1", len);
18321       }
18322    } else {
18323       ast_channel_unlock(chan);
18324       return -1;
18325    }
18326    ast_channel_unlock(chan);
18327 
18328    return 0;
18329 }

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

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

18174 {
18175    struct sip_peer *peer;
18176    char *colname;
18177 
18178    if ((colname = strchr(data, ':'))) {   /*! \todo Will be deprecated after 1.4 */
18179       static int deprecation_warning = 0;
18180       *colname++ = '\0';
18181       if (deprecation_warning++ % 10 == 0)
18182          ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated.  Please use ',' instead.\n");
18183    } else if ((colname = strchr(data, ',')))
18184       *colname++ = '\0';
18185    else
18186       colname = "ip";
18187 
18188    if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0)))
18189       return -1;
18190 
18191    if (!strcasecmp(colname, "ip")) {
18192       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
18193    } else  if (!strcasecmp(colname, "port")) {
18194       snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr));
18195    } else  if (!strcasecmp(colname, "status")) {
18196       peer_status(peer, buf, len);
18197    } else  if (!strcasecmp(colname, "language")) {
18198       ast_copy_string(buf, peer->language, len);
18199    } else  if (!strcasecmp(colname, "regexten")) {
18200       ast_copy_string(buf, peer->regexten, len);
18201    } else  if (!strcasecmp(colname, "limit")) {
18202       snprintf(buf, len, "%d", peer->call_limit);
18203    } else  if (!strcasecmp(colname, "busylevel")) {
18204       snprintf(buf, len, "%d", peer->busy_level);
18205    } else  if (!strcasecmp(colname, "curcalls")) {
18206       snprintf(buf, len, "%d", peer->inUse);
18207    } else if (!strcasecmp(colname, "maxforwards")) {
18208       snprintf(buf, len, "%d", peer->maxforwards);
18209    } else  if (!strcasecmp(colname, "accountcode")) {
18210       ast_copy_string(buf, peer->accountcode, len);
18211    } else  if (!strcasecmp(colname, "callgroup")) {
18212       ast_print_group(buf, len, peer->callgroup);
18213    } else  if (!strcasecmp(colname, "pickupgroup")) {
18214       ast_print_group(buf, len, peer->pickupgroup);
18215    } else  if (!strcasecmp(colname, "useragent")) {
18216       ast_copy_string(buf, peer->useragent, len);
18217    } else  if (!strcasecmp(colname, "mailbox")) {
18218       struct ast_str *mailbox_str = ast_str_alloca(512);
18219       peer_mailboxes_to_str(&mailbox_str, peer);
18220       ast_copy_string(buf, mailbox_str->str, len);
18221    } else  if (!strcasecmp(colname, "context")) {
18222       ast_copy_string(buf, peer->context, len);
18223    } else  if (!strcasecmp(colname, "expire")) {
18224       snprintf(buf, len, "%d", peer->expire);
18225    } else  if (!strcasecmp(colname, "dynamic")) {
18226       ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len);
18227    } else  if (!strcasecmp(colname, "callerid_name")) {
18228       ast_copy_string(buf, peer->cid_name, len);
18229    } else  if (!strcasecmp(colname, "callerid_num")) {
18230       ast_copy_string(buf, peer->cid_num, len);
18231    } else  if (!strcasecmp(colname, "codecs")) {
18232       ast_getformatname_multiple(buf, len -1, peer->capability);
18233    } else if (!strcasecmp(colname, "encryption")) {
18234       snprintf(buf, len, "%d", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP));
18235    } else  if (!strncasecmp(colname, "chanvar[", 8)) {
18236       char *chanvar=colname + 8;
18237       struct ast_variable *v;
18238    
18239       chanvar = strsep(&chanvar, "]");
18240       for (v = peer->chanvars ; v ; v = v->next) {
18241          if (!strcasecmp(v->name, chanvar)) {
18242             ast_copy_string(buf, v->value, len);
18243          }
18244       }
18245    } else  if (!strncasecmp(colname, "codec[", 6)) {
18246       char *codecnum;
18247       format_t codec = 0;
18248       
18249       codecnum = colname + 6; /* move past the '[' */
18250       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
18251       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
18252          ast_copy_string(buf, ast_getformatname(codec), len);
18253       } else {
18254          buf[0] = '\0';
18255       }
18256    } else {
18257       buf[0] = '\0';
18258    }
18259 
18260    unref_peer(peer, "unref_peer from function_sippeer, just before return");
18261 
18262    return 0;
18263 }

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

Generate 32 byte random string for callid's etc.

Definition at line 6957 of file chan_sip.c.

References ast_random().

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

06958 {
06959    long val[4];
06960    int x;
06961 
06962    for (x=0; x<4; x++)
06963       val[x] = ast_random();
06964    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
06965 
06966    return buf;
06967 }

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

Definition at line 6969 of file chan_sip.c.

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

06970 {
06971    struct ast_str *uri = ast_str_alloca(size);
06972    ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:");
06973    /* Here would be a great place to generate a UUID, but for now we'll
06974     * use the handy random string generation function we already have
06975     */
06976    ast_str_append(&uri, 0, "%s", generate_random_string(buf, size));
06977    ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify(&pvt->ourip));
06978    ast_copy_string(buf, ast_str_buffer(uri), size);
06979    return buf;
06980 }

int get_address_family_filter ( const struct ast_sockaddr addr  )  [static]

Helper for dns resolution to filter by address family.

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

Definition at line 23938 of file chan_sip.c.

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

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

23939 {
23940    if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) {
23941       return 0;
23942    }
23943 
23944    return addr->ss.ss_family;
23945 }

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

Referenced by handle_request_bye().

14645 {
14646    char tmp[256] = "", *c, *a;
14647    struct sip_request *req = oreq ? oreq : &p->initreq;
14648    struct sip_refer *referdata = NULL;
14649    const char *transfer_context = NULL;
14650    
14651    if (!p->refer && !sip_refer_allocate(p))
14652       return -1;
14653 
14654    referdata = p->refer;
14655 
14656    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
14657    c = get_in_brackets(tmp);
14658 
14659    if (parse_uri(c, "sip:,sips:", &c, NULL, &a, NULL)) {
14660       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
14661       return -1;
14662    }
14663    
14664    SIP_PEDANTIC_DECODE(c);
14665    SIP_PEDANTIC_DECODE(a);
14666 
14667    if (!ast_strlen_zero(a)) {
14668       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
14669    }
14670 
14671    if (sip_debug_test_pvt(p))
14672       ast_verbose("Looking for %s in %s\n", c, p->context);
14673 
14674    if (p->owner)  /* Mimic behaviour in res_features.c */
14675       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
14676 
14677    /* By default, use the context in the channel sending the REFER */
14678    if (ast_strlen_zero(transfer_context)) {
14679       transfer_context = S_OR(p->owner->macrocontext,
14680                S_OR(p->context, sip_cfg.default_context));
14681    }
14682    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
14683       /* This is a blind transfer */
14684       ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
14685       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
14686       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
14687       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
14688       referdata->refer_call = dialog_unref(referdata->refer_call, "unreffing referdata->refer_call");
14689       /* Set new context */
14690       ast_string_field_set(p, context, transfer_context);
14691       return 0;
14692    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
14693       return 1;
14694    }
14695 
14696    return -1;
14697 }

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

Get a specific line from the message body.

Definition at line 6724 of file chan_sip.c.

References get_body_by_line(), and len().

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

06725 {
06726    int x;
06727    int len = strlen(name);
06728    char *r;
06729 
06730    for (x = 0; x < req->lines; x++) {
06731       r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter);
06732       if (r[0] != '\0')
06733          return r;
06734    }
06735 
06736    return "";
06737 }

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

References ast_skip_blanks().

Referenced by get_body(), and get_sdp_iterate().

06670 {
06671    if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter)
06672       return ast_skip_blanks(line + nameLen + 1);
06673 
06674    return "";
06675 }

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

Get cached MWI info.

Return values:
0 At least one message is waiting
1 no messages waiting

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

24082 {
24083    struct sip_mailbox *mailbox;
24084 
24085    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
24086       struct ast_event *event;
24087       event = ast_event_get_cached(AST_EVENT_MWI,
24088          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
24089          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
24090          AST_EVENT_IE_END);
24091       if (!event)
24092          continue;
24093       *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
24094       *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
24095       ast_event_destroy(event);
24096    }
24097 
24098    return (*new || *old) ? 0 : 1;
24099 }

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

Definition at line 10382 of file chan_sip.c.

References ast_log(), and LOG_WARNING.

Referenced by add_sdp().

10383 {
10384    /* Set encryption properties */
10385    if (srtp) {
10386       if (!srtp->crypto) {
10387          srtp->crypto = sdp_crypto_setup();
10388       }
10389       if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) {
10390          *a_crypto = sdp_crypto_attrib(srtp->crypto);
10391       }
10392 
10393       if (!*a_crypto) {
10394          ast_log(LOG_WARNING, "No SRTP key management enabled\n");
10395       }
10396    }
10397 }

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

References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, check_sip_domain(), context, ast_cc_agent::core_id, ast_cc_agent::device_name, dummy(), exten, find_sip_cc_agent_by_notify_uri(), get_header(), LOG_WARNING, ast_cc_agent::private_data, 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().

14231 {
14232    char tmp[256] = "", *uri, *domain, *dummy = NULL;
14233    char tmpf[256] = "", *from = NULL;
14234    struct sip_request *req;
14235    char *decoded_uri;
14236 
14237    req = oreq;
14238    if (!req) {
14239       req = &p->initreq;
14240    }
14241 
14242    /* Find the request URI */
14243    if (req->rlPart2)
14244       ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp));
14245    
14246    uri = ast_strdupa(get_in_brackets(tmp));
14247 
14248    if (parse_uri(uri, "sip:,sips:", &uri, &dummy, &domain, NULL)) {
14249       ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
14250       return SIP_GET_DEST_INVALID_URI;
14251    }
14252 
14253    SIP_PEDANTIC_DECODE(domain);
14254    SIP_PEDANTIC_DECODE(uri);
14255 
14256    ast_string_field_set(p, domain, domain);
14257 
14258    /* Now find the From: caller ID and name */
14259    /* XXX Why is this done in get_destination? Isn't it already done?
14260       Needs to be checked
14261         */
14262    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
14263    if (!ast_strlen_zero(tmpf)) {
14264       from = get_in_brackets(tmpf);
14265       if (parse_uri(from, "sip:,sips:", &from, NULL, &domain, NULL)) {
14266          ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from);
14267          return SIP_GET_DEST_INVALID_URI;
14268       }
14269 
14270       SIP_PEDANTIC_DECODE(from);
14271       SIP_PEDANTIC_DECODE(domain);
14272 
14273       ast_string_field_set(p, fromdomain, domain);
14274    }
14275 
14276    if (!AST_LIST_EMPTY(&domain_list)) {
14277       char domain_context[AST_MAX_EXTENSION];
14278 
14279       domain_context[0] = '\0';
14280       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
14281          if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
14282             ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
14283             return SIP_GET_DEST_REFUSED;
14284          }
14285       }
14286       /* If we don't have a peer (i.e. we're a guest call),
14287        * overwrite the original context */
14288       if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) {
14289          ast_string_field_set(p, context, domain_context);
14290       }
14291    }
14292 
14293    /* If the request coming in is a subscription and subscribecontext has been specified use it */
14294    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) {
14295       ast_string_field_set(p, context, p->subscribecontext);
14296    }
14297 
14298    if (sip_debug_test_pvt(p)) {
14299       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
14300    }
14301 
14302    /* If this is a subscription we actually just need to see if a hint exists for the extension */
14303    if (req->method == SIP_SUBSCRIBE) {
14304       char hint[AST_MAX_EXTENSION];
14305       return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ?
14306          SIP_GET_DEST_EXTEN_FOUND :
14307          SIP_GET_DEST_EXTEN_NOT_FOUND);
14308    } else {
14309       struct ast_cc_agent *agent;
14310       decoded_uri = ast_strdupa(uri);
14311       ast_uri_decode(decoded_uri);
14312       /* Check the dialplan for the username part of the request URI,
14313          the domain will be stored in the SIPDOMAIN variable
14314          Since extensions.conf can have unescaped characters, try matching a decoded
14315          uri in addition to the non-decoded uri
14316          Return 0 if we have a matching extension */
14317       if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) ||
14318          ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) ||
14319           !strcmp(decoded_uri, ast_pickup_ext())) {
14320          if (!oreq) {
14321             ast_string_field_set(p, exten, decoded_uri);
14322          }
14323          return SIP_GET_DEST_EXTEN_FOUND;
14324       } else if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) {
14325          struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
14326          /* This is a CC recall. We can set p's extension to the exten from
14327           * the original INVITE
14328           */
14329          ast_string_field_set(p, exten, agent_pvt->original_exten);
14330          /* And we need to let the CC core know that the caller is attempting
14331           * his recall
14332           */
14333          ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall",
14334                agent->device_name);
14335          if (cc_recall_core_id) {
14336             *cc_recall_core_id = agent->core_id;
14337          }
14338          ao2_ref(agent, -1);
14339          return SIP_GET_DEST_EXTEN_FOUND;
14340       }
14341    }
14342 
14343    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
14344    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) &&
14345        ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) ||
14346        !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) {
14347       return SIP_GET_DEST_PICKUP_EXTEN_FOUND;
14348    }
14349 
14350    return SIP_GET_DEST_EXTEN_NOT_FOUND;
14351 }

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

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

Referenced by get_realm().

09890 {
09891    char tmpf[256];
09892    char *a, *from;
09893 
09894    *domain = '\0';
09895    ast_copy_string(tmpf, str, sizeof(tmpf));
09896    from = get_in_brackets(tmpf);
09897    if (!ast_strlen_zero(from)) {
09898       if (strncasecmp(from, "sip:", 4)) {
09899          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
09900          return -1;
09901       }
09902       from += 4;
09903    } else
09904       from = NULL;
09905 
09906    if (from) {
09907       int bracket = 0;
09908 
09909       /* Strip any params or options from user */
09910       if ((a = strchr(from, ';')))
09911          *a = '\0';
09912       /* Strip port from domain if present */
09913       for (a = from; *a != '\0'; ++a) {
09914          if (*a == ':' && bracket == 0) {
09915             *a = '\0';
09916             break;
09917          } else if (*a == '[') {
09918             ++bracket;
09919          } else if (*a == ']') {
09920             --bracket;
09921          }
09922       }
09923       if ((a = strchr(from, '@'))) {
09924          *a = '\0';
09925          ast_copy_string(domain, a + 1, len);
09926       } else
09927          ast_copy_string(domain, from, len);
09928    }
09929 
09930    return ast_strlen_zero(domain);
09931 }

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

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

00980                                                                                 {
00981    int i;
00982    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
00983       if (!strcasecmp(event_package, event_state_compositors[i].name)) {
00984          return &event_state_compositors[i];
00985       }
00986    }
00987    return NULL;
00988 }

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

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

00990                                                                                                         {
00991    struct sip_esc_entry *entry;
00992    struct sip_esc_entry finder;
00993 
00994    ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag));
00995 
00996    entry = ao2_find(esc->compositor, &finder, OBJ_POINTER);
00997 
00998    return entry;
00999 }

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

References __get_header().

06818 {
06819    int start = 0;
06820    return __get_header(req, name, &start);
06821 }

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

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

04342 {
04343    struct ast_variable *var = NULL;
04344    struct ast_flags flags = {0};
04345    char *cat = NULL;
04346    const char *insecure;
04347    while ((cat = ast_category_browse(cfg, cat))) {
04348       insecure = ast_variable_retrieve(cfg, cat, "insecure");
04349       set_insecure_flags(&flags, insecure, -1);
04350       if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
04351          var = ast_category_root(cfg, cat);
04352          break;
04353       }
04354    }
04355    return var;
04356 }

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

07932 {
07933    const char *m;
07934    const char *c;
07935    int miterator = req->sdp_start;
07936    int citerator = req->sdp_start;
07937    int x = 0;
07938    int numberofports;
07939    int len;
07940    int af;
07941    char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */
07942 
07943    c = get_sdp_iterate(&citerator, req, "c");
07944    if (sscanf(c, "IN %3s %256s", proto, host) != 2) {
07945          ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
07946          /* Continue since there may be a valid host in a c= line specific to the audio stream */
07947    }
07948    /* We only want the m and c lines for audio */
07949    for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) {
07950       if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
07951           (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) ||
07952          (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
07953           (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) {
07954          /* See if there's a c= line for this media stream.
07955           * XXX There is no guarantee that we'll be grabbing the c= line for this
07956           * particular media stream here. However, this is the same logic used in process_sdp.
07957           */
07958          c = get_sdp_iterate(&citerator, req, "c");
07959          if (!ast_strlen_zero(c)) {
07960             sscanf(c, "IN %3s %256s", proto, host);
07961          }
07962          break;
07963       }
07964    }
07965 
07966    if (!strcmp("IP4", proto)) {
07967       af = AF_INET;
07968    } else if (!strcmp("IP6", proto)) {
07969       af = AF_INET6;
07970    } else {
07971       ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
07972       return -1;
07973    }
07974 
07975    if (ast_strlen_zero(host) || x == 0) {
07976       ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video");
07977       return -1;
07978    }
07979 
07980    if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
07981       ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video");
07982       return -1;
07983    }
07984 
07985    return 0;
07986 }

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

Get text out of a SIP MESSAGE packet.

Definition at line 15106 of file chan_sip.c.

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

15107 {
15108    int x;
15109    int y;
15110 
15111    buf[0] = '\0';
15112    /*XXX isn't strlen(buf) going to always be 0? */
15113    y = len - strlen(buf) - 5;
15114    if (y < 0)
15115       y = 0;
15116    for (x = 0; x < req->lines; x++) {
15117       const char *line = REQ_OFFSET_TO_STR(req, line[x]);
15118       strncat(buf, line, y); /* safe */
15119       y -= strlen(line) + 1;
15120       if (y < 0)
15121          y = 0;
15122       if (y != 0 && addnewline)
15123          strcat(buf, "\n"); /* safe */
15124    }
15125    return 0;
15126 }

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

Definition at line 4358 of file chan_sip.c.

References ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by realtime_peer().

04359 {
04360    struct ast_variable *tmp;
04361    for (tmp = var; tmp; tmp = tmp->next) {
04362       if (!newpeername && !strcasecmp(tmp->name, "name"))
04363          newpeername = tmp->value;
04364    }
04365    return newpeername;
04366 }

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

10293 {
10294    int use_externip = 0;
10295 
10296    /* First, get our address */
10297    ast_rtp_instance_get_local_address(p->rtp, addr);
10298    if (p->vrtp) {
10299       ast_rtp_instance_get_local_address(p->vrtp, vaddr);
10300    }
10301    if (p->trtp) {
10302       ast_rtp_instance_get_local_address(p->trtp, taddr);
10303    }
10304 
10305    /* If our real IP differs from the local address returned by the RTP engine, use it. */
10306    /* The premise is that if we are already using that IP to communicate with the client, */
10307    /* we should be using it for RTP too. */
10308         use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr);
10309 
10310    /* Now, try to figure out where we want them to send data */
10311    /* Is this a re-invite to move the media out, then use the original offer from caller  */
10312    if (!ast_sockaddr_isnull(&p->redirip)) {  /* If we have a redirection IP, use it */
10313       ast_sockaddr_copy(dest, &p->redirip);
10314    } else {
10315       /*
10316        * Audio Destination IP:
10317        *
10318        * 1. Specifically configured media address.
10319        * 2. Local address as specified by the RTP engine.
10320        * 3. The local IP as defined by chan_sip.
10321        *
10322        * Audio Destination Port:
10323        *
10324        * 1. Provided by the RTP engine.
10325        */
10326       ast_sockaddr_copy(dest,
10327               !ast_sockaddr_isnull(&media_address) ? &media_address :
10328               !ast_sockaddr_is_any(addr) && !use_externip ? addr    :
10329               &p->ourip);
10330       ast_sockaddr_set_port(dest, ast_sockaddr_port(addr));
10331    }
10332 
10333    if (needvideo) {
10334       /* Determine video destination */
10335       if (!ast_sockaddr_isnull(&p->vredirip)) {
10336          ast_sockaddr_copy(vdest, &p->vredirip);
10337       } else {
10338          /*
10339           * Video Destination IP:
10340           *
10341           * 1. Specifically configured media address.
10342           * 2. Local address as specified by the RTP engine.
10343           * 3. The local IP as defined by chan_sip.
10344           *
10345           * Video Destination Port:
10346           *
10347           * 1. Provided by the RTP engine.
10348           */
10349          ast_sockaddr_copy(vdest,
10350                  !ast_sockaddr_isnull(&media_address) ? &media_address :
10351                  !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr  :
10352                  &p->ourip);
10353          ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr));
10354       }
10355    }
10356 
10357    if (needtext) {
10358       /* Determine text destination */
10359       if (!ast_sockaddr_isnull(&p->tredirip)) {
10360          ast_sockaddr_copy(tdest, &p->tredirip);
10361       } else {
10362          /*
10363           * Text Destination IP:
10364           *
10365           * 1. Specifically configured media address.
10366           * 2. Local address as specified by the RTP engine.
10367           * 3. The local IP as defined by chan_sip.
10368           *
10369           * Text Destination Port:
10370           *
10371           * 1. Provided by the RTP engine.
10372           */
10373          ast_sockaddr_copy(tdest,
10374                  !ast_sockaddr_isnull(&media_address) ? &media_address  :
10375                  !ast_sockaddr_is_any(taddr) && !use_externip ? taddr   :
10376                  &p->ourip);
10377          ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr));
10378       }
10379    }
10380 }

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

References ast_copy_string(), 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_skip_blanks(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), cid_name, cid_num, and get_header().

Referenced by get_rpid().

13952 {
13953    char pai[256];
13954    char privacy[64];
13955    char *cid_num = "";
13956    char *cid_name = "";
13957    int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
13958    char *start = NULL, *end = NULL, *uri = NULL;
13959 
13960    ast_copy_string(pai, get_header(req, "P-Asserted-Identity"), sizeof(pai));
13961 
13962    if (ast_strlen_zero(pai)) {
13963       return 0;
13964    }
13965 
13966    start = pai;
13967    if (*start == '"') {
13968       *start++ = '\0';
13969       end = strchr(start, '"');
13970       if (!end) {
13971          return 0;
13972       }
13973       *end++ = '\0';
13974       cid_name = start;
13975       start = ast_skip_blanks(end);
13976    }
13977 
13978    if (*start != '<')
13979       return 0;
13980    /* At this point, 'start' points to the URI in brackets.
13981     * We need a copy so that our comparison to the anonymous
13982     * URI is valid.
13983     */
13984    uri = ast_strdupa(start);
13985    *start++ = '\0';
13986    end = strchr(start, '@');
13987    if (!end) {
13988       return 0;
13989    }
13990    *end++ = '\0';
13991    if (!strncasecmp(uri, "anonymous@anonymous.invalid", 27)) {
13992       callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
13993       /*XXX Assume no change in cid_num. Perhaps it should be
13994        * blanked?
13995        */
13996       cid_num = (char *)p->cid_num;
13997    } else if (!strncasecmp(start, "sip:", 4)) {
13998       cid_num = start + 4;
13999       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num))
14000          ast_shrink_phone_number(cid_num);
14001       start = end;
14002 
14003       end = strchr(start, '>');
14004       if (!end) {
14005          return 0;
14006       }
14007       *end = '\0';
14008    } else {
14009       return 0;
14010    }
14011 
14012    ast_copy_string(privacy, get_header(req, "Privacy"), sizeof(privacy));
14013    if (!ast_strlen_zero(privacy) && strncmp(privacy, "id", 2)) {
14014       callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
14015    }
14016 
14017    /* Only return true if the supplied caller id is different */
14018    if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) {
14019       return 0;
14020    }
14021 
14022    ast_string_field_set(p, cid_num, cid_num);
14023    ast_string_field_set(p, cid_name, cid_name);
14024    p->callingpres = callingpres;
14025 
14026    if (p->owner) {
14027       ast_set_callerid(p->owner, cid_num, cid_name, NULL);
14028       p->owner->caller.id.name.presentation = callingpres;
14029       p->owner->caller.id.number.presentation = callingpres;
14030    }
14031 
14032    return 1;
14033 }

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

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

Referenced by change_redirecting_information().

14137 {
14138    char tmp[256], *exten, *rexten, *rdomain, *rname = NULL;
14139    char *params, *reason_param = NULL;
14140    struct sip_request *req;
14141 
14142    req = oreq ? oreq : &p->initreq;
14143 
14144    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
14145    if (ast_strlen_zero(tmp))
14146       return -1;
14147 
14148    if ((params = strchr(tmp, '>'))) {
14149       params = strchr(params, ';');
14150    }
14151 
14152    exten = get_in_brackets(tmp);
14153    if (!strncasecmp(exten, "sip:", 4)) {
14154       exten += 4;
14155    } else if (!strncasecmp(exten, "sips:", 5)) {
14156       exten += 5;
14157    } else {
14158       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", exten);
14159       return -1;
14160    }
14161 
14162    /* Get diversion-reason param if present */
14163    if (params) {
14164       *params = '\0';   /* Cut off parameters  */
14165       params++;
14166       while (*params == ';' || *params == ' ')
14167          params++;
14168       /* Check if we have a reason parameter */
14169       if ((reason_param = strcasestr(params, "reason="))) {
14170          char *end;
14171          reason_param+=7;
14172          if ((end = strchr(reason_param, ';'))) {
14173             *end = '\0';
14174          }
14175          /* Remove enclosing double-quotes */
14176          if (*reason_param == '"')
14177             ast_strip_quoted(reason_param, "\"", "\"");
14178          if (!ast_strlen_zero(reason_param)) {
14179             sip_set_redirstr(p, reason_param);
14180             if (p->owner) {
14181                pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause);
14182                pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param);
14183             }
14184          }
14185       }
14186    }
14187 
14188    rdomain = exten;
14189    rexten = strsep(&rdomain, "@");  /* trim anything after @ */
14190    if (p->owner)
14191       pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain);
14192 
14193    if (sip_debug_test_pvt(p))
14194       ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, reason ? reason_param : "");
14195 
14196    /*ast_string_field_set(p, rdnis, rexten);*/
14197 
14198    if (*tmp == '\"') {
14199       char *end_quote;
14200       rname = tmp + 1;
14201       end_quote = strchr(rname, '\"');
14202       *end_quote = '\0';
14203    }
14204 
14205    if (number) {
14206       *number = ast_strdup(rexten);
14207    }
14208 
14209    if (name && rname) {
14210       *name = ast_strdup(rname);
14211    }
14212 
14213    if (reason && !ast_strlen_zero(reason_param)) {
14214       *reason = sip_reason_str_to_code(reason_param);
14215    }
14216 
14217    return 0;
14218 }

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

09938 {
09939    char domain[MAXHOSTNAMELEN];
09940 
09941    if (!ast_strlen_zero(p->realm))
09942       return;
09943 
09944    if (sip_cfg.domainsasrealm &&
09945        !AST_LIST_EMPTY(&domain_list))
09946    {
09947       /* Check From header first */
09948       if (!get_domain(get_header(req, "From"), domain, sizeof(domain))) {
09949          if (check_sip_domain(domain, NULL, 0)) {
09950             ast_string_field_set(p, realm, domain);
09951             return;
09952          }
09953       }
09954       /* Check To header */
09955       if (!get_domain(get_header(req, "To"), domain, sizeof(domain))) {
09956          if (check_sip_domain(domain, NULL, 0)) {
09957             ast_string_field_set(p, realm, domain);
09958             return;
09959          }
09960       }
09961    }
09962    
09963    /* Use default realm from config file */
09964    ast_string_field_set(p, realm, sip_cfg.realm);
09965 }

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 14445 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(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and strcasestr().

Referenced by handle_request_refer().

14446 {
14447 
14448    const char *p_referred_by = NULL;
14449    char *h_refer_to = NULL;
14450    char *h_referred_by = NULL;
14451    char *refer_to;
14452    const char *p_refer_to;
14453    char *referred_by_uri = NULL;
14454    char *ptr;
14455    struct sip_request *req = NULL;
14456    const char *transfer_context = NULL;
14457    struct sip_refer *referdata;
14458 
14459 
14460    req = outgoing_req;
14461    referdata = transferer->refer;
14462 
14463    if (!req) {
14464       req = &transferer->initreq;
14465    }
14466 
14467    p_refer_to = get_header(req, "Refer-To");
14468    if (ast_strlen_zero(p_refer_to)) {
14469       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
14470       return -2;  /* Syntax error */
14471    }
14472    h_refer_to = ast_strdupa(p_refer_to);
14473    refer_to = get_in_brackets(h_refer_to);
14474    if (!strncasecmp(refer_to, "sip:", 4)) {
14475       refer_to += 4;       /* Skip sip: */
14476    } else if (!strncasecmp(refer_to, "sips:", 5)) {
14477       refer_to += 5;
14478    } else {
14479       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
14480       return -3;
14481    }
14482 
14483    /* Get referred by header if it exists */
14484    p_referred_by = get_header(req, "Referred-By");
14485 
14486    /* Give useful transfer information to the dialplan */
14487    if (transferer->owner) {
14488       struct ast_channel *peer = ast_bridged_channel(transferer->owner);
14489       if (peer) {
14490          pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context);
14491          pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by);
14492       }
14493    }
14494 
14495    if (!ast_strlen_zero(p_referred_by)) {
14496       char *lessthan;
14497       h_referred_by = ast_strdupa(p_referred_by);
14498 
14499       /* Store referrer's caller ID name */
14500       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
14501       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
14502          *(lessthan - 1) = '\0'; /* Space */
14503       }
14504 
14505       referred_by_uri = get_in_brackets(h_referred_by);
14506 
14507       if (!strncasecmp(referred_by_uri, "sip:", 4)) {
14508          referred_by_uri += 4;      /* Skip sip: */
14509       } else if (!strncasecmp(referred_by_uri, "sips:", 5)) {
14510          referred_by_uri += 5;      /* Skip sips: */
14511       } else {
14512          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
14513          referred_by_uri = NULL;
14514       }
14515    }
14516 
14517    /* Check for arguments in the refer_to header */
14518    if ((ptr = strcasestr(refer_to, "replaces="))) {
14519       char *to = NULL, *from = NULL;
14520       
14521       /* This is an attended transfer */
14522       referdata->attendedtransfer = 1;
14523       ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
14524       ast_uri_decode(referdata->replaces_callid);
14525       if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
14526          *ptr++ = '\0';
14527       }
14528       
14529       if (ptr) {
14530          /* Find the different tags before we destroy the string */
14531          to = strcasestr(ptr, "to-tag=");
14532          from = strcasestr(ptr, "from-tag=");
14533       }
14534       
14535       /* Grab the to header */
14536       if (to) {
14537          ptr = to + 7;
14538          if ((to = strchr(ptr, '&'))) {
14539             *to = '\0';
14540          }
14541          if ((to = strchr(ptr, ';'))) {
14542             *to = '\0';
14543          }
14544          ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
14545       }
14546       
14547       if (from) {
14548          ptr = from + 9;
14549          if ((to = strchr(ptr, '&'))) {
14550             *to = '\0';
14551          }
14552          if ((to = strchr(ptr, ';'))) {
14553             *to = '\0';
14554          }
14555          ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
14556       }
14557       
14558       if (!sip_cfg.pedanticsipchecking) {
14559          ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
14560       } else {
14561          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>" );
14562       }
14563    }
14564    
14565    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
14566       char *urioption = NULL, *domain;
14567       int bracket = 0;
14568       *ptr++ = '\0';
14569 
14570       if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */
14571          *urioption++ = '\0';
14572       }
14573 
14574       domain = ptr;
14575 
14576       /* Remove :port */
14577       for (; *ptr != '\0'; ++ptr) {
14578          if (*ptr == ':' && bracket == 0) {
14579             *ptr = '\0';
14580             break;
14581          } else if (*ptr == '[') {
14582             ++bracket;
14583          } else if (*ptr == ']') {
14584             --bracket;
14585          }
14586       }
14587 
14588       SIP_PEDANTIC_DECODE(domain);
14589       SIP_PEDANTIC_DECODE(urioption);
14590 
14591       /* Save the domain for the dial plan */
14592       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
14593       if (urioption) {
14594          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
14595       }
14596    }
14597 
14598    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
14599       *ptr = '\0';
14600 
14601    SIP_PEDANTIC_DECODE(refer_to);
14602    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
14603    
14604    if (referred_by_uri) {
14605       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
14606          *ptr = '\0';
14607       SIP_PEDANTIC_DECODE(referred_by_uri);
14608       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
14609    } else {
14610       referdata->referred_by[0] = '\0';
14611    }
14612 
14613    /* Determine transfer context */
14614    if (transferer->owner)  /* Mimic behaviour in res_features.c */
14615       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
14616 
14617    /* By default, use the context in the channel sending the REFER */
14618    if (ast_strlen_zero(transfer_context)) {
14619       transfer_context = S_OR(transferer->owner->macrocontext,
14620                S_OR(transferer->context, sip_cfg.default_context));
14621    }
14622 
14623    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
14624    
14625    /* Either an existing extension or the parking extension */
14626    if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
14627       if (sip_debug_test_pvt(transferer)) {
14628          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
14629       }
14630       /* We are ready to transfer to the extension */
14631       return 0;
14632    }
14633    if (sip_debug_test_pvt(transferer))
14634       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
14635 
14636    /* Failure, we can't find this extension */
14637    return -1;
14638 }

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

14040 {
14041    char tmp[256];
14042    struct sip_request *req;
14043    char *cid_num = "";
14044    char *cid_name = "";
14045    int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
14046    char *privacy = "";
14047    char *screen = "";
14048    char *start, *end;
14049 
14050    if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID))
14051       return 0;
14052    req = oreq;
14053    if (!req)
14054       req = &p->initreq;
14055    ast_copy_string(tmp, get_header(req, "Remote-Party-ID"), sizeof(tmp));
14056    if (ast_strlen_zero(tmp)) {
14057       return get_pai(p, req);
14058    }
14059 
14060    start = tmp;
14061    if (*start == '"') {
14062       *start++ = '\0';
14063       end = strchr(start, '"');
14064       if (!end)
14065          return 0;
14066       *end++ = '\0';
14067       cid_name = start;
14068       start = ast_skip_blanks(end);
14069    }
14070 
14071    if (*start != '<')
14072       return 0;
14073    *start++ = '\0';
14074    end = strchr(start, '@');
14075    if (!end)
14076       return 0;
14077    *end++ = '\0';
14078    if (strncasecmp(start, "sip:", 4))
14079       return 0;
14080    cid_num = start + 4;
14081    if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num))
14082       ast_shrink_phone_number(cid_num);
14083    start = end;
14084 
14085    end = strchr(start, '>');
14086    if (!end)
14087       return 0;
14088    *end++ = '\0';
14089    if (*end) {
14090       start = end;
14091       if (*start != ';')
14092          return 0;
14093       *start++ = '\0';
14094       while (!ast_strlen_zero(start)) {
14095          end = strchr(start, ';');
14096          if (end)
14097             *end++ = '\0';
14098          if (!strncasecmp(start, "privacy=", 8))
14099             privacy = start + 8;
14100          else if (!strncasecmp(start, "screen=", 7))
14101             screen = start + 7;
14102          start = end;
14103       }
14104 
14105       if (!strcasecmp(privacy, "full")) {
14106          if (!strcasecmp(screen, "yes"))
14107             callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
14108          else if (!strcasecmp(screen, "no"))
14109             callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
14110       } else {
14111          if (!strcasecmp(screen, "yes"))
14112             callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
14113          else if (!strcasecmp(screen, "no"))
14114             callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
14115       }
14116    }
14117 
14118    /* Only return true if the supplied caller id is different */
14119    if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres)
14120       return 0;
14121 
14122    ast_string_field_set(p, cid_num, cid_num);
14123    ast_string_field_set(p, cid_name, cid_name);
14124    p->callingpres = callingpres;
14125 
14126    if (p->owner) {
14127       ast_set_callerid(p->owner, cid_num, cid_name, NULL);
14128       p->owner->caller.id.name.presentation = callingpres;
14129       p->owner->caller.id.number.presentation = callingpres;
14130    }
14131 
14132    return 1;
14133 }

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

References get_body_by_line(), and len().

06682 {
06683    int len = strlen(name);
06684 
06685    while (*start < (req->sdp_start + req->sdp_count)) {
06686       const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '=');
06687       if (r[0] != '\0')
06688          return r;
06689    }
06690 
06691    /* if the line was not found, ensure that *start points past the SDP */
06692    (*start)++;
06693 
06694    return "";
06695 }

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

References ast_skip_blanks(), and type.

Referenced by process_sdp().

06703 {
06704    char type = '\0';
06705    const char *line = NULL;
06706 
06707    if (stop > (req->sdp_start + req->sdp_count)) {
06708       stop = req->sdp_start + req->sdp_count;
06709    }
06710 
06711    while (*start < stop) {
06712       line = REQ_OFFSET_TO_STR(req, line[(*start)++]);
06713       if (line[1] == '=') {
06714          type = line[0];
06715          *value = ast_skip_blanks(line + 2);
06716          break;
06717       }
06718    }
06719 
06720    return type;
06721 }

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

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

Referenced by handle_request_invite(), and local_attended_transfer().

14357 {
14358    struct sip_pvt *sip_pvt_ptr;
14359    struct sip_pvt tmp_dialog = {
14360       .callid = callid,
14361    };
14362 
14363    if (totag) {
14364       ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
14365    }
14366 
14367    /* Search dialogs and find the match */
14368    
14369    sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table");
14370    if (sip_pvt_ptr) {
14371       /* Go ahead and lock it (and its owner) before returning */
14372       sip_pvt_lock(sip_pvt_ptr);
14373       if (sip_cfg.pedanticsipchecking) {
14374          unsigned char frommismatch = 0, tomismatch = 0;
14375 
14376          if (ast_strlen_zero(fromtag)) {
14377             sip_pvt_unlock(sip_pvt_ptr);
14378             ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n",
14379                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
14380             return NULL;
14381          }
14382 
14383          if (ast_strlen_zero(totag)) {
14384             sip_pvt_unlock(sip_pvt_ptr);
14385             ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n",
14386                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
14387             return NULL;
14388          }
14389          /* RFC 3891
14390           * > 3.  User Agent Server Behavior: Receiving a Replaces Header
14391           * > The Replaces header contains information used to match an existing
14392           * > SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
14393           * > with a Replaces header, the User Agent (UA) attempts to match this
14394           * > information with a confirmed or early dialog.  The User Agent Server
14395           * > (UAS) matches the to-tag and from-tag parameters as if they were tags
14396           * > present in an incoming request.  In other words, the to-tag parameter
14397           * > is compared to the local tag, and the from-tag parameter is compared
14398           * > to the remote tag.
14399           *
14400           * Thus, the totag is always compared to the local tag, regardless if
14401           * this our call is an incoming or outgoing call.
14402           */
14403          frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag);
14404          tomismatch = !!strcmp(totag, sip_pvt_ptr->tag);
14405 
14406          if (frommismatch || tomismatch) {
14407             sip_pvt_unlock(sip_pvt_ptr);
14408             if (frommismatch) {
14409                ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n",
14410                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
14411                     fromtag, sip_pvt_ptr->theirtag);
14412             }
14413             if (tomismatch) {
14414                ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n",
14415                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
14416                     totag, sip_pvt_ptr->tag);
14417             }
14418             return NULL;
14419          }
14420       }
14421       
14422       if (totag)
14423          ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n",
14424                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING",
14425                  sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
14426 
14427       /* deadlock avoidance... */
14428       while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
14429          sip_pvt_unlock(sip_pvt_ptr);
14430          usleep(1);
14431          sip_pvt_lock(sip_pvt_ptr);
14432       }
14433    }
14434    
14435    return sip_pvt_ptr;
14436 }

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

Return protocol string for srv dns query.

Definition at line 3034 of file chan_sip.c.

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

03035 {
03036    switch (t) {
03037    case SIP_TRANSPORT_UDP:
03038       return "udp";
03039    case SIP_TRANSPORT_TLS:
03040    case SIP_TRANSPORT_TCP:
03041       return "tcp";
03042    }
03043 
03044    return "udp";
03045 }

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

Return service string for srv dns query.

Definition at line 3048 of file chan_sip.c.

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

03049 {
03050    switch (t) {
03051    case SIP_TRANSPORT_TCP:
03052    case SIP_TRANSPORT_UDP:
03053       return "sip";
03054    case SIP_TRANSPORT_TLS:
03055       return "sips";
03056    }
03057    return "sip";
03058 }

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

Return transport as string.

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

03020 {
03021    switch (t) {
03022    case SIP_TRANSPORT_UDP:
03023       return "UDP";
03024    case SIP_TRANSPORT_TCP:
03025       return "TCP";
03026    case SIP_TRANSPORT_TLS:
03027       return "TLS";
03028    }
03029 
03030    return "UNKNOWN";
03031 }

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

Return configuration of transports for a device.

Definition at line 2998 of file chan_sip.c.

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

02998                                                                       {
02999    switch (transports) {
03000       case SIP_TRANSPORT_UDP:
03001          return "UDP";
03002       case SIP_TRANSPORT_TCP:
03003          return "TCP";
03004       case SIP_TRANSPORT_TLS:
03005          return "TLS";
03006       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP:
03007          return "TCP,UDP";
03008       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS:
03009          return "TLS,UDP";
03010       case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS:
03011          return "TLS,TCP";
03012       default:
03013          return transports ?
03014             "TLS,TCP,UDP" : "UNKNOWN"; 
03015    }
03016 }

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

References get_transport(), and set_socket_transport().

Referenced by __sip_xmit(), and build_via().

03067 {
03068    if (p->outboundproxy && p->outboundproxy->transport) {
03069       set_socket_transport(&p->socket, p->outboundproxy->transport);
03070    }
03071 
03072    return get_transport(p->socket.type);
03073 }

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

References ast_strlen_zero().

Referenced by __set_address_from_contact(), and parse_register_contact().

02977 {
02978    int res = 0;
02979 
02980    if (ast_strlen_zero(transport)) {
02981       return res;
02982    }
02983 
02984    if (!strcasecmp(transport, "udp")) {
02985       res |= SIP_TRANSPORT_UDP;
02986    }
02987    if (!strcasecmp(transport, "tcp")) {
02988       res |= SIP_TRANSPORT_TCP;
02989    }
02990    if (!strcasecmp(transport, "tls")) {
02991       res |= SIP_TRANSPORT_TLS;
02992    }
02993 
02994    return res;
02995 }

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

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

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

20252 {
20253    const char *thetag;
20254 
20255    if (!tagbuf)
20256       return NULL;
20257    tagbuf[0] = '\0';    /* reset the buffer */
20258    thetag = get_header(req, header);
20259    thetag = strcasestr(thetag, ";tag=");
20260    if (thetag) {
20261       thetag += 5;
20262       ast_copy_string(tagbuf, thetag, tagbufsize);
20263       return strsep(&tagbuf, ";");
20264    }
20265    return NULL;
20266 }

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

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

Referenced by handle_request_notify().

20269 {
20270    struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
20271          find_sip_monitor_instance_by_subscription_pvt, pvt);
20272    const char *status = get_body(req, "cc-state", ':');
20273    struct cc_epa_entry *cc_entry;
20274    char *uri;
20275 
20276    if (!monitor_instance) {
20277       transmit_response(pvt, "400 Bad Request", req);
20278       return -1;
20279    }
20280 
20281    if (ast_strlen_zero(status)) {
20282       ao2_ref(monitor_instance, -1);
20283       transmit_response(pvt, "400 Bad Request", req);
20284       return -1;
20285    }
20286 
20287    if (!strcmp(status, "queued")) {
20288       /* We've been told that we're queued. This is the endpoint's way of telling
20289        * us that it has accepted our CC request. We need to alert the core of this
20290        * development
20291        */
20292       ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name);
20293       transmit_response(pvt, "200 OK", req);
20294       ao2_ref(monitor_instance, -1);
20295       return 0;
20296    }
20297 
20298    /* It's open! Yay! */
20299    uri = get_body(req, "cc-URI", ':');
20300    if (ast_strlen_zero(uri)) {
20301       uri = get_in_brackets((char *)get_header(req, "From"));
20302    }
20303 
20304    ast_string_field_set(monitor_instance, notify_uri, uri);
20305    if (monitor_instance->suspension_entry) {
20306       cc_entry = monitor_instance->suspension_entry->instance_data;
20307       if (cc_entry->current_state == CC_CLOSED) {
20308          /* If we've created a suspension entry and the current state is closed, then that means
20309           * we got a notice from the CC core earlier to suspend monitoring, but because this particular
20310           * call leg had not yet notified us that it was ready for recall, it meant that we
20311           * could not yet send a PUBLISH. Now, however, we can.
20312           */
20313          construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body,
20314                sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
20315          transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri);
20316       } else {
20317          ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
20318       }
20319    } else {
20320       ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
20321    }
20322    ao2_ref(monitor_instance, -1);
20323    transmit_response(pvt, "200 OK", req);
20324 
20325    return 0;
20326 }

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

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

22896 {
22897    const char *uri = REQ_OFFSET_TO_STR(req, rlPart2);
22898    char *param_separator;
22899    struct ast_cc_agent *agent;
22900    struct sip_cc_agent_pvt *agent_pvt;
22901    const char *expires_str = get_header(req, "Expires");
22902    int expires = -1; /* Just need it to be non-zero */
22903 
22904    if (!ast_strlen_zero(expires_str)) {
22905       sscanf(expires_str, "%d", &expires);
22906    }
22907 
22908    if ((param_separator = strchr(uri, ';'))) {
22909       *param_separator = '\0';
22910    }
22911 
22912    if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) {
22913       if (!expires) {
22914          /* Typically, if a 0 Expires reaches us and we can't find
22915           * the corresponding agent, it means that the CC transaction
22916           * has completed and so the calling side is just trying to
22917           * clean up its subscription. We'll just respond with a
22918           * 200 OK and be done with it
22919           */
22920          transmit_response(p, "200 OK", req);
22921          return 0;
22922       }
22923       ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri);
22924       transmit_response(p, "404 Not Found", req);
22925       return -1;
22926    }
22927 
22928    agent_pvt = agent->private_data;
22929 
22930    if (!expires) {
22931       /* We got sent a SUBSCRIBE and found an agent. This means that CC
22932        * is being canceled.
22933        */
22934       ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name);
22935       transmit_response(p, "200 OK", req);
22936       ao2_ref(agent, -1);
22937       return 0;
22938    }
22939 
22940    agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog");
22941    ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE",
22942          agent->device_name);
22943    p->subscribed = CALL_COMPLETION;
22944 
22945    /* We don't send a response here. That is done in the agent's ack callback or in the
22946     * agent destructor, should a failure occur before we have responded
22947     */
22948    ao2_ref(agent, -1);
22949    return 0;
22950 }

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 25136 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(), strsep(), ast_variable::value, and word.

Referenced by build_peer(), and reload_config().

25137 {
25138    int res = 1;
25139 
25140    if (!strcasecmp(v->name, "trustrpid")) {
25141       ast_set_flag(&mask[0], SIP_TRUSTRPID);
25142       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
25143    } else if (!strcasecmp(v->name, "sendrpid")) {
25144       ast_set_flag(&mask[0], SIP_SENDRPID);
25145       if (!strcasecmp(v->value, "pai")) {
25146          ast_set_flag(&flags[0], SIP_SENDRPID_PAI);
25147       } else if (!strcasecmp(v->value, "rpid")) {
25148          ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
25149       } else if (ast_true(v->value)) {
25150          ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
25151       }
25152    } else if (!strcasecmp(v->name, "rpid_update")) {
25153       ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE);
25154       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE);
25155    } else if (!strcasecmp(v->name, "rpid_immediate")) {
25156       ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE);
25157       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE);
25158    } else if (!strcasecmp(v->name, "g726nonstandard")) {
25159       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
25160       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
25161    } else if (!strcasecmp(v->name, "useclientcode")) {
25162       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
25163       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
25164    } else if (!strcasecmp(v->name, "dtmfmode")) {
25165       ast_set_flag(&mask[0], SIP_DTMF);
25166       ast_clear_flag(&flags[0], SIP_DTMF);
25167       if (!strcasecmp(v->value, "inband"))
25168          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
25169       else if (!strcasecmp(v->value, "rfc2833"))
25170          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
25171       else if (!strcasecmp(v->value, "info"))
25172          ast_set_flag(&flags[0], SIP_DTMF_INFO);
25173       else if (!strcasecmp(v->value, "shortinfo"))
25174          ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO);
25175       else if (!strcasecmp(v->value, "auto"))
25176          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
25177       else {
25178          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
25179          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
25180       }
25181    } else if (!strcasecmp(v->name, "nat")) {
25182       ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT);
25183       if (!strcasecmp(v->value, "no")) {
25184          ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT);
25185       } else if (!strcasecmp(v->value, "force_rport")) {
25186          ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT);
25187       } else if (!strcasecmp(v->value, "yes")) {
25188          ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT);
25189          ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP);
25190          ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP);
25191       } else if (!strcasecmp(v->value, "comedia")) {
25192          ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT);
25193          ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP);
25194          ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP);
25195       }
25196    } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
25197       ast_set_flag(&mask[0], SIP_REINVITE);
25198       ast_clear_flag(&flags[0], SIP_REINVITE);
25199       if (ast_true(v->value)) {
25200          ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT);
25201       } else if (!ast_false(v->value)) {
25202          char buf[64];
25203          char *word, *next = buf;
25204 
25205          ast_copy_string(buf, v->value, sizeof(buf));
25206          while ((word = strsep(&next, ","))) {
25207             if (!strcasecmp(word, "update")) {
25208                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA);
25209             } else if (!strcasecmp(word, "nonat")) {
25210                ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
25211                ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT);
25212             } else {
25213                ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno);
25214             }
25215          }
25216       }
25217    } else if (!strcasecmp(v->name, "insecure")) {
25218       ast_set_flag(&mask[0], SIP_INSECURE);
25219       ast_clear_flag(&flags[0], SIP_INSECURE);
25220       set_insecure_flags(&flags[0], v->value, v->lineno);   
25221    } else if (!strcasecmp(v->name, "progressinband")) {
25222       ast_set_flag(&mask[0], SIP_PROG_INBAND);
25223       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
25224       if (ast_true(v->value))
25225          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
25226       else if (strcasecmp(v->value, "never"))
25227          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
25228    } else if (!strcasecmp(v->name, "promiscredir")) {
25229       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
25230       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
25231    } else if (!strcasecmp(v->name, "videosupport")) {
25232       if (!strcasecmp(v->value, "always")) {
25233          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
25234          ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
25235       } else {
25236          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
25237          ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
25238       }
25239    } else if (!strcasecmp(v->name, "textsupport")) {
25240       ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT);
25241       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT);
25242       res = 1;
25243    } else if (!strcasecmp(v->name, "allowoverlap")) {
25244       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
25245       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
25246    } else if (!strcasecmp(v->name, "allowsubscribe")) {
25247       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
25248       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
25249    } else if (!strcasecmp(v->name, "ignoresdpversion")) {
25250       ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION);
25251       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION);
25252    } else if (!strcasecmp(v->name, "faxdetect")) {
25253       ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT);
25254       if (ast_true(v->value)) {
25255          ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH);
25256       } else if (ast_false(v->value)) {
25257          ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH);
25258       } else {
25259          char *buf = ast_strdupa(v->value);
25260          char *word, *next = buf;
25261 
25262          while ((word = strsep(&next, ","))) {
25263             if (!strcasecmp(word, "cng")) {
25264                ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG);
25265             } else if (!strcasecmp(word, "t38")) {
25266                ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38);
25267             } else {
25268                ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
25269             }
25270          }
25271       }
25272    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
25273       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
25274       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
25275    } else if (!strcasecmp(v->name, "buggymwi")) {
25276       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
25277       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
25278    } else
25279       res = 0;
25280 
25281    return res;
25282 }

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

Definition at line 23392 of file chan_sip.c.

References __sip_ack(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_log(), ast_skip_blanks(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_verbose, check_pendings(), debug, 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, ast_channel::name, 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(), and transmit_response_with_allow().

Referenced by handle_request_do(), and process_request_queue().

23393 {
23394    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
23395       relatively static */
23396    const char *cmd;
23397    const char *cseq;
23398    const char *useragent;
23399    int seqno;
23400    int len;
23401    int respid;
23402    int res = 0;
23403    int debug = sip_debug_test_pvt(p);
23404    const char *e;
23405    int error = 0;
23406    int oldmethod = p->method;
23407    int acked = 0;
23408 
23409    /* Get Method and Cseq */
23410    cseq = get_header(req, "Cseq");
23411    cmd = REQ_OFFSET_TO_STR(req, header[0]);
23412 
23413    /* Must have Cseq */
23414    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
23415       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
23416       error = 1;
23417    }
23418    if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) {
23419       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
23420       error = 1;
23421    }
23422    if (error) {
23423       if (!p->initreq.headers) { /* New call */
23424          pvt_set_needdestroy(p, "no headers");
23425       }
23426       return -1;
23427    }
23428    /* Get the command XXX */
23429 
23430    cmd = REQ_OFFSET_TO_STR(req, rlPart1);
23431    e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2));
23432 
23433    /* Save useragent of the client */
23434    useragent = get_header(req, "User-Agent");
23435    if (!ast_strlen_zero(useragent))
23436       ast_string_field_set(p, useragent, useragent);
23437 
23438    /* Find out SIP method for incoming request */
23439    if (req->method == SIP_RESPONSE) {  /* Response to our request */
23440       /* ignore means "don't do anything with it" but still have to
23441        * respond appropriately.
23442        * But in this case this is a response already, so we really
23443        * have nothing to do with this message, and even setting the
23444        * ignore flag is pointless.
23445        */
23446       if (ast_strlen_zero(e)) {
23447          return 0;
23448       }
23449       if (sscanf(e, "%30d %n", &respid, &len) != 1) {
23450          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
23451          return 0;
23452       }
23453       if (respid <= 0) {
23454          ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
23455          return 0;
23456       }
23457       if (p->ocseq && (p->ocseq < seqno)) {
23458          ast_debug(1, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
23459          return -1;
23460       } else {
23461          char causevar[256], causeval[256];
23462 
23463          if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
23464             extract_uri(p, req);
23465          }
23466 
23467          handle_response(p, respid, e + len, req, seqno);
23468 
23469          if (p->owner) {
23470             struct ast_channel *owner = p->owner;
23471 
23472             snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
23473             snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
23474 
23475             ast_channel_ref(owner);
23476             sip_pvt_unlock(p);
23477             ast_channel_unlock(owner);
23478             *nounlock = 1;
23479             pbx_builtin_setvar_helper(owner, causevar, causeval);
23480             ast_channel_unref(owner);
23481             sip_pvt_lock(p);
23482          }
23483       }
23484       return 0;
23485    }
23486 
23487    /* New SIP request coming in
23488       (could be new request in existing SIP dialog as well...)
23489     */         
23490    
23491    p->method = req->method;   /* Find out which SIP method they are using */
23492    ast_debug(4, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd);
23493 
23494    if (p->icseq && (p->icseq > seqno) ) {
23495       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
23496          ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n");
23497       }  else {
23498          ast_debug(1, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
23499          if (req->method != SIP_ACK)
23500             transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
23501          return -1;
23502       }
23503    } else if (p->icseq &&
23504          p->icseq == seqno &&
23505          req->method != SIP_ACK &&
23506          (p->method != SIP_CANCEL || p->alreadygone)) {
23507       /* ignore means "don't do anything with it" but still have to
23508          respond appropriately.  We do this if we receive a repeat of
23509          the last sequence number  */
23510       req->ignore = 1;
23511       ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
23512    }
23513 
23514    /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has
23515     * already given a final response." */
23516    if (!p->pendinginvite && (req->method == SIP_CANCEL)) {
23517       transmit_response(p, "481 Call/Transaction Does Not Exist", req);
23518       return res;
23519    }
23520 
23521    if (seqno >= p->icseq)
23522       /* Next should follow monotonically (but not necessarily
23523          incrementally -- thanks again to the genius authors of SIP --
23524          increasing */
23525       p->icseq = seqno;
23526 
23527    /* Find their tag if we haven't got it */
23528    if (ast_strlen_zero(p->theirtag)) {
23529       char tag[128];
23530 
23531       gettag(req, "From", tag, sizeof(tag));
23532       ast_string_field_set(p, theirtag, tag);
23533    }
23534    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
23535 
23536    if (sip_cfg.pedanticsipchecking) {
23537       /* If this is a request packet without a from tag, it's not
23538          correct according to RFC 3261  */
23539       /* Check if this a new request in a new dialog with a totag already attached to it,
23540          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
23541       if (!p->initreq.headers && req->has_to_tag) {
23542          /* If this is a first request and it got a to-tag, it is not for us */
23543          if (!req->ignore && req->method == SIP_INVITE) {
23544             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
23545             /* Will cease to exist after ACK */
23546          } else if (req->method != SIP_ACK) {
23547             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
23548             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23549          } else {
23550             ast_debug(1, "Got ACK for unknown dialog... strange.\n");
23551          }
23552          return res;
23553       }
23554    }
23555 
23556    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) {
23557       transmit_response(p, "400 Bad request", req);
23558       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23559       return -1;
23560    }
23561 
23562    /* Handle various incoming SIP methods in requests */
23563    switch (p->method) {
23564    case SIP_OPTIONS:
23565       res = handle_request_options(p, req, addr, e);
23566       break;
23567    case SIP_INVITE:
23568       res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock);
23569       break;
23570    case SIP_REFER:
23571       res = handle_request_refer(p, req, debug, seqno, nounlock);
23572       break;
23573    case SIP_CANCEL:
23574       res = handle_request_cancel(p, req);
23575       break;
23576    case SIP_BYE:
23577       res = handle_request_bye(p, req);
23578       break;
23579    case SIP_MESSAGE:
23580       res = handle_request_message(p, req);
23581       break;
23582    case SIP_PUBLISH:
23583       res = handle_request_publish(p, req, addr, seqno, e);
23584       break;
23585    case SIP_SUBSCRIBE:
23586       res = handle_request_subscribe(p, req, addr, seqno, e);
23587       break;
23588    case SIP_REGISTER:
23589       res = handle_request_register(p, req, addr, e);
23590       break;
23591    case SIP_INFO:
23592       if (req->debug)
23593          ast_verbose("Receiving INFO!\n");
23594       if (!req->ignore)
23595          handle_request_info(p, req);
23596       else  /* if ignoring, transmit response */
23597          transmit_response(p, "200 OK", req);
23598       break;
23599    case SIP_NOTIFY:
23600       res = handle_request_notify(p, req, addr, seqno, e);
23601       break;
23602    case SIP_UPDATE:
23603       res = handle_request_update(p, req);
23604       break;
23605    case SIP_ACK:
23606       /* Make sure we don't ignore this */
23607       if (seqno == p->pendinginvite) {
23608          p->invitestate = INV_TERMINATED;
23609          p->pendinginvite = 0;
23610          acked = __sip_ack(p, seqno, 1 /* response */, 0);
23611          if (find_sdp(req)) {
23612             if (process_sdp(p, req, SDP_T38_NONE))
23613                return -1;
23614          }
23615          check_pendings(p);
23616       } else if (p->glareinvite == seqno) {
23617          /* handle ack for the 491 pending sent for glareinvite */
23618          p->glareinvite = 0;
23619          acked = __sip_ack(p, seqno, 1, 0);
23620       }
23621       if (!acked) {
23622          /* Got an ACK that did not match anything. Ignore
23623           * silently and restore previous method */
23624          p->method = oldmethod;
23625       }
23626       if (!p->lastinvite && ast_strlen_zero(p->randdata)) {
23627          pvt_set_needdestroy(p, "unmatched ACK");
23628       }
23629       break;
23630    default:
23631       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
23632       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n",
23633          cmd, ast_sockaddr_stringify(&p->sa));
23634       /* If this is some new method, and we don't have a call, destroy it now */
23635       if (!p->initreq.headers) {
23636          pvt_set_needdestroy(p, "unimplemented method");
23637       }
23638       break;
23639    }
23640    return res;
23641 }

static int handle_invite_replaces ( struct sip_pvt *  p,
struct sip_request *  req,
int  debug,
int  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 20573 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_lock, ast_channel_masquerade(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_quiet_chan(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, FALSE, ast_channel::hangupcause, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, 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().

20574 {
20575    int earlyreplace = 0;
20576    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
20577    struct ast_channel *c = p->owner;   /* Our incoming call */
20578    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
20579    struct ast_channel *targetcall;     /* The bridge to the take-over target */
20580 
20581    /* Check if we're in ring state */
20582    if (replacecall->_state == AST_STATE_RING)
20583       earlyreplace = 1;
20584 
20585    /* Check if we have a bridge */
20586    if (!(targetcall = ast_bridged_channel(replacecall))) {
20587       /* We have no bridge */
20588       if (!earlyreplace) {
20589          ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
20590          oneleggedreplace = 1;
20591       }
20592    }
20593    if (targetcall && targetcall->_state == AST_STATE_RINGING)
20594       ast_debug(4, "SIP transfer: Target channel is in ringing state\n");
20595 
20596    if (targetcall)
20597       ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name);
20598    else
20599       ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name);
20600 
20601    if (req->ignore) {
20602       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
20603       /* We should answer something here. If we are here, the
20604          call we are replacing exists, so an accepted
20605          can't harm */
20606       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
20607       /* Do something more clever here */
20608       if (c) {
20609          *nounlock = 1;
20610          ast_channel_unlock(c);
20611       }
20612       ast_channel_unlock(replacecall);
20613       sip_pvt_unlock(p->refer->refer_call);
20614       return 1;
20615    }
20616    if (!c) {
20617       /* What to do if no channel ??? */
20618       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
20619       transmit_response_reliable(p, "503 Service Unavailable", req);
20620       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
20621       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20622       ast_channel_unlock(replacecall);
20623       sip_pvt_unlock(p->refer->refer_call);
20624       return 1;
20625    }
20626    append_history(p, "Xfer", "INVITE/Replace received");
20627    /* We have three channels to play with
20628       channel c: New incoming call
20629       targetcall: Call from PBX to target
20630       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
20631       replacecall: The owner of the previous
20632       We need to masq C into refer_call to connect to
20633       targetcall;
20634       If we are talking to internal audio stream, target call is null.
20635    */
20636 
20637    /* Fake call progress */
20638    transmit_response(p, "100 Trying", req);
20639    ast_setstate(c, AST_STATE_RING);
20640 
20641    /* Masquerade the new call into the referred call to connect to target call
20642       Targetcall is not touched by the masq */
20643 
20644    /* Answer the incoming call and set channel to UP state */
20645    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
20646 
20647    ast_setstate(c, AST_STATE_UP);
20648 
20649    /* Stop music on hold and other generators */
20650    ast_quiet_chan(replacecall);
20651    ast_quiet_chan(targetcall);
20652    ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
20653 
20654    /* Make sure that the masq does not free our PVT for the old call */
20655    if (! earlyreplace && ! oneleggedreplace )
20656       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
20657 
20658    /* Prepare the masquerade - if this does not happen, we will be gone */
20659    if(ast_channel_masquerade(replacecall, c))
20660       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
20661    else
20662       ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
20663 
20664    /* C should now be in place of replacecall. all channel locks and pvt locks should be removed
20665     * before issuing the masq.  Since we are unlocking both the pvt (p) and its owner channel (c)
20666     * it is possible for channel c to be destroyed on us.  To prevent this, we must give c a reference
20667     * before any unlocking takes place and remove it only once we are completely done with it */
20668    ast_channel_ref(c);
20669    ast_channel_unlock(replacecall);
20670    ast_channel_unlock(c);
20671    sip_pvt_unlock(p->refer->refer_call);
20672    sip_pvt_unlock(p);
20673    if (ast_do_masquerade(replacecall)) {
20674       ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n");
20675    }
20676    ast_channel_lock(c);
20677    if (earlyreplace || oneleggedreplace ) {
20678       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
20679    }
20680    ast_setstate(c, AST_STATE_DOWN);
20681    ast_channel_unlock(c);
20682 
20683    /* The call should be down with no ast_channel, so hang it up */
20684    c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt");
20685 
20686    /* c and c's tech pvt must be unlocked at this point for ast_hangup */
20687    ast_hangup(c);
20688    /* this indicates to handle_request_do that the owner channel has already been unlocked */
20689    *nounlock = 1;
20690    /* lock PVT structure again after hangup */
20691    sip_pvt_lock(p);
20692    ast_channel_unref(c);
20693    return 0;
20694 }

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

Handle incoming BYE request.

Definition at line 22250 of file chan_sip.c.

References __sip_pretend_ack(), append_history, 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_set_hangupsource(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), ast_channel::context, context, copy_request(), get_also_info(), get_header(), LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), quality, sip_alreadygone(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy_final(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, cfsip_methods::text, transmit_response(), and transmit_response_reliable().

Referenced by handle_incoming().

22251 {
22252    struct ast_channel *c=NULL;
22253    int res;
22254    struct ast_channel *bridged_to;
22255    
22256    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
22257    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) {
22258       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
22259    }
22260 
22261    __sip_pretend_ack(p);
22262 
22263    p->invitestate = INV_TERMINATED;
22264 
22265    copy_request(&p->initreq, req);
22266    if (sipdebug)
22267       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
22268    check_via(p, req);
22269    sip_alreadygone(p);
22270 
22271    /* Get RTCP quality before end of call */
22272    if (p->do_history || p->owner) {
22273       char quality_buf[AST_MAX_USER_FIELD], *quality;
22274       struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
22275 
22276       /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt
22277        * to lock the bridge. This may get hairy...
22278        */
22279       while (bridge && ast_channel_trylock(bridge)) {
22280          ast_channel_unlock(p->owner);
22281          do {
22282             /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */
22283             sip_pvt_unlock(p);
22284             usleep(1);
22285             sip_pvt_lock(p);
22286          } while (p->owner && ast_channel_trylock(p->owner));
22287          bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
22288       }
22289 
22290 
22291       if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
22292          if (p->do_history) {
22293             append_history(p, "RTCPaudio", "Quality:%s", quality);
22294 
22295             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) {
22296                append_history(p, "RTCPaudioJitter", "Quality:%s", quality);
22297             }
22298             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) {
22299                append_history(p, "RTCPaudioLoss", "Quality:%s", quality);
22300             }
22301             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) {
22302                append_history(p, "RTCPaudioRTT", "Quality:%s", quality);
22303             }
22304          }
22305 
22306          if (p->owner) {
22307             ast_rtp_instance_set_stats_vars(p->owner, p->rtp);
22308          }
22309 
22310       }
22311 
22312       if (bridge) {
22313          struct sip_pvt *q = bridge->tech_pvt;
22314 
22315          if (IS_SIP_TECH(bridge->tech) && q && q->rtp) {
22316             ast_rtp_instance_set_stats_vars(bridge, q->rtp);
22317          }
22318          ast_channel_unlock(bridge);
22319       }
22320 
22321       if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
22322          if (p->do_history) {
22323             append_history(p, "RTCPvideo", "Quality:%s", quality);
22324          }
22325          if (p->owner) {
22326             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality);
22327          }
22328       }
22329       if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
22330          if (p->do_history) {
22331             append_history(p, "RTCPtext", "Quality:%s", quality);
22332          }
22333          if (p->owner) {
22334             pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality);
22335          }
22336       }
22337    }
22338 
22339    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
22340    stop_session_timer(p); /* Stop Session-Timer */
22341 
22342    if (!ast_strlen_zero(get_header(req, "Also"))) {
22343       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
22344          ast_sockaddr_stringify(&p->recv));
22345       if (ast_strlen_zero(p->context))
22346          ast_string_field_set(p, context, sip_cfg.default_context);
22347       res = get_also_info(p, req);
22348       if (!res) {
22349          c = p->owner;
22350          if (c) {
22351             bridged_to = ast_bridged_channel(c);
22352             if (bridged_to) {
22353                /* Don't actually hangup here... */
22354                ast_queue_control(c, AST_CONTROL_UNHOLD);
22355                ast_channel_unlock(c);  /* async_goto can do a masquerade, no locks can be held during a masq */
22356                ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1);
22357                ast_channel_lock(c);
22358             } else
22359                ast_queue_hangup(p->owner);
22360          }
22361       } else {
22362          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv));
22363          if (p->owner)
22364             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
22365       }
22366    } else if (p->owner) {
22367       ast_set_hangupsource(p->owner, p->owner->name, 0);
22368       ast_queue_hangup(p->owner);
22369       sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT);
22370       ast_debug(3, "Received bye, issuing owner hangup\n");
22371    } else {
22372       sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT);
22373       ast_debug(3, "Received bye, no owner, selfdestruct soon.\n");
22374    }
22375    ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
22376    transmit_response(p, "200 OK", req);
22377 
22378    return 1;
22379 }

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

Handle incoming CANCEL request.

Definition at line 22185 of file chan_sip.c.

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

Referenced by handle_incoming().

22186 {
22187 
22188    check_via(p, req);
22189    sip_alreadygone(p);
22190 
22191    if (p->owner && p->owner->_state == AST_STATE_UP) {
22192       /* This call is up, cancel is ignored, we need a bye */
22193       transmit_response(p, "200 OK", req);
22194       ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n");
22195       return 0;
22196    }
22197 
22198    /* At this point, we could have cancelled the invite at the same time
22199       as the other side sends a CANCEL. Our final reply with error code
22200       might not have been received by the other side before the CANCEL
22201       was sent, so let's just give up retransmissions and waiting for
22202       ACK on our error code. The call is hanging up any way. */
22203    if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) {
22204       __sip_pretend_ack(p);
22205    }
22206    if (p->invitestate != INV_TERMINATED)
22207       p->invitestate = INV_CANCELLED;
22208 
22209    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
22210       update_call_counter(p, DEC_CALL_LIMIT);
22211 
22212    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
22213    if (p->owner) {
22214       ast_set_hangupsource(p->owner, p->owner->name, 0);
22215       ast_queue_hangup(p->owner);
22216    }
22217    else
22218       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22219    if (p->initreq.len > 0) {
22220       struct sip_pkt *pkt, *prev_pkt;
22221       /* If the CANCEL we are receiving is a retransmission, and we already have scheduled
22222        * a reliable 487, then we don't want to schedule another one on top of the previous
22223        * one.
22224        *
22225        * As odd as this may sound, we can't rely on the previously-transmitted "reliable"
22226        * response in this situation. What if we've sent all of our reliable responses
22227        * already and now all of a sudden, we get this second CANCEL?
22228        *
22229        * The only way to do this correctly is to cancel our previously-scheduled reliably-
22230        * transmitted response and send a new one in its place.
22231        */
22232       for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) {
22233          if (pkt->seqno == p->lastinvite && pkt->response_code == 487) {
22234             AST_SCHED_DEL(sched, pkt->retransid);
22235             UNLINK(pkt, p->packets, prev_pkt);
22236             ast_free(pkt);
22237             break;
22238          }
22239       }
22240       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
22241       transmit_response(p, "200 OK", req);
22242       return 1;
22243    } else {
22244       transmit_response(p, "481 Call Leg Does Not Exist", req);
22245       return 0;
22246    }
22247 }

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

References ao2_t_ref, append_history, ast_channel_trylock, ast_channel_unlock, ast_debug, AST_LIST_EMPTY, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL_UNREF, ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_str_reset(), ast_update_use_count(), ast_verbose, copy_socket_data(), find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), LOG_ERROR, lws2sws(), netlock, parse_request(), process_request_queue(), queue_request(), S_OR, sip_cfg, sip_debug_test_addr(), sip_pvt_unlock, and transmit_response().

Referenced by _sip_tcp_helper_thread(), and sipsock_read().

23782 {
23783    struct sip_pvt *p;
23784    int recount = 0;
23785    int nounlock = 0;
23786    int lockretry;
23787 
23788    if (sip_debug_test_addr(addr))   /* Set the debug flag early on packet level */
23789       req->debug = 1;
23790    if (sip_cfg.pedanticsipchecking)
23791       req->len = lws2sws(req->data->str, req->len);   /* Fix multiline headers */
23792    if (req->debug) {
23793       ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n",
23794          get_transport(req->socket.type), ast_sockaddr_stringify(addr), req->data->str);
23795    }
23796 
23797    if (parse_request(req) == -1) { /* Bad packet, can't parse */
23798       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
23799       return 1;
23800    }
23801    req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1));
23802 
23803    if (req->debug)
23804       ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : "");
23805 
23806    if (req->headers < 2) { /* Must have at least two headers */
23807       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
23808       return 1;
23809    }
23810 
23811    /* Process request, with netlock held, and with usual deadlock avoidance */
23812    for (lockretry = 10; lockretry > 0; lockretry--) {
23813       ast_mutex_lock(&netlock);
23814 
23815       /* Find the active SIP dialog or create a new one */
23816       p = find_call(req, addr, req->method); /* returns p locked */
23817       if (p == NULL) {
23818          ast_debug(1, "Invalid SIP message - rejected , no callid, len %d\n", req->len);
23819          ast_mutex_unlock(&netlock);
23820          return 1;
23821       }
23822 
23823       copy_socket_data(&p->socket, &req->socket);
23824 
23825       /* Go ahead and lock the owner if it has one -- we may need it */
23826       /* becaues this is deadlock-prone, we need to try and unlock if failed */
23827       if (!p->owner || !ast_channel_trylock(p->owner))
23828          break;   /* locking succeeded */
23829 
23830       if (lockretry != 1) {
23831          sip_pvt_unlock(p);
23832          ao2_t_ref(p, -1, "release p (from find_call) inside lockretry loop"); /* we'll look for it again, but p is dead now */
23833          ast_mutex_unlock(&netlock);
23834          /* Sleep for a very short amount of time */
23835          usleep(1);
23836       }
23837    }
23838    ast_sockaddr_copy(&p->recv, addr);
23839 
23840    if (p->do_history) /* This is a request or response, note what it was for */
23841       append_history(p, "Rx", "%s / %s / %s", req->data->str, get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2));
23842 
23843    if (!lockretry) {
23844       if (!queue_request(p, req)) {
23845          /* the request has been queued for later handling */
23846          sip_pvt_unlock(p);
23847          ao2_t_ref(p, -1, "release p (from find_call) after queueing request");
23848          ast_mutex_unlock(&netlock);
23849          return 1;
23850       }
23851 
23852       if (p->owner)
23853          ast_log(LOG_ERROR, "Channel lock for %s could not be obtained, and request was unable to be queued.\n", S_OR(p->owner->name, "- no channel name ??? - "));
23854       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
23855       if (req->method != SIP_ACK)
23856          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
23857       /* XXX We could add retry-after to make sure they come back */
23858       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
23859       sip_pvt_unlock(p);
23860       ao2_t_ref(p, -1, "release p (from find_call) at end of lockretry"); /* p is gone after the return */
23861       ast_mutex_unlock(&netlock);
23862       return 1;
23863    }
23864 
23865    /* if there are queued requests on this sip_pvt, process them first, so that everything is
23866       handled in order
23867    */
23868    if (!AST_LIST_EMPTY(&p->request_queue)) {
23869       AST_SCHED_DEL_UNREF(sched, p->request_queue_sched_id, dialog_unref(p, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr"));
23870       process_request_queue(p, &recount, &nounlock);
23871    }
23872 
23873    if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) {
23874       /* Request failed */
23875       ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
23876    }
23877       
23878    if (recount)
23879       ast_update_use_count();
23880 
23881    if (p->owner && !nounlock)
23882       ast_channel_unlock(p->owner);
23883    sip_pvt_unlock(p);
23884    ast_mutex_unlock(&netlock);
23885    ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
23886    return 1;
23887 }

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

Receive SIP INFO Message.

Todo:
Note: Doesn't read the duration of the DTMF. Should be fixed.

Definition at line 17511 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_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, transmit_response(), and TRUE.

Referenced by handle_incoming().

17512 {
17513    char buf[1024];
17514    unsigned int event;
17515    const char *c = get_header(req, "Content-Type");
17516 
17517    /* Need to check the media/type */
17518    if (!strcasecmp(c, "application/dtmf-relay") ||
17519        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
17520       unsigned int duration = 0;
17521 
17522       if (!p->owner) {  /* not a PBX call */
17523          transmit_response(p, "481 Call leg/transaction does not exist", req);
17524          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17525          return;
17526       }
17527 
17528       /* Try getting the "signal=" part */
17529       if (ast_strlen_zero(c = get_body(req, "Signal", '=')) && ast_strlen_zero(c = get_body(req, "d", '='))) {
17530          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
17531          transmit_response(p, "200 OK", req); /* Should return error */
17532          return;
17533       } else {
17534          ast_copy_string(buf, c, sizeof(buf));
17535       }
17536 
17537       if (!ast_strlen_zero((c = get_body(req, "Duration", '=')))) {
17538          duration = atoi(c);
17539       }
17540       if (!duration) {
17541          duration = 100; /* 100 ms */
17542       }
17543 
17544 
17545       if (ast_strlen_zero(buf)) {
17546          transmit_response(p, "200 OK", req);
17547          return;
17548       }
17549 
17550       if (buf[0] == '*') {
17551          event = 10;
17552       } else if (buf[0] == '#') {
17553          event = 11;
17554       } else if ((buf[0] >= 'A') && (buf[0] <= 'D')) {
17555          event = 12 + buf[0] - 'A';
17556       } else if (buf[0] == '!') {
17557          event = 16;
17558       } else {
17559          event = atoi(buf);
17560       }
17561       if (event == 16) {
17562          /* send a FLASH event */
17563          struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
17564          ast_queue_frame(p->owner, &f);
17565          if (sipdebug) {
17566             ast_verbose("* DTMF-relay event received: FLASH\n");
17567          }
17568       } else {
17569          /* send a DTMF event */
17570          struct ast_frame f = { AST_FRAME_DTMF, };
17571          if (event < 10) {
17572             f.subclass.integer = '0' + event;
17573          } else if (event == 10) {
17574             f.subclass.integer = '*';
17575          } else if (event == 11) {
17576             f.subclass.integer = '#';
17577          } else if (event < 16) {
17578             f.subclass.integer = 'A' + (event - 12);
17579          }
17580          f.len = duration;
17581          ast_queue_frame(p->owner, &f);
17582          if (sipdebug) {
17583             ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
17584          }
17585       }
17586       transmit_response(p, "200 OK", req);
17587       return;
17588    } else if (!strcasecmp(c, "application/dtmf")) {
17589       /*! \todo Note: Doesn't read the duration of the DTMF. Should be fixed. */
17590       unsigned int duration = 0;
17591 
17592       if (!p->owner) {  /* not a PBX call */
17593          transmit_response(p, "481 Call leg/transaction does not exist", req);
17594          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17595          return;
17596       }
17597 
17598       get_msg_text(buf, sizeof(buf), req, TRUE);
17599       duration = 100; /* 100 ms */
17600 
17601       if (ast_strlen_zero(buf)) {
17602          transmit_response(p, "200 OK", req);
17603          return;
17604       }
17605       event = atoi(buf);
17606       if (event == 16) {
17607          /* send a FLASH event */
17608          struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH }, };
17609          ast_queue_frame(p->owner, &f);
17610          if (sipdebug) {
17611             ast_verbose("* DTMF-relay event received: FLASH\n");
17612          }
17613       } else {
17614          /* send a DTMF event */
17615          struct ast_frame f = { AST_FRAME_DTMF, };
17616          if (event < 10) {
17617             f.subclass.integer = '0' + event;
17618          } else if (event == 10) {
17619             f.subclass.integer = '*';
17620          } else if (event == 11) {
17621             f.subclass.integer = '#';
17622          } else if (event < 16) {
17623             f.subclass.integer = 'A' + (event - 12);
17624          }
17625          f.len = duration;
17626          ast_queue_frame(p->owner, &f);
17627          if (sipdebug) {
17628             ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
17629          }
17630       }
17631       transmit_response(p, "200 OK", req);
17632       return;
17633 
17634    } else if (!strcasecmp(c, "application/media_control+xml")) {
17635       /* Eh, we'll just assume it's a fast picture update for now */
17636       if (p->owner) {
17637          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
17638       }
17639       transmit_response(p, "200 OK", req);
17640       return;
17641    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
17642       /* Client code (from SNOM phone) */
17643       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
17644          if (p->owner && p->owner->cdr) {
17645             ast_cdr_setuserfield(p->owner, c);
17646          }
17647          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) {
17648             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
17649          }
17650          transmit_response(p, "200 OK", req);
17651       } else {
17652          transmit_response(p, "403 Forbidden", req);
17653       }
17654       return;
17655    } else if (!ast_strlen_zero(c = get_header(req, "Record"))) {
17656       /* INFO messages generated by some phones to start/stop recording
17657          on phone calls.
17658          OEJ: I think this should be something that is enabled/disabled
17659          per device. I don't want incoming callers to record calls in my
17660          pbx.
17661       */
17662       /* first, get the feature string, if it exists */
17663       struct ast_call_feature *feat;
17664       int j;
17665       struct ast_frame f = { AST_FRAME_DTMF, };
17666 
17667       ast_rdlock_call_features();
17668       feat = ast_find_call_feature("automon");
17669       if (!feat || ast_strlen_zero(feat->exten)) {
17670          ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
17671          /* 403 means that we don't support this feature, so don't request it again */
17672          transmit_response(p, "403 Forbidden", req);
17673          ast_unlock_call_features();
17674          return;
17675       }
17676       /* Send the feature code to the PBX as DTMF, just like the handset had sent it */
17677       f.len = 100;
17678       for (j=0; j < strlen(feat->exten); j++) {
17679          f.subclass.integer = feat->exten[j];
17680          ast_queue_frame(p->owner, &f);
17681          if (sipdebug) {
17682             ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer);
17683          }
17684       }
17685       ast_unlock_call_features();
17686 
17687       ast_debug(1, "Got a Request to Record the channel, state %s\n", c);
17688       transmit_response(p, "200 OK", req);
17689       return;
17690    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
17691       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
17692       transmit_response(p, "200 OK", req);
17693       return;
17694    }
17695 
17696    /* Other type of INFO message, not really understood by Asterisk */
17697    /* if (get_msg_text(buf, sizeof(buf), req)) { */
17698 
17699    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
17700    transmit_response(p, "415 Unsupported media type", req);
17701    return;
17702 }

static int handle_request_invite ( struct sip_pvt *  p,
struct sip_request *  req,
int  debug,
int  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 20789 of file chan_sip.c.

References __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_cc_agent_set_interfaces_chanvar(), ast_channel_lock, 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_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_call(), 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_set_flag, ast_setstate(), ast_setup_cc_recall_datastore(), ast_skip_blanks(), 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_udptl_new_with_bindaddr(), ast_uri_decode(), ast_verbose, bindaddr, build_contact(), build_route(), 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(), ast_channel::hangupcause, ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_our_tag(), ast_channel::name, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_minse(), parse_ok_contact(), parse_session_expires(), ast_party_name::presentation, ast_party_number::presentation, process_sdp(), ref_peer(), restart_session_timer(), S_OR, set_pvt_allowed_methods(), set_t38_capabilities(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_new(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_st_alloc(), sip_t38_abort(), ast_party_connected_line::source, st_get_mode(), st_get_refresher(), st_get_se(), start_session_timer(), ast_party_name::str, ast_party_number::str, strcasestr(), strsep(), ast_party_id::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, unref_peer(), update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_incoming().

20790 {
20791    int res = 1;
20792    int gotdest;
20793    const char *p_replaces;
20794    char *replace_id = NULL;
20795    int refer_locked = 0;
20796    const char *required;
20797    unsigned int required_profile = 0;
20798    struct ast_channel *c = NULL;    /* New channel */
20799    struct sip_peer *authpeer = NULL;   /* Matching Peer */
20800    int reinvite = 0;
20801    int rtn;
20802    struct ast_party_redirecting redirecting;
20803    struct ast_set_party_redirecting update_redirecting;
20804 
20805    const char *p_uac_se_hdr;       /* UAC's Session-Expires header string                      */
20806    const char *p_uac_min_se;       /* UAC's requested Min-SE interval (char string)            */
20807    int uac_max_se = -1;            /* UAC's Session-Expires in integer format                  */
20808    int uac_min_se = -1;            /* UAC's Min-SE in integer format                           */
20809    int st_active = FALSE;          /* Session-Timer on/off boolean                             */
20810    int st_interval = 0;            /* Session-Timer negotiated refresh interval                */
20811    enum st_refresher st_ref;       /* Session-Timer session refresher                          */
20812    int dlg_min_se = -1;
20813    struct {
20814       char exten[AST_MAX_EXTENSION];
20815       char context[AST_MAX_CONTEXT];
20816    } pickup = {
20817          .exten = "",
20818    };
20819    st_ref = SESSION_TIMER_REFRESHER_AUTO;
20820 
20821    /* Find out what they support */
20822    if (!p->sipoptions) {
20823       const char *supported = get_header(req, "Supported");
20824       if (!ast_strlen_zero(supported)) {
20825          p->sipoptions = parse_sip_options(supported, NULL, 0);
20826       }
20827    }
20828 
20829    /* Find out what they require */
20830    required = get_header(req, "Require");
20831    if (!ast_strlen_zero(required)) {
20832       char unsupported[256] = { 0, };
20833       required_profile = parse_sip_options(required, unsupported, ARRAY_LEN(unsupported));
20834 
20835       /* If there are any options required that we do not support,
20836        * then send a 420 with only those unsupported options listed */
20837       if (!ast_strlen_zero(unsupported)) {
20838          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported);
20839          ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported);
20840          p->invitestate = INV_COMPLETED;
20841          if (!p->lastinvite)
20842             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20843          res = -1;
20844          goto request_invite_cleanup;
20845       }
20846    }
20847 
20848    /* The option tags may be present in Supported: or Require: headers.
20849    Include the Require: option tags for further processing as well */
20850    p->sipoptions |= required_profile;
20851    p->reqsipoptions = required_profile;
20852 
20853    /* Check if this is a loop */
20854    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) {
20855       /* This is a call to ourself.  Send ourselves an error code and stop
20856          processing immediately, as SIP really has no good mechanism for
20857          being able to call yourself */
20858       /* If pedantic is on, we need to check the tags. If they're different, this is
20859          in fact a forked call through a SIP proxy somewhere. */
20860       int different;
20861       const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2);
20862       const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2);
20863       if (sip_cfg.pedanticsipchecking)
20864          different = sip_uri_cmp(initial_rlPart2, this_rlPart2);
20865       else
20866          different = strcmp(initial_rlPart2, this_rlPart2);
20867       if (!different) {
20868          transmit_response(p, "482 Loop Detected", req);
20869          p->invitestate = INV_COMPLETED;
20870          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20871          res = 0;
20872          goto request_invite_cleanup;
20873       } else {
20874          /*! This is a spiral. What we need to do is to just change the outgoing INVITE
20875           * so that it now routes to the new Request URI. Since we created the INVITE ourselves
20876           * that should be all we need to do.
20877           *
20878           * \todo XXX This needs to be reviewed.  YOu don't change the request URI really, you route the packet
20879           * correctly instead...
20880           */
20881          char *uri = ast_strdupa(this_rlPart2);
20882          char *at = strchr(uri, '@');
20883          char *peerorhost;
20884          ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2);
20885          transmit_response(p, "100 Trying", req);
20886          if (at) {
20887             *at = '\0';
20888          }
20889          /* Parse out "sip:" */
20890          if ((peerorhost = strchr(uri, ':'))) {
20891             *peerorhost++ = '\0';
20892          }
20893          ast_string_field_set(p, theirtag, NULL);
20894          /* Treat this as if there were a call forward instead...
20895           */
20896          ast_string_field_set(p->owner, call_forward, peerorhost);
20897          ast_queue_control(p->owner, AST_CONTROL_BUSY);
20898          res = 0;
20899          goto request_invite_cleanup;
20900       }
20901    }
20902 
20903    if (!req->ignore && p->pendinginvite) {
20904       if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) {
20905          /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we
20906           * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero).
20907           * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set.
20908           * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with
20909           * credentials based on one we challenged earlier.
20910           *
20911           * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous
20912           * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response
20913           * from the previous transaction from the list of outstanding packets.
20914           */
20915          __sip_ack(p, p->pendinginvite, 1, 0);
20916       } else {
20917          /* We already have a pending invite. Sorry. You are on hold. */
20918          p->glareinvite = seqno;
20919          if (p->rtp && find_sdp(req)) {
20920             struct ast_sockaddr addr;
20921             if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) {
20922                ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n");
20923             } else {
20924                ast_rtp_instance_set_alt_remote_address(p->rtp, &addr);
20925             }
20926             if (p->vrtp) {
20927                if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) {
20928                   ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n");
20929                } else {
20930                   ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr);
20931                }
20932             }
20933          }
20934          transmit_response_reliable(p, "491 Request Pending", req);
20935          ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
20936          /* Don't destroy dialog here */
20937          res = 0;
20938          goto request_invite_cleanup;
20939       }
20940    }
20941 
20942    p_replaces = get_header(req, "Replaces");
20943    if (!ast_strlen_zero(p_replaces)) {
20944       /* We have a replaces header */
20945       char *ptr;
20946       char *fromtag = NULL;
20947       char *totag = NULL;
20948       char *start, *to;
20949       int error = 0;
20950 
20951       if (p->owner) {
20952          ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
20953          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
20954          /* Do not destroy existing call */
20955          res = -1;
20956          goto request_invite_cleanup;
20957       }
20958 
20959       if (sipdebug)
20960          ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
20961       /* Create a buffer we can manipulate */
20962       replace_id = ast_strdupa(p_replaces);
20963       ast_uri_decode(replace_id);
20964 
20965       if (!p->refer && !sip_refer_allocate(p)) {
20966          transmit_response_reliable(p, "500 Server Internal Error", req);
20967          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
20968          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20969          p->invitestate = INV_COMPLETED;
20970          res = -1;
20971          goto request_invite_cleanup;
20972       }
20973 
20974       /*  Todo: (When we find phones that support this)
20975          if the replaces header contains ";early-only"
20976          we can only replace the call in early
20977          stage, not after it's up.
20978 
20979          If it's not in early mode, 486 Busy.
20980       */
20981 
20982       /* Skip leading whitespace */
20983       replace_id = ast_skip_blanks(replace_id);
20984 
20985       start = replace_id;
20986       while ( (ptr = strsep(&start, ";")) ) {
20987          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
20988          if ( (to = strcasestr(ptr, "to-tag=") ) )
20989             totag = to + 7;   /* skip the keyword */
20990          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
20991             fromtag = to + 9; /* skip the keyword */
20992             fromtag = strsep(&fromtag, "&"); /* trim what ? */
20993          }
20994       }
20995 
20996       if (sipdebug)
20997          ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n",
20998                  replace_id,
20999                  fromtag ? fromtag : "<no from tag>",
21000                  totag ? totag : "<no to tag>");
21001 
21002       /* Try to find call that we are replacing.
21003          If we have a Replaces header, we need to cancel that call if we succeed with this call.
21004          First we cheat a little and look for a magic call-id from phones that support
21005          dialog-info+xml so we can do technology independent pickup... */
21006       if (strncmp(replace_id, "pickup-", 7) == 0) {
21007          struct sip_pvt *subscription = NULL;
21008          replace_id += 7; /* Worst case we are looking at \0 */
21009 
21010          if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
21011             ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id);
21012             transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
21013             error = 1;
21014          } else {
21015             ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context);
21016             ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten));
21017             ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context));
21018             sip_pvt_unlock(subscription);
21019             if (subscription->owner) {
21020                ast_channel_unlock(subscription->owner);
21021             }
21022          }
21023       }
21024 
21025       /* This locks both refer_call pvt and refer_call pvt's owner!!!*/
21026       if (!error && ast_strlen_zero(pickup.exten) && (p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
21027          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
21028          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
21029          error = 1;
21030       } else {
21031          refer_locked = 1;
21032       }
21033 
21034       /* The matched call is the call from the transferer to Asterisk .
21035          We want to bridge the bridged part of the call to the
21036          incoming invite, thus taking over the refered call */
21037 
21038       if (p->refer->refer_call == p) {
21039          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
21040          p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
21041          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
21042          error = 1;
21043       }
21044 
21045       if (!error && ast_strlen_zero(pickup.exten) && !p->refer->refer_call->owner) {
21046          /* Oops, someting wrong anyway, no owner, no call */
21047          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
21048          /* Check for better return code */
21049          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req);
21050          error = 1;
21051       }
21052 
21053       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) {
21054          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
21055          transmit_response_reliable(p, "603 Declined (Replaces)", req);
21056          error = 1;
21057       }
21058 
21059       if (error) {   /* Give up this dialog */
21060          append_history(p, "Xfer", "INVITE/Replace Failed.");
21061          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21062          sip_pvt_unlock(p);
21063          if (p->refer->refer_call) {
21064             sip_pvt_unlock(p->refer->refer_call);
21065             if (p->refer->refer_call->owner) {
21066                ast_channel_unlock(p->refer->refer_call->owner);
21067             }
21068          }
21069          refer_locked = 0;
21070          p->invitestate = INV_COMPLETED;
21071          res = -1;
21072          goto request_invite_cleanup;
21073       }
21074    }
21075 
21076    /* Check if this is an INVITE that sets up a new dialog or
21077       a re-invite in an existing dialog */
21078 
21079    if (!req->ignore) {
21080       int newcall = (p->initreq.headers ? TRUE : FALSE);
21081 
21082       if (sip_cancel_destroy(p))
21083          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
21084       /* This also counts as a pending invite */
21085       p->pendinginvite = seqno;
21086       check_via(p, req);
21087 
21088       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
21089       if (sipdebug)
21090          ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
21091       if (!p->owner) {  /* Not a re-invite */
21092          if (debug)
21093             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
21094          if (newcall)
21095             append_history(p, "Invite", "New call: %s", p->callid);
21096          parse_ok_contact(p, req);
21097       } else { /* Re-invite on existing call */
21098          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
21099          if (get_rpid(p, req)) {
21100             struct ast_party_connected_line connected;
21101             struct ast_set_party_connected_line update_connected;
21102 
21103             ast_party_connected_line_init(&connected);
21104             memset(&update_connected, 0, sizeof(update_connected));
21105             if (p->cid_num) {
21106                update_connected.id.number = 1;
21107                connected.id.number.valid = 1;
21108                connected.id.number.str = (char *) p->cid_num;
21109                connected.id.number.presentation = p->callingpres;
21110             }
21111             if (p->cid_name) {
21112                update_connected.id.name = 1;
21113                connected.id.name.valid = 1;
21114                connected.id.name.str = (char *) p->cid_name;
21115                connected.id.name.presentation = p->callingpres;
21116             }
21117             connected.id.tag = (char *) p->cid_tag;
21118             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
21119             ast_channel_queue_connected_line_update(p->owner, &connected,
21120                &update_connected);
21121          }
21122          /* Handle SDP here if we already have an owner */
21123          if (find_sdp(req)) {
21124             if (process_sdp(p, req, SDP_T38_INITIATE)) {
21125                transmit_response_reliable(p, "488 Not acceptable here", req);
21126                if (!p->lastinvite)
21127                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21128                res = -1;
21129                goto request_invite_cleanup;
21130             }
21131             ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
21132          } else {
21133             p->jointcapability = p->capability;
21134             ast_debug(1, "Hm....  No sdp for the moment\n");
21135          }
21136          if (p->do_history) /* This is a response, note what it was for */
21137             append_history(p, "ReInv", "Re-invite received");
21138       }
21139    } else if (debug)
21140       ast_verbose("Ignoring this INVITE request\n");
21141 
21142    if (!p->lastinvite && !req->ignore && !p->owner) {
21143       /* This is a new invite */
21144       /* Handle authentication if this is our first invite */
21145       int cc_recall_core_id = -1;
21146       set_pvt_allowed_methods(p, req);
21147       res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer);
21148       if (res == AUTH_CHALLENGE_SENT) {
21149          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
21150          res = 0;
21151          goto request_invite_cleanup;
21152       }
21153       if (res < 0) { /* Something failed in authentication */
21154          if (res == AUTH_FAKE_AUTH) {
21155             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
21156             transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
21157          } else {
21158             ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
21159             transmit_response_reliable(p, "403 Forbidden", req);
21160          }
21161          p->invitestate = INV_COMPLETED;
21162          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21163          ast_string_field_set(p, theirtag, NULL);
21164          res = 0;
21165          goto request_invite_cleanup;
21166       }
21167 
21168       /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */
21169       if (p->relatedpeer) {
21170          p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
21171       }
21172       if (authpeer) {
21173          p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");
21174       }
21175       /* If T38 is needed but not present, then make it magically appear */
21176       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && !p->udptl) {
21177          if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) {
21178             p->t38_maxdatagram = global_t38_maxdatagram;
21179             set_t38_capabilities(p);
21180          } else {
21181             /* udptl creation failed, T38 can not be supported on this dialog */
21182             ast_debug(1, "UDPTL creation failed on dialog.\n");
21183             ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT);
21184          }
21185       }
21186 
21187       /* We have a successful authentication, process the SDP portion if there is one */
21188       if (find_sdp(req)) {
21189          if (process_sdp(p, req, SDP_T38_INITIATE)) {
21190             /* Unacceptable codecs */
21191             transmit_response_reliable(p, "488 Not acceptable here", req);
21192             p->invitestate = INV_COMPLETED;
21193             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21194             ast_debug(1, "No compatible codecs for this SIP call.\n");
21195             res = -1;
21196             goto request_invite_cleanup;
21197          }
21198       } else { /* No SDP in invite, call control session */
21199          p->jointcapability = p->capability;
21200          ast_debug(2, "No SDP in Invite, third party call control\n");
21201       }
21202 
21203       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
21204       /* This seems redundant ... see !p-owner above */
21205       if (p->owner)
21206          ast_queue_frame(p->owner, &ast_null_frame);
21207 
21208 
21209       /* Initialize the context if it hasn't been already */
21210       if (ast_strlen_zero(p->context))
21211          ast_string_field_set(p, context, sip_cfg.default_context);
21212 
21213 
21214       /* Check number of concurrent calls -vs- incoming limit HERE */
21215       ast_debug(1, "Checking SIP call limits for device %s\n", p->username);
21216       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
21217          if (res < 0) {
21218             ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username);
21219             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
21220             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21221             p->invitestate = INV_COMPLETED;
21222          }
21223          res = 0;
21224          goto request_invite_cleanup;
21225       }
21226       gotdest = get_destination(p, NULL, &cc_recall_core_id);  /* Get destination right away */
21227       extract_uri(p, req);       /* Get the Contact URI */
21228       build_contact(p);       /* Build our contact header */
21229 
21230       if (p->rtp) {
21231          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
21232          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
21233       }
21234 
21235       if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */
21236          switch(gotdest) {
21237          case SIP_GET_DEST_INVALID_URI:
21238             transmit_response_reliable(p, "416 Unsupported URI scheme", req);
21239             break;
21240          case SIP_GET_DEST_PICKUP_EXTEN_FOUND:
21241             if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
21242                transmit_response_reliable(p, "484 Address Incomplete", req);
21243                break;
21244             }
21245          /* INTENTIONAL FALL THROUGH */
21246          case SIP_GET_DEST_EXTEN_NOT_FOUND:
21247          case SIP_GET_DEST_REFUSED:
21248          default:
21249             {
21250                char *decoded_exten = ast_strdupa(p->exten);
21251                transmit_response_reliable(p, "404 Not Found", req);
21252                ast_uri_decode(decoded_exten);
21253                ast_log(LOG_NOTICE, "Call from '%s' to extension"
21254                   " '%s' rejected because extension not found in context '%s'.\n",
21255                   S_OR(p->username, p->peername), decoded_exten, p->context);
21256             }
21257          } /* end switch */
21258 
21259          p->invitestate = INV_COMPLETED;
21260          update_call_counter(p, DEC_CALL_LIMIT);
21261          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21262          res = 0;
21263          goto request_invite_cleanup;
21264       } else {
21265 
21266          /* If no extension was specified, use the s one */
21267          /* Basically for calling to IP/Host name only */
21268          if (ast_strlen_zero(p->exten))
21269             ast_string_field_set(p, exten, "s");
21270          /* Initialize our tag */
21271 
21272          make_our_tag(p->tag, sizeof(p->tag));
21273          /* First invitation - create the channel */
21274          c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL);
21275          if (cc_recall_core_id != -1) {
21276             ast_setup_cc_recall_datastore(c, cc_recall_core_id);
21277             ast_cc_agent_set_interfaces_chanvar(c);
21278          }
21279          *recount = 1;
21280 
21281          /* Save Record-Route for any later requests we make on this dialogue */
21282          build_route(p, req, 0);
21283 
21284          if (c) {
21285             ast_party_redirecting_init(&redirecting);
21286             memset(&update_redirecting, 0, sizeof(update_redirecting));
21287             /* Pre-lock the call */
21288             ast_channel_lock(c);
21289             change_redirecting_information(p, req, &redirecting, &update_redirecting,
21290                FALSE); /*Will return immediately if no Diversion header is present */
21291             ast_channel_set_redirecting(c, &redirecting, &update_redirecting);
21292             ast_party_redirecting_free(&redirecting);
21293          }
21294       }
21295    } else {
21296       ast_party_redirecting_init(&redirecting);
21297       memset(&update_redirecting, 0, sizeof(update_redirecting));
21298       if (sipdebug) {
21299          if (!req->ignore)
21300             ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid);
21301          else
21302             ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
21303       }
21304       if (!req->ignore)
21305          reinvite = 1;
21306       c = p->owner;
21307       change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */
21308       if (c) {
21309          ast_channel_set_redirecting(c, &redirecting, &update_redirecting);
21310       }
21311       ast_party_redirecting_free(&redirecting);
21312    }
21313 
21314    /* Session-Timers */
21315    if ((p->sipoptions & SIP_OPT_TIMER) && !ast_strlen_zero(get_header(req, "Session-Expires"))) {
21316       /* The UAC has requested session-timers for this session. Negotiate
21317       the session refresh interval and who will be the refresher */
21318       ast_debug(2, "Incoming INVITE with 'timer' option supported and \"Session-Expires\" header.\n");
21319 
21320       /* Allocate Session-Timers struct w/in the dialog */
21321       if (!p->stimer)
21322          sip_st_alloc(p);
21323 
21324       /* Parse the Session-Expires header */
21325       p_uac_se_hdr = get_header(req, "Session-Expires");
21326       rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref);
21327       if (rtn != 0) {
21328          transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
21329          p->invitestate = INV_COMPLETED;
21330          if (!p->lastinvite) {
21331             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21332          }
21333          res = -1;
21334          goto request_invite_cleanup;
21335       }
21336 
21337       /* Parse the Min-SE header */
21338       p_uac_min_se = get_header(req, "Min-SE");
21339       if (!ast_strlen_zero(p_uac_min_se)) {
21340          rtn = parse_minse(p_uac_min_se, &uac_min_se);
21341          if (rtn != 0) {
21342             transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req);
21343             p->invitestate = INV_COMPLETED;
21344             if (!p->lastinvite) {
21345                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21346             }
21347             res = -1;
21348             goto request_invite_cleanup;
21349          }
21350       }
21351 
21352       dlg_min_se = st_get_se(p, FALSE);
21353       switch (st_get_mode(p)) {
21354       case SESSION_TIMER_MODE_ACCEPT:
21355       case SESSION_TIMER_MODE_ORIGINATE:
21356          if (uac_max_se > 0 && uac_max_se < dlg_min_se) {
21357             transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se);
21358             p->invitestate = INV_COMPLETED;
21359             if (!p->lastinvite) {
21360                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21361             }
21362             res = -1;
21363             goto request_invite_cleanup;
21364          }
21365 
21366          p->stimer->st_active_peer_ua = TRUE;
21367          st_active = TRUE;
21368          if (st_ref == SESSION_TIMER_REFRESHER_AUTO) {
21369             st_ref = st_get_refresher(p);
21370          }
21371 
21372          if (uac_max_se > 0) {
21373             int dlg_max_se = st_get_se(p, TRUE);
21374             if (dlg_max_se >= uac_min_se) {
21375                st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se;
21376             } else {
21377                st_interval = uac_max_se;
21378             }
21379          } else {
21380             /* Set to default max value */
21381             st_interval = global_max_se;
21382          }
21383          break;
21384 
21385       case SESSION_TIMER_MODE_REFUSE:
21386          if (p->reqsipoptions & SIP_OPT_TIMER) {
21387             transmit_response_with_unsupported(p, "420 Option Disabled", req, required);
21388             ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required);
21389             p->invitestate = INV_COMPLETED;
21390             if (!p->lastinvite) {
21391                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21392             }
21393             res = -1;
21394             goto request_invite_cleanup;
21395          }
21396          break;
21397 
21398       default:
21399          ast_log(LOG_ERROR, "Internal Error %d at %s:%d\n", st_get_mode(p), __FILE__, __LINE__);
21400          break;
21401       }
21402    } else {
21403       /* The UAC did not request session-timers.  Asterisk (UAS), will now decide
21404       (based on session-timer-mode in sip.conf) whether to run session-timers for
21405       this session or not. */
21406       switch (st_get_mode(p)) {
21407       case SESSION_TIMER_MODE_ORIGINATE:
21408          st_active = TRUE;
21409          st_interval = st_get_se(p, TRUE);
21410          st_ref = SESSION_TIMER_REFRESHER_UAS;
21411          p->stimer->st_active_peer_ua = FALSE;
21412          break;
21413 
21414       default:
21415          break;
21416       }
21417    }
21418 
21419    if (reinvite == 0) {
21420       /* Session-Timers: Start session refresh timer based on negotiation/config */
21421       if (st_active == TRUE) {
21422          p->stimer->st_active   = TRUE;
21423          p->stimer->st_interval = st_interval;
21424          p->stimer->st_ref      = st_ref;
21425          start_session_timer(p);
21426       }
21427    } else {
21428       if (p->stimer->st_active == TRUE) {
21429          /* Session-Timers:  A re-invite request sent within a dialog will serve as
21430          a refresh request, no matter whether the re-invite was sent for refreshing
21431          the session or modifying it.*/
21432          ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid);
21433 
21434          /* The UAC may be adjusting the session-timers mid-session */
21435          if (st_interval > 0) {
21436             p->stimer->st_interval = st_interval;
21437             p->stimer->st_ref      = st_ref;
21438          }
21439 
21440          restart_session_timer(p);
21441          if (p->stimer->st_expirys > 0) {
21442             p->stimer->st_expirys--;
21443          }
21444       }
21445    }
21446 
21447    if (!req->ignore && p)
21448       p->lastinvite = seqno;
21449 
21450    if (replace_id) { /* Attended transfer or call pickup - we're the target */
21451       if (!ast_strlen_zero(pickup.exten)) {
21452          append_history(p, "Xfer", "INVITE/Replace received");
21453 
21454          /* Let the caller know we're giving it a shot */
21455          transmit_response(p, "100 Trying", req);
21456          p->invitestate = INV_PROCEEDING;
21457          ast_setstate(c, AST_STATE_RING);
21458 
21459          /* Do the pickup itself */
21460          ast_channel_unlock(c);
21461          *nounlock = 1;
21462 
21463          /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both
21464           * magic pickup and ast_hangup.  Both of these functions will attempt to lock
21465           * p->owner again, which can cause a deadlock if we already hold a lock on p.
21466           * Locking order is, channel then pvt.  Dead lock avoidance must be used if
21467           * called the other way around. */
21468          sip_pvt_unlock(p);
21469          do_magic_pickup(c, pickup.exten, pickup.context);
21470          /* Now we're either masqueraded or we failed to pickup, in either case we... */
21471          ast_hangup(c);
21472          sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */
21473 
21474          res = 0;
21475          goto request_invite_cleanup;
21476       } else {
21477          /* Go and take over the target call */
21478          if (sipdebug)
21479             ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
21480          res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock);
21481          refer_locked = 0;
21482          goto request_invite_cleanup;
21483       }
21484    }
21485 
21486 
21487    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
21488       enum ast_channel_state c_state = c->_state;
21489 
21490       if (c_state != AST_STATE_UP && reinvite &&
21491          (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
21492          /* If these conditions are true, and the channel is still in the 'ringing'
21493           * state, then this likely means that we have a situation where the initial
21494           * INVITE transaction has completed *but* the channel's state has not yet been
21495           * changed to UP. The reason this could happen is if the reinvite is received
21496           * on the SIP socket prior to an application calling ast_read on this channel
21497           * to read the answer frame we earlier queued on it. In this case, the reinvite
21498           * is completely legitimate so we need to handle this the same as if the channel
21499           * were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
21500           */
21501          c_state = AST_STATE_UP;
21502       }
21503 
21504       switch(c_state) {
21505       case AST_STATE_DOWN:
21506          ast_debug(2, "%s: New call is still down.... Trying... \n", c->name);
21507          transmit_provisional_response(p, "100 Trying", req, 0);
21508          p->invitestate = INV_PROCEEDING;
21509          ast_setstate(c, AST_STATE_RING);
21510          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
21511             enum ast_pbx_result result;
21512 
21513             result = ast_pbx_start(c);
21514 
21515             switch(result) {
21516             case AST_PBX_FAILED:
21517                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
21518                p->invitestate = INV_COMPLETED;
21519                transmit_response_reliable(p, "503 Unavailable", req);
21520                break;
21521             case AST_PBX_CALL_LIMIT:
21522                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
21523                p->invitestate = INV_COMPLETED;
21524                transmit_response_reliable(p, "480 Temporarily Unavailable", req);
21525                break;
21526             case AST_PBX_SUCCESS:
21527                /* nothing to do */
21528                break;
21529             }
21530 
21531             if (result) {
21532 
21533                /* Unlock locks so ast_hangup can do its magic */
21534                ast_channel_unlock(c);
21535                sip_pvt_unlock(p);
21536                ast_hangup(c);
21537                sip_pvt_lock(p);
21538                c = NULL;
21539             }
21540          } else { /* Pickup call in call group */
21541             ast_channel_unlock(c);
21542             *nounlock = 1;
21543             if (ast_pickup_call(c)) {
21544                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
21545                transmit_response_reliable(p, "503 Unavailable", req);
21546                sip_alreadygone(p);
21547                /* Unlock locks so ast_hangup can do its magic */
21548                sip_pvt_unlock(p);
21549                c->hangupcause = AST_CAUSE_CALL_REJECTED;
21550             } else {
21551                sip_pvt_unlock(p);
21552                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
21553             }
21554             p->invitestate = INV_COMPLETED;
21555             ast_hangup(c);
21556             sip_pvt_lock(p);
21557             c = NULL;
21558          }
21559          break;
21560       case AST_STATE_RING:
21561          transmit_provisional_response(p, "100 Trying", req, 0);
21562          p->invitestate = INV_PROCEEDING;
21563          break;
21564       case AST_STATE_RINGING:
21565          transmit_provisional_response(p, "180 Ringing", req, 0);
21566          p->invitestate = INV_PROCEEDING;
21567          break;
21568       case AST_STATE_UP:
21569          ast_debug(2, "%s: This call is UP.... \n", c->name);
21570 
21571          transmit_response(p, "100 Trying", req);
21572 
21573          if (p->t38.state == T38_PEER_REINVITE) {
21574             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."));
21575          } else if (p->t38.state == T38_ENABLED) {
21576             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21577             transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)));
21578          } else if (p->t38.state == T38_DISABLED) {
21579             /* If this is not a re-invite or something to ignore - it's critical */
21580             if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) {
21581                ast_log(LOG_WARNING, "Target does not support required crypto\n");
21582                transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req);
21583             } else {
21584                ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21585                transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE);
21586             }
21587          }
21588 
21589          p->invitestate = INV_TERMINATED;
21590          break;
21591       default:
21592          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
21593          transmit_response(p, "100 Trying", req);
21594          break;
21595       }
21596    } else {
21597       if (p && (p->autokillid == -1)) {
21598          const char *msg;
21599 
21600          if (!p->jointcapability)
21601             msg = "488 Not Acceptable Here (codec error)";
21602          else {
21603             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
21604             msg = "503 Unavailable";
21605          }
21606          transmit_response_reliable(p, msg, req);
21607          p->invitestate = INV_COMPLETED;
21608          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21609       }
21610    }
21611 
21612 request_invite_cleanup:
21613 
21614    if (refer_locked && p->refer && p->refer->refer_call) {
21615       sip_pvt_unlock(p->refer->refer_call);
21616       if (p->refer->refer_call->owner) {
21617          ast_channel_unlock(p->refer->refer_call->owner);
21618       }
21619    }
21620    if (authpeer) {
21621       authpeer = unref_peer(authpeer, "unref_peer, from handle_request_invite authpeer");
21622    }
21623 
21624    return res;
21625 }

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

Handle incoming MESSAGE request.

Definition at line 22382 of file chan_sip.c.

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

Referenced by handle_incoming().

22383 {
22384    if (!req->ignore) {
22385       if (req->debug)
22386          ast_verbose("Receiving message!\n");
22387       receive_message(p, req);
22388    } else
22389       transmit_response(p, "202 Accepted", req);
22390    return 1;
22391 }

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

Handle incoming notifications.

Definition at line 20329 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(), strsep(), transmit_response(), TRUE, and unref_peer().

Referenced by handle_incoming().

20330 {
20331    /* This is mostly a skeleton for future improvements */
20332    /* Mostly created to return proper answers on notifications on outbound REFER's */
20333    int res = 0;
20334    const char *event = get_header(req, "Event");
20335    char *eventid = NULL;
20336    char *sep;
20337 
20338    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
20339       *sep++ = '\0';
20340       eventid = sep;
20341    }
20342    
20343    if (sipdebug)
20344       ast_debug(2, "Got NOTIFY Event: %s\n", event);
20345 
20346    if (!strcmp(event, "refer")) {
20347       /* Save nesting depth for now, since there might be other events we will
20348          support in the future */
20349 
20350       /* Handle REFER notifications */
20351 
20352       char buf[1024];
20353       char *cmd, *code;
20354       int respcode;
20355       int success = TRUE;
20356 
20357       /* EventID for each transfer... EventID is basically the REFER cseq
20358 
20359        We are getting notifications on a call that we transfered
20360        We should hangup when we are getting a 200 OK in a sipfrag
20361        Check if we have an owner of this event */
20362       
20363       /* Check the content type */
20364       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
20365          /* We need a sipfrag */
20366          transmit_response(p, "400 Bad request", req);
20367          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20368          return -1;
20369       }
20370 
20371       /* Get the text of the attachment */
20372       if (get_msg_text(buf, sizeof(buf), req, TRUE)) {
20373          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
20374          transmit_response(p, "400 Bad request", req);
20375          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20376          return -1;
20377       }
20378 
20379       /*
20380       From the RFC...
20381       A minimal, but complete, implementation can respond with a single
20382       NOTIFY containing either the body:
20383          SIP/2.0 100 Trying
20384       
20385       if the subscription is pending, the body:
20386          SIP/2.0 200 OK
20387       if the reference was successful, the body:
20388          SIP/2.0 503 Service Unavailable
20389       if the reference failed, or the body:
20390          SIP/2.0 603 Declined
20391 
20392       if the REFER request was accepted before approval to follow the
20393       reference could be obtained and that approval was subsequently denied
20394       (see Section 2.4.7).
20395       
20396       If there are several REFERs in the same dialog, we need to
20397       match the ID of the event header...
20398       */
20399       ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
20400       cmd = ast_skip_blanks(buf);
20401       code = cmd;
20402       /* We are at SIP/2.0 */
20403       while(*code && (*code > 32)) {   /* Search white space */
20404          code++;
20405       }
20406       *code++ = '\0';
20407       code = ast_skip_blanks(code);
20408       sep = code;
20409       sep++;
20410       while(*sep && (*sep > 32)) {  /* Search white space */
20411          sep++;
20412       }
20413       *sep++ = '\0';       /* Response string */
20414       respcode = atoi(code);
20415       switch (respcode) {
20416       case 200:   /* OK: The new call is up, hangup this call */
20417          /* Hangup the call that we are replacing */
20418          break;
20419       case 301: /* Moved permenantly */
20420       case 302: /* Moved temporarily */
20421          /* Do we get the header in the packet in this case? */
20422          success = FALSE;
20423          break;
20424       case 503:   /* Service Unavailable: The new call failed */
20425       case 603:   /* Declined: Not accepted */
20426             /* Cancel transfer, continue the current call */
20427          success = FALSE;
20428          break;
20429       case 0:     /* Parse error */
20430             /* Cancel transfer, continue the current call */
20431          ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n");
20432          success = FALSE;
20433          break;
20434       default:
20435          if (respcode < 200) {
20436             /* ignore provisional responses */
20437             success = -1;
20438          } else {
20439             ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode);
20440             success = FALSE;
20441          }
20442          break;
20443       }
20444       if (success == FALSE) {
20445          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
20446       }
20447 
20448       if (p->owner && success != -1) {
20449          enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED;
20450          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
20451       }
20452       /* Confirm that we received this packet */
20453       transmit_response(p, "200 OK", req);
20454    } else if (!strcmp(event, "message-summary")) {
20455       const char *mailbox = NULL;
20456       char *c = ast_strdupa(get_body(req, "Voice-Message", ':'));
20457 
20458       if (!p->mwi) {
20459          struct sip_peer *peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
20460 
20461          if (peer) {
20462             mailbox = ast_strdupa(peer->unsolicited_mailbox);
20463             unref_peer(peer, "removing unsolicited mwi ref");
20464          }
20465       } else {
20466          mailbox = p->mwi->mailbox;
20467       }
20468 
20469       if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) {
20470          char *old = strsep(&c, " ");
20471          char *new = strsep(&old, "/");
20472          struct ast_event *event;
20473 
20474          if ((event = ast_event_new(AST_EVENT_MWI,
20475                      AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
20476                      AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "SIP_Remote",
20477                      AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(new),
20478                      AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(old),
20479                      AST_EVENT_IE_END))) {
20480             ast_event_queue_and_cache(event);
20481          }
20482          transmit_response(p, "200 OK", req);
20483       } else {
20484          transmit_response(p, "489 Bad event", req);
20485          res = -1;
20486       }
20487    } else if (!strcmp(event, "keep-alive")) {
20488        /* Used by Sipura/Linksys for NAT pinhole,
20489         * just confirm that we recieved the packet. */
20490       transmit_response(p, "200 OK", req);
20491    } else if (!strcmp(event, "call-completion")) {
20492       res = handle_cc_notify(p, req);
20493    } else {
20494       /* We don't understand this event. */
20495       transmit_response(p, "489 Bad event", req);
20496       res = -1;
20497    }
20498 
20499    if (!p->lastinvite)
20500       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20501 
20502    return res;
20503 }

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 20508 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_fake_auth_response(), transmit_response(), and transmit_response_with_allow().

Referenced by handle_incoming().

20509 {
20510    int res;
20511 
20512    if (p->lastinvite) {
20513       /* if this is a request in an active dialog, just confirm that the dialog exists. */
20514       transmit_response_with_allow(p, "200 OK", req, 0);
20515       return 0;
20516    }
20517 
20518    if (sip_cfg.auth_options_requests) {
20519       /* Do authentication if this OPTIONS request began the dialog */
20520       copy_request(&p->initreq, req);
20521       set_pvt_allowed_methods(p, req);
20522       res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr);
20523       if (res == AUTH_CHALLENGE_SENT) {
20524          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20525          return 0;
20526       }
20527       if (res < 0) { /* Something failed in authentication */
20528          if (res == AUTH_FAKE_AUTH) {
20529             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
20530             transmit_fake_auth_response(p, SIP_OPTIONS, req, XMIT_UNRELIABLE);
20531          } else {
20532             ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
20533             transmit_response(p, "403 Forbidden", req);
20534          }
20535          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20536          return 0;
20537       }
20538    }
20539 
20540    /* must go through authentication before getting here */
20541    res = (get_destination(p, req, NULL) == SIP_GET_DEST_EXTEN_FOUND ? 0 : -1);
20542    build_contact(p);
20543 
20544    if (ast_strlen_zero(p->context))
20545       ast_string_field_set(p, context, sip_cfg.default_context);
20546 
20547    if (ast_shutting_down())
20548       transmit_response_with_allow(p, "503 Unavailable", req, 0);
20549    else if (res < 0)
20550       transmit_response_with_allow(p, "404 Not Found", req, 0);
20551    else
20552       transmit_response_with_allow(p, "200 OK", req, 0);
20553 
20554    /* Destroy if this OPTIONS was the opening request, but not if
20555       it's in the middle of a normal call flow. */
20556    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20557 
20558    return res;
20559 }

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

Definition at line 22813 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, sip_scheddestroy(), transmit_fake_auth_response(), transmit_response(), and transmit_response_reliable().

Referenced by handle_incoming().

22814 {
22815    const char *etag = get_header(req, "SIP-If-Match");
22816    const char *event = get_header(req, "Event");
22817    struct event_state_compositor *esc;
22818    enum sip_publish_type publish_type;
22819    const char *expires_str = get_header(req, "Expires");
22820    int expires_int;
22821    int auth_result;
22822    int handler_result = -1;
22823 
22824    if (ast_strlen_zero(event)) {
22825       transmit_response(p, "489 Bad Event", req);
22826       return -1;
22827    }
22828 
22829    if (!(esc = get_esc(event))) {
22830       transmit_response(p, "489 Bad Event", req);
22831       return -1;
22832    }
22833 
22834    auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, addr);
22835    if (auth_result == AUTH_CHALLENGE_SENT) {
22836       p->lastinvite = seqno;
22837       return 0;
22838    } else if (auth_result < 0) {
22839       if (auth_result == AUTH_FAKE_AUTH) {
22840          ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
22841          transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
22842       } else {
22843          ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
22844          transmit_response_reliable(p, "403 Forbidden", req);
22845       }
22846       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22847       ast_string_field_set(p, theirtag, NULL);
22848       return 0;
22849    } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) {
22850       /* We need to stop retransmitting the 401 */
22851       __sip_ack(p, p->lastinvite, 1, 0);
22852    }
22853 
22854    publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int);
22855 
22856    /* It is the responsibility of these handlers to formulate any response
22857     * sent for a PUBLISH
22858     */
22859    switch (publish_type) {
22860    case SIP_PUBLISH_UNKNOWN:
22861       transmit_response(p, "400 Bad Request", req);
22862       break;
22863    case SIP_PUBLISH_INITIAL:
22864       handler_result = handle_sip_publish_initial(p, req, esc, expires_int);
22865       break;
22866    case SIP_PUBLISH_REFRESH:
22867       handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int);
22868       break;
22869    case SIP_PUBLISH_MODIFY:
22870       handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int);
22871       break;
22872    case SIP_PUBLISH_REMOVE:
22873       handler_result = handle_sip_publish_remove(p, req, esc, etag);
22874       break;
22875    default:
22876       transmit_response(p, "400 Impossible Condition", req);
22877       break;
22878    }
22879 
22880    return handler_result;
22881 }

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

Definition at line 21881 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_ref, ast_channel_trylock, ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, AST_LIST_EMPTY, ast_manager_event_multichan, ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_sip_domain(), context, copy_request(), EVENT_FLAG_CALL, FALSE, get_refer_info(), local_attended_transfer(), ast_channel::name, 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().

21882 {
21883    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
21884                /* Chan2: Call between asterisk and transferee */
21885 
21886    int res = 0;
21887    struct ast_channel *chans[2];
21888    current.req.data = NULL;
21889 
21890    if (req->debug)
21891       ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", p->callid, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller");
21892 
21893    if (!p->owner) {
21894       /* This is a REFER outside of an existing SIP dialog */
21895       /* We can't handle that, so decline it */
21896       ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
21897       transmit_response(p, "603 Declined (No dialog)", req);
21898       if (!req->ignore) {
21899          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
21900          sip_alreadygone(p);
21901          pvt_set_needdestroy(p, "outside of dialog");
21902       }
21903       return 0;
21904    }
21905 
21906 
21907    /* Check if transfer is allowed from this device */
21908    if (p->allowtransfer == TRANSFER_CLOSED ) {
21909       /* Transfer not allowed, decline */
21910       transmit_response(p, "603 Declined (policy)", req);
21911       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
21912       /* Do not destroy SIP session */
21913       return 0;
21914    }
21915 
21916    if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
21917       /* Already have a pending REFER */
21918       transmit_response(p, "491 Request pending", req);
21919       append_history(p, "Xfer", "Refer failed. Request pending.");
21920       return 0;
21921    }
21922 
21923    /* Allocate memory for call transfer data */
21924    if (!p->refer && !sip_refer_allocate(p)) {
21925       transmit_response(p, "500 Internal Server Error", req);
21926       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
21927       return -3;
21928    }
21929 
21930    res = get_refer_info(p, req); /* Extract headers */
21931 
21932    p->refer->status = REFER_SENT;
21933 
21934    if (res != 0) {
21935       switch (res) {
21936       case -2: /* Syntax error */
21937          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
21938          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
21939          if (req->debug)
21940             ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n");
21941          break;
21942       case -3:
21943          transmit_response(p, "603 Declined (Non sip: uri)", req);
21944          append_history(p, "Xfer", "Refer failed. Non SIP uri");
21945          if (req->debug)
21946             ast_debug(1, "SIP transfer to non-SIP uri denied\n");
21947          break;
21948       default:
21949          /* Refer-to extension not found, fake a failed transfer */
21950          transmit_response(p, "202 Accepted", req);
21951          append_history(p, "Xfer", "Refer failed. Bad extension.");
21952          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
21953          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
21954          if (req->debug)
21955             ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
21956          break;
21957       }
21958       return 0;
21959    }
21960    if (ast_strlen_zero(p->context))
21961       ast_string_field_set(p, context, sip_cfg.default_context);
21962 
21963    /* If we do not support SIP domains, all transfers are local */
21964    if (sip_cfg.allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
21965       p->refer->localtransfer = 1;
21966       if (sipdebug)
21967          ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
21968    } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
21969       /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
21970       p->refer->localtransfer = 1;
21971    } else if (sipdebug)
21972          ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
21973 
21974    /* Is this a repeat of a current request? Ignore it */
21975    /* Don't know what else to do right now. */
21976    if (req->ignore)
21977       return res;
21978 
21979    /* If this is a blind transfer, we have the following
21980    channels to work with:
21981    - chan1, chan2: The current call between transferer and transferee (2 channels)
21982    - target_channel: A new call from the transferee to the target (1 channel)
21983    We need to stay tuned to what happens in order to be able
21984    to bring back the call to the transferer */
21985 
21986    /* If this is a attended transfer, we should have all call legs within reach:
21987    - chan1, chan2: The call between the transferer and transferee (2 channels)
21988    - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
21989    We want to bridge chan2 with targetcall_pvt!
21990    
21991    The replaces call id in the refer message points
21992    to the call leg between Asterisk and the transferer.
21993    So we need to connect the target and the transferee channel
21994    and hangup the two other channels silently
21995    
21996    If the target is non-local, the call ID could be on a remote
21997    machine and we need to send an INVITE with replaces to the
21998    target. We basically handle this as a blind transfer
21999    and let the sip_call function catch that we need replaces
22000    header in the INVITE.
22001    */
22002 
22003 
22004    /* Get the transferer's channel */
22005    chans[0] = current.chan1 = p->owner;
22006 
22007    /* Find the other part of the bridge (2) - transferee */
22008    chans[1] = current.chan2 = ast_bridged_channel(current.chan1);
22009 
22010    if (sipdebug)
22011       ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>");
22012 
22013    if (!current.chan2 && !p->refer->attendedtransfer) {
22014       /* No bridged channel, propably IVR or echo or similar... */
22015       /* Guess we should masquerade or something here */
22016       /* Until we figure it out, refuse transfer of such calls */
22017       if (sipdebug)
22018          ast_debug(3, "Refused SIP transfer on non-bridged channel.\n");
22019       p->refer->status = REFER_FAILED;
22020       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
22021       transmit_response(p, "603 Declined", req);
22022       return -1;
22023    }
22024 
22025    if (current.chan2) {
22026       if (sipdebug)
22027          ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
22028 
22029       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
22030    }
22031 
22032    ast_set_flag(&p->flags[0], SIP_GOTREFER);
22033 
22034    /* Attended transfer: Find all call legs and bridge transferee with target*/
22035    if (p->refer->attendedtransfer) {
22036       if ((res = local_attended_transfer(p, &current, req, seqno, nounlock)))
22037          return res; /* We're done with the transfer */
22038       /* Fall through for remote transfers that we did not find locally */
22039       if (sipdebug)
22040          ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
22041       /* Fallthrough if we can't find the call leg internally */
22042    }
22043 
22044 
22045    /* Parking a call */
22046    if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
22047       /* Must release c's lock now, because it will not longer be accessible after the transfer! */
22048       *nounlock = 1;
22049       ast_channel_unlock(current.chan1);
22050       copy_request(&current.req, req);
22051       ast_clear_flag(&p->flags[0], SIP_GOTREFER);
22052       p->refer->status = REFER_200OK;
22053       append_history(p, "Xfer", "REFER to call parking.");
22054       ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransfer2Parking: Yes\r\n",
22055          current.chan1->name,
22056          current.chan1->uniqueid,
22057          p->callid,
22058          current.chan2->name,
22059          current.chan2->uniqueid,
22060          p->refer->refer_to);
22061       if (sipdebug)
22062          ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
22063       sip_park(current.chan2, current.chan1, req, seqno);
22064       return res;
22065    }
22066 
22067    /* Blind transfers and remote attended xfers */
22068    transmit_response(p, "202 Accepted", req);
22069 
22070    if (current.chan1 && current.chan2) {
22071       ast_debug(3, "chan1->name: %s\n", current.chan1->name);
22072       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
22073    }
22074    if (current.chan2) {
22075       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
22076       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
22077       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
22078       /* One for the new channel */
22079       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
22080       /* Attended transfer to remote host, prepare headers for the INVITE */
22081       if (p->refer->referred_by)
22082          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
22083    }
22084    /* Generate a Replaces string to be used in the INVITE during attended transfer */
22085    if (!ast_strlen_zero(p->refer->replaces_callid)) {
22086       char tempheader[SIPBUFSIZE];
22087       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid,
22088             p->refer->replaces_callid_totag ? ";to-tag=" : "",
22089             p->refer->replaces_callid_totag,
22090             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
22091             p->refer->replaces_callid_fromtag);
22092       if (current.chan2)
22093          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
22094    }
22095    /* Must release lock now, because it will not longer
22096       be accessible after the transfer! */
22097    *nounlock = 1;
22098    /*
22099     * Increase ref count so that we can delay channel destruction until after
22100     * we get a chance to fire off some events.
22101     */
22102    ast_channel_ref(current.chan1);
22103    ast_channel_unlock(current.chan1);
22104 
22105    /* Connect the call */
22106 
22107    /* FAKE ringing if not attended transfer */
22108    if (!p->refer->attendedtransfer)
22109       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE);
22110 
22111    /* For blind transfer, this will lead to a new call */
22112    /* For attended transfer to remote host, this will lead to
22113       a new SIP call with a replaces header, if the dial plan allows it
22114    */
22115    if (!current.chan2) {
22116       /* We have no bridge, so we're talking with Asterisk somehow */
22117       /* We need to masquerade this call */
22118       /* What to do to fix this situation:
22119          * Set up the new call in a new channel
22120          * Let the new channel masq into this channel
22121          Please add that code here :-)
22122       */
22123       p->refer->status = REFER_FAILED;
22124       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
22125       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
22126       append_history(p, "Xfer", "Refer failed (only bridged calls).");
22127       ast_channel_unref(current.chan1);
22128       return -1;
22129    }
22130    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
22131 
22132 
22133    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
22134       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
22135    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
22136 
22137    if (!res) {
22138       ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransferContext: %s\r\n",
22139          current.chan1->name,
22140          current.chan1->uniqueid,
22141          p->callid,
22142          current.chan2->name,
22143          current.chan2->uniqueid,
22144          p->refer->refer_to, p->refer->refer_to_context);
22145       /* Success  - we have a new channel */
22146       ast_debug(3, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
22147 
22148       while (ast_channel_trylock(current.chan1)) {
22149          sip_pvt_unlock(p);
22150          sched_yield();
22151          sip_pvt_lock(p);
22152       }
22153 
22154       /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */
22155       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);
22156       ast_channel_unlock(current.chan1);
22157 
22158       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
22159       if (p->refer->localtransfer)
22160          p->refer->status = REFER_200OK;
22161       if (p->owner)
22162          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
22163       append_history(p, "Xfer", "Refer succeeded.");
22164       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
22165       /* Do not hangup call, the other side do that when we say 200 OK */
22166       /* We could possibly implement a timer here, auto congestion */
22167       res = 0;
22168    } else {
22169       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
22170       ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
22171       append_history(p, "Xfer", "Refer failed.");
22172       /* Failure of some kind */
22173       p->refer->status = REFER_FAILED;
22174       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
22175       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
22176       res = -1;
22177    }
22178 
22179    ast_channel_unref(current.chan1);
22180 
22181    return res;
22182 }

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

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

Referenced by handle_incoming().

23337 {
23338    enum check_auth_result res;
23339 
23340    /* Use this as the basis */
23341    copy_request(&p->initreq, req);
23342    if (sipdebug)
23343       ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
23344    check_via(p, req);
23345    if ((res = register_verify(p, addr, req, e)) < 0) {
23346       const char *reason;
23347 
23348       switch (res) {
23349       case AUTH_SECRET_FAILED:
23350          reason = "Wrong password";
23351          break;
23352       case AUTH_USERNAME_MISMATCH:
23353          reason = "Username/auth name mismatch";
23354          break;
23355       case AUTH_NOT_FOUND:
23356          reason = "No matching peer found";
23357          break;
23358       case AUTH_UNKNOWN_DOMAIN:
23359          reason = "Not a local domain";
23360          break;
23361       case AUTH_PEER_NOT_DYNAMIC:
23362          reason = "Peer is not supposed to register";
23363          break;
23364       case AUTH_ACL_FAILED:
23365          reason = "Device does not match ACL";
23366          break;
23367       case AUTH_BAD_TRANSPORT:
23368          reason = "Device not configured to use this transport type";
23369          break;
23370       default:
23371          reason = "Unknown failure";
23372          break;
23373       }
23374       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
23375          get_header(req, "To"), ast_sockaddr_stringify(addr),
23376          reason);
23377       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
23378    } else
23379       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
23380 
23381    if (res < 1) {
23382       /* Destroy the session, but keep us around for just a bit in case they don't
23383          get our 200 OK */
23384       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23385    }
23386    return res;
23387 }

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

Handle incoming SUBSCRIBE request.

Definition at line 22953 of file chan_sip.c.

References __get_header(), add_peer_mwi_subs(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_t_ref, ao2_unlock, append_history, ast_debug, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_stringify(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose, build_contact(), build_route(), cb_extensionstate(), 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(), NONE, option_debug, parse_ok_contact(), pvt_set_needdestroy(), ref_peer(), 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_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minexpires(), transmit_state_notify(), TRUE, and unref_peer().

Referenced by handle_incoming().

22954 {
22955    int gotdest = 0;
22956    int res = 0;
22957    int firststate = AST_EXTENSION_REMOVED;
22958    struct sip_peer *authpeer = NULL;
22959    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
22960    int resubscribe = (p->subscribed != NONE);
22961    char *temp, *event;
22962    struct ao2_iterator i;
22963 
22964    if (p->initreq.headers) {  
22965       /* We already have a dialog */
22966       if (p->initreq.method != SIP_SUBSCRIBE) {
22967          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
22968          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
22969          transmit_response(p, "403 Forbidden (within dialog)", req);
22970          /* Do not destroy session, since we will break the call if we do */
22971          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);
22972          return 0;
22973       } else if (req->debug) {
22974          if (resubscribe)
22975             ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid);
22976          else
22977             ast_debug(1, "Got a new subscription %s (possibly with auth)\n", p->callid);
22978       }
22979    }
22980 
22981    /* Check if we have a global disallow setting on subscriptions.
22982       if so, we don't have to check peer settings after auth, which saves a lot of processing
22983    */
22984    if (!sip_cfg.allowsubscribe) {
22985       transmit_response(p, "403 Forbidden (policy)", req);
22986       pvt_set_needdestroy(p, "forbidden");
22987       return 0;
22988    }
22989 
22990    if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */
22991       const char *to = get_header(req, "To");
22992       char totag[128];
22993       set_pvt_allowed_methods(p, req);
22994 
22995       /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
22996       if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
22997          if (req->debug)
22998             ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
22999          transmit_response(p, "481 Subscription does not exist", req);
23000          pvt_set_needdestroy(p, "subscription does not exist");
23001          return 0;
23002       }
23003 
23004       /* Use this as the basis */
23005       if (req->debug)
23006          ast_verbose("Creating new subscription\n");
23007 
23008       copy_request(&p->initreq, req);
23009       if (sipdebug)
23010          ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
23011       check_via(p, req);
23012       build_route(p, req, 0);
23013    } else if (req->debug && req->ignore)
23014       ast_verbose("Ignoring this SUBSCRIBE request\n");
23015 
23016    /* Find parameters to Event: header value and remove them for now */
23017    if (ast_strlen_zero(eventheader)) {
23018       transmit_response(p, "489 Bad Event", req);
23019       ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n");
23020       pvt_set_needdestroy(p, "unknown event package in subscribe");
23021       return 0;
23022    }
23023 
23024    if ( (strchr(eventheader, ';'))) {
23025       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
23026       temp = strchr(event, ';');       
23027       *temp = '\0';           /* Remove any options for now */
23028                      /* We might need to use them later :-) */
23029    } else
23030       event = (char *) eventheader;    /* XXX is this legal ? */
23031 
23032    /* Handle authentication */
23033    res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, addr, &authpeer);
23034    /* if an authentication response was sent, we are done here */
23035    if (res == AUTH_CHALLENGE_SENT)  /* authpeer = NULL here */
23036       return 0;
23037    if (res < 0) {
23038       if (res == AUTH_FAKE_AUTH) {
23039          ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
23040          transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
23041       } else {
23042          ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", get_header(req, "From"));
23043          transmit_response_reliable(p, "403 Forbidden", req);
23044       }
23045       pvt_set_needdestroy(p, "authentication failed");
23046       return 0;
23047    }
23048 
23049    /* At this point, authpeer cannot be NULL. Remember we hold a reference,
23050     * so we must release it when done.
23051     * XXX must remove all the checks for authpeer == NULL.
23052     */
23053 
23054    /* Check if this device  is allowed to subscribe at all */
23055    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
23056       transmit_response(p, "403 Forbidden (policy)", req);
23057       pvt_set_needdestroy(p, "subscription not allowed");
23058       if (authpeer)
23059          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)");
23060       return 0;
23061    }
23062 
23063    if (strcmp(event, "message-summary") && strcmp(event, "call-completion")) {
23064       /* Get destination right away */
23065       gotdest = get_destination(p, NULL, NULL);
23066    }
23067 
23068    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
23069    parse_ok_contact(p, req);
23070 
23071    build_contact(p);
23072    if (gotdest != SIP_GET_DEST_EXTEN_FOUND) {
23073       if (gotdest == SIP_GET_DEST_INVALID_URI) {
23074          transmit_response(p, "416 Unsupported URI scheme", req);
23075       } else {
23076          transmit_response(p, "404 Not Found", req);
23077       }
23078       pvt_set_needdestroy(p, "subscription target not found");
23079       if (authpeer)
23080          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
23081       return 0;
23082    }
23083 
23084    /* Initialize tag for new subscriptions */   
23085    if (ast_strlen_zero(p->tag))
23086       make_our_tag(p->tag, sizeof(p->tag));
23087 
23088    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
23089       unsigned int pidf_xml;
23090       const char *accept;
23091       int start = 0;
23092       enum subscriptiontype subscribed = NONE;
23093       const char *unknown_acceptheader = NULL;
23094 
23095       if (authpeer)  /* We do not need the authpeer any more */
23096          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
23097 
23098       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
23099       accept = __get_header(req, "Accept", &start);
23100       while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
23101          pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0;
23102 
23103          /* Older versions of Polycom firmware will claim pidf+xml, but really
23104           * they only support xpidf+xml. */
23105          if (pidf_xml && strstr(p->useragent, "Polycom")) {
23106             subscribed = XPIDF_XML;
23107          } else if (pidf_xml) {
23108             subscribed = PIDF_XML;         /* RFC 3863 format */
23109          } else if (strstr(accept, "application/dialog-info+xml")) {
23110             subscribed = DIALOG_INFO_XML;
23111             /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
23112          } else if (strstr(accept, "application/cpim-pidf+xml")) {
23113             subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
23114          } else if (strstr(accept, "application/xpidf+xml")) {
23115             subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
23116          } else {
23117             unknown_acceptheader = accept;
23118          }
23119          /* check to see if there is another Accept header present */
23120          accept = __get_header(req, "Accept", &start);
23121       }
23122 
23123       if (!start) {
23124          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
23125             transmit_response(p, "489 Bad Event", req);
23126             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: "
23127                "stateid: %d, laststate: %d, dialogver: %d, subscribecont: "
23128                "'%s', subscribeuri: '%s'\n",
23129                p->stateid,
23130                p->laststate,
23131                p->dialogver,
23132                p->subscribecontext,
23133                p->subscribeuri);
23134             pvt_set_needdestroy(p, "no Accept header");
23135             return 0;
23136          }
23137          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
23138             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
23139       } else if (subscribed == NONE) {
23140          /* Can't find a format for events that we know about */
23141          char mybuf[200];
23142          if (!ast_strlen_zero(unknown_acceptheader)) {
23143             snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader);
23144          } else {
23145             snprintf(mybuf, sizeof(mybuf), "489 Bad Event");
23146          }
23147          transmit_response(p, mybuf, req);
23148          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:"
23149             "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d,"
23150             "dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
23151             unknown_acceptheader,
23152             (int)p->subscribed,
23153             p->stateid,
23154             p->laststate,
23155             p->dialogver,
23156             p->subscribecontext,
23157             p->subscribeuri);
23158          pvt_set_needdestroy(p, "unrecognized format");
23159          return 0;
23160       } else {
23161          p->subscribed = subscribed;
23162       }
23163    } else if (!strcmp(event, "message-summary")) {
23164       int start = 0;
23165       int found_supported = 0;
23166       const char *acceptheader;
23167 
23168       acceptheader = __get_header(req, "Accept", &start);
23169       while (!found_supported && !ast_strlen_zero(acceptheader)) {
23170          found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1;
23171          if (!found_supported && (option_debug > 2)) {
23172             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
23173          }
23174          acceptheader = __get_header(req, "Accept", &start);
23175       }
23176       if (start && !found_supported) {
23177          /* Format requested that we do not support */
23178          transmit_response(p, "406 Not Acceptable", req);
23179          ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
23180          pvt_set_needdestroy(p, "unknown format");
23181          if (authpeer)
23182             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
23183          return 0;
23184       }
23185       /* Looks like they actually want a mailbox status
23186         This version of Asterisk supports mailbox subscriptions
23187         The subscribed URI needs to exist in the dial plan
23188         In most devices, this is configurable to the voicemailmain extension you use
23189       */
23190       if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) {
23191          transmit_response(p, "404 Not found (no mailbox)", req);
23192          pvt_set_needdestroy(p, "received 404 response");
23193          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
23194          if (authpeer)
23195             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 4)");
23196          return 0;
23197       }
23198 
23199       p->subscribed = MWI_NOTIFICATION;
23200       if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) {
23201          add_peer_mwi_subs(authpeer);
23202       }
23203       if (authpeer->mwipvt && authpeer->mwipvt != p) {   /* Destroy old PVT if this is a new one */
23204          /* We only allow one subscription per peer */
23205          dialog_unlink_all(authpeer->mwipvt, TRUE, TRUE);
23206          authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
23207          /* sip_destroy(authpeer->mwipvt); */
23208       }
23209       if (authpeer->mwipvt)
23210          dialog_unref(authpeer->mwipvt, "Unref previously stored mwipvt dialog pointer");
23211       authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");      /* Link from peer to pvt UH- should this be dialog_ref()? */
23212       if (p->relatedpeer)
23213          unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
23214       p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");  /* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */
23215       /* Do not release authpeer here */
23216    } else if (!strcmp(event, "call-completion")) {
23217       handle_cc_subscribe(p, req);
23218    } else { /* At this point, Asterisk does not understand the specified event */
23219       transmit_response(p, "489 Bad Event", req);
23220       ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event);
23221       pvt_set_needdestroy(p, "unknown event package");
23222       if (authpeer)
23223          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)");
23224       return 0;
23225    }
23226 
23227    /* Add subscription for extension state from the PBX core */
23228    if (p->subscribed != MWI_NOTIFICATION  && p->subscribed != CALL_COMPLETION && !resubscribe) {
23229       if (p->stateid > -1) {
23230          ast_extension_state_del(p->stateid, cb_extensionstate);
23231          /* we need to dec the refcount, now that the extensionstate is removed */
23232          dialog_unref(p, "the extensionstate containing this dialog ptr was deleted");
23233       }
23234       p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, dialog_ref(p,"copying dialog ptr into extension state struct"));
23235    }
23236 
23237    if (!req->ignore && p)
23238       p->lastinvite = seqno;
23239    if (p && !p->needdestroy) {
23240       p->expiry = atoi(get_header(req, "Expires"));
23241 
23242       /* check if the requested expiry-time is within the approved limits from sip.conf */
23243       if (p->expiry > max_expiry) {
23244          p->expiry = max_expiry;
23245       } else if (p->expiry < min_expiry && p->expiry > 0) {
23246          transmit_response_with_minexpires(p, "423 Interval too small", req);
23247          ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" "
23248             "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n",
23249             p->exten, p->context, p->expiry, min_expiry);
23250          p->expiry = min_expiry;
23251          pvt_set_needdestroy(p, "Expires is less that the min expires allowed. ");
23252          return 0;
23253       }
23254 
23255       if (sipdebug) {
23256          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) {
23257             ast_debug(2, "Adding subscription for mailbox notification - peer %s\n", p->relatedpeer->name);
23258          } else if (p->subscribed == CALL_COMPLETION) {
23259             ast_debug(2, "Adding CC subscription for peer %s\n", p->username);
23260          } else {
23261             ast_debug(2, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
23262          }
23263       }
23264       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
23265          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
23266       if (p->expiry > 0)
23267          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
23268 
23269       if (p->subscribed == MWI_NOTIFICATION) {
23270          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
23271          transmit_response(p, "200 OK", req);
23272          if (p->relatedpeer) {   /* Send first notification */
23273             ao2_lock(p->relatedpeer); /* was WRLOCK */
23274             sip_send_mwi_to_peer(p->relatedpeer, NULL, 0);
23275             ao2_unlock(p->relatedpeer);
23276          }
23277       } else if (p->subscribed != CALL_COMPLETION) {
23278          struct sip_pvt *p_old;
23279 
23280          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
23281 
23282             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));
23283             transmit_response(p, "404 Not found", req);
23284             pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
23285             return 0;
23286          }
23287          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
23288          transmit_response(p, "200 OK", req);
23289          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
23290          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
23291          /* hide the 'complete' exten/context in the refer_to field for later display */
23292          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
23293 
23294          /* remove any old subscription from this peer for the same exten/context,
23295          as the peer has obviously forgotten about it and it's wasteful to wait
23296          for it to expire and send NOTIFY messages to the peer only to have them
23297          ignored (or generate errors)
23298          */
23299          i = ao2_iterator_init(dialogs, 0);
23300          while ((p_old = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
23301             if (p_old == p) {
23302                ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
23303                continue;
23304             }
23305             if (p_old->initreq.method != SIP_SUBSCRIBE) {
23306                ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
23307                continue;
23308             }
23309             if (p_old->subscribed == NONE) {
23310                ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
23311                continue;
23312             }
23313             sip_pvt_lock(p_old);
23314             if (!strcmp(p_old->username, p->username)) {
23315                if (!strcmp(p_old->exten, p->exten) &&
23316                    !strcmp(p_old->context, p->context)) {
23317                   pvt_set_needdestroy(p_old, "replacing subscription");
23318                   sip_pvt_unlock(p_old);
23319                   ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before break");
23320                   break;
23321                }
23322             }
23323             sip_pvt_unlock(p_old);
23324             ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next");
23325          }
23326          ao2_iterator_destroy(&i);
23327       }
23328       if (!p->expiry) {
23329          pvt_set_needdestroy(p, "forcing expiration");
23330       }
23331    }
23332    return 1;
23333 }

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

20752 {
20753    if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) {
20754       transmit_response(p, "501 Method Not Implemented", req);
20755       return 0;
20756    }
20757    if (get_rpid(p, req)) {
20758       struct ast_party_connected_line connected;
20759       struct ast_set_party_connected_line update_connected;
20760       ast_party_connected_line_init(&connected);
20761       memset(&update_connected, 0, sizeof(update_connected));
20762       if (p->cid_num) {
20763          update_connected.id.number = 1;
20764          connected.id.number.valid = 1;
20765          connected.id.number.str = (char *) p->cid_num;
20766          connected.id.number.presentation = p->callingpres;
20767       }
20768       if (p->cid_name) {
20769          update_connected.id.name = 1;
20770          connected.id.name.valid = 1;
20771          connected.id.name.str = (char *) p->cid_name;
20772          connected.id.name.presentation = p->callingpres;
20773       }
20774       connected.id.tag = (char *) p->cid_tag;
20775       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
20776       ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
20777    }
20778    transmit_response(p, "200 OK", req);
20779    return 0;
20780 }

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

Handle SIP response in dialogue.

Note:
only called by handle_incoming

Definition at line 19546 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), ao2_callback, append_history, AST_CAUSE_PROTOCOL_ERROR, AST_CC_CCBS, ast_cc_monitor_failed(), 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, cb_extensionstate(), change_redirecting_information(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), find_sip_monitor_instance_by_subscription_pvt(), get_header(), gettag(), handle_response_invite(), 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().

19547 {
19548    struct ast_channel *owner;
19549    int sipmethod;
19550    int res = 1;
19551    const char *c = get_header(req, "Cseq");
19552    /* 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 */
19553    char *c_copy = ast_strdupa(c);
19554    /* Skip the Cseq and its subsequent spaces */
19555    const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
19556 
19557    if (!msg)
19558       msg = "";
19559 
19560    sipmethod = find_sip_method(msg);
19561 
19562    owner = p->owner;
19563    if (owner) {
19564       const char *rp = NULL, *rh = NULL;
19565 
19566       owner->hangupcause = 0;
19567       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && (rh = get_header(req, "Reason"))) {
19568          rh = ast_skip_blanks(rh);
19569          if (!strncasecmp(rh, "Q.850", 5)) {
19570             rp = strstr(rh, "cause=");
19571             if (rp && sscanf(rp + 6, "%30d", &owner->hangupcause) == 1) {
19572                owner->hangupcause &= 0x7f;
19573                if (req->debug)
19574                   ast_verbose("Using Reason header for cause code: %d\n", owner->hangupcause);
19575             }
19576          }
19577       }
19578 
19579       if (!owner->hangupcause)
19580          owner->hangupcause = hangup_sip2cause(resp);
19581    }
19582 
19583    if (p->socket.type == SIP_TRANSPORT_UDP) {
19584       int ack_res = FALSE;
19585 
19586       /* Acknowledge whatever it is destined for */
19587       if ((resp >= 100) && (resp <= 199)) {
19588          /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */
19589          if (sipmethod == SIP_INVITE) {
19590             ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
19591          }
19592       } else {
19593          ack_res = __sip_ack(p, seqno, 0, sipmethod);
19594       }
19595 
19596       if (ack_res == FALSE) {
19597          /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */
19598          if (sipmethod == SIP_INVITE && resp >= 200) {
19599             transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE);
19600          }
19601 
19602          append_history(p, "Ignore", "Ignoring this retransmit\n");
19603          return;
19604       }
19605    }
19606 
19607    /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
19608    if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite)
19609       p->pendinginvite = 0;
19610 
19611    /* Get their tag if we haven't already */
19612    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
19613       char tag[128];
19614 
19615       gettag(req, "To", tag, sizeof(tag));
19616       ast_string_field_set(p, theirtag, tag);
19617    }
19618    /* This needs to be configurable on a channel/peer level,
19619       not mandatory for all communication. Sadly enough, NAT implementations
19620       are not so stable so we can always rely on these headers.
19621       Temporarily disabled, while waiting for fix.
19622       Fix assigned to Rizzo :-)
19623    */
19624    /* check_via_response(p, req); */
19625 
19626    /* RFC 3261 Section 15 specifies that if we receive a 408 or 481
19627     * in response to a BYE, then we should end the current dialog
19628     * and session.  It is known that at least one phone manufacturer
19629     * potentially will send a 404 in response to a BYE, so we'll be
19630     * liberal in what we accept and end the dialog and session if we
19631     * receive any of those responses to a BYE.
19632     */
19633    if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) {
19634       pvt_set_needdestroy(p, "received 4XX response to a BYE");
19635       return;
19636    }
19637 
19638    if (p->relatedpeer && p->method == SIP_OPTIONS) {
19639       /* We don't really care what the response is, just that it replied back.
19640          Well, as long as it's not a 100 response...  since we might
19641          need to hang around for something more "definitive" */
19642       if (resp != 100)
19643          handle_response_peerpoke(p, resp, req);
19644    } else if (sipmethod == SIP_REFER && resp >= 200) {
19645       handle_response_refer(p, resp, rest, req, seqno);
19646    } else if (sipmethod == SIP_PUBLISH) {
19647       /* SIP PUBLISH transcends this morass of doodoo and instead
19648        * we just always call the response handler. Good gravy!
19649        */
19650       handle_response_publish(p, resp, rest, req, seqno);
19651    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
19652       switch(resp) {
19653       case 100:   /* 100 Trying */
19654       case 101:   /* 101 Dialog establishment */
19655       case 183:   /* 183 Session Progress */
19656       case 180:   /* 180 Ringing */
19657       case 182:   /* 182 Queued */
19658       case 181:   /* 181 Call Is Being Forwarded */
19659          if (sipmethod == SIP_INVITE)
19660             handle_response_invite(p, resp, rest, req, seqno);
19661          break;
19662       case 200:   /* 200 OK */
19663          p->authtries = 0; /* Reset authentication counter */
19664          if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
19665             /* We successfully transmitted a message
19666                or a video update request in INFO */
19667             /* Nothing happens here - the message is inside a dialog */
19668          } else if (sipmethod == SIP_INVITE) {
19669             handle_response_invite(p, resp, rest, req, seqno);
19670          } else if (sipmethod == SIP_NOTIFY) {
19671             handle_response_notify(p, resp, rest, req, seqno);
19672          } else if (sipmethod == SIP_REGISTER) {
19673             res = handle_response_register(p, resp, rest, req, seqno);
19674          } else if (sipmethod == SIP_SUBSCRIBE) {
19675             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
19676             handle_response_subscribe(p, resp, rest, req, seqno);
19677          } else if (sipmethod == SIP_BYE) {     /* Ok, we're ready to go */
19678             pvt_set_needdestroy(p, "received 200 response");
19679             ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
19680          }
19681          break;
19682       case 401: /* Not www-authorized on SIP method */
19683       case 407: /* Proxy auth required */
19684          if (sipmethod == SIP_INVITE)
19685             handle_response_invite(p, resp, rest, req, seqno);
19686          else if (sipmethod == SIP_NOTIFY)
19687             handle_response_notify(p, resp, rest, req, seqno);
19688          else if (sipmethod == SIP_SUBSCRIBE)
19689             handle_response_subscribe(p, resp, rest, req, seqno);
19690          else if (p->registry && sipmethod == SIP_REGISTER)
19691             res = handle_response_register(p, resp, rest, req, seqno);
19692          else if (sipmethod == SIP_UPDATE) {
19693             handle_response_update(p, resp, rest, req, seqno);
19694          } else if (sipmethod == SIP_BYE) {
19695             if (p->options)
19696                p->options->auth_type = resp;
19697             if (ast_strlen_zero(p->authname)) {
19698                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n",
19699                      msg, ast_sockaddr_stringify(&p->recv));
19700                pvt_set_needdestroy(p, "unable to authenticate BYE");
19701             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp,  sipmethod, 0)) {
19702                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
19703                pvt_set_needdestroy(p, "failed to authenticate BYE");
19704             }
19705          } else {
19706             ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To"));
19707             pvt_set_needdestroy(p, "received 407 response");
19708          }
19709          break;
19710       case 403: /* Forbidden - we failed authentication */
19711          if (sipmethod == SIP_INVITE)
19712             handle_response_invite(p, resp, rest, req, seqno);
19713          else if (sipmethod == SIP_SUBSCRIBE)
19714             handle_response_subscribe(p, resp, rest, req, seqno);
19715          else if (p->registry && sipmethod == SIP_REGISTER)
19716             res = handle_response_register(p, resp, rest, req, seqno);
19717          else {
19718             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
19719             pvt_set_needdestroy(p, "received 403 response");
19720          }
19721          break;
19722       case 404: /* Not found */
19723          if (p->registry && sipmethod == SIP_REGISTER)
19724             res = handle_response_register(p, resp, rest, req, seqno);
19725          else if (sipmethod == SIP_INVITE)
19726             handle_response_invite(p, resp, rest, req, seqno);
19727          else if (sipmethod == SIP_SUBSCRIBE)
19728             handle_response_subscribe(p, resp, rest, req, seqno);
19729          else if (owner)
19730             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19731          break;
19732       case 423: /* Interval too brief */
19733          if (sipmethod == SIP_REGISTER)
19734             res = handle_response_register(p, resp, rest, req, seqno);
19735          break;
19736       case 408: /* Request timeout - terminate dialog */
19737          if (sipmethod == SIP_INVITE)
19738             handle_response_invite(p, resp, rest, req, seqno);
19739          else if (sipmethod == SIP_REGISTER)
19740             res = handle_response_register(p, resp, rest, req, seqno);
19741          else if (sipmethod == SIP_BYE) {
19742             pvt_set_needdestroy(p, "received 408 response");
19743             ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
19744          } else {
19745             if (owner)
19746                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19747             pvt_set_needdestroy(p, "received 408 response");
19748          }
19749          break;
19750 
19751       case 422: /* Session-Timers: Session Interval Too Small */
19752          if (sipmethod == SIP_INVITE) {
19753             handle_response_invite(p, resp, rest, req, seqno);
19754          }
19755          break;
19756 
19757       case 481: /* Call leg does not exist */
19758          if (sipmethod == SIP_INVITE) {
19759             handle_response_invite(p, resp, rest, req, seqno);
19760          } else if (sipmethod == SIP_SUBSCRIBE) {
19761             handle_response_subscribe(p, resp, rest, req, seqno);
19762          } else if (sipmethod == SIP_BYE) {
19763             /* The other side has no transaction to bye,
19764             just assume it's all right then */
19765             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
19766          } else if (sipmethod == SIP_CANCEL) {
19767             /* The other side has no transaction to cancel,
19768             just assume it's all right then */
19769             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
19770          } else {
19771             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
19772             /* Guessing that this is not an important request */
19773          }
19774          break;
19775       case 487:
19776          if (sipmethod == SIP_INVITE)
19777             handle_response_invite(p, resp, rest, req, seqno);
19778          break;
19779       case 415: /* Unsupported media type */
19780       case 488: /* Not acceptable here - codec error */
19781       case 606: /* Not Acceptable */
19782          if (sipmethod == SIP_INVITE)
19783             handle_response_invite(p, resp, rest, req, seqno);
19784          break;
19785       case 491: /* Pending */
19786          if (sipmethod == SIP_INVITE)
19787             handle_response_invite(p, resp, rest, req, seqno);
19788          else {
19789             ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
19790             pvt_set_needdestroy(p, "received 491 response");
19791          }
19792          break;
19793       case 405:
19794       case 501: /* Not Implemented */
19795          mark_method_unallowed(&p->allowed_methods, sipmethod);
19796          if (p->relatedpeer) {
19797             mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod);
19798          }
19799          if (sipmethod == SIP_INVITE)
19800             handle_response_invite(p, resp, rest, req, seqno);
19801          else
19802             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg);
19803          break;
19804          /* Fallthrough */
19805       default:
19806          if ((resp >= 300) && (resp < 700)) {
19807             /* Fatal response */
19808             if ((resp != 487))
19809                ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
19810    
19811             if (sipmethod == SIP_INVITE)
19812                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
19813 
19814             /* XXX Locking issues?? XXX */
19815             switch(resp) {
19816             case 300: /* Multiple Choices */
19817             case 301: /* Moved permanently */
19818             case 302: /* Moved temporarily */
19819             case 305: /* Use Proxy */
19820             if (p->owner) {
19821                struct ast_party_redirecting redirecting;
19822                struct ast_set_party_redirecting update_redirecting;
19823 
19824                ast_party_redirecting_init(&redirecting);
19825                change_redirecting_information(p, req, &redirecting,
19826                   &update_redirecting, TRUE);
19827                ast_channel_set_redirecting(p->owner, &redirecting,
19828                   &update_redirecting);
19829                ast_party_redirecting_free(&redirecting);
19830             }
19831                /* Fall through */
19832             case 486: /* Busy here */
19833             case 600: /* Busy everywhere */
19834             case 603: /* Decline */
19835                if (p->owner) {
19836                   sip_handle_cc(p, req, AST_CC_CCBS);
19837                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
19838                }
19839                break;
19840             case 482: /* Loop Detected */
19841             case 480: /* Temporarily Unavailable */
19842             case 404: /* Not Found */
19843             case 410: /* Gone */
19844             case 400: /* Bad Request */
19845             case 500: /* Server error */
19846                if (sipmethod == SIP_SUBSCRIBE) {
19847                   handle_response_subscribe(p, resp, rest, req, seqno);
19848                   break;
19849                }
19850                /* Fall through */
19851             case 502: /* Bad gateway */
19852             case 503: /* Service Unavailable */
19853             case 504: /* Server Timeout */
19854                if (owner)
19855                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19856                break;
19857             default:
19858                /* Send hangup */ 
19859                if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE)
19860                   ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
19861                break;
19862             }
19863             /* ACK on invite */
19864             if (sipmethod == SIP_INVITE)
19865                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19866             if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO)
19867                sip_alreadygone(p);
19868             if (!p->owner) {
19869                pvt_set_needdestroy(p, "transaction completed");
19870             }
19871          } else if ((resp >= 100) && (resp < 200)) {
19872             if (sipmethod == SIP_INVITE) {
19873                if (!req->ignore && sip_cancel_destroy(p))
19874                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19875                if (find_sdp(req))
19876                   process_sdp(p, req, SDP_T38_NONE);
19877                if (p->owner) {
19878                   /* Queue a progress frame */
19879                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
19880                }
19881             }
19882          } else
19883             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));
19884       }
19885    } else { 
19886       /* Responses to OUTGOING SIP requests on INCOMING calls
19887          get handled here. As well as out-of-call message responses */
19888       if (req->debug)
19889          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
19890 
19891       if (sipmethod == SIP_INVITE && resp == 200) {
19892          /* Tags in early session is replaced by the tag in 200 OK, which is
19893          the final reply to our INVITE */
19894          char tag[128];
19895 
19896          gettag(req, "To", tag, sizeof(tag));
19897          ast_string_field_set(p, theirtag, tag);
19898       }
19899 
19900       if (sipmethod == SIP_SUBSCRIBE && resp >= 400) {
19901          struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances,
19902                0, find_sip_monitor_instance_by_subscription_pvt, p);
19903          if (monitor_instance) {
19904             ast_cc_monitor_failed(monitor_instance->core_id, monitor_instance->device_name,
19905                   "Received error response to our SUBSCRIBE");
19906             return;
19907          }
19908       }
19909 
19910       switch(resp) {
19911       case 200:
19912          if (sipmethod == SIP_INVITE) {
19913             handle_response_invite(p, resp, rest, req, seqno);
19914          } else if (sipmethod == SIP_CANCEL) {
19915             ast_debug(1, "Got 200 OK on CANCEL\n");
19916 
19917             /* Wait for 487, then destroy */
19918          } else if (sipmethod == SIP_NOTIFY) {
19919             /* They got the notify, this is the end */
19920             if (p->owner) {
19921                if (p->refer) {
19922                   ast_debug(1, "Got 200 OK on NOTIFY for transfer\n");
19923                } else
19924                   ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
19925                /* ast_queue_hangup(p->owner); Disabled */
19926             } else {
19927                if (!p->subscribed && !p->refer) {
19928                   pvt_set_needdestroy(p, "transaction completed");
19929                }
19930                if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
19931                   /* Ready to send the next state we have on queue */
19932                   ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
19933                   cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
19934                }
19935             }
19936          } else if (sipmethod == SIP_BYE) {
19937             pvt_set_needdestroy(p, "transaction completed");
19938          } else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
19939             /* We successfully transmitted a message or
19940                a video update request in INFO */
19941             ;
19942          }
19943          break;
19944       case 401:   /* www-auth */
19945       case 407:
19946          if (sipmethod == SIP_INVITE)
19947             handle_response_invite(p, resp, rest, req, seqno);
19948          else if (sipmethod == SIP_BYE) {
19949             if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) {
19950                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
19951                pvt_set_needdestroy(p, "failed to authenticate BYE");
19952             }
19953          }
19954          break;
19955       case 481:   /* Call leg does not exist */
19956          if (sipmethod == SIP_INVITE) {
19957             /* Re-invite failed */
19958             handle_response_invite(p, resp, rest, req, seqno);
19959          } else if (sipmethod == SIP_BYE) {
19960             pvt_set_needdestroy(p, "received 481 response");
19961          } else if (sipdebug) {
19962             ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
19963          }
19964          break;
19965       case 501: /* Not Implemented */
19966          if (sipmethod == SIP_INVITE)
19967             handle_response_invite(p, resp, rest, req, seqno);
19968          break;
19969       default: /* Errors without handlers */
19970          if ((resp >= 100) && (resp < 200)) {
19971             if (sipmethod == SIP_INVITE) {   /* re-invite */
19972                if (!req->ignore && sip_cancel_destroy(p))
19973                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19974             }
19975          }
19976          if ((resp >= 300) && (resp < 700)) {
19977             if ((resp != 487))
19978                ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
19979             switch(resp) {
19980             case 415: /* Unsupported media type */
19981             case 488: /* Not acceptable here - codec error */
19982             case 603: /* Decline */
19983             case 500: /* Server error */
19984             case 502: /* Bad gateway */
19985             case 503: /* Service Unavailable */
19986             case 504: /* Server timeout */
19987 
19988                /* re-invite failed */
19989                if (sipmethod == SIP_INVITE && sip_cancel_destroy(p))
19990                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19991                break;
19992             }
19993          }
19994          break;
19995       }
19996    }
19997 }

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

Handle SIP response to INVITE dialogue.

Definition at line 18703 of file chan_sip.c.

References append_history, 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_debug, ast_log(), ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_instance_activate(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_route(), change_redirecting_information(), change_t38_state(), check_pendings(), connected, do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), get_header(), get_rpid(), ast_party_connected_line::id, ast_set_party_connected_line::id, LOG_NOTICE, LOG_WARNING, manager_event, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, parse_ok_contact(), parse_session_expires(), ast_party_name::presentation, ast_party_number::presentation, proc_422_rsp(), process_sdp(), pvt_set_needdestroy(), set_address_from_contact(), set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_handle_cc(), sip_reinvite_retry(), sip_scheddestroy(), ast_party_connected_line::source, st_get_mode(), start_session_timer(), ast_party_name::str, ast_party_number::str, ast_party_id::tag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, update_call_counter(), update_redirecting(), ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_response().

18704 {
18705    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
18706    int res = 0;
18707    int xmitres = 0;
18708    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
18709    char *p_hdrval;
18710    int rtn;
18711    struct ast_party_connected_line connected;
18712    struct ast_set_party_connected_line update_connected;
18713 
18714    if (reinvite)
18715       ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
18716    else
18717       ast_debug(4, "SIP response %d to standard invite\n", resp);
18718 
18719    if (p->alreadygone) { /* This call is already gone */
18720       ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
18721       return;
18722    }
18723 
18724    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
18725    /* Don't auto congest anymore since we've gotten something useful back */
18726    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"));
18727 
18728    /* RFC3261 says we must treat every 1xx response (but not 100)
18729       that we don't recognize as if it was 183.
18730    */
18731    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183)
18732       resp = 183;
18733 
18734    /* Any response between 100 and 199 is PROCEEDING */
18735    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
18736       p->invitestate = INV_PROCEEDING;
18737 
18738    /* Final response, not 200 ? */
18739    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
18740       p->invitestate = INV_COMPLETED;
18741    
18742    /* Final response, clear out pending invite */
18743    if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite)
18744       p->pendinginvite = 0;
18745 
18746    /* If this is a response to our initial INVITE, we need to set what we can use
18747     * for this peer.
18748     */
18749    if (!reinvite) {
18750       set_pvt_allowed_methods(p, req);
18751    }     
18752 
18753    switch (resp) {
18754    case 100:   /* Trying */
18755    case 101:   /* Dialog establishment */
18756       if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p))
18757          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
18758       check_pendings(p);
18759       break;
18760 
18761    case 180:   /* 180 Ringing */
18762    case 182:       /* 182 Queued */
18763       if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p))
18764          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
18765       if (!req->ignore && p->owner) {
18766          if (get_rpid(p, req)) {
18767             ast_party_connected_line_init(&connected);
18768             memset(&update_connected, 0, sizeof(update_connected));
18769             if (p->cid_num) {
18770                update_connected.id.number = 1;
18771                connected.id.number.valid = 1;
18772                connected.id.number.str = (char *) p->cid_num;
18773                connected.id.number.presentation = p->callingpres;
18774             }
18775             if (p->cid_name) {
18776                update_connected.id.name = 1;
18777                connected.id.name.valid = 1;
18778                connected.id.name.str = (char *) p->cid_name;
18779                connected.id.name.presentation = p->callingpres;
18780             }
18781             connected.id.tag = (char *) p->cid_tag;
18782             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
18783             ast_channel_queue_connected_line_update(p->owner, &connected,
18784                &update_connected);
18785          }
18786          sip_handle_cc(p, req, AST_CC_CCNR);
18787          ast_queue_control(p->owner, AST_CONTROL_RINGING);
18788          if (p->owner->_state != AST_STATE_UP) {
18789             ast_setstate(p->owner, AST_STATE_RINGING);
18790          }
18791       }
18792       if (find_sdp(req)) {
18793          if (p->invitestate != INV_CANCELLED)
18794             p->invitestate = INV_EARLY_MEDIA;
18795          res = process_sdp(p, req, SDP_T38_NONE);
18796          if (!req->ignore && p->owner) {
18797             /* Queue a progress frame only if we have SDP in 180 or 182 */
18798             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
18799          }
18800          ast_rtp_instance_activate(p->rtp);
18801       }
18802       check_pendings(p);
18803       break;
18804 
18805    case 181:   /* Call Is Being Forwarded */
18806       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
18807          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
18808       if (!req->ignore && p->owner) {
18809          struct ast_party_redirecting redirecting;
18810          struct ast_set_party_redirecting update_redirecting;
18811 
18812          ast_party_redirecting_init(&redirecting);
18813          memset(&update_redirecting, 0, sizeof(update_redirecting));
18814          change_redirecting_information(p, req, &redirecting, &update_redirecting,
18815             FALSE);
18816          ast_channel_queue_redirecting_update(p->owner, &redirecting,
18817             &update_redirecting);
18818          ast_party_redirecting_free(&redirecting);
18819          sip_handle_cc(p, req, AST_CC_CCNR);
18820       }
18821       check_pendings(p);
18822       break;
18823 
18824    case 183:   /* Session progress */
18825       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
18826          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
18827       if (!req->ignore && p->owner) {
18828          if (get_rpid(p, req)) {
18829             /* Queue a connected line update */
18830             ast_party_connected_line_init(&connected);
18831             memset(&update_connected, 0, sizeof(update_connected));
18832             if (p->cid_num) {
18833                update_connected.id.number = 1;
18834                connected.id.number.valid = 1;
18835                connected.id.number.str = (char *) p->cid_num;
18836                connected.id.number.presentation = p->callingpres;
18837             }
18838             if (p->cid_name) {
18839                update_connected.id.name = 1;
18840                connected.id.name.valid = 1;
18841                connected.id.name.str = (char *) p->cid_name;
18842                connected.id.name.presentation = p->callingpres;
18843             }
18844             connected.id.tag = (char *) p->cid_tag;
18845             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
18846             ast_channel_queue_connected_line_update(p->owner, &connected,
18847                &update_connected);
18848          }
18849          sip_handle_cc(p, req, AST_CC_CCNR);
18850       }
18851       if (find_sdp(req)) {
18852          if (p->invitestate != INV_CANCELLED)
18853             p->invitestate = INV_EARLY_MEDIA;
18854          res = process_sdp(p, req, SDP_T38_NONE);
18855          if (!req->ignore && p->owner) {
18856             /* Queue a progress frame */
18857             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
18858          }
18859          ast_rtp_instance_activate(p->rtp);
18860       } else {
18861          /* Alcatel PBXs are known to send 183s with no SDP after sending
18862           * a 100 Trying response. We're just going to treat this sort of thing
18863           * the same as we would treat a 180 Ringing
18864           */
18865          if (!req->ignore && p->owner) {
18866             ast_queue_control(p->owner, AST_CONTROL_RINGING);
18867          }
18868       }
18869       check_pendings(p);
18870       break;
18871 
18872    case 200:   /* 200 OK on invite - someone's answering our call */
18873       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
18874          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
18875       p->authtries = 0;
18876       if (find_sdp(req)) {
18877          if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore)
18878             if (!reinvite)
18879                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
18880                /* For re-invites, we try to recover */
18881                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
18882          ast_rtp_instance_activate(p->rtp);
18883       }
18884 
18885       if (!req->ignore && p->owner && (get_rpid(p, req) || !reinvite)) {
18886          /* Queue a connected line update */
18887          ast_party_connected_line_init(&connected);
18888          memset(&update_connected, 0, sizeof(update_connected));
18889          if (p->cid_num) {
18890             update_connected.id.number = 1;
18891             connected.id.number.valid = 1;
18892             connected.id.number.str = (char *) p->cid_num;
18893             connected.id.number.presentation = p->callingpres;
18894          }
18895          if (p->cid_name) {
18896             update_connected.id.name = 1;
18897             connected.id.name.valid = 1;
18898             connected.id.name.str = (char *) p->cid_name;
18899             connected.id.name.presentation = p->callingpres;
18900          }
18901          connected.id.tag = (char *) p->cid_tag;
18902          connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
18903          ast_channel_queue_connected_line_update(p->owner, &connected,
18904             &update_connected);
18905       }
18906 
18907       /* Parse contact header for continued conversation */
18908       /* When we get 200 OK, we know which device (and IP) to contact for this call */
18909       /* This is important when we have a SIP proxy between us and the phone */
18910       if (outgoing) {
18911          update_call_counter(p, DEC_CALL_RINGING);
18912          parse_ok_contact(p, req);
18913          /* Save Record-Route for any later requests we make on this dialogue */
18914          if (!reinvite)
18915             build_route(p, req, 1);
18916 
18917          if(set_address_from_contact(p)) {
18918             /* Bad contact - we don't know how to reach this device */
18919             /* We need to ACK, but then send a bye */
18920             if (!p->route && !req->ignore)
18921                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
18922          }
18923 
18924       }
18925 
18926       if (!req->ignore && p->owner) {
18927          if (!reinvite) {
18928             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
18929             if (sip_cfg.callevents)
18930                manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
18931                   "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
18932                   p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername);
18933          } else { /* RE-invite */
18934             ast_queue_frame(p->owner, &ast_null_frame);
18935          }
18936       } else {
18937           /* It's possible we're getting an 200 OK after we've tried to disconnect
18938               by sending CANCEL */
18939          /* First send ACK, then send bye */
18940          if (!req->ignore)
18941             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
18942       }
18943 
18944       /* Check for Session-Timers related headers */
18945       if (st_get_mode(p) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) {
18946          p_hdrval = (char*)get_header(req, "Session-Expires");
18947          if (!ast_strlen_zero(p_hdrval)) {
18948             /* UAS supports Session-Timers */
18949             enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO;
18950             int tmp_st_interval = 0;
18951             rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &tmp_st_ref);
18952             if (rtn != 0) {
18953                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
18954             }
18955             if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC ||
18956                tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) {
18957                p->stimer->st_ref = tmp_st_ref;
18958             }
18959             if (tmp_st_interval) {
18960                p->stimer->st_interval = tmp_st_interval;
18961             }
18962             p->stimer->st_active = TRUE;
18963             p->stimer->st_active_peer_ua = TRUE;
18964             start_session_timer(p);
18965          } else {
18966             /* UAS doesn't support Session-Timers */
18967             if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) {
18968                p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC;
18969                p->stimer->st_active_peer_ua = FALSE;
18970                start_session_timer(p);
18971             }
18972          }
18973       }
18974 
18975 
18976       /* If I understand this right, the branch is different for a non-200 ACK only */
18977       p->invitestate = INV_TERMINATED;
18978       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
18979       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
18980       check_pendings(p);
18981       break;
18982 
18983    case 407: /* Proxy authentication */
18984    case 401: /* Www auth */
18985       /* First we ACK */
18986       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
18987       if (p->options)
18988          p->options->auth_type = resp;
18989 
18990       /* Then we AUTH */
18991       ast_string_field_set(p, theirtag, NULL);  /* forget their old tag, so we don't match tags when getting response */
18992       if (!req->ignore) {
18993          if (p->authtries < MAX_AUTHTRIES)
18994             p->invitestate = INV_CALLING;
18995          if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) {
18996             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
18997             pvt_set_needdestroy(p, "failed to authenticate on INVITE");
18998             sip_alreadygone(p);
18999             if (p->owner)
19000                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19001          }
19002       }
19003       break;
19004 
19005    case 403: /* Forbidden */
19006       /* First we ACK */
19007       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19008       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
19009       if (!req->ignore && p->owner) {
19010          ast_set_hangupsource(p->owner, p->owner->name, 0);
19011          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19012       }
19013       pvt_set_needdestroy(p, "received 403 response");
19014       sip_alreadygone(p);
19015       break;
19016 
19017    case 404: /* Not found */
19018       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19019       if (p->owner && !req->ignore) {
19020          ast_set_hangupsource(p->owner, p->owner->name, 0);
19021          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19022       }
19023       sip_alreadygone(p);
19024       break;
19025 
19026    case 408: /* Request timeout */
19027    case 481: /* Call leg does not exist */
19028       /* Could be REFER caused INVITE with replaces */
19029       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
19030       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19031       if (p->owner)
19032          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19033       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19034       break;
19035 
19036    case 422: /* Session-Timers: Session interval too small */
19037       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19038       ast_string_field_set(p, theirtag, NULL);
19039       proc_422_rsp(p, req);
19040       break;
19041 
19042    case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */
19043       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19044       append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk.");
19045       ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid);
19046       if (p->owner)
19047          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19048       break;
19049 
19050       
19051 
19052    case 487: /* Cancelled transaction */
19053       /* We have sent CANCEL on an outbound INVITE
19054          This transaction is already scheduled to be killed by sip_hangup().
19055       */
19056       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19057       if (p->owner && !req->ignore) {
19058          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING);
19059          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
19060       } else if (!req->ignore) {
19061          update_call_counter(p, DEC_CALL_LIMIT);
19062          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
19063          pvt_set_needdestroy(p, "received 487 response");
19064          sip_alreadygone(p);
19065       }
19066       break;
19067    case 415: /* Unsupported media type */
19068    case 488: /* Not acceptable here */
19069    case 606: /* Not Acceptable */
19070       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19071       if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
19072          change_t38_state(p, T38_DISABLED);
19073          /* Try to reset RTP timers */
19074          //ast_rtp_set_rtptimers_onhold(p->rtp);
19075 
19076          /* Trigger a reinvite back to audio */
19077          transmit_reinvite_with_sdp(p, FALSE, FALSE);
19078       } else {
19079          /* We can't set up this call, so give up */
19080          if (p->owner && !req->ignore)
19081             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19082          pvt_set_needdestroy(p, "received 488 response");
19083          /* If there's no dialog to end, then mark p as already gone */
19084          if (!reinvite)
19085             sip_alreadygone(p);
19086       }
19087       break;
19088    case 491: /* Pending */
19089       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19090       if (p->owner && !req->ignore) {
19091          if (p->owner->_state != AST_STATE_UP) {
19092             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19093             pvt_set_needdestroy(p, "received 491 response");
19094          } else {
19095             /* This is a re-invite that failed. */
19096             /* Reset the flag after a while
19097              */
19098             int wait;
19099             /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds,
19100              * if not owner of call, wait 0 to 2 seconds */
19101             if (p->outgoing_call) {
19102                wait = 2100 + ast_random() % 2000;
19103             } else {
19104                wait = ast_random() % 2000;
19105             }
19106             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."));
19107             ast_log(LOG_WARNING, "just did sched_add waitid(%d) for sip_reinvite_retry for dialog %s in handle_response_invite\n", p->waitid, p->callid);
19108             ast_debug(2, "Reinvite race. Waiting %d secs before retry\n", wait);
19109          }
19110       }
19111       break;
19112 
19113    case 405: /* Not allowed */
19114    case 501: /* Not implemented */
19115       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19116       if (p->owner)
19117          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19118       break;
19119    }
19120    if (xmitres == XMIT_ERROR)
19121       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
19122 }

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

Definition at line 19127 of file chan_sip.c.

References AST_CAUSE_NORMAL_UNSPECIFIED, ast_clear_flag, ast_debug, ast_log(), ast_queue_hangup_with_cause(), 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().

19128 {
19129    switch (resp) {
19130    case 200:   /* Notify accepted */
19131       /* They got the notify, this is the end */
19132       if (p->owner) {
19133          if (!p->refer) {
19134             ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
19135             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_UNSPECIFIED);
19136          } else {
19137             ast_debug(4, "Got OK on REFER Notify message\n");
19138          }
19139       } else {
19140          if (p->subscribed == NONE) {
19141             ast_debug(4, "Got 200 accepted on NOTIFY\n");
19142             pvt_set_needdestroy(p, "received 200 response");
19143          }
19144          if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
19145             /* Ready to send the next state we have on queue */
19146             ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
19147             cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
19148          }
19149       }
19150       break;
19151    case 401:   /* Not www-authorized on SIP method */
19152    case 407:   /* Proxy auth */
19153       if (!p->notify) {
19154          break; /* Only device notify can use NOTIFY auth */
19155       }
19156       ast_string_field_set(p, theirtag, NULL);
19157       if (ast_strlen_zero(p->authname)) {
19158          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));
19159          pvt_set_needdestroy(p, "unable to authenticate NOTIFY");
19160       }
19161       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) {
19162          ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", get_header(&p->initreq, "From"));
19163          pvt_set_needdestroy(p, "failed to authenticate NOTIFY");
19164       }
19165       break;
19166    }
19167 }

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

Handle qualification responses (OPTIONS).

Definition at line 19476 of file chan_sip.c.

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

Referenced by handle_response().

19477 {
19478    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! */
19479    int statechanged, is_reachable, was_reachable;
19480    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
19481 
19482    /*
19483     * Compute the response time to a ping (goes in peer->lastms.)
19484     * -1 means did not respond, 0 means unknown,
19485     * 1..maxms is a valid response, >maxms means late response.
19486     */
19487    if (pingtime < 1) /* zero = unknown, so round up to 1 */
19488       pingtime = 1;
19489 
19490    /* Now determine new state and whether it has changed.
19491     * Use some helper variables to simplify the writing
19492     * of the expressions.
19493     */
19494    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
19495    is_reachable = pingtime <= peer->maxms;
19496    statechanged = peer->lastms == 0 /* yes, unknown before */
19497       || was_reachable != is_reachable;
19498 
19499    peer->lastms = pingtime;
19500    peer->call = dialog_unref(peer->call, "unref dialog peer->call");
19501    if (statechanged) {
19502       const char *s = is_reachable ? "Reachable" : "Lagged";
19503       char str_lastms[20];
19504       snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime);
19505 
19506       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
19507          peer->name, s, pingtime, peer->maxms);
19508       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
19509       if (sip_cfg.peer_rtupdate) {
19510          ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
19511       }
19512       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
19513          "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
19514          peer->name, s, pingtime);
19515       if (is_reachable && sip_cfg.regextenonqualify)
19516          register_peer_exten(peer, TRUE);
19517    }
19518 
19519    pvt_set_needdestroy(p, "got OPTIONS response");
19520 
19521    /* Try again eventually */
19522    AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
19523          is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK,
19524          sip_poke_peer_s, peer,
19525          unref_peer(_data, "removing poke peer ref"),
19526          unref_peer(peer, "removing poke peer ref"),
19527          ref_peer(peer, "adding poke peer ref"));
19528 }

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

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

18653 {
18654    struct sip_epa_entry *epa_entry = p->epa_entry;
18655    const char *etag = get_header(req, "Sip-ETag");
18656 
18657    ast_assert(epa_entry != NULL);
18658 
18659    if (resp == 401 || resp == 407) {
18660       ast_string_field_set(p, theirtag, NULL);
18661       if (p->options) {
18662          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
18663       }
18664       if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) {
18665          ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From"));
18666          pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH");
18667          sip_alreadygone(p);
18668       }
18669       return;
18670    }
18671 
18672    if (resp == 501 || resp == 405) {
18673       mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH);
18674    }
18675 
18676    if (resp == 200) {
18677       p->authtries = 0;
18678       /* If I've read section 6, item 6 of RFC 3903 correctly,
18679        * an ESC will only generate a new etag when it sends a 200 OK
18680        */
18681       if (!ast_strlen_zero(etag)) {
18682          ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag));
18683       }
18684       /* The nominal case. Everything went well. Everybody is happy.
18685        * Each EPA will have a specific action to take as a result of this
18686        * development, so ... callbacks!
18687        */
18688       if (epa_entry->static_data->handle_ok) {
18689          epa_entry->static_data->handle_ok(p, req, epa_entry);
18690       }
18691    } else {
18692       /* Rather than try to make individual callbacks for each error
18693        * type, there is just a single error callback. The callback
18694        * can distinguish between error messages and do what it needs to
18695        */
18696       if (epa_entry->static_data->handle_error) {
18697          epa_entry->static_data->handle_error(p, resp, req, epa_entry);
18698       }
18699    }
18700 }

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

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

19233 {
19234    enum ast_control_transfer message = AST_TRANSFER_FAILED;
19235 
19236    /* If no refer structure exists, then do nothing */
19237    if (!p->refer)
19238       return;
19239 
19240    switch (resp) {
19241    case 202:   /* Transfer accepted */
19242       /* We need  to do something here */
19243       /* The transferee is now sending INVITE to target */
19244       p->refer->status = REFER_ACCEPTED;
19245       /* Now wait for next message */
19246       ast_debug(3, "Got 202 accepted on transfer\n");
19247       /* We should hang along, waiting for NOTIFY's here */
19248       break;
19249 
19250    case 401:   /* Not www-authorized on SIP method */
19251    case 407:   /* Proxy auth */
19252       if (ast_strlen_zero(p->authname)) {
19253          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n",
19254             ast_sockaddr_stringify(&p->recv));
19255          if (p->owner) {
19256             ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19257          }
19258          pvt_set_needdestroy(p, "unable to authenticate REFER");
19259       }
19260       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) {
19261          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
19262          p->refer->status = REFER_NOAUTH;
19263          if (p->owner) {
19264             ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19265          }
19266          pvt_set_needdestroy(p, "failed to authenticate REFER");
19267       }
19268       break;
19269    
19270    case 405:   /* Method not allowed */
19271       /* Return to the current call onhold */
19272       /* Status flag needed to be reset */
19273       ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to);
19274       pvt_set_needdestroy(p, "received 405 response");
19275       p->refer->status = REFER_FAILED;
19276       if (p->owner) {
19277          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19278       }
19279       break;
19280 
19281    case 481: /* Call leg does not exist */
19282 
19283       /* A transfer with Replaces did not work */
19284       /* OEJ: We should Set flag, cancel the REFER, go back
19285       to original call - but right now we can't */
19286       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
19287       if (p->owner)
19288          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19289       pvt_set_needdestroy(p, "received 481 response");
19290       break;
19291 
19292    case 500:   /* Server error */
19293    case 501:   /* Method not implemented */
19294       /* Return to the current call onhold */
19295       /* Status flag needed to be reset */
19296       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
19297       pvt_set_needdestroy(p, "received 500/501 response");
19298       p->refer->status = REFER_FAILED;
19299       if (p->owner) {
19300          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19301       }
19302       break;
19303    case 603:   /* Transfer declined */
19304       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
19305       p->refer->status = REFER_FAILED;
19306       pvt_set_needdestroy(p, "received 603 response");
19307       if (p->owner) {
19308          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19309       }
19310       break;
19311    default:
19312       /* We should treat unrecognized 9xx as 900.  400 is actually
19313          specified as a possible response, but any 4-6xx is 
19314          theoretically possible. */
19315 
19316       if (resp < 299) { /* 1xx cases don't get here */
19317          ast_log(LOG_WARNING, "SIP transfer to %s had unxpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp);
19318       } else {
19319          ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp);
19320       }
19321 
19322       p->refer->status = REFER_FAILED;
19323       pvt_set_needdestroy(p, "received failure response");
19324       if (p->owner) {
19325          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19326       }
19327       break;
19328    }
19329 }

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

Handle responses on REGISTER to services.

Definition at line 19332 of file chan_sip.c.

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

Referenced by handle_response().

19333 {
19334    int expires, expires_ms;
19335    struct sip_registry *r;
19336    r=p->registry;
19337    
19338    switch (resp) {
19339    case 401:   /* Unauthorized */
19340       if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
19341          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
19342          pvt_set_needdestroy(p, "failed to authenticate REGISTER");
19343       }
19344       break;
19345    case 403:   /* Forbidden */
19346       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
19347       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403"));
19348       r->regstate = REG_STATE_NOAUTH;
19349       pvt_set_needdestroy(p, "received 403 response");
19350       break;
19351    case 404:   /* Not found */
19352       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname);
19353       pvt_set_needdestroy(p, "received 404 response");
19354       if (r->call)
19355          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404");
19356       r->regstate = REG_STATE_REJECTED;
19357       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404"));
19358       break;
19359    case 407:   /* Proxy auth */
19360       if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
19361          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
19362          pvt_set_needdestroy(p, "failed to authenticate REGISTER");
19363       }
19364       break;
19365    case 408:   /* Request timeout */
19366       /* Got a timeout response, so reset the counter of failed responses */
19367       if (r) {
19368          r->regattempts = 0;
19369       } else {
19370          ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid);
19371       }
19372       break;
19373    case 423:   /* Interval too brief */
19374       r->expiry = atoi(get_header(req, "Min-Expires"));
19375       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);
19376       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423"));
19377       if (r->call) {
19378          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423");
19379          pvt_set_needdestroy(p, "received 423 response");
19380       }
19381       if (r->expiry > max_expiry) {
19382          ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname);
19383          r->expiry = r->configured_expiry;
19384          r->regstate = REG_STATE_REJECTED;
19385       } else {
19386          r->regstate = REG_STATE_UNREGISTERED;
19387          transmit_register(r, SIP_REGISTER, NULL, NULL);
19388       }
19389       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));
19390       break;
19391    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
19392       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname);
19393       pvt_set_needdestroy(p, "received 479 response");
19394       if (r->call)
19395          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479");
19396       r->regstate = REG_STATE_REJECTED;
19397       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479"));
19398       break;
19399    case 200:   /* 200 OK */
19400       if (!r) {
19401          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));
19402          pvt_set_needdestroy(p, "received erroneous 200 response");
19403          return 0;
19404       }
19405       
19406       r->regstate = REG_STATE_REGISTERED;
19407       r->regtime = ast_tvnow();     /* Reset time of last successful registration */
19408       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
19409       r->regattempts = 0;
19410       ast_debug(1, "Registration successful\n");
19411       if (r->timeout > -1) {
19412          ast_debug(1, "Cancelling timeout %d\n", r->timeout);
19413       }
19414       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200"));
19415       if (r->call)
19416          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200");
19417       p->registry = registry_unref(p->registry, "unref registry entry p->registry");
19418       /* Let this one hang around until we have all the responses */
19419       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19420       /* p->needdestroy = 1; */
19421       
19422       /* set us up for re-registering
19423        * figure out how long we got registered for
19424        * according to section 6.13 of RFC, contact headers override
19425        * expires headers, so check those first */
19426       expires = 0;
19427 
19428       /* XXX todo: try to save the extra call */
19429       if (!ast_strlen_zero(get_header(req, "Contact"))) {
19430          const char *contact = NULL;
19431          const char *tmptmp = NULL;
19432          int start = 0;
19433          for(;;) {
19434             contact = __get_header(req, "Contact", &start);
19435             /* this loop ensures we get a contact header about our register request */
19436             if(!ast_strlen_zero(contact)) {
19437                if( (tmptmp=strstr(contact, p->our_contact))) {
19438                   contact=tmptmp;
19439                   break;
19440                }
19441             } else
19442                break;
19443          }
19444          tmptmp = strcasestr(contact, "expires=");
19445          if (tmptmp) {
19446             if (sscanf(tmptmp + 8, "%30d;", &expires) != 1)
19447                expires = 0;
19448          }
19449          
19450       }
19451       if (!expires)
19452          expires=atoi(get_header(req, "expires"));
19453       if (!expires)
19454          expires=default_expiry;
19455       
19456       expires_ms = expires * 1000;
19457       if (expires <= EXPIRY_GUARD_LIMIT)
19458          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN);
19459       else
19460          expires_ms -= EXPIRY_GUARD_SECS * 1000;
19461       if (sipdebug)
19462          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000);
19463       
19464       r->refresh= (int) expires_ms / 1000;
19465       
19466       /* Schedule re-registration before we expire */
19467       AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r,
19468                         registry_unref(_data,"unref in REPLACE del fail"),
19469                         registry_unref(r,"unref in REPLACE add fail"),
19470                         registry_addref(r,"The Addition side of REPLACE"));
19471    }
19472    return 1;
19473 }

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

Definition at line 19170 of file chan_sip.c.

References ast_debug, ast_free, ast_log(), ast_sched_add(), ast_string_field_set, ASTOBJ_REF, ASTOBJ_UNREF, do_proxy_auth(), 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().

19171 {
19172    if (!p->mwi) {
19173       return;
19174    }
19175 
19176    switch (resp) {
19177    case 200: /* Subscription accepted */
19178       ast_debug(3, "Got 200 OK on subscription for MWI\n");
19179       set_pvt_allowed_methods(p, req);
19180       if (p->options) {
19181          ast_free(p->options);
19182          p->options = NULL;
19183       }
19184       p->mwi->subscribed = 1;
19185       if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) {
19186          ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19187       }
19188       break;
19189    case 401:
19190    case 407:
19191       ast_string_field_set(p, theirtag, NULL);
19192       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) {
19193          ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", get_header(&p->initreq, "From"));
19194          p->mwi->call = NULL;
19195          ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19196          pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE");
19197       }
19198       break;
19199    case 403:
19200       transmit_response_with_date(p, "200 OK", req);
19201       ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n");
19202       p->mwi->call = NULL;
19203       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19204       pvt_set_needdestroy(p, "received 403 response");
19205       sip_alreadygone(p);
19206       break;
19207    case 404:
19208       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n");
19209       p->mwi->call = NULL;
19210       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19211       pvt_set_needdestroy(p, "received 404 response");
19212       break;
19213    case 481:
19214       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n");
19215       p->mwi->call = NULL;
19216       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19217       pvt_set_needdestroy(p, "received 481 response");
19218       break;
19219    case 500:
19220    case 501:
19221       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n");
19222       p->mwi->call = NULL;
19223       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19224       pvt_set_needdestroy(p, "received 500/501 response");
19225       break;
19226    }
19227 }

static void handle_response_update ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  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 18592 of file chan_sip.c.

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

Referenced by handle_response().

18593 {
18594    if (p->options) {
18595       p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
18596    }
18597    if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) {
18598       ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From"));
18599    }
18600 }

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

22708 {
22709    struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires);
22710    int res = 0;
22711 
22712    if (!esc_entry) {
22713       transmit_response(p, "503 Internal Server Failure", req);
22714       return -1;
22715    }
22716 
22717    if (esc->callbacks->initial_handler) {
22718       res = esc->callbacks->initial_handler(p, req, esc, esc_entry);
22719    }
22720 
22721    if (!res) {
22722       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0);
22723    }
22724 
22725    ao2_ref(esc_entry, -1);
22726    return res;
22727 }

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

22758 {
22759    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
22760    int expires_ms = expires * 1000;
22761    int res = 0;
22762 
22763    if (!esc_entry) {
22764       transmit_response(p, "412 Conditional Request Failed", req);
22765       return -1;
22766    }
22767 
22768    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
22769          ao2_ref(_data, -1),
22770          ao2_ref(esc_entry, -1),
22771          ao2_ref(esc_entry, +1));
22772 
22773    if (esc->callbacks->modify_handler) {
22774       res = esc->callbacks->modify_handler(p, req, esc, esc_entry);
22775    }
22776 
22777    if (!res) {
22778       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
22779    }
22780 
22781    ao2_ref(esc_entry, -1);
22782    return res;
22783 }

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

22730 {
22731    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
22732    int expires_ms = expires * 1000;
22733    int res = 0;
22734 
22735    if (!esc_entry) {
22736       transmit_response(p, "412 Conditional Request Failed", req);
22737       return -1;
22738    }
22739 
22740    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
22741          ao2_ref(_data, -1),
22742          ao2_ref(esc_entry, -1),
22743          ao2_ref(esc_entry, +1));
22744 
22745    if (esc->callbacks->refresh_handler) {
22746       res = esc->callbacks->refresh_handler(p, req, esc, esc_entry);
22747    }
22748 
22749    if (!res) {
22750       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
22751    }
22752 
22753    ao2_ref(esc_entry, -1);
22754    return res;
22755 }

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

22786 {
22787    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
22788    int res = 0;
22789 
22790    if (!esc_entry) {
22791       transmit_response(p, "412 Conditional Request Failed", req);
22792       return -1;
22793    }
22794 
22795    AST_SCHED_DEL(sched, esc_entry->sched_id);
22796    /* Scheduler's ref of the esc_entry */
22797    ao2_ref(esc_entry, -1);
22798 
22799    if (esc->callbacks->remove_handler) {
22800       res = esc->callbacks->remove_handler(p, req, esc, esc_entry);
22801    }
22802 
22803    if (!res) {
22804       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
22805    }
22806 
22807    /* Ref from finding the esc_entry earlier in function */
22808    ao2_unlink(esc->compositor, esc_entry);
22809    ao2_ref(esc_entry, -1);
22810    return res;
22811 }

static int handle_t38_options ( struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v,
int *  maxdatagram 
) [static]

Handle T.38 configuration options common to users and peers.

Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 25091 of file chan_sip.c.

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

Referenced by build_peer(), and reload_config().

25093 {
25094    int res = 1;
25095 
25096    if (!strcasecmp(v->name, "t38pt_udptl")) {
25097       char *buf = ast_strdupa(v->value);
25098       char *word, *next = buf;
25099 
25100       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT);
25101 
25102       while ((word = strsep(&next, ","))) {
25103          if (ast_true(word) || !strcasecmp(word, "fec")) {
25104             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
25105             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC);
25106          } else if (!strcasecmp(word, "redundancy")) {
25107             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
25108             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY);
25109          } else if (!strcasecmp(word, "none")) {
25110             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
25111             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL);
25112          } else if (!strncasecmp(word, "maxdatagram=", 12)) {
25113             if (sscanf(&word[12], "%30u", maxdatagram) != 1) {
25114                ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config);
25115                *maxdatagram = global_t38_maxdatagram;
25116             }
25117          }
25118       }
25119    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
25120       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
25121       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
25122    } else {
25123       res = 0;
25124    }
25125 
25126    return res;
25127 }

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

05693 {
05694    switch (cause) {
05695       case AST_CAUSE_UNALLOCATED:      /* 1 */
05696       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
05697       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
05698          return "404 Not Found";
05699       case AST_CAUSE_CONGESTION:    /* 34 */
05700       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
05701          return "503 Service Unavailable";
05702       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
05703          return "408 Request Timeout";
05704       case AST_CAUSE_NO_ANSWER:     /* 19 */
05705       case AST_CAUSE_UNREGISTERED:        /* 20 */
05706          return "480 Temporarily unavailable";
05707       case AST_CAUSE_CALL_REJECTED:    /* 21 */
05708          return "403 Forbidden";
05709       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
05710          return "410 Gone";
05711       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
05712          return "480 Temporarily unavailable";
05713       case AST_CAUSE_INVALID_NUMBER_FORMAT:
05714          return "484 Address incomplete";
05715       case AST_CAUSE_USER_BUSY:
05716          return "486 Busy here";
05717       case AST_CAUSE_FAILURE:
05718          return "500 Server internal failure";
05719       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
05720          return "501 Not Implemented";
05721       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
05722          return "503 Service Unavailable";
05723       /* Used in chan_iax2 */
05724       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
05725          return "502 Bad Gateway";
05726       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
05727          return "488 Not Acceptable Here";
05728          
05729       case AST_CAUSE_NOTDEFINED:
05730       default:
05731          ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause);
05732          return NULL;
05733    }
05734 
05735    /* Never reached */
05736    return 0;
05737 }

int hangup_sip2cause ( int  cause  ) 

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 5570 of file chan_sip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by __transmit_response(), and handle_response().

05571 {
05572    /* Possible values taken from causes.h */
05573 
05574    switch(cause) {
05575       case 401:   /* Unauthorized */
05576          return AST_CAUSE_CALL_REJECTED;
05577       case 403:   /* Not found */
05578          return AST_CAUSE_CALL_REJECTED;
05579       case 404:   /* Not found */
05580          return AST_CAUSE_UNALLOCATED;
05581       case 405:   /* Method not allowed */
05582          return AST_CAUSE_INTERWORKING;
05583       case 407:   /* Proxy authentication required */
05584          return AST_CAUSE_CALL_REJECTED;
05585       case 408:   /* No reaction */
05586          return AST_CAUSE_NO_USER_RESPONSE;
05587       case 409:   /* Conflict */
05588          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
05589       case 410:   /* Gone */
05590          return AST_CAUSE_NUMBER_CHANGED;
05591       case 411:   /* Length required */
05592          return AST_CAUSE_INTERWORKING;
05593       case 413:   /* Request entity too large */
05594          return AST_CAUSE_INTERWORKING;
05595       case 414:   /* Request URI too large */
05596          return AST_CAUSE_INTERWORKING;
05597       case 415:   /* Unsupported media type */
05598          return AST_CAUSE_INTERWORKING;
05599       case 420:   /* Bad extension */
05600          return AST_CAUSE_NO_ROUTE_DESTINATION;
05601       case 480:   /* No answer */
05602          return AST_CAUSE_NO_ANSWER;
05603       case 481:   /* No answer */
05604          return AST_CAUSE_INTERWORKING;
05605       case 482:   /* Loop detected */
05606          return AST_CAUSE_INTERWORKING;
05607       case 483:   /* Too many hops */
05608          return AST_CAUSE_NO_ANSWER;
05609       case 484:   /* Address incomplete */
05610          return AST_CAUSE_INVALID_NUMBER_FORMAT;
05611       case 485:   /* Ambiguous */
05612          return AST_CAUSE_UNALLOCATED;
05613       case 486:   /* Busy everywhere */
05614          return AST_CAUSE_BUSY;
05615       case 487:   /* Request terminated */
05616          return AST_CAUSE_INTERWORKING;
05617       case 488:   /* No codecs approved */
05618          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05619       case 491:   /* Request pending */
05620          return AST_CAUSE_INTERWORKING;
05621       case 493:   /* Undecipherable */
05622          return AST_CAUSE_INTERWORKING;
05623       case 500:   /* Server internal failure */
05624          return AST_CAUSE_FAILURE;
05625       case 501:   /* Call rejected */
05626          return AST_CAUSE_FACILITY_REJECTED;
05627       case 502:
05628          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
05629       case 503:   /* Service unavailable */
05630          return AST_CAUSE_CONGESTION;
05631       case 504:   /* Gateway timeout */
05632          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
05633       case 505:   /* SIP version not supported */
05634          return AST_CAUSE_INTERWORKING;
05635       case 600:   /* Busy everywhere */
05636          return AST_CAUSE_USER_BUSY;
05637       case 603:   /* Decline */
05638          return AST_CAUSE_CALL_REJECTED;
05639       case 604:   /* Does not exist anywhere */
05640          return AST_CAUSE_UNALLOCATED;
05641       case 606:   /* Not acceptable */
05642          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05643       default:
05644          if (cause < 500 && cause >= 400) {
05645             /* 4xx class error that is unknown - someting wrong with our request */
05646             return AST_CAUSE_INTERWORKING;
05647          } else if (cause < 600 && cause >= 500) {
05648             /* 5xx class error - problem in the remote end */
05649             return AST_CAUSE_CONGESTION;
05650          } else if (cause < 700 && cause >= 600) {
05651             /* 6xx - global errors in the 4xx class */
05652             return AST_CAUSE_INTERWORKING;
05653          }
05654          return AST_CAUSE_NORMAL;
05655    }
05656    /* Never reached */
05657    return 0;
05658 }

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

Initialize SIP request.

Definition at line 9347 of file chan_sip.c.

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

09348 {
09349    /* Initialize a request */
09350    memset(req, 0, sizeof(*req));
09351    if (!(req->data = ast_str_create(SIP_MIN_PACKET)))
09352       goto e_return;
09353    if (!(req->content = ast_str_create(SIP_MIN_PACKET)))
09354       goto e_free_data;
09355    req->method = sipmethod;
09356    req->header[0] = 0;
09357    ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
09358    req->len = ast_str_strlen(req->data);
09359    req->headers++;
09360    return 0;
09361 
09362 e_free_data:
09363    ast_free(req->data);
09364    req->data = NULL;
09365 e_return:
09366    return -1;
09367 }

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

Initialize SIP response, based on SIP request.

Definition at line 9324 of file chan_sip.c.

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

09325 {
09326    /* Initialize a response */
09327    memset(resp, 0, sizeof(*resp));
09328    resp->method = SIP_RESPONSE;
09329    if (!(resp->data = ast_str_create(SIP_MIN_PACKET)))
09330       goto e_return;
09331    if (!(resp->content = ast_str_create(SIP_MIN_PACKET)))
09332       goto e_free_data;
09333    resp->header[0] = 0;
09334    ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg);
09335    resp->len = resp->data->used;
09336    resp->headers++;
09337    return 0;
09338 
09339 e_free_data:
09340    ast_free(resp->data);
09341    resp->data = NULL;
09342 e_return:
09343    return -1;
09344 }

static int initialize_escs ( void   )  [static]

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

01049 {
01050    int i, res = 0;
01051    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01052       if (!((event_state_compositors[i].compositor) =
01053                ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) {
01054          res = -1;
01055       }
01056    }
01057    return res;
01058 }

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

02816 {
02817    if (p->initreq.headers) {
02818       ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
02819    } else {
02820       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
02821    }
02822    /* Use this as the basis */
02823    copy_request(&p->initreq, req);
02824    parse_request(&p->initreq);
02825    if (req->debug) {
02826       ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
02827    }
02828 }

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

References add_header(), add_header_max_forwards(), add_route(), AST_DIGIT_ANYNUM, ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_append(), ast_str_set(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), exten, init_req(), ourport, S_OR, sip_cfg, sip_methods, sip_standard_port(), and cfsip_methods::text.

Referenced by transmit_invite(), and transmit_notify_with_mwi().

11027 {
11028    struct ast_str *invite = ast_str_alloca(256);
11029    char from[256];
11030    char to[256];
11031    char tmp_n[SIPBUFSIZE/2];  /* build a local copy of 'n' if needed */
11032    char tmp_l[SIPBUFSIZE/2];  /* build a local copy of 'l' if needed */
11033    const char *l = NULL;   /* XXX what is this, exactly ? */
11034    const char *n = NULL;   /* XXX what is this, exactly ? */
11035    const char *d = NULL;   /* domain in from header */
11036    const char *urioptions = "";
11037    int ourport;
11038 
11039    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
11040       const char *s = p->username;  /* being a string field, cannot be NULL */
11041 
11042       /* Test p->username against allowed characters in AST_DIGIT_ANY
11043          If it matches the allowed characters list, then sipuser = ";user=phone"
11044          If not, then sipuser = ""
11045       */
11046       /* + is allowed in first position in a tel: uri */
11047       if (*s == '+')
11048          s++;
11049       for (; *s; s++) {
11050          if (!strchr(AST_DIGIT_ANYNUM, *s) )
11051             break;
11052       }
11053       /* If we have only digits, add ;user=phone to the uri */
11054       if (!*s)
11055          urioptions = ";user=phone";
11056    }
11057 
11058 
11059    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
11060 
11061    d = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
11062    if (p->owner) {
11063       if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
11064          l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL;
11065          n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL;
11066       } else if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
11067          /* if we are not sending RPID and user wants his callerid restricted */    
11068          l = CALLERID_UNKNOWN;
11069          n = l;
11070          d = FROMDOMAIN_INVALID;
11071       }
11072    }
11073 
11074    /* Hey, it's a NOTIFY! See if they've configured a mwi_from.
11075     * XXX Right now, this logic works because the only place that mwi_from
11076     * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then
11077     * we might end up putting the mwi_from setting into other types of NOTIFY
11078     * messages as well.
11079     */
11080    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) {
11081       l = p->mwi_from;
11082    }
11083 
11084    if (ast_strlen_zero(l))
11085       l = default_callerid;
11086    if (ast_strlen_zero(n))
11087       n = l;
11088    /* Allow user to be overridden */
11089    if (!ast_strlen_zero(p->fromuser))
11090       l = p->fromuser;
11091    else /* Save for any further attempts */
11092       ast_string_field_set(p, fromuser, l);
11093 
11094    /* Allow user to be overridden */
11095    if (!ast_strlen_zero(p->fromname))
11096       n = p->fromname;
11097    else /* Save for any further attempts */
11098       ast_string_field_set(p, fromname, n);
11099 
11100    if (sip_cfg.pedanticsipchecking) {
11101       ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0);
11102       n = tmp_n;
11103       ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0);
11104       l = tmp_l;
11105    }
11106 
11107    ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
11108    if (!sip_standard_port(p->socket.type, ourport)) {
11109       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag);
11110    } else {
11111       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag);
11112    }
11113 
11114    if (!ast_strlen_zero(explicit_uri)) {
11115       ast_str_set(&invite, 0, "%s", explicit_uri);
11116    } else {
11117       /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
11118       if (!ast_strlen_zero(p->fullcontact)) {
11119          /* If we have full contact, trust it */
11120          ast_str_append(&invite, 0, "%s", p->fullcontact);
11121       } else {
11122          /* Otherwise, use the username while waiting for registration */
11123          ast_str_append(&invite, 0, "sip:");
11124          if (!ast_strlen_zero(p->username)) {
11125             n = p->username;
11126             if (sip_cfg.pedanticsipchecking) {
11127                ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0);
11128                n = tmp_n;
11129             }
11130             ast_str_append(&invite, 0, "%s@", n);
11131          }
11132          ast_str_append(&invite, 0, "%s", p->tohost);
11133          if (p->portinuri) {
11134             ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa));
11135          }
11136          ast_str_append(&invite, 0, "%s", urioptions);
11137       }
11138    }
11139 
11140    /* If custom URI options have been provided, append them */
11141    if (p->options && !ast_strlen_zero(p->options->uri_options))
11142       ast_str_append(&invite, 0, ";%s", p->options->uri_options);
11143    
11144    /* This is the request URI, which is the next hop of the call
11145       which may or may not be the destination of the call
11146    */
11147    ast_string_field_set(p, uri, invite->str);
11148 
11149    if (!ast_strlen_zero(p->todnid)) {
11150       /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
11151       if (!strchr(p->todnid, '@')) {
11152          /* We have no domain in the dnid */
11153          snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
11154       } else {
11155          snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
11156       }
11157    } else {
11158       if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
11159          /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
11160          snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag);
11161       } else if (p->options && p->options->vxml_url) {
11162          /* If there is a VXML URL append it to the SIP URL */
11163          snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
11164       } else {
11165          snprintf(to, sizeof(to), "<%s>", p->uri);
11166       }
11167    }
11168 
11169    init_req(req, sipmethod, p->uri);
11170    /* now tmp_n is available so reuse it to build the CSeq */
11171    snprintf(tmp_n, sizeof(tmp_n), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
11172 
11173    add_header(req, "Via", p->via);
11174    add_header_max_forwards(p, req);
11175    /* This will be a no-op most of the time. However, under certain circumstances,
11176     * NOTIFY messages will use this function for preparing the request and should
11177     * have Route headers present.
11178     */
11179    add_route(req, p->route);
11180 
11181    add_header(req, "From", from);
11182    add_header(req, "To", to);
11183    ast_string_field_set(p, exten, l);
11184    build_contact(p);
11185    add_header(req, "Contact", p->our_contact);
11186    add_header(req, "Call-ID", p->callid);
11187    add_header(req, "CSeq", tmp_n);
11188    if (!ast_strlen_zero(global_useragent)) {
11189       add_header(req, "User-Agent", global_useragent);
11190    }
11191 }

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

Convert Insecure setting to printable string.

Definition at line 15775 of file chan_sip.c.

References map_x_s().

Referenced by _sip_show_peer().

15776 {
15777    return map_x_s(insecurestr, mode, "<error>");
15778 }

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

References AST_CONTROL_T38_PARAMETERS, ast_queue_control_data(), AST_SCHED_DEL, 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().

06223 {
06224    int res = 0;
06225 
06226    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) {
06227       return -1;
06228    }
06229    switch (parameters->request_response) {
06230    case AST_T38_NEGOTIATED:
06231    case AST_T38_REQUEST_NEGOTIATE:         /* Request T38 */
06232       /* Negotiation can not take place without a valid max_ifp value. */
06233       if (!parameters->max_ifp) {
06234          change_t38_state(p, T38_DISABLED);
06235          if (p->t38.state == T38_PEER_REINVITE) {
06236             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"));
06237             transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
06238          }
06239          break;
06240       } else if (p->t38.state == T38_PEER_REINVITE) {
06241          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"));
06242          p->t38.our_parms = *parameters;
06243          /* modify our parameters to conform to the peer's parameters,
06244           * based on the rules in the ITU T.38 recommendation
06245           */
06246          if (!p->t38.their_parms.fill_bit_removal) {
06247             p->t38.our_parms.fill_bit_removal = FALSE;
06248          }
06249          if (!p->t38.their_parms.transcoding_mmr) {
06250             p->t38.our_parms.transcoding_mmr = FALSE;
06251          }
06252          if (!p->t38.their_parms.transcoding_jbig) {
06253             p->t38.our_parms.transcoding_jbig = FALSE;
06254          }
06255          p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version);
06256          p->t38.our_parms.rate_management = p->t38.their_parms.rate_management;
06257          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
06258          change_t38_state(p, T38_ENABLED);
06259          transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
06260       } else if (p->t38.state != T38_ENABLED) {
06261          p->t38.our_parms = *parameters;
06262          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
06263          change_t38_state(p, T38_LOCAL_REINVITE);
06264          if (!p->pendinginvite) {
06265             transmit_reinvite_with_sdp(p, TRUE, FALSE);
06266          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
06267             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
06268          }
06269       }
06270       break;
06271    case AST_T38_TERMINATED:
06272    case AST_T38_REFUSED:
06273    case AST_T38_REQUEST_TERMINATE:         /* Shutdown T38 */
06274       if (p->t38.state == T38_PEER_REINVITE) {
06275          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"));
06276          change_t38_state(p, T38_DISABLED);
06277          transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
06278       } else if (p->t38.state == T38_ENABLED)
06279          transmit_reinvite_with_sdp(p, FALSE, FALSE);
06280       break;
06281    case AST_T38_REQUEST_PARMS: {    /* Application wants remote's parameters re-sent */
06282       struct ast_control_t38_parameters parameters = p->t38.their_parms;
06283 
06284       if (p->t38.state == T38_PEER_REINVITE) {
06285          AST_SCHED_DEL(sched, p->t38id);
06286          parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
06287          parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
06288          ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
06289          /* we need to return a positive value here, so that applications that
06290           * send this request can determine conclusively whether it was accepted or not...
06291           * older versions of chan_sip would just silently accept it and return zero.
06292           */
06293          res = AST_T38_REQUEST_PARMS;
06294       }
06295       break;
06296    }
06297    default:
06298       res = -1;
06299       break;
06300    }
06301 
06302    return res;
06303 }

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

Referenced by sip_sendtext(), and update_connectedline().

07605 {
07606    return ((*allowed_methods) >> method) & 1;
07607 }

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

List all routes - mostly for debugging.

Definition at line 13112 of file chan_sip.c.

References ast_verbose.

Referenced by build_route().

13113 {
13114    if (!route) {
13115       ast_verbose("list_route: no route\n");
13116    } else {
13117       for (;route; route = route->next)
13118          ast_verbose("list_route: hop: <%s>\n", route->hop);
13119    }
13120 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 28364 of file chan_sip.c.

References ao2_container_alloc, ao2_t_container_alloc, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_check_realtime(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_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_TEST_REGISTER, ast_udptl_proto_register(), ast_verbose, ASTOBJ_CONTAINER_INIT, 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_send_all_mwi_subscriptions(), sip_send_all_registers(), sip_tech_info, submwil, threadt_cmp_cb(), and threadt_hash_cb().

28365 {
28366    ast_verbose("SIP channel loading...\n");
28367    /* the fact that ao2_containers can't resize automatically is a major worry! */
28368    /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
28369    peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers");
28370    peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip");
28371    dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs");
28372    threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
28373    
28374    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
28375    ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
28376 
28377    if (!(sched = sched_context_create())) {
28378       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
28379       return AST_MODULE_LOAD_FAILURE;
28380    }
28381 
28382    if (!(io = io_context_create())) {
28383       ast_log(LOG_ERROR, "Unable to create I/O context\n");
28384       sched_context_destroy(sched);
28385       return AST_MODULE_LOAD_FAILURE;
28386    }
28387 
28388    sip_reloadreason = CHANNEL_MODULE_LOAD;
28389 
28390    can_parse_xml = sip_is_xml_parsable();
28391    if(reload_config(sip_reloadreason)) {  /* Load the configuration from sip.conf */
28392       return AST_MODULE_LOAD_DECLINE;
28393    }
28394 
28395    /* Prepare the version that does not require DTMF BEGIN frames.
28396     * We need to use tricks such as memcpy and casts because the variable
28397     * has const fields.
28398     */
28399    memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
28400    memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
28401 
28402    /* Make sure we can register our sip channel type */
28403    if (ast_channel_register(&sip_tech)) {
28404       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
28405       io_context_destroy(io);
28406       sched_context_destroy(sched);
28407       return AST_MODULE_LOAD_FAILURE;
28408    }
28409 
28410 #ifdef TEST_FRAMEWORK
28411    AST_TEST_REGISTER(test_sip_peers_get);
28412 #endif
28413 
28414    /* Register AstData providers */
28415    ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers));
28416 
28417    /* Register all CLI functions for SIP */
28418    ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip));
28419 
28420    /* Tell the UDPTL subdriver that we're here */
28421    ast_udptl_proto_register(&sip_udptl);
28422 
28423    /* Tell the RTP engine about our RTP glue */
28424    ast_rtp_glue_register(&sip_rtp_glue);
28425 
28426    /* Register dialplan applications */
28427    ast_register_application_xml(app_dtmfmode, sip_dtmfmode);
28428    ast_register_application_xml(app_sipaddheader, sip_addheader);
28429    ast_register_application_xml(app_sipremoveheader, sip_removeheader);
28430 
28431    /* Register dialplan functions */
28432    ast_custom_function_register(&sip_header_function);
28433    ast_custom_function_register(&sippeer_function);
28434    ast_custom_function_register(&sipchaninfo_function);
28435    ast_custom_function_register(&checksipdomain_function);
28436 
28437    /* Register manager commands */
28438    ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers);
28439    ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer);
28440    ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer);
28441    ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry);
28442    ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify);
28443    sip_poke_all_peers();   
28444    sip_send_all_registers();
28445    sip_send_all_mwi_subscriptions();
28446    initialize_escs();
28447 
28448    if (sip_epa_register(&cc_epa_static_data)) {
28449       return AST_MODULE_LOAD_DECLINE;
28450    }
28451 
28452    if (sip_reqresp_parser_init() == -1) {
28453       ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n");
28454       return AST_MODULE_LOAD_DECLINE;
28455    }
28456 
28457    if (can_parse_xml) {
28458       /* SIP CC agents require the ability to parse XML PIDF bodies
28459        * in incoming PUBLISH requests
28460        */
28461       if (ast_cc_agent_register(&sip_cc_agent_callbacks)) {
28462          return AST_MODULE_LOAD_DECLINE;
28463       }
28464    }
28465    if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) {
28466       return AST_MODULE_LOAD_DECLINE;
28467    }
28468    if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) {
28469       return AST_MODULE_LOAD_DECLINE;
28470    }
28471 
28472    /* And start the monitor for the first time */
28473    restart_monitor();
28474 
28475    ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
28476       "name", RQ_CHAR, 10,
28477       "ipaddr", RQ_CHAR, 15,
28478       "port", RQ_UINTEGER2, 5,
28479       "regseconds", RQ_INTEGER4, 11,
28480       "defaultuser", RQ_CHAR, 10,
28481       "fullcontact", RQ_CHAR, 35,
28482       "regserver", RQ_CHAR, 20,
28483       "useragent", RQ_CHAR, 20,
28484       "lastms", RQ_INTEGER4, 11,
28485       SENTINEL);
28486 
28487 
28488    sip_register_tests();
28489    network_change_event_subscribe();
28490 
28491    return AST_MODULE_LOAD_SUCCESS;
28492 }

static int local_attended_transfer ( struct sip_pvt *  transferer,
struct sip_dual *  current,
struct sip_request *  req,
int  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 21640 of file chan_sip.c.

References ao2_t_ref, append_history, 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_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(), ast_channel::name, pbx_builtin_getvar_helper(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, transmit_notify_with_sipfrag(), transmit_response(), TRUE, and xfersound.

Referenced by handle_request_refer().

21641 {
21642    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
21643                /* Chan 2: Call from Asterisk to target */
21644    int res = 0;
21645    struct sip_pvt *targetcall_pvt;
21646    struct ast_party_connected_line connected_to_transferee;
21647    struct ast_party_connected_line connected_to_target;
21648    char transferer_linkedid[32];
21649    struct ast_channel *chans[2];
21650 
21651    /* Check if the call ID of the replaces header does exist locally */
21652    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag,
21653       transferer->refer->replaces_callid_fromtag))) {
21654       if (transferer->refer->localtransfer) {
21655          /* We did not find the refered call. Sorry, can't accept then */
21656          transmit_response(transferer, "202 Accepted", req);
21657          /* Let's fake a response from someone else in order
21658             to follow the standard */
21659          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
21660          append_history(transferer, "Xfer", "Refer failed");
21661          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
21662          transferer->refer->status = REFER_FAILED;
21663          return -1;
21664       }
21665       /* Fall through for remote transfers that we did not find locally */
21666       ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
21667       return 0;
21668    }
21669 
21670    /* Ok, we can accept this transfer */
21671    transmit_response(transferer, "202 Accepted", req);
21672    append_history(transferer, "Xfer", "Refer accepted");
21673    if (!targetcall_pvt->owner) { /* No active channel */
21674       ast_debug(4, "SIP attended transfer: Error: No owner of target call\n");
21675       /* Cancel transfer */
21676       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
21677       append_history(transferer, "Xfer", "Refer failed");
21678       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
21679       transferer->refer->status = REFER_FAILED;
21680       sip_pvt_unlock(targetcall_pvt);
21681       if (targetcall_pvt)
21682          ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer");
21683       return -1;
21684    }
21685 
21686    /* We have a channel, find the bridge */
21687    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
21688    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
21689 
21690    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
21691       /* Wrong state of new channel */
21692       if (target.chan2)
21693          ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
21694       else if (target.chan1->_state != AST_STATE_RING)
21695          ast_debug(4, "SIP attended transfer: Error: No target channel\n");
21696       else
21697          ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n");
21698    }
21699 
21700    /* Transfer */
21701    if (sipdebug) {
21702       if (current->chan2)  /* We have two bridges */
21703          ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
21704       else        /* One bridge, propably transfer of IVR/voicemail etc */
21705          ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
21706    }
21707 
21708    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
21709 
21710    ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid));
21711 
21712    /* Perform the transfer */
21713    chans[0] = transferer->owner;
21714    chans[1] = target.chan1;
21715    ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, "TransferMethod: SIP\r\nTransferType: Attended\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\n",
21716       transferer->owner->name,
21717       transferer->owner->uniqueid,
21718       transferer->callid,
21719       target.chan1->name,
21720       target.chan1->uniqueid);
21721    ast_party_connected_line_init(&connected_to_transferee);
21722    ast_party_connected_line_init(&connected_to_target);
21723    /* No need to lock current->chan1 here since it was locked in sipsock_read */
21724    ast_party_connected_line_copy(&connected_to_transferee, &current->chan1->connected);
21725    /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */
21726    ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected);
21727    connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
21728    res = attempt_transfer(current, &target);
21729    if (res) {
21730       /* Failed transfer */
21731       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
21732       append_history(transferer, "Xfer", "Refer failed");
21733       ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
21734       /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */
21735       sip_pvt_unlock(targetcall_pvt);
21736       ast_channel_unlock(target.chan1);
21737    } else {
21738       /* Transfer succeeded! */
21739       const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND");
21740 
21741       /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */
21742       ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2);
21743 
21744       /* Tell transferer that we're done. */
21745       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
21746       append_history(transferer, "Xfer", "Refer succeeded");
21747       transferer->refer->status = REFER_200OK;
21748       if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, target.chan2->language) >= 0) {
21749          ast_waitstream(target.chan2, "");
21750       }
21751 
21752       /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then
21753        * can queue connected line updates where they need to go.
21754        *
21755        * before a masquerade, all channel and pvt locks must be unlocked.  Any recursive
21756        * channel locks held before this function invalidates channel container locking order.
21757        * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1)
21758        * it is possible for current.chan1 to be destroyed in the pbx thread.  To prevent this
21759        * we must give c a reference before any unlocking takes place.
21760        */
21761 
21762       ast_channel_ref(current->chan1);
21763       ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/
21764       ast_channel_unlock(target.chan1);
21765       *nounlock = 1;  /* we just unlocked the dialog's channel and have no plans of locking it again. */
21766       sip_pvt_unlock(targetcall_pvt);
21767       sip_pvt_unlock(transferer);
21768 
21769       ast_do_masquerade(target.chan1);
21770 
21771       sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */
21772 
21773       ast_indicate(target.chan1, AST_CONTROL_UNHOLD);
21774 
21775       if (target.chan2) {
21776          ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
21777          ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL);
21778       } else {
21779          /* Since target.chan1 isn't actually connected to another channel, there is no way for us
21780           * to queue a frame so that its connected line status will be updated.
21781           *
21782           * Instead, we use the somewhat hackish approach of using a special control frame type that
21783           * instructs ast_read to perform a specific action. In this case, the frame we queue tells
21784           * ast_read to call the connected line interception macro configured for target.chan1.
21785           */
21786          struct ast_control_read_action_payload *frame_payload;
21787          int payload_size;
21788          int frame_size;
21789          unsigned char connected_line_data[1024];
21790          payload_size = ast_connected_line_build_data(connected_line_data,
21791             sizeof(connected_line_data), &connected_to_target, NULL);
21792          frame_size = payload_size + sizeof(*frame_payload);
21793          if (payload_size != -1 && (frame_payload = alloca(frame_size))) {
21794             frame_payload->payload_size = payload_size;
21795             memcpy(frame_payload->payload, connected_line_data, payload_size);
21796             frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
21797             ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size);
21798          }
21799          /* In addition to queueing the read action frame so that target.chan1's connected line info
21800           * will be updated, we also are going to queue a plain old connected line update on target.chan1. This
21801           * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel.
21802           */
21803          ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
21804 
21805       }
21806       ast_channel_unref(current->chan1);
21807    }
21808 
21809    /* at this point if the transfer is successful only the transferer pvt should be locked. */
21810    ast_party_connected_line_free(&connected_to_target);
21811    ast_party_connected_line_free(&connected_to_transferee);
21812    if (targetcall_pvt)
21813       ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt");
21814    return 1;
21815 }

static int lws2sws ( char *  msgbuf,
int  len 
) [static]

Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.

Definition at line 7692 of file chan_sip.c.

Referenced by handle_request_do().

07693 {
07694    int h = 0, t = 0;
07695    int lws = 0;
07696 
07697    for (; h < len;) {
07698       /* Eliminate all CRs */
07699       if (msgbuf[h] == '\r') {
07700          h++;
07701          continue;
07702       }
07703       /* Check for end-of-line */
07704       if (msgbuf[h] == '\n') {
07705          /* Check for end-of-message */
07706          if (h + 1 == len)
07707             break;
07708          /* Check for a continuation line */
07709          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') {
07710             /* Merge continuation line */
07711             h++;
07712             continue;
07713          }
07714          /* Propagate LF and start new line */
07715          msgbuf[t++] = msgbuf[h++];
07716          lws = 0;
07717          continue;
07718       }
07719       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') {
07720          if (lws) {
07721             h++;
07722             continue;
07723          }
07724          msgbuf[t++] = msgbuf[h++];
07725          lws = 1;
07726          continue;
07727       }
07728       msgbuf[t++] = msgbuf[h++];
07729       if (lws)
07730          lws = 0;
07731    }
07732    msgbuf[t] = '\0';
07733    return t;
07734 }

static void make_our_tag ( char *  tagbuf,
size_t  len 
) [static]

Make our SIP dialog tag.

Definition at line 7004 of file chan_sip.c.

References ast_random().

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

07005 {
07006    snprintf(tagbuf, len, "as%08lx", ast_random());
07007 }

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

Show SIP registrations in the manager API.

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

15414 {
15415    const char *id = astman_get_header(m, "ActionID");
15416    char idtext[256] = "";
15417    int total = 0;
15418 
15419    if (!ast_strlen_zero(id))
15420       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
15421 
15422    astman_send_listack(s, m, "Registrations will follow", "start");
15423 
15424    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
15425       ASTOBJ_RDLOCK(iterator);
15426       astman_append(s,
15427          "Event: RegistryEntry\r\n"
15428          "%s"
15429          "Host: %s\r\n"
15430          "Port: %d\r\n"
15431          "Username: %s\r\n"
15432          "Domain: %s\r\n"
15433          "DomainPort: %d\r\n"
15434          "Refresh: %d\r\n"
15435          "State: %s\r\n"
15436          "RegistrationTime: %ld\r\n"
15437          "\r\n",
15438          idtext,
15439          iterator->hostname,
15440          iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
15441          iterator->username,
15442          S_OR(iterator->regdomain,iterator->hostname),
15443          iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT,
15444          iterator->refresh,
15445          regstate2str(iterator->regstate),
15446          (long) iterator->regtime.tv_sec);
15447       ASTOBJ_UNLOCK(iterator);
15448       total++;
15449    } while(0));
15450 
15451    astman_append(s,
15452       "Event: RegistrationsComplete\r\n"
15453       "EventList: Complete\r\n"
15454       "ListItems: %d\r\n"
15455       "%s"
15456       "\r\n", total, idtext);
15457    
15458    return 0;
15459 }

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

Qualify SIP peers in the manager API.

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

16134 {
16135    const char *a[4];
16136    const char *peer;
16137 
16138    peer = astman_get_header(m, "Peer");
16139    if (ast_strlen_zero(peer)) {
16140       astman_send_error(s, m, "Peer: <name> missing.");
16141       return 0;
16142    }
16143    a[0] = "sip";
16144    a[1] = "qualify";
16145    a[2] = "peer";
16146    a[3] = peer;
16147 
16148    _sip_qualify_peer(1, -1, s, m, 4, a);
16149    astman_append(s, "\r\n\r\n" );
16150    return 0;
16151 }

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

Show SIP peers in the manager API.

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

16075 {
16076    const char *a[4];
16077    const char *peer;
16078 
16079    peer = astman_get_header(m, "Peer");
16080    if (ast_strlen_zero(peer)) {
16081       astman_send_error(s, m, "Peer: <name> missing.");
16082       return 0;
16083    }
16084    a[0] = "sip";
16085    a[1] = "show";
16086    a[2] = "peer";
16087    a[3] = peer;
16088 
16089    _sip_show_peer(1, -1, s, m, 4, a);
16090    astman_append(s, "\r\n\r\n" );
16091    return 0;
16092 }

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

Show SIP peers in the manager API.

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

15464 {
15465    const char *id = astman_get_header(m, "ActionID");
15466    const char *a[] = {"sip", "show", "peers"};
15467    char idtext[256] = "";
15468    int total = 0;
15469 
15470    if (!ast_strlen_zero(id))
15471       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
15472 
15473    astman_send_listack(s, m, "Peer status list will follow", "start");
15474    /* List the peers in separate manager events */
15475    _sip_show_peers(-1, &total, s, m, 3, a);
15476    /* Send final confirmation */
15477    astman_append(s,
15478    "Event: PeerlistComplete\r\n"
15479    "EventList: Complete\r\n"
15480    "ListItems: %d\r\n"
15481    "%s"
15482    "\r\n", total, idtext);
15483    return 0;
15484 }

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

Definition at line 11920 of file chan_sip.c.

References ast_log(), ast_set_flag, ast_str_append(), ast_str_strlen(), ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), create_addr(), dialog_unlink_all(), LOG_WARNING, ast_variable::name, ast_variable::next, sip_alloc(), sip_notify_allocate(), sip_scheddestroy(), transmit_invite(), TRUE, ast_variable::value, and var.

Referenced by load_module().

11921 {
11922    const char *channame = astman_get_header(m, "Channel");
11923    struct ast_variable *vars = astman_get_variables(m);
11924    struct sip_pvt *p;
11925    struct ast_variable *header, *var;
11926 
11927    if (ast_strlen_zero(channame)) {
11928       astman_send_error(s, m, "SIPNotify requires a channel name");
11929       return 0;
11930    }
11931 
11932    if (!strncasecmp(channame, "sip/", 4)) {
11933       channame += 4;
11934    }
11935 
11936    if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
11937       astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
11938       return 0;
11939    }
11940 
11941    if (create_addr(p, channame, NULL, 0, NULL)) {
11942       /* Maybe they're not registered, etc. */
11943       dialog_unlink_all(p, TRUE, TRUE);
11944       dialog_unref(p, "unref dialog inside for loop" );
11945       /* sip_destroy(p); */
11946       astman_send_error(s, m, "Could not create address");
11947       return 0;
11948    }
11949 
11950    /* Notify is outgoing call */
11951    ast_set_flag(&p->flags[0], SIP_OUTGOING);
11952    sip_notify_allocate(p);
11953 
11954    p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
11955 
11956    for (var = vars; var; var = var->next) {
11957       if (!strcasecmp(var->name, "Content")) {
11958          if (ast_str_strlen(p->notify->content))
11959             ast_str_append(&p->notify->content, 0, "\r\n");
11960          ast_str_append(&p->notify->content, 0, "%s", var->value);
11961       } else if (!strcasecmp(var->name, "Content-Length")) {
11962          ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring");
11963       } else {
11964          header->next = ast_variable_new(var->name, var->value, "");
11965          header = header->next;
11966       }
11967    }
11968 
11969    dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement.");
11970    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
11971    transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
11972 
11973    astman_send_ack(s, m, "Notify Sent");
11974    ast_variables_destroy(vars);
11975    return 0;
11976 }

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

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

02213 {
02214    const struct _map_x_s *cur;
02215 
02216    for (cur = table; cur->s; cur++)
02217       if (!strcasecmp(cur->s, s))
02218          return cur->x;
02219    return errorvalue;
02220 }

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

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

02200 {
02201    const struct _map_x_s *cur;
02202 
02203    for (cur = table; cur->s; cur++)
02204       if (cur->x == x)
02205          return cur->s;
02206    return errorstring;
02207 }

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

Definition at line 7593 of file chan_sip.c.

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

07594 {
07595    (*allowed_methods) |= (1 << method);
07596 }

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

Definition at line 7598 of file chan_sip.c.

Referenced by handle_response(), and handle_response_publish().

07599 {
07600    (*allowed_methods) &= ~(1 << method);
07601 }

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

Definition at line 7609 of file chan_sip.c.

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

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

07610 {
07611    char *method;
07612    for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) {
07613       int id = find_sip_method(ast_skip_blanks(method));
07614       if (id == SIP_UNKNOWN) {
07615          continue;
07616       }
07617       mark_method_allowed(methods, id);
07618    }
07619 }

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

Definition at line 7204 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, match_req_args::totag, match_req_args::viabranch, and match_req_args::viasentby.

Referenced by find_call().

07205 {
07206    const char *init_ruri = NULL;
07207    if (sip_pvt_ptr->initreq.headers) {
07208       init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2);
07209    }
07210 
07211    /*
07212     * Match Tags and call-id to Dialog
07213     */
07214    if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) {
07215       /* call-id does not match. */
07216       return SIP_REQ_NOT_MATCH;
07217    }
07218    if (arg->method == SIP_RESPONSE) {
07219       /* Verify totag if we have one stored for this dialog, but never be strict about this for
07220        * a response until the dialog is established */
07221       if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
07222          if (ast_strlen_zero(arg->totag)) {
07223             /* missing totag when they already gave us one earlier */
07224             return SIP_REQ_NOT_MATCH;
07225          }
07226          if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) {
07227             /* The totag of the response does not match the one we have stored */
07228             return SIP_REQ_NOT_MATCH;
07229          }
07230       }
07231       /* Verify fromtag of response matches the tag we gave them. */
07232       if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) {
07233          /* fromtag from response does not match our tag */
07234          return SIP_REQ_NOT_MATCH;
07235       }
07236    } else {
07237       /* Verify the fromtag of Request matches the tag they provided earlier. */
07238       if (strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) {
07239          /* their tag does not match the one was have stored for them */
07240          return SIP_REQ_NOT_MATCH;
07241       }
07242       /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */
07243       if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) {
07244          /* totag from Request does not match our tag */
07245          return SIP_REQ_NOT_MATCH;
07246       }
07247    }
07248 
07249    /*
07250     * Compare incoming request against initial transaction.
07251     * 
07252     * This is a best effort attempt at distinguishing forked requests from
07253     * our initial transaction.  If all the elements are NOT in place to evaluate
07254     * this, this block is ignored and the dialog match is made regardless.
07255     * Once the totag is established after the dialog is confirmed, this is not necessary.
07256     *
07257     * CRITERIA required for initial transaction matching.
07258     * 
07259     * 1. Is a Request
07260     * 2. Callid and theirtag match (this is done in the dialog matching block)
07261     * 3. totag is NOT present
07262     * 4. CSeq matchs our initial transaction's cseq number
07263     * 5. pvt has init via branch parameter stored
07264     */
07265    if ((arg->method != SIP_RESPONSE) &&                 /* must be a Request */
07266       ast_strlen_zero(arg->totag) &&                   /* must not have a totag */
07267       (sip_pvt_ptr->init_icseq == arg->seqno) &&       /* the cseq must be the same as this dialogs initial cseq */
07268       !ast_strlen_zero(sip_pvt_ptr->initviabranch) &&  /* The dialog must have started with a RFC3261 compliant branch tag */
07269       init_ruri) {                                     /* the dialog must have an initial request uri associated with it */
07270       /* This Request matches all the criteria required for Loop/Merge detection.
07271        * Now we must go down the path of comparing VIA's and RURIs. */
07272       if (ast_strlen_zero(arg->viabranch) ||
07273          strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) ||
07274          ast_strlen_zero(arg->viasentby) ||
07275          strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) {
07276          /* At this point, this request does not match this Dialog.*/
07277 
07278          /* if methods are different this is just a mismatch */
07279          if ((sip_pvt_ptr->method != arg->method)) {
07280             return SIP_REQ_NOT_MATCH;
07281          }
07282 
07283          /* If RUIs are different, this is a forked request to a separate URI.
07284           * Returning a mismatch allows this Request to be processed separately. */
07285          if (sip_uri_cmp(init_ruri, arg->ruri)) {
07286             /* not a match, request uris are different */
07287             return SIP_REQ_NOT_MATCH;
07288          }
07289 
07290          /* Loop/Merge Detected
07291           *
07292           * ---Current Matches to Initial Request---
07293           * request uri
07294           * Call-id
07295           * their-tag
07296           * no totag present
07297           * method
07298           * cseq
07299           *
07300           * --- Does not Match Initial Request ---
07301           * Top Via
07302           *
07303           * Without the same Via, this can not match our initial transaction for this dialog,
07304           * but given that this Request matches everything else associated with that initial
07305           * Request this is most certainly a Forked request in which we have already received
07306           * part of the fork.
07307           */
07308          return SIP_REQ_LOOP_DETECTED;
07309       }
07310    } /* end of Request Via check */
07311 
07312    /* Match Authentication Request.
07313     *
07314     * A Request with an Authentication header must come back with the
07315     * same Request URI.  Otherwise it is not a match.
07316     */
07317    if ((arg->method != SIP_RESPONSE) &&      /* Must be a Request type to even begin checking this */
07318       ast_strlen_zero(arg->totag) &&        /* no totag is present to match */
07319       arg->authentication_present &&        /* Authentication header is present in Request */
07320       sip_uri_cmp(init_ruri, arg->ruri)) {  /* Compare the Request URI of both the last Request and this new one */
07321 
07322       /* Authentication was provided, but the Request URI did not match the last one on this dialog. */
07323       return SIP_REQ_NOT_MATCH;
07324    }
07325 
07326    return SIP_REQ_MATCH;
07327 }

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

References len(), sip_methods, and text.

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

02903 {
02904    int len = strlen(sip_methods[id].text);
02905    int l_name = name ? strlen(name) : 0;
02906    /* true if the string is long enough, and ends with whitespace, and matches */
02907    return (l_name >= len && name[len] < 33 &&
02908       !strncasecmp(sip_methods[id].text, name, len));
02909 }

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

Receive MWI events that we have subscribed to.

Definition at line 13453 of file chan_sip.c.

References ao2_lock, ao2_unlock, and sip_send_mwi_to_peer().

13454 {
13455    struct sip_peer *peer = userdata;
13456 
13457    ao2_lock(peer);
13458    sip_send_mwi_to_peer(peer, event, 0);
13459    ao2_unlock(peer);
13460 }

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

Definition at line 13487 of file chan_sip.c.

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

13488 {
13489    ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n");
13490    if (network_change_event_sched_id == -1) {
13491       network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
13492    }
13493 }

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

Definition at line 13479 of file chan_sip.c.

References sip_send_all_mwi_subscriptions(), and sip_send_all_registers().

13480 {
13481    network_change_event_sched_id = -1;
13482    sip_send_all_registers();
13483    sip_send_all_mwi_subscriptions();
13484    return 0;
13485 }

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

References append_history, ast_debug, and sip_cfg.

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

02875 {
02876    if (peer && peer->outboundproxy) {
02877       if (sipdebug) {
02878          ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n");
02879       }
02880       append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name);
02881       return peer->outboundproxy;
02882    }
02883    if (sip_cfg.outboundproxy.name[0]) {
02884       if (sipdebug) {
02885          ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n");
02886       }
02887       append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name);
02888       return &sip_cfg.outboundproxy;
02889    }
02890    if (sipdebug) {
02891       ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n");
02892    }
02893    return NULL;
02894 }

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

07637 {
07638    char *allow = ast_strdupa(get_header(req, "Allow"));
07639    unsigned int allowed_methods = SIP_UNKNOWN;
07640 
07641    if (ast_strlen_zero(allow)) {
07642       /* I have witnessed that REGISTER requests from Polycom phones do not
07643        * place the phone's allowed methods in an Allow header. Instead, they place the
07644        * allowed methods in a methods= parameter in the Contact header.
07645        */
07646       char *contact = ast_strdupa(get_header(req, "Contact"));
07647       char *methods = strstr(contact, ";methods=");
07648 
07649       if (ast_strlen_zero(methods)) {
07650          /* RFC 3261 states:
07651           *
07652           * "The absence of an Allow header field MUST NOT be
07653           * interpreted to mean that the UA sending the message supports no
07654           * methods.   Rather, it implies that the UA is not providing any
07655           * information on what methods it supports."
07656           *
07657           * For simplicity, we'll assume that the peer allows all known
07658           * SIP methods if they have no Allow header. We can then clear out the necessary
07659           * bits if the peer lets us know that we have sent an unsupported method.
07660           */
07661          return UINT_MAX;
07662       }
07663       allow = ast_strip_quoted(methods + 9, "\"", "\"");
07664    }
07665    mark_parsed_methods(&allowed_methods, allow);
07666    return allowed_methods;
07667 }

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

Copy SIP request, parse it.

Definition at line 3808 of file chan_sip.c.

References copy_request(), and parse_request().

Referenced by send_request(), and send_response().

03809 {
03810    copy_request(dst, src);
03811    parse_request(dst);
03812 }

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

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

Definition at line 24464 of file chan_sip.c.

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

Referenced by handle_request_invite(), and proc_422_rsp().

24465 {
24466    if (ast_strlen_zero(p_hdrval)) {
24467       ast_log(LOG_WARNING, "Null Min-SE header\n");
24468       return -1;
24469    }
24470 
24471    *p_interval = 0;
24472    p_hdrval = ast_skip_blanks(p_hdrval);
24473    if (!sscanf(p_hdrval, "%30d", p_interval)) {
24474       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
24475       return -1;
24476    }
24477 
24478    ast_debug(2, "Received Min-SE: %d\n", *p_interval);
24479    return 0;
24480 }

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 18414 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_transport(), LOG_NOTICE, pbx_builtin_setvar_helper(), remove_uri_parameters(), set_socket_transport(), and strcasestr().

Referenced by change_redirecting_information().

18415 {
18416    char contact[SIPBUFSIZE];
18417    char *contact_name = NULL;
18418    char *contact_number = NULL;
18419    char *separator, *trans;
18420    char *domain;
18421    enum sip_transport transport = SIP_TRANSPORT_UDP;
18422 
18423    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
18424    if ((separator = strchr(contact, ',')))
18425       *separator = '\0';
18426 
18427    contact_number = get_in_brackets(contact);
18428    if ((trans = strcasestr(contact_number, ";transport="))) {
18429       trans += 11;
18430 
18431       if ((separator = strchr(trans, ';')))
18432          *separator = '\0';
18433 
18434       if (!strncasecmp(trans, "tcp", 3))
18435          transport = SIP_TRANSPORT_TCP;
18436       else if (!strncasecmp(trans, "tls", 3))
18437          transport = SIP_TRANSPORT_TLS;
18438       else {
18439          if (strncasecmp(trans, "udp", 3))
18440             ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number);
18441          /* This will assume UDP for all unknown transports */
18442          transport = SIP_TRANSPORT_UDP;
18443       }
18444    }
18445    contact_number = remove_uri_parameters(contact_number);
18446 
18447    if (p->socket.tcptls_session) {
18448       ao2_ref(p->socket.tcptls_session, -1);
18449       p->socket.tcptls_session = NULL;
18450    }
18451 
18452    set_socket_transport(&p->socket, transport);
18453 
18454    if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
18455       char *host = NULL;
18456       if (!strncasecmp(contact_number, "sip:", 4))
18457          contact_number += 4;
18458       else if (!strncasecmp(contact_number, "sips:", 5))
18459          contact_number += 5;
18460       separator = strchr(contact_number, '/');
18461       if (separator)
18462          *separator = '\0';
18463       if ((host = strchr(contact_number, '@'))) {
18464          *host++ = '\0';
18465          ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, get_transport(transport), host);
18466          if (p->owner)
18467             ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", contact_number, get_transport(transport), host);
18468       } else {
18469          ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), contact_number);
18470          if (p->owner)
18471             ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), contact_number);
18472       }
18473    } else {
18474       separator = strchr(contact, '@');
18475       if (separator) {
18476          *separator++ = '\0';
18477          domain = separator;
18478       } else {
18479          /* No username part */
18480          domain = contact;
18481       }
18482       separator = strchr(contact, '/');   /* WHEN do we hae a forward slash in the URI? */
18483       if (separator)
18484          *separator = '\0';
18485 
18486       if (!strncasecmp(contact_number, "sip:", 4))
18487          contact_number += 4;
18488       else if (!strncasecmp(contact_number, "sips:", 5))
18489          contact_number += 5;
18490       separator = strchr(contact_number, ';');  /* And username ; parameters? */
18491       if (separator)
18492          *separator = '\0';
18493       ast_uri_decode(contact_number);
18494       if (set_call_forward) {
18495          ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain);
18496          if (p->owner) {
18497             pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
18498             ast_string_field_set(p->owner, call_forward, contact_number);
18499          }
18500       }
18501    }
18502 
18503    /* We've gotten the number for the contact, now get the name */
18504 
18505    if (*contact == '\"') {
18506       contact_name = contact + 1;
18507       if (!(separator = (char *)find_closing_quote(contact_name, NULL))) {
18508          ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact);
18509       }
18510       *separator = '\0';
18511    }
18512 
18513    if (name && !ast_strlen_zero(contact_name)) {
18514       *name = ast_strdup(contact_name);
18515    }
18516    if (number) {
18517       *number = ast_strdup(contact_number);
18518    }
18519 }

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

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

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

12816 {
12817    char contact[SIPBUFSIZE];
12818    char *c;
12819 
12820    /* Look for brackets */
12821    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
12822    c = get_in_brackets(contact);
12823 
12824    /* Save full contact to call pvt for later bye or re-invite */
12825    ast_string_field_set(pvt, fullcontact, c);
12826 
12827    /* Save URI for later ACKs, BYE or RE-invites */
12828    ast_string_field_set(pvt, okcontacturi, c);
12829 
12830    /* We should return false for URI:s we can't handle,
12831       like tel:, mailto:,ldap: etc */
12832    return TRUE;      
12833 }

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

References ao2_t_link, ao2_t_unlink, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_sched_when(), AST_SENSE_ALLOW, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, copy_socket_data(), destroy_association(), EVENT_FLAG_SYSTEM, expire_register(), FALSE, get_header(), get_transport_str2enum(), LOG_NOTICE, LOG_WARNING, manager_event, ref_peer(), register_peer_exten(), set_socket_transport(), sip_cfg, sip_poke_peer(), strcasestr(), strsep(), TRUE, unref_peer(), VERBOSE_PREFIX_3, and VERBOSITY_ATLEAST.

Referenced by register_verify().

12898 {
12899    char contact[SIPBUFSIZE];
12900    char data[SIPBUFSIZE];
12901    const char *expires = get_header(req, "Expires");
12902    int expire = atoi(expires);
12903    char *curi, *domain, *transport;
12904    int transport_type;
12905    const char *useragent;
12906    struct ast_sockaddr oldsin, testsa;
12907 
12908    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
12909 
12910    if (ast_strlen_zero(expires)) {  /* No expires header, try look in Contact: */
12911       char *s = strcasestr(contact, ";expires=");
12912       if (s) {
12913          expires = strsep(&s, ";"); /* trim ; and beyond */
12914          if (sscanf(expires + 9, "%30d", &expire) != 1) {
12915             expire = default_expiry;
12916          }
12917       } else {
12918          /* Nothing has been specified */
12919          expire = default_expiry;
12920       }
12921    }
12922 
12923    copy_socket_data(&pvt->socket, &req->socket);
12924 
12925    /* Look for brackets */
12926    curi = contact;
12927    if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
12928       strsep(&curi, ";");  /* This is Header options, not URI options */
12929    curi = get_in_brackets(contact);
12930 
12931    /* if they did not specify Contact: or Expires:, they are querying
12932       what we currently have stored as their contact address, so return
12933       it
12934    */
12935    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
12936       /* If we have an active registration, tell them when the registration is going to expire */
12937       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) {
12938          pvt->expiry = ast_sched_when(sched, peer->expire);
12939       }
12940       return PARSE_REGISTER_QUERY;
12941    } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */
12942       /* This means remove all registrations and return OK */
12943       memset(&peer->addr, 0, sizeof(peer->addr));
12944       set_socket_transport(&peer->socket, peer->default_outbound_transport);
12945 
12946       AST_SCHED_DEL_UNREF(sched, peer->expire,
12947             unref_peer(peer, "remove register expire ref"));
12948 
12949       destroy_association(peer);
12950 
12951       register_peer_exten(peer, FALSE);   /* Remove extension from regexten= setting in sip.conf */
12952       ast_string_field_set(peer, fullcontact, "");
12953       ast_string_field_set(peer, useragent, "");
12954       peer->sipoptions = 0;
12955       peer->lastms = 0;
12956       peer->portinuri = 0;
12957       pvt->expiry = 0;
12958 
12959       ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
12960 
12961       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
12962       return PARSE_REGISTER_UPDATE;
12963    }
12964 
12965    /* Store whatever we got as a contact from the client */
12966    ast_string_field_set(peer, fullcontact, curi);
12967 
12968    /* For the 200 OK, we should use the received contact */
12969    ast_string_field_build(pvt, our_contact, "<%s>", curi);
12970 
12971    /* Make sure it's a SIP URL */
12972    if (parse_uri(curi, "sip:,sips:", &curi, NULL, &domain, &transport)) {
12973       ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n");
12974    }
12975 
12976    /* handle the transport type specified in Contact header. */
12977    if (!(transport_type = get_transport_str2enum(transport))) {
12978       transport_type = pvt->socket.type;
12979    }
12980 
12981    /* if the peer's socket type is different than the Registration
12982     * transport type, change it.  If it got this far, it is a
12983     * supported type, but check just in case */
12984    if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) {
12985       set_socket_transport(&peer->socket, transport_type);
12986    }
12987 
12988    oldsin = peer->addr;
12989 
12990    /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */
12991    if (!ast_sockaddr_isnull(&peer->addr)) {
12992       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
12993    }
12994 
12995    if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) {
12996        /* use the data provided in the Contact header for call routing */
12997       ast_debug(1, "Store REGISTER's Contact header for call routing.\n");
12998       /* XXX This could block for a long time XXX */
12999       /*! \todo Check NAPTR/SRV if we have not got a port in the URI */
13000       if (ast_sockaddr_resolve_first(&testsa, domain, 0)) {
13001          ast_log(LOG_WARNING, "Invalid domain '%s'\n", domain);
13002          ast_string_field_set(peer, fullcontact, "");
13003          ast_string_field_set(pvt, our_contact, "");
13004          return PARSE_REGISTER_FAILED;
13005       }
13006 
13007       /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records.
13008          The domain part is actually a host. */
13009       peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE;
13010 
13011       if (!ast_sockaddr_port(&testsa)) {
13012          ast_sockaddr_set_port(&testsa,
13013                     transport_type == SIP_TRANSPORT_TLS ?
13014                     STANDARD_TLS_PORT : STANDARD_SIP_PORT);
13015       }
13016 
13017       ast_sockaddr_copy(&peer->addr, &testsa);
13018    } else {
13019       /* Don't trust the contact field.  Just use what they came to us
13020          with */
13021       ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n");
13022       peer->addr = pvt->recv;
13023    }
13024 
13025    /* Check that they're allowed to register at this IP */
13026    if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW ||
13027          ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) {
13028       ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", domain,
13029          ast_sockaddr_stringify_addr(&testsa));
13030       ast_string_field_set(peer, fullcontact, "");
13031       ast_string_field_set(pvt, our_contact, "");
13032       return PARSE_REGISTER_DENIED;
13033    }
13034 
13035    /* if the Contact header information copied into peer->addr matches the
13036     * received address, and the transport types are the same, then copy socket
13037     * data into the peer struct */
13038    if ((peer->socket.type == pvt->socket.type) &&
13039       !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) {
13040       copy_socket_data(&peer->socket, &pvt->socket);
13041    }
13042 
13043    /* Now that our address has been updated put ourselves back into the container for lookups */
13044    ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table");
13045 
13046    /* Save SIP options profile */
13047    peer->sipoptions = pvt->sipoptions;
13048 
13049    if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) {
13050       ast_string_field_set(peer, username, curi);
13051    }
13052 
13053    AST_SCHED_DEL_UNREF(sched, peer->expire,
13054          unref_peer(peer, "remove register expire ref"));
13055 
13056    if (expire > max_expiry) {
13057       expire = max_expiry;
13058    }
13059    if (expire < min_expiry) {
13060       expire = min_expiry;
13061    }
13062    if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
13063       peer->expire = -1;
13064    } else {
13065       peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register,
13066             ref_peer(peer, "add registration ref"));
13067       if (peer->expire == -1) {
13068          unref_peer(peer, "remote registration ref");
13069       }
13070    }
13071    pvt->expiry = expire;
13072    snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr),
13073        expire, peer->username, peer->fullcontact);
13074    /* Saving TCP connections is useless, we won't be able to reconnect
13075       XXX WHY???? XXX
13076       \todo Fix this immediately.
13077    */
13078    if (!peer->rt_fromcontact && (peer->socket.type & SIP_TRANSPORT_UDP))
13079       ast_db_put("SIP/Registry", peer->name, data);
13080    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));
13081 
13082    /* Is this a new IP address for us? */
13083    if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) {
13084       ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name,
13085             ast_sockaddr_stringify(&peer->addr));
13086    }
13087    sip_poke_peer(peer, 0);
13088    register_peer_exten(peer, 1);
13089    
13090    /* Save User agent */
13091    useragent = get_header(req, "User-Agent");
13092    if (strcasecmp(useragent, peer->useragent)) {
13093       ast_string_field_set(peer, useragent, useragent);
13094       ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);
13095    }
13096    return PARSE_REGISTER_UPDATE;
13097 }

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

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

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

07740 {
07741    char *c = req->data->str;
07742    ptrdiff_t *dst = req->header;
07743    int i = 0, lim = SIP_MAX_HEADERS - 1;
07744    unsigned int skipping_headers = 0;
07745    ptrdiff_t current_header_offset = 0;
07746    char *previous_header = "";
07747 
07748    req->header[0] = 0;
07749    req->headers = -1;   /* mark that we are working on the header */
07750    for (; *c; c++) {
07751       if (*c == '\r') {    /* remove \r */
07752          *c = '\0';
07753       } else if (*c == '\n') {   /* end of this line */
07754          *c = '\0';
07755          current_header_offset = (c + 1) - req->data->str;
07756          previous_header = req->data->str + dst[i];
07757          if (skipping_headers) {
07758             /* check to see if this line is blank; if so, turn off
07759                the skipping flag, so the next line will be processed
07760                as a body line */
07761             if (ast_strlen_zero(previous_header)) {
07762                skipping_headers = 0;
07763             }
07764             dst[i] = current_header_offset; /* record start of next line */
07765             continue;
07766          }
07767          if (sipdebug) {
07768             ast_debug(4, "%7s %2d [%3d]: %s\n",
07769                  req->headers < 0 ? "Header" : "Body",
07770                  i, (int) strlen(previous_header), previous_header);
07771          }
07772          if (ast_strlen_zero(previous_header) && req->headers < 0) {
07773             req->headers = i; /* record number of header lines */
07774             dst = req->line;  /* start working on the body */
07775             i = 0;
07776             lim = SIP_MAX_LINES - 1;
07777          } else { /* move to next line, check for overflows */
07778             if (i++ == lim) {
07779                /* if we're processing headers, then skip any remaining
07780                   headers and move on to processing the body, otherwise
07781                   we're done */
07782                if (req->headers != -1) {
07783                   break;
07784                } else {
07785                   req->headers = i;
07786                   dst = req->line;
07787                   i = 0;
07788                   lim = SIP_MAX_LINES - 1;
07789                   skipping_headers = 1;
07790                }
07791             }
07792          }
07793          dst[i] = current_header_offset; /* record start of next line */
07794       }
07795    }
07796 
07797    /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF,
07798       but since some devices send without, we'll be generous in what we accept. However,
07799       if we've already reached the maximum number of lines for portion of the message
07800       we were parsing, we can't accept any more, so just ignore it.
07801    */
07802    previous_header = req->data->str + dst[i];
07803    if ((i < lim) && !ast_strlen_zero(previous_header)) {
07804       if (sipdebug) {
07805          ast_debug(4, "%7s %2d [%3d]: %s\n",
07806               req->headers < 0 ? "Header" : "Body",
07807               i, (int) strlen(previous_header), previous_header );
07808       }
07809       i++;
07810    }
07811 
07812    /* update count of header or body lines */
07813    if (req->headers >= 0) {   /* we are in the body */
07814       req->lines = i;
07815    } else {       /* no body */
07816       req->headers = i;
07817       req->lines = 0;
07818       /* req->data->used will be a NULL byte */
07819       req->line[0] = ast_str_strlen(req->data);
07820    }
07821 
07822    if (*c) {
07823       ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c);
07824    }
07825 
07826    /* Split up the first line parts */
07827    return determine_firstline_parts(req);
07828 }

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

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

Definition at line 24484 of file chan_sip.c.

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

Referenced by handle_request_invite(), and handle_response_invite().

24485 {
24486    char *p_token;
24487    int  ref_idx;
24488    char *p_se_hdr;
24489 
24490    if (ast_strlen_zero(p_hdrval)) {
24491       ast_log(LOG_WARNING, "Null Session-Expires header\n");
24492       return -1;
24493    }
24494 
24495    *p_ref = SESSION_TIMER_REFRESHER_AUTO;
24496    *p_interval = 0;
24497 
24498    p_se_hdr = ast_strdupa(p_hdrval);
24499    p_se_hdr = ast_skip_blanks(p_se_hdr);
24500 
24501    while ((p_token = strsep(&p_se_hdr, ";"))) {
24502       p_token = ast_skip_blanks(p_token);
24503       if (!sscanf(p_token, "%30d", p_interval)) {
24504          ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n");
24505          return -1;
24506       }
24507 
24508       ast_debug(2, "Session-Expires: %d\n", *p_interval);
24509 
24510       if (!p_se_hdr)
24511          continue;
24512 
24513       p_se_hdr = ast_skip_blanks(p_se_hdr);
24514       ref_idx = strlen("refresher=");
24515       if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
24516          p_se_hdr += ref_idx;
24517          p_se_hdr = ast_skip_blanks(p_se_hdr);
24518 
24519          if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) {
24520             *p_ref = SESSION_TIMER_REFRESHER_UAC;
24521             ast_debug(2, "Refresher: UAC\n");
24522          } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) {
24523             *p_ref = SESSION_TIMER_REFRESHER_UAS;
24524             ast_debug(2, "Refresher: UAS\n");
24525          } else {
24526             ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr);
24527             return -1;
24528          }
24529          break;
24530       }
24531    }
24532    return 0;
24533 }

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

References CMP_MATCH, and CMP_STOP.

27975 {
27976    struct sip_peer *peer = obj, *peer2 = arg;
27977 
27978    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
27979 }

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

Definition at line 15688 of file chan_sip.c.

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

Referenced by sip_show_objects().

15689 {
15690    struct sip_peer *peer = userobj;
15691    int refc = ao2_t_ref(userobj, 0, "");
15692    struct ast_cli_args *a = (struct ast_cli_args *) arg;
15693    
15694    ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n",
15695       peer->name, 0, refc);
15696    return 0;
15697 }

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

References ast_str_case_hash().

27965 {
27966    const struct sip_peer *peer = obj;
27967 
27968    return ast_str_case_hash(peer->name);
27969 }

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

28023 {
28024    struct sip_peer *peer = obj, *peer2 = arg;
28025 
28026    if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) {
28027       /* IP doesn't match */
28028       return 0;
28029    }
28030 
28031    /* We matched the IP, check to see if we need to match by port as well. */
28032    if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) {
28033       /* peer matching on port is not possible with TCP/TLS */
28034       return CMP_MATCH | CMP_STOP;
28035    } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
28036       /* We are allowing match without port for peers configured that
28037        * way in this pass through the peers. */
28038       return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ?
28039             (CMP_MATCH | CMP_STOP) : 0;
28040    }
28041 
28042    /* Now only return a match if the port matches, as well. */
28043    return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ?
28044          (CMP_MATCH | CMP_STOP) : 0;
28045 }

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

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

Referenced by load_module().

27987 {
27988    const struct sip_peer *peer = obj;
27989    int ret = 0;
27990 
27991    if (ast_sockaddr_isnull(&peer->addr)) {
27992       ast_log(LOG_ERROR, "Empty address\n");
27993    }
27994 
27995    ret = ast_sockaddr_hash(&peer->addr);
27996 
27997    if (ret < 0) {
27998       ret = -ret;
27999    }
28000 
28001    return ret;
28002 }

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

Definition at line 2627 of file chan_sip.c.

References CMP_MATCH.

Referenced by unlink_marked_peers_from_tables().

02628 {
02629    struct sip_peer *peer = peerobj;
02630    return peer->the_mark ? CMP_MATCH : 0;
02631 }

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

list peer mailboxes to CLI

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

16172 {
16173    struct sip_mailbox *mailbox;
16174 
16175    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
16176       ast_str_append(mailbox_str, 0, "%s%s%s%s",
16177          mailbox->mailbox,
16178          ast_strlen_zero(mailbox->context) ? "" : "@",
16179          S_OR(mailbox->context, ""),
16180          AST_LIST_NEXT(mailbox, entry) ? "," : "");
16181    }
16182 }

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

Definition at line 26240 of file chan_sip.c.

Referenced by reload_config().

26241 {
26242    struct sip_peer *peer = device;
26243    peer->the_mark = 1;
26244    return 0;
26245 }

static int peer_status ( struct sip_peer *  peer,
char *  status,
int  statuslen 
) [static]

Definition at line 15278 of file chan_sip.c.

References ast_copy_string().

15279 {
15280    int res = 0;
15281    if (peer->maxms) {
15282       if (peer->lastms < 0) {
15283          ast_copy_string(status, "UNREACHABLE", statuslen);
15284       } else if (peer->lastms > peer->maxms) {
15285          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
15286          res = 1;
15287       } else if (peer->lastms) {
15288          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
15289          res = 1;
15290       } else {
15291          ast_copy_string(status, "UNKNOWN", statuslen);
15292       }
15293    } else {
15294       ast_copy_string(status, "Unmonitored", statuslen);
15295       /* Checking if port is 0 */
15296       res = -1;
15297    }
15298    return res;
15299 }

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

Definition at line 15506 of file chan_sip.c.

Referenced by _sip_show_peers().

15507 {
15508    struct sip_peer **ap = (struct sip_peer **)a;
15509    struct sip_peer **bp = (struct sip_peer **)b;
15510    return strcmp((*ap)->name, (*bp)->name);
15511 }

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

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

28254 {
28255    struct sip_peer *peer;
28256    struct ao2_iterator i;
28257    struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node;
28258    struct ast_data *data_sip_options;
28259    int total_mailboxes, x;
28260    struct sip_mailbox *mailbox;
28261 
28262    i = ao2_iterator_init(peers, 0);
28263    while ((peer = ao2_iterator_next(&i))) {
28264       ao2_lock(peer);
28265 
28266       data_peer = ast_data_add_node(data_root, "peer");
28267       if (!data_peer) {
28268          ao2_unlock(peer);
28269          ao2_ref(peer, -1);
28270          continue;
28271       }
28272 
28273       ast_data_add_structure(sip_peer, data_peer, peer);
28274 
28275       /* transfer mode */
28276       enum_node = ast_data_add_node(data_peer, "allowtransfer");
28277       if (!enum_node) {
28278          continue;
28279       }
28280       ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer));
28281       ast_data_add_int(enum_node, "value", peer->allowtransfer);
28282 
28283       /* transports */
28284       ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports));
28285 
28286       /* peer type */
28287       if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) {
28288          ast_data_add_str(data_peer, "type", "friend");
28289       } else if (peer->type & SIP_TYPE_PEER) {
28290          ast_data_add_str(data_peer, "type", "peer");
28291       } else if (peer->type & SIP_TYPE_USER) {
28292          ast_data_add_str(data_peer, "type", "user");
28293       }
28294 
28295       /* mailboxes */
28296       total_mailboxes = 0;
28297       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
28298          if (!total_mailboxes) {
28299             data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes");
28300             if (!data_peer_mailboxes) {
28301                break;
28302             }
28303             total_mailboxes++;
28304          }
28305 
28306          data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox");
28307          if (!data_peer_mailbox) {
28308             continue;
28309          }
28310          ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox);
28311          ast_data_add_str(data_peer_mailbox, "context", mailbox->context);
28312       }
28313 
28314       /* amaflags */
28315       enum_node = ast_data_add_node(data_peer, "amaflags");
28316       if (!enum_node) {
28317          continue;
28318       }
28319       ast_data_add_int(enum_node, "value", peer->amaflags);
28320       ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags));
28321 
28322       /* sip options */
28323       data_sip_options = ast_data_add_node(data_peer, "sipoptions");
28324       if (!data_sip_options) {
28325          continue;
28326       }
28327       for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
28328          ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id);
28329       }
28330 
28331       /* callingpres */
28332       enum_node = ast_data_add_node(data_peer, "callingpres");
28333       if (!enum_node) {
28334          continue;
28335       }
28336       ast_data_add_int(enum_node, "value", peer->callingpres);
28337       ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres));
28338 
28339       /* codecs */
28340       ast_data_add_codecs(data_peer, "codecs", peer->capability);
28341 
28342       if (!ast_data_search_match(search, data_peer)) {
28343          ast_data_remove_node(data_root, data_peer);
28344       }
28345 
28346       ao2_unlock(peer);
28347       ao2_ref(peer, -1);
28348    }
28349    ao2_iterator_destroy(&i);
28350 
28351    return 0;
28352 }

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

References ast_strlen_zero().

Referenced by build_peer(), and reload_config().

02864 {
02865    int port = standard;
02866    if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) {
02867       port = standard;
02868    }
02869 
02870    return port;
02871 }

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

References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.

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

16009 {
16010    int x;
16011    format_t codec;
16012 
16013    for(x = 0; x < 64 ; x++) {
16014       codec = ast_codec_pref_index(pref, x);
16015       if (!codec)
16016          break;
16017       ast_cli(fd, "%s", ast_getformatname(codec));
16018       ast_cli(fd, ":%d", pref->framing[x]);
16019       if (x < 31 && ast_codec_pref_index(pref, x + 1))
16020          ast_cli(fd, ",");
16021    }
16022    if (!x)
16023       ast_cli(fd, "none");
16024 }

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

Print call group and pickup group.

Definition at line 15738 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

15739 {
15740    char buf[256];
15741    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
15742 }

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

24544 {
24545    int rtn;
24546    const char *p_hdrval;
24547    int minse;
24548 
24549    p_hdrval = get_header(rsp, "Min-SE");
24550    if (ast_strlen_zero(p_hdrval)) {
24551       ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval);
24552       return;
24553    }
24554    rtn = parse_minse(p_hdrval, &minse);
24555    if (rtn != 0) {
24556       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
24557       return;
24558    }
24559    p->stimer->st_interval = minse;
24560    transmit_invite(p, SIP_INVITE, 1, 2, NULL);
24561 }

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

Session-Timers: Process session refresh timeout event.

Definition at line 24383 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_ERROR, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, stop_session_timer(), transmit_reinvite_with_sdp(), and TRUE.

Referenced by start_session_timer().

24384 {
24385    struct sip_pvt *p = (struct sip_pvt *) vp;
24386    int sendreinv = FALSE;
24387    int res = 0;
24388 
24389    if (!p->stimer) {
24390       ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid);
24391       goto return_unref;
24392    }
24393 
24394    ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid);
24395 
24396    if (!p->owner) {
24397       goto return_unref;
24398    }
24399 
24400    if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) {
24401       goto return_unref;
24402    }
24403 
24404    switch (p->stimer->st_ref) {
24405    case SESSION_TIMER_REFRESHER_UAC:
24406       if (p->outgoing_call == TRUE) {
24407          sendreinv = TRUE;
24408       }
24409       break;
24410    case SESSION_TIMER_REFRESHER_UAS:
24411       if (p->outgoing_call != TRUE) {
24412          sendreinv = TRUE;
24413       }
24414       break;
24415    default:
24416       ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->stimer->st_ref);
24417       goto return_unref;
24418    }
24419 
24420    if (sendreinv == TRUE) {
24421       res = 1;
24422       transmit_reinvite_with_sdp(p, FALSE, TRUE);
24423    } else {
24424       p->stimer->st_expirys++;
24425       if (p->stimer->st_expirys >= 2) {
24426          if (p->stimer->quit_flag) {
24427             goto return_unref;
24428          }
24429          ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
24430          sip_pvt_lock(p);
24431          while (p->owner && ast_channel_trylock(p->owner)) {
24432             sip_pvt_unlock(p);
24433             usleep(1);
24434             if (p->stimer && p->stimer->quit_flag) {
24435                goto return_unref;
24436             }
24437             sip_pvt_lock(p);
24438          }
24439 
24440          ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
24441          ast_channel_unlock(p->owner);
24442          sip_pvt_unlock(p);
24443       }
24444    }
24445 
24446 return_unref:
24447    if (!res) {
24448       /* An error occurred.  Stop session timer processing */
24449       if (p->stimer) {
24450          p->stimer->st_schedid = -1;
24451          stop_session_timer(p);
24452       }
24453 
24454       /* If we are not asking to be rescheduled, then we need to release our
24455        * reference to the dialog. */
24456       dialog_unref(p, "removing session timer ref");
24457    }
24458 
24459    return res;
24460 }

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

Definition at line 27825 of file chan_sip.c.

References ast_debug, ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_WARNING, setup_srtp(), and TRUE.

Referenced by process_sdp().

27826 {
27827    if (strncasecmp(a, "crypto:", 7)) {
27828       return FALSE;
27829    }
27830    if (!*srtp) {
27831       if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
27832          ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
27833          return FALSE;
27834       }
27835 
27836       if (setup_srtp(srtp) < 0) {
27837          return FALSE;
27838       }
27839    }
27840 
27841    /* For now, when we receive an INVITE just take the first successful crypto line */
27842    if ((*srtp)->crypto && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
27843       ast_debug(3, "We've already processed a crypto attribute, skipping '%s'\n", a);
27844       return FALSE;
27845    }
27846 
27847    if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) {
27848       return FALSE;
27849    }
27850 
27851    if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) {
27852       return FALSE;
27853    }
27854 
27855    ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK);
27856 
27857    return TRUE;
27858 }

static void process_request_queue ( struct sip_pvt *  p,
int *  recount,
int *  nounlock 
) [static]

Definition at line 23643 of file chan_sip.c.

References ast_debug, ast_free, AST_LIST_REMOVE_HEAD, and handle_incoming().

Referenced by handle_request_do(), and scheduler_process_request_queue().

23644 {
23645    struct sip_request *req;
23646 
23647    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
23648       if (handle_incoming(p, req, &p->recv, recount, nounlock) == -1) {
23649          /* Request failed */
23650          ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
23651       }
23652       ast_free(req);
23653    }
23654 }

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

Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().

< RTP Audio host IP

< RTP video host IP

< RTP text host IP

< UDPTL host ip

< RTP Audio port number

< RTP Video port number

< RTP Text port number

< UDPTL Image port number

Definition at line 7993 of file chan_sip.c.

References append_history, ast_async_goto(), ast_channel_lock, 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_manager_event, 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_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_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_t38_state(), debug, EVENT_FLAG_CALL, FALSE, get_sdp_iterate(), get_sdp_line(), 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_cfg, sip_debug_test_pvt(), sip_peer_hold(), text, TRUE, type, UDPTL_ERROR_CORRECTION_NONE, value, and VERBOSE_PREFIX_2.

07994 {
07995    /* Iterators for SDP parsing */
07996    int start = req->sdp_start;
07997    int next = start;
07998    int iterator = start;
07999 
08000    /* Temporary vars for SDP parsing */
08001    char type = '\0';
08002    const char *value = NULL;
08003    const char *m = NULL;           /* SDP media offer */
08004    const char *nextm = NULL;
08005    int len = -1;
08006 
08007    /* Host information */
08008    struct ast_sockaddr sessionsa;
08009    struct ast_sockaddr audiosa;
08010    struct ast_sockaddr videosa;
08011    struct ast_sockaddr textsa;
08012    struct ast_sockaddr imagesa;
08013    struct ast_sockaddr *sa = NULL;  /*!< RTP Audio host IP */
08014    struct ast_sockaddr *vsa = NULL; /*!< RTP video host IP */
08015    struct ast_sockaddr *tsa = NULL; /*!< RTP text host IP */
08016    struct ast_sockaddr *isa = NULL;     /*!< UDPTL host ip */
08017    int portno = -1;     /*!< RTP Audio port number */
08018    int vportno = -1;    /*!< RTP Video port number */
08019    int tportno = -1;    /*!< RTP Text port number */
08020    int udptlportno = -1;      /*!< UDPTL Image port number */
08021 
08022    /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 
08023    format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0;
08024    int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0;
08025 
08026    struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp;
08027    format_t newjointcapability;           /* Negotiated capability */
08028    format_t newpeercapability;
08029    int newnoncodeccapability;
08030 
08031    const char *codecs;
08032    int codec;
08033 
08034    /* SRTP */
08035    int secure_audio = FALSE;
08036    int secure_video = FALSE;
08037 
08038    /* Others */
08039    int sendonly = -1;
08040    int vsendonly = -1;
08041    int numberofports;
08042    int numberofmediastreams = 0;
08043    int last_rtpmap_codec = 0;
08044    int red_data_pt[10];    /* For T.140 red */
08045    int red_num_gen = 0;    /* For T.140 red */
08046    char red_fmtp[100] = "empty"; /* For T.140 red */
08047    int debug = sip_debug_test_pvt(p);
08048 
08049    /* START UNKNOWN */
08050    char buf[SIPBUFSIZE];
08051    /* END UNKNOWN */
08052 
08053    /* Initial check */
08054    if (!p->rtp) {
08055       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
08056       return -1;
08057    }
08058 
08059    /* Make sure that the codec structures are all cleared out */
08060    ast_rtp_codecs_payloads_clear(&newaudiortp, NULL);
08061    ast_rtp_codecs_payloads_clear(&newvideortp, NULL);
08062    ast_rtp_codecs_payloads_clear(&newtextrtp, NULL);
08063 
08064    /* Update our last rtprx when we receive an SDP, too */
08065    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
08066 
08067    memset(p->offered_media, 0, sizeof(p->offered_media));
08068 
08069 
08070    /* default: novideo and notext set */
08071    p->novideo = TRUE;
08072    p->notext = TRUE;
08073 
08074    if (p->vrtp) {
08075       ast_rtp_codecs_payloads_clear(&newvideortp, NULL);
08076    }
08077 
08078    if (p->trtp) {
08079       ast_rtp_codecs_payloads_clear(&newtextrtp, NULL);
08080    }
08081 
08082    /* Scan for the first media stream (m=) line to limit scanning of globals */
08083    nextm = get_sdp_iterate(&next, req, "m");
08084    if (ast_strlen_zero(nextm)) {
08085       ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n");
08086       return -1;
08087    }
08088 
08089    /* Scan session level SDP parameters (lines before first media stream) */
08090    while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
08091       int processed = FALSE;
08092       switch (type) {
08093       case 'o':
08094          /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal
08095           * error. We just want to ignore the SDP and let the rest of the packet be handled as normal.
08096           */
08097          if (!process_sdp_o(value, p))
08098             return (p->session_modify == FALSE) ? 0 : -1;
08099          break;
08100       case 'c':
08101          if (process_sdp_c(value, &sessionsa)) {
08102             processed = TRUE;
08103             sa = &sessionsa;
08104             vsa = sa;
08105             tsa = sa;
08106             isa = sa;
08107          }
08108          break;
08109       case 'a':
08110          if (process_sdp_a_sendonly(value, &sendonly)) {
08111             processed = TRUE;
08112             vsendonly = sendonly;
08113          }
08114          else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
08115             processed = TRUE;
08116          else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
08117             processed = TRUE;
08118          else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
08119             processed = TRUE;
08120          else if (process_sdp_a_image(value, p))
08121             processed = TRUE;
08122          break;
08123       }
08124 
08125       ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED.");
08126    }
08127 
08128 
08129 
08130    /* Scan media stream (m=) specific parameters loop */
08131    while (!ast_strlen_zero(nextm)) {
08132       int audio = FALSE;
08133       int video = FALSE;
08134       int image = FALSE;
08135       int text = FALSE;
08136       char protocol[5] = {0,};
08137       int x;
08138 
08139       numberofports = 1;
08140       len = -1;
08141       start = next;
08142       m = nextm;
08143       iterator = next;
08144       nextm = get_sdp_iterate(&next, req, "m");
08145 
08146       /* Search for audio media definition */
08147       if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
08148           (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) {
08149          if (!strcmp(protocol, "SAVP")) {
08150             secure_audio = 1;
08151          } else if (strcmp(protocol, "AVP")) {
08152             ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol);
08153             continue;
08154          }
08155          audio = TRUE;
08156          p->offered_media[SDP_AUDIO].offered = TRUE;
08157          numberofmediastreams++;
08158          portno = x;
08159 
08160          /* Scan through the RTP payload types specified in a "m=" line: */
08161          codecs = m + len;
08162          ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs));
08163          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
08164             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
08165                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
08166                return -1;
08167             }
08168             if (debug)
08169                ast_verbose("Found RTP audio format %d\n", codec);
08170             
08171             ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec);
08172          }
08173       /* Search for video media definition */
08174       } else if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
08175             (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len >= 0)) {
08176          if (!strcmp(protocol, "SAVP")) {
08177             secure_video = 1;
08178          } else if (strcmp(protocol, "AVP")) {
08179             ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol);
08180             continue;
08181          }
08182          video = TRUE;
08183          p->novideo = FALSE;
08184          p->offered_media[SDP_VIDEO].offered = TRUE;
08185          numberofmediastreams++;
08186          vportno = x;
08187 
08188          /* Scan through the RTP payload types specified in a "m=" line: */
08189          codecs = m + len;
08190          ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs));
08191          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
08192             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
08193                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
08194                return -1;
08195             }
08196             if (debug)
08197                ast_verbose("Found RTP video format %d\n", codec);
08198             ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec);
08199          }
08200       /* Search for text media definition */
08201       } else if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
08202             (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) {
08203          text = TRUE;
08204          p->notext = FALSE;
08205          p->offered_media[SDP_TEXT].offered = TRUE;
08206          numberofmediastreams++;
08207          tportno = x;
08208 
08209          /* Scan through the RTP payload types specified in a "m=" line: */
08210          codecs = m + len;
08211          ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs));
08212          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
08213             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
08214                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
08215                return -1;
08216             }
08217             if (debug)
08218                ast_verbose("Found RTP text format %d\n", codec);
08219             ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec);
08220          }
08221       /* Search for image media definition */
08222       } else if (p->udptl && ((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) ||
08223                (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0) )) {
08224          image = TRUE;
08225          if (debug)
08226             ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
08227          p->offered_media[SDP_IMAGE].offered = TRUE;
08228          udptlportno = x;
08229          numberofmediastreams++;
08230 
08231          if (p->t38.state != T38_ENABLED) {
08232             memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms));
08233 
08234             /* default EC to none, the remote end should
08235              * respond with the EC they want to use */
08236             ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
08237          }
08238       } else {
08239          ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
08240          continue;
08241       }
08242 
08243       /* Check for number of ports */
08244       if (numberofports > 1)
08245          ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
08246       
08247       /* Media stream specific parameters */
08248       while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
08249          int processed = FALSE;
08250 
08251          switch (type) {
08252          case 'c':
08253             if (audio) {
08254                if (process_sdp_c(value, &audiosa)) {
08255                   processed = TRUE;
08256                   sa = &audiosa;
08257                }
08258             } else if (video) {
08259                if (process_sdp_c(value, &videosa)) {
08260                   processed = TRUE;
08261                   vsa = &videosa;
08262                }
08263             } else if (text) {
08264                if (process_sdp_c(value, &textsa)) {
08265                   processed = TRUE;
08266                   tsa = &textsa;
08267                }
08268             } else if (image) {
08269                if (process_sdp_c(value, &imagesa)) {
08270                   processed = TRUE;
08271                   isa = &imagesa;
08272                }
08273             }
08274             break;
08275          case 'a':
08276             /* Audio specific scanning */
08277             if (audio) {
08278                if (process_sdp_a_sendonly(value, &sendonly))
08279                   processed = TRUE;
08280                else if (process_crypto(p, p->rtp, &p->srtp, value))
08281                   processed = TRUE;
08282                else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
08283                   processed = TRUE;
08284             }
08285             /* Video specific scanning */
08286             else if (video) {
08287                if (process_sdp_a_sendonly(value, &vsendonly))
08288                   processed = TRUE;
08289                else if (process_crypto(p, p->vrtp, &p->vsrtp, value))
08290                   processed = TRUE;
08291                else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
08292                   processed = TRUE;
08293             }
08294             /* Text (T.140) specific scanning */
08295             else if (text) {
08296                if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
08297                   processed = TRUE;
08298                else if (process_crypto(p, p->trtp, &p->tsrtp, value))
08299                   processed = TRUE;
08300             }
08301             /* Image (T.38 FAX) specific scanning */
08302             else if (image) {
08303                if (process_sdp_a_image(value, p))
08304                   processed = TRUE;
08305             }
08306             break;
08307          }
08308 
08309          ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n",
08310                (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image",
08311                type, value,
08312                (processed == TRUE)? "OK." : "UNSUPPORTED.");
08313       }
08314    }
08315 
08316 
08317    /* Sanity checks */
08318    if (!sa && !vsa && !tsa && !isa) {
08319       ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
08320       return -1;
08321    }
08322 
08323    if (portno == -1 && vportno == -1 && udptlportno == -1  && tportno == -1) {
08324       /* No acceptable offer found in SDP  - we have no ports */
08325       /* Do not change RTP or VRTP if this is a re-invite */
08326       ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n");
08327       return -2;
08328    }
08329 
08330    if (numberofmediastreams > 3) {
08331       /* We have too many fax, audio and/or video and/or text media streams, fail this offer */
08332       ast_log(LOG_WARNING, "Faling due to too many media streams\n");
08333       return -3;
08334    }
08335 
08336    if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) {
08337       ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
08338       return -4;
08339    }
08340 
08341    if (!secure_audio && p->srtp) {
08342       ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
08343       return -4;
08344    }
08345 
08346    if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) {
08347       ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
08348       return -4;
08349    }
08350 
08351    if (!p->novideo && !secure_video && p->vsrtp) {
08352       ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
08353       return -4;
08354    }
08355 
08356    if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
08357       ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n");
08358       return -4;
08359    }
08360 
08361    if (udptlportno == -1) {
08362       change_t38_state(p, T38_DISABLED);
08363    }
08364 
08365    /* Now gather all of the codecs that we are asked for: */
08366    ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability);
08367    ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability);
08368    ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability);
08369 
08370    newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability);
08371    newpeercapability = (peercapability | vpeercapability | tpeercapability);
08372    newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
08373 
08374    if (debug) {
08375       /* shame on whoever coded this.... */
08376       char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE];
08377 
08378       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n",
08379              ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability),
08380              ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability),
08381              ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
08382              ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability),
08383              ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability));
08384    }
08385    if (debug) {
08386       struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE);
08387       struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE);
08388       struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE);
08389 
08390       ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
08391              ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0),
08392              ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0),
08393              ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0));
08394    }
08395    if (!newjointcapability && (portno != -1)) {
08396       ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
08397       /* Do NOT Change current setting */
08398       return -1;
08399    }
08400 
08401    /* Setup audio address and port */
08402    if (p->rtp) {
08403       if (portno > 0) {
08404          ast_sockaddr_set_port(sa, portno);
08405          ast_rtp_instance_set_remote_address(p->rtp, sa);
08406          if (debug) {
08407             ast_verbose("Peer audio RTP is at port %s\n",
08408                    ast_sockaddr_stringify(sa));
08409          }
08410          /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
08411             they are acceptable */
08412          p->jointcapability = newjointcapability;                /* Our joint codec profile for this call */
08413          p->peercapability = newpeercapability;                  /* The other sides capability in latest offer */
08414          p->jointnoncodeccapability = newnoncodeccapability;     /* DTMF capabilities */
08415 
08416          if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { /* respond with single most preferred joint codec, limiting the other side's choice */
08417             p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1);
08418          }
08419 
08420          ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp);
08421 
08422          if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
08423             ast_clear_flag(&p->flags[0], SIP_DTMF);
08424             if (newnoncodeccapability & AST_RTP_DTMF) {
08425                /* XXX Would it be reasonable to drop the DSP at this point? XXX */
08426                ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
08427                /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
08428                ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
08429                ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
08430             } else {
08431                ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
08432             }
08433          }
08434       } else if (udptlportno > 0) {
08435          if (debug)
08436             ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
08437       } else {
08438          ast_rtp_instance_stop(p->rtp);
08439          if (debug)
08440             ast_verbose("Peer doesn't provide audio\n");
08441       }
08442    }
08443 
08444    /* Setup video address and port */
08445    if (p->vrtp) {
08446       if (vportno > 0) {
08447          ast_sockaddr_set_port(vsa, vportno);
08448          ast_rtp_instance_set_remote_address(p->vrtp, vsa);
08449          if (debug) {
08450             ast_verbose("Peer video RTP is at port %s\n",
08451                    ast_sockaddr_stringify(vsa));
08452          }
08453          ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp);
08454       } else {
08455          ast_rtp_instance_stop(p->vrtp);
08456          if (debug)
08457             ast_verbose("Peer doesn't provide video\n");
08458       }
08459    }
08460 
08461    /* Setup text address and port */
08462    if (p->trtp) {
08463       if (tportno > 0) {
08464          ast_sockaddr_set_port(tsa, tportno);
08465          ast_rtp_instance_set_remote_address(p->trtp, tsa);
08466          if (debug) {
08467             ast_verbose("Peer T.140 RTP is at port %s\n",
08468                    ast_sockaddr_stringify(tsa));
08469          }
08470          if ((p->jointcapability & AST_FORMAT_T140RED)) {
08471             p->red = 1;
08472             ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
08473          } else {
08474             p->red = 0;
08475          }
08476          ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp);
08477       } else {
08478          ast_rtp_instance_stop(p->trtp);
08479          if (debug)
08480             ast_verbose("Peer doesn't provide T.140\n");
08481       }
08482    }
08483    /* Setup image address and port */
08484    if (p->udptl) {
08485       if (udptlportno > 0) {
08486          if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
08487             ast_rtp_instance_get_remote_address(p->rtp, isa);
08488             if (!ast_sockaddr_isnull(isa) && debug) {
08489                ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa));
08490             }
08491          }
08492          ast_sockaddr_set_port(isa, udptlportno);
08493          ast_udptl_set_peer(p->udptl, isa);
08494          if (debug)
08495             ast_debug(1,"Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa));
08496 
08497          /* verify the far max ifp can be calculated. this requires far max datagram to be set. */
08498          if (!ast_udptl_get_far_max_datagram(p->udptl)) {
08499             /* setting to zero will force a default if none was provided by the SDP */
08500             ast_udptl_set_far_max_datagram(p->udptl, 0);
08501          }
08502 
08503          /* Remote party offers T38, we need to update state */
08504          if ((t38action == SDP_T38_ACCEPT) &&
08505              (p->t38.state == T38_LOCAL_REINVITE)) {
08506             change_t38_state(p, T38_ENABLED);
08507          } else if ((t38action == SDP_T38_INITIATE) &&
08508                p->owner && p->lastinvite) {
08509             change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */
08510             /* If fax detection is enabled then send us off to the fax extension */
08511             if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) {
08512                ast_channel_lock(p->owner);
08513                if (strcmp(p->owner->exten, "fax")) {
08514                   const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
08515                   ast_channel_unlock(p->owner);
08516                   if (ast_exists_extension(p->owner, target_context, "fax", 1,
08517                      S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) {
08518                      ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name);
08519                      pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);
08520                      if (ast_async_goto(p->owner, target_context, "fax", 1)) {
08521                         ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context);
08522                      }
08523                   } else {
08524                      ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n");
08525                   }
08526                } else {
08527                   ast_channel_unlock(p->owner);
08528                }
08529             }
08530          }
08531       } else {
08532          ast_udptl_stop(p->udptl);
08533          if (debug)
08534             ast_debug(1, "Peer doesn't provide T.38 UDPTL\n");
08535       }
08536    }
08537 
08538    if ((portno == -1) && (p->t38.state != T38_DISABLED)) {
08539       ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n");
08540       return 0;
08541         }
08542 
08543    /* Ok, we're going with this offer */
08544    ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability));
08545 
08546    if (!p->owner)    /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
08547       return 0;
08548 
08549    ast_debug(4, "We have an owner, now see if we need to change this call\n");
08550 
08551    if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
08552       if (debug) {
08553          char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
08554          ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n",
08555             ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability),
08556             ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats));
08557       }
08558       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability);
08559       ast_set_read_format(p->owner, p->owner->readformat);
08560       ast_set_write_format(p->owner, p->owner->writeformat);
08561    }
08562    
08563    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)) {
08564       ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
08565       /* Activate a re-invite */
08566       ast_queue_frame(p->owner, &ast_null_frame);
08567       /* Queue Manager Unhold event */
08568       append_history(p, "Unhold", "%s", req->data->str);
08569       if (sip_cfg.callevents)
08570          ast_manager_event(p->owner, EVENT_FLAG_CALL, "Hold",
08571                   "Status: Off\r\n"
08572                   "Channel: %s\r\n"
08573                   "Uniqueid: %s\r\n",
08574                   p->owner->name,
08575                   p->owner->uniqueid);
08576       if (sip_cfg.notifyhold)
08577          sip_peer_hold(p, FALSE);
08578       ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
08579    } else if ((ast_sockaddr_isnull(sa) && ast_sockaddr_isnull(vsa) && ast_sockaddr_isnull(tsa) && ast_sockaddr_isnull(isa)) || (sendonly && sendonly != -1)) {
08580       int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);
08581       ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
08582                    S_OR(p->mohsuggest, NULL),
08583                    !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
08584       if (sendonly)
08585          ast_rtp_instance_stop(p->rtp);
08586       /* RTCP needs to go ahead, even if we're on hold!!! */
08587       /* Activate a re-invite */
08588       ast_queue_frame(p->owner, &ast_null_frame);
08589       /* Queue Manager Hold event */
08590       append_history(p, "Hold", "%s", req->data->str);
08591       if (sip_cfg.callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
08592          ast_manager_event(p->owner, EVENT_FLAG_CALL, "Hold",
08593                   "Status: On\r\n"
08594                   "Channel: %s\r\n"
08595                   "Uniqueid: %s\r\n",
08596                   p->owner->name,
08597                   p->owner->uniqueid);
08598       }
08599       if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
08600          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
08601       else if (sendonly == 2) /* Inactive stream */
08602          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
08603       else
08604          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
08605       if (sip_cfg.notifyhold && !already_on_hold)
08606          sip_peer_hold(p, TRUE);
08607    }
08608    
08609    return 0;
08610 }

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 8738 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, debug, FALSE, format, LOG_WARNING, LONG_MAX, LONG_MIN, ast_rtp_codecs::pref, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

08739 {
08740    int found = FALSE;
08741    int codec;
08742    char mimeSubtype[128];
08743    char fmtp_string[64];
08744    unsigned int sample_rate;
08745    int debug = sip_debug_test_pvt(p);
08746 
08747    if (!strncasecmp(a, "ptime", 5)) {
08748       char *tmp = strrchr(a, ':');
08749       long int framing = 0;
08750       if (tmp) {
08751          tmp++;
08752          framing = strtol(tmp, NULL, 10);
08753          if (framing == LONG_MIN || framing == LONG_MAX) {
08754             framing = 0;
08755             ast_debug(1, "Can't read framing from SDP: %s\n", a);
08756          }
08757       }
08758       if (framing && p->autoframing) {
08759          struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
08760          int codec_n;
08761          for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) {
08762             struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n);
08763             if (!format.asterisk_format || !format.code) /* non-codec or not found */
08764                continue;
08765             ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing);
08766             ast_codec_pref_setsize(pref, format.code, framing);
08767          }
08768          ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref);
08769       }
08770       found = TRUE;
08771    } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
08772       /* We have a rtpmap to handle */
08773       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
08774          if (ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype,
08775              ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate) != -1) {
08776             if (debug)
08777                ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec);
08778             //found_rtpmap_codecs[last_rtpmap_codec] = codec;
08779             (*last_rtpmap_codec)++;
08780             found = TRUE;
08781          } else {
08782             ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
08783             if (debug)
08784                ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
08785          }
08786       } else {
08787          if (debug)
08788             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
08789       }
08790    } else if (sscanf(a, "fmtp: %30u %63s", &codec, fmtp_string) == 2) {
08791       struct ast_rtp_payload_type payload;
08792 
08793       payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec);
08794       if (payload.code && payload.asterisk_format) {
08795          unsigned int bit_rate;
08796 
08797          switch (payload.code) {
08798          case AST_FORMAT_SIREN7:
08799             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
08800                if (bit_rate != 32000) {
08801                   ast_log(LOG_WARNING, "Got Siren7 offer at %d bps, but only 32000 bps supported; ignoring.\n", bit_rate);
08802                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
08803                } else {
08804                   found = TRUE;
08805                }
08806             }
08807             break;
08808          case AST_FORMAT_SIREN14:
08809             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
08810                if (bit_rate != 48000) {
08811                   ast_log(LOG_WARNING, "Got Siren14 offer at %d bps, but only 48000 bps supported; ignoring.\n", bit_rate);
08812                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
08813                } else {
08814                   found = TRUE;
08815                }
08816             }
08817             break;
08818          case AST_FORMAT_G719:
08819             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
08820                if (bit_rate != 64000) {
08821                   ast_log(LOG_WARNING, "Got G.719 offer at %d bps, but only 64000 bps supported; ignoring.\n", bit_rate);
08822                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
08823                } else {
08824                   found = TRUE;
08825                }
08826             }
08827          }
08828       }
08829    }
08830 
08831    return found;
08832 }

static int process_sdp_a_image ( const char *  a,
struct sip_pvt *  p 
) [static]

Definition at line 8917 of file chan_sip.c.

References ast_debug, 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, TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by process_sdp().

08918 {
08919    int found = FALSE;
08920    char s[256];
08921    unsigned int x;
08922 
08923    if ((sscanf(a, "T38FaxMaxBuffer:%30u", &x) == 1)) {
08924       ast_debug(3, "MaxBufferSize:%d\n", x);
08925       found = TRUE;
08926    } else if ((sscanf(a, "T38MaxBitRate:%30u", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30u", &x) == 1)) {
08927       ast_debug(3, "T38MaxBitRate: %d\n", x);
08928       switch (x) {
08929       case 14400:
08930          p->t38.their_parms.rate = AST_T38_RATE_14400;
08931          break;
08932       case 12000:
08933          p->t38.their_parms.rate = AST_T38_RATE_12000;
08934          break;
08935       case 9600:
08936          p->t38.their_parms.rate = AST_T38_RATE_9600;
08937          break;
08938       case 7200:
08939          p->t38.their_parms.rate = AST_T38_RATE_7200;
08940          break;
08941       case 4800:
08942          p->t38.their_parms.rate = AST_T38_RATE_4800;
08943          break;
08944       case 2400:
08945          p->t38.their_parms.rate = AST_T38_RATE_2400;
08946          break;
08947       }
08948       found = TRUE;
08949    } else if ((sscanf(a, "T38FaxVersion:%30u", &x) == 1)) {
08950       ast_debug(3, "FaxVersion: %u\n", x);
08951       p->t38.their_parms.version = x;
08952       found = TRUE;
08953    } else if ((sscanf(a, "T38FaxMaxDatagram:%30u", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30u", &x) == 1)) {
08954       /* override the supplied value if the configuration requests it */
08955       if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) {
08956          ast_debug(1, "Overriding T38FaxMaxDatagram '%d' with '%d'\n", x, p->t38_maxdatagram);
08957          x = p->t38_maxdatagram;
08958       }
08959       ast_debug(3, "FaxMaxDatagram: %u\n", x);
08960       ast_udptl_set_far_max_datagram(p->udptl, x);
08961       found = TRUE;
08962    } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) {
08963       if (sscanf(a, "T38FaxFillBitRemoval:%30u", &x) == 1) {
08964          ast_debug(3, "FillBitRemoval: %d\n", x);
08965          if (x == 1) {
08966             p->t38.their_parms.fill_bit_removal = TRUE;
08967          }
08968       } else {
08969          ast_debug(3, "FillBitRemoval\n");
08970          p->t38.their_parms.fill_bit_removal = TRUE;
08971       }
08972       found = TRUE;
08973    } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) {
08974       if (sscanf(a, "T38FaxTranscodingMMR:%30u", &x) == 1) {
08975          ast_debug(3, "Transcoding MMR: %d\n", x);
08976          if (x == 1) {
08977             p->t38.their_parms.transcoding_mmr = TRUE;
08978          }
08979       } else {
08980          ast_debug(3, "Transcoding MMR\n");
08981          p->t38.their_parms.transcoding_mmr = TRUE;
08982       }
08983       found = TRUE;
08984    } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) {
08985       if (sscanf(a, "T38FaxTranscodingJBIG:%30u", &x) == 1) {
08986          ast_debug(3, "Transcoding JBIG: %d\n", x);
08987          if (x == 1) {
08988             p->t38.their_parms.transcoding_jbig = TRUE;
08989          }
08990       } else {
08991          ast_debug(3, "Transcoding JBIG\n");
08992          p->t38.their_parms.transcoding_jbig = TRUE;
08993       }
08994       found = TRUE;
08995    } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) {
08996       ast_debug(3, "RateManagement: %s\n", s);
08997       if (!strcasecmp(s, "localTCF"))
08998          p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF;
08999       else if (!strcasecmp(s, "transferredTCF"))
09000          p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF;
09001       found = TRUE;
09002    } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) {
09003       ast_debug(3, "UDP EC: %s\n", s);
09004       if (!strcasecmp(s, "t38UDPRedundancy")) {
09005          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
09006       } else if (!strcasecmp(s, "t38UDPFEC")) {
09007          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
09008       } else {
09009          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
09010       }
09011       found = TRUE;
09012    }
09013 
09014    return found;
09015 }

static int process_sdp_a_sendonly ( const char *  a,
int *  sendonly 
) [static]

Definition at line 8718 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by process_sdp().

08719 {
08720    int found = FALSE;
08721 
08722    if (!strcasecmp(a, "sendonly")) {
08723       if (*sendonly == -1)
08724          *sendonly = 1;
08725       found = TRUE;
08726    } else if (!strcasecmp(a, "inactive")) {
08727       if (*sendonly == -1)
08728          *sendonly = 2;
08729       found = TRUE;
08730    }  else if (!strcasecmp(a, "sendrecv")) {
08731       if (*sendonly == -1)
08732          *sendonly = 0;
08733       found = TRUE;
08734    }
08735    return found;
08736 }

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

References AST_RED_MAX_GENERATION, ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_verbose, debug, FALSE, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

08869 {
08870    int found = FALSE;
08871    int codec;
08872    char mimeSubtype[128];
08873    unsigned int sample_rate;
08874    char *red_cp;
08875    int debug = sip_debug_test_pvt(p);
08876 
08877    if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
08878       /* We have a rtpmap to handle */
08879       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
08880          if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */
08881             if (p->trtp) {
08882                /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
08883                ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
08884                found = TRUE;
08885             }
08886          } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */
08887             if (p->trtp) {
08888                ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
08889                sprintf(red_fmtp, "fmtp:%d ", codec);
08890                if (debug)
08891                   ast_verbose("RED submimetype has payload type: %d\n", codec);
08892                found = TRUE;
08893             }
08894          }
08895       } else {
08896          if (debug)
08897             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
08898       }
08899    } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) {
08900       /* count numbers of generations in fmtp */
08901       red_cp = &red_fmtp[strlen(red_fmtp)];
08902       strncpy(red_fmtp, a, 100);
08903 
08904       sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]);
08905       red_cp = strtok(red_cp, "/");
08906       while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) {
08907          sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]);
08908          red_cp = strtok(NULL, "/");
08909       }
08910       red_cp = red_fmtp;
08911       found = TRUE;
08912    }
08913 
08914    return found;
08915 }

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

References ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_verbose, debug, FALSE, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

08835 {
08836    int found = FALSE;
08837    int codec;
08838    char mimeSubtype[128];
08839    unsigned int sample_rate;
08840    int debug = sip_debug_test_pvt(p);
08841 
08842    if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
08843       /* We have a rtpmap to handle */
08844       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
08845          /* Note: should really look at the '#chans' params too */
08846          if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) {
08847             if (ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate) != -1) {
08848                if (debug)
08849                   ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec);
08850                //found_rtpmap_codecs[last_rtpmap_codec] = codec;
08851                (*last_rtpmap_codec)++;
08852                found = TRUE;
08853             } else {
08854                ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec);
08855                if (debug)
08856                   ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
08857             }
08858          }
08859       } else {
08860          if (debug)
08861             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
08862       }
08863    }
08864 
08865    return found;
08866 }

static int process_sdp_c ( const char *  c,
struct ast_sockaddr addr 
) [static]

Definition at line 8691 of file chan_sip.c.

References ast_log(), ast_sockaddr_resolve_first_af(), FALSE, LOG_WARNING, and TRUE.

Referenced by process_sdp().

08692 {
08693    char proto[4], host[258];
08694    int af;
08695 
08696    /* Check for Media-description-level-address */
08697    if (sscanf(c, "IN %3s %255s", proto, host) == 2) {
08698       if (!strcmp("IP4", proto)) {
08699          af = AF_INET;
08700       } else if (!strcmp("IP6", proto)) {
08701          af = AF_INET6;
08702       } else {
08703          ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
08704          return FALSE;
08705       }
08706       if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
08707          ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c);
08708          return FALSE;
08709       }
08710       return TRUE;
08711    } else {
08712       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
08713       return FALSE;
08714    }
08715    return FALSE;
08716 }

static int process_sdp_o ( const char *  o,
struct sip_pvt *  p 
) [static]

Definition at line 8612 of file chan_sip.c.

References ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, FALSE, LOG_WARNING, strsep(), and TRUE.

Referenced by process_sdp().

08613 {
08614    char *o_copy;
08615    char *token;
08616    int64_t rua_version;
08617 
08618    /* Store the SDP version number of remote UA. This will allow us to
08619    distinguish between session modifications and session refreshes. If
08620    the remote UA does not send an incremented SDP version number in a
08621    subsequent RE-INVITE then that means its not changing media session.
08622    The RE-INVITE may have been sent to update connected party, remote
08623    target or to refresh the session (Session-Timers).  Asterisk must not
08624    change media session and increment its own version number in answer
08625    SDP in this case. */
08626 
08627    p->session_modify = TRUE;
08628 
08629    if (ast_strlen_zero(o)) {
08630       ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n");
08631       return FALSE;
08632    }
08633 
08634    o_copy = ast_strdupa(o);
08635    token = strsep(&o_copy, " ");  /* Skip username   */
08636    if (!o_copy) {
08637       ast_log(LOG_WARNING, "SDP syntax error in o= line username\n");
08638       return FALSE;
08639    }
08640    token = strsep(&o_copy, " ");  /* Skip session-id */
08641    if (!o_copy) {
08642       ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n");
08643       return FALSE;
08644    }
08645    token = strsep(&o_copy, " ");  /* Version         */
08646    if (!o_copy) {
08647       ast_log(LOG_WARNING, "SDP syntax error in o= line\n");
08648       return FALSE;
08649    }
08650    if (!sscanf(token, "%30" SCNd64, &rua_version)) {
08651       ast_log(LOG_WARNING, "SDP syntax error in o= line version\n");
08652       return FALSE;
08653    }
08654 
08655    /* we need to check the SDP version number the other end sent us;
08656     * our rules for deciding what to accept are a bit complex.
08657     *
08658     * 1) if 'ignoresdpversion' has been set for this dialog, then
08659     *    we will just accept whatever they sent and assume it is
08660     *    a modification of the session, even if it is not
08661     * 2) otherwise, if this is the first SDP we've seen from them
08662     *    we accept it
08663     * 3) otherwise, if the new SDP version number is higher than the
08664     *    old one, we accept it
08665     * 4) otherwise, if this SDP is in response to us requesting a switch
08666     *    to T.38, we accept the SDP, but also generate a warning message
08667     *    that this peer should have the 'ignoresdpversion' option set,
08668     *    because it is not following the SDP offer/answer RFC; if we did
08669     *    not request a switch to T.38, then we stop parsing the SDP, as it
08670     *    has not changed from the previous version
08671     */
08672 
08673    if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) ||
08674        (p->sessionversion_remote < 0) ||
08675        (p->sessionversion_remote < rua_version)) {
08676       p->sessionversion_remote = rua_version;
08677    } else {
08678       if (p->t38.state == T38_LOCAL_REINVITE) {
08679          p->sessionversion_remote = rua_version;
08680          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);
08681       } else {
08682          p->session_modify = FALSE;
08683          ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid);
08684          return FALSE;
08685       }
08686    }
08687 
08688    return TRUE;
08689 }

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

Resolve DNS srv name or host name in a sip_proxy structure

Definition at line 2838 of file chan_sip.c.

References ast_get_ip_or_srv(), ast_log(), ast_sockaddr_parse(), ast_sockaddr_set_port, bindaddr, FALSE, get_address_family_filter(), LOG_WARNING, sip_cfg, and TRUE.

Referenced by build_peer(), and reload_config().

02839 {
02840    /* if it's actually an IP address and not a name,
02841            there's no need for a managed lookup */
02842    if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) {
02843       /* Ok, not an IP address, then let's check if it's a domain or host */
02844       /* XXX Todo - if we have proxy port, don't do SRV */
02845       proxy->ip.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
02846       if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) {
02847             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
02848             return FALSE;
02849       }
02850 
02851    }
02852 
02853    ast_sockaddr_set_port(&proxy->ip, proxy->port);
02854 
02855    proxy->last_dnsupdate = time(NULL);
02856    return TRUE;
02857 }

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

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

01002 {
01003    struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data;
01004    struct event_state_compositor *esc = get_esc(esc_entry->event);
01005 
01006    ast_assert(esc != NULL);
01007 
01008    ao2_unlink(esc->compositor, esc_entry);
01009    ao2_ref(esc_entry, -1);
01010    return 0;
01011 }

static void pvt_set_needdestroy ( struct sip_pvt *  pvt,
const char *  reason 
) [inline, static]

Definition at line 2803 of file chan_sip.c.

References append_history.

Referenced by __sip_autodestruct(), handle_incoming(), 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().

02804 {
02805    if (pvt->final_destruction_scheduled) {
02806       return; /* This is already scheduled for final destruction, let the scheduler take care of it. */
02807    }
02808    append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason);
02809    pvt->needdestroy = 1;
02810 }

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

Definition at line 23711 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), and scheduler_process_request_queue().

Referenced by handle_request_do().

23712 {
23713    struct sip_request *newreq;
23714 
23715    if (!(newreq = ast_calloc(1, sizeof(*newreq)))) {
23716       return -1;
23717    }
23718 
23719    copy_request(newreq, req);
23720    AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next);
23721    if (p->request_queue_sched_id == -1) {
23722       if ((p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, dialog_ref(p, "Increment refcount to pass dialog pointer to sched callback"))) == -1) {
23723          dialog_unref(p, "Decrement refcount due to sched_add failure");
23724       }
23725    }
23726 
23727    return 0;
23728 }

static struct sip_peer * realtime_peer ( const char *  peername,
struct ast_sockaddr sin,
int  devstate_only 
) [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:
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 4374 of file chan_sip.c.

References ao2_t_link, ast_check_realtime(), ast_config_destroy(), ast_copy_flags, ast_copy_string(), ast_debug, ast_free, ast_load_realtime(), ast_load_realtime_multientry(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_sockaddr_cmp(), ast_sockaddr_isnull(), ast_sockaddr_resolve(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_test_flag, ast_variables_destroy(), bindaddr, build_peer(), expire_register(), get_address_family_filter(), get_insecure_variable_from_config(), get_name_from_variable(), ipaddr, LOG_WARNING, ast_variable::name, ast_variable::next, PARSE_PORT_FORBID, ref_peer(), SENTINEL, sip_cfg, TRUE, unref_peer(), ast_variable::value, and var.

04375 {
04376    struct sip_peer *peer;
04377    struct ast_variable *var = NULL;
04378    struct ast_variable *varregs = NULL;
04379    struct ast_variable *tmp;
04380    struct ast_config *peerlist = NULL;
04381    char ipaddr[INET_ADDRSTRLEN];
04382    char portstring[6]; /*up to 5 digits plus null terminator*/
04383    char *cat = NULL;
04384    int realtimeregs = ast_check_realtime("sipregs");
04385 
04386    /* First check on peer name */
04387    if (newpeername) {
04388       if (realtimeregs)
04389          varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04390 
04391       var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", SENTINEL);
04392       if (!var && addr) {
04393          var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_sockaddr_stringify_addr(addr), SENTINEL);
04394       }
04395       if (!var) {
04396          var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04397          /*!\note
04398           * If this one loaded something, then we need to ensure that the host
04399           * field matched.  The only reason why we can't have this as a criteria
04400           * is because we only have the IP address and the host field might be
04401           * set as a name (and the reverse PTR might not match).
04402           */
04403          if (var && addr) {
04404             for (tmp = var; tmp; tmp = tmp->next) {
04405                if (!strcasecmp(tmp->name, "host")) {
04406                   struct ast_sockaddr *addrs = NULL;
04407 
04408                   if (ast_sockaddr_resolve(&addrs,
04409                             tmp->value,
04410                             PARSE_PORT_FORBID,
04411                             get_address_family_filter(&bindaddr)) <= 0 ||
04412                       ast_sockaddr_cmp(&addrs[0], addr)) {
04413                      /* No match */
04414                      ast_variables_destroy(var);
04415                      var = NULL;
04416                   }
04417                   ast_free(addrs);
04418                   break;
04419                }
04420             }
04421          }
04422       }
04423    }
04424 
04425    if (!var && addr) {  /* Then check on IP address for dynamic peers */
04426       ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
04427       ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring));
04428       var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL);  /* First check for fixed IP hosts */
04429       if (var) {
04430          if (realtimeregs) {
04431             newpeername = get_name_from_variable(var, newpeername);
04432             varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04433          }
04434       } else {
04435          if (realtimeregs)
04436             varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL); /* Then check for registered hosts */
04437          else
04438             var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL); /* Then check for registered hosts */
04439          if (varregs) {
04440             newpeername = get_name_from_variable(varregs, newpeername);
04441             var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04442          }
04443       }
04444       if (!var) { /*We couldn't match on ipaddress and port, so we need to check if port is insecure*/
04445          peerlist = ast_load_realtime_multientry("sippeers", "host", ipaddr, SENTINEL);
04446          if (peerlist) {
04447             var = get_insecure_variable_from_config(peerlist);
04448             if(var) {
04449                if (realtimeregs) {
04450                   newpeername = get_name_from_variable(var, newpeername);
04451                   varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04452                }
04453             } else { /*var wasn't found in the list of "hosts", so try "ipaddr"*/
04454                peerlist = NULL;
04455                cat = NULL;
04456                peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, SENTINEL);
04457                if(peerlist) {
04458                   var = get_insecure_variable_from_config(peerlist);
04459                   if(var) {
04460                      if (realtimeregs) {
04461                         newpeername = get_name_from_variable(var, newpeername);
04462                         varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04463                      }
04464                   }
04465                }
04466             }
04467          } else {
04468             if (realtimeregs) {
04469                peerlist = ast_load_realtime_multientry("sipregs", "ipaddr", ipaddr, SENTINEL);
04470                if (peerlist) {
04471                   varregs = get_insecure_variable_from_config(peerlist);
04472                   if (varregs) {
04473                      newpeername = get_name_from_variable(varregs, newpeername);
04474                      var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04475                   }
04476                }
04477             } else {
04478                peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, SENTINEL);
04479                if (peerlist) {
04480                   var = get_insecure_variable_from_config(peerlist);
04481                   if (var) {
04482                      newpeername = get_name_from_variable(var, newpeername);
04483                      varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04484                   }
04485                }
04486             }
04487          }
04488       }
04489    }
04490 
04491    if (!var) {
04492       if (peerlist)
04493          ast_config_destroy(peerlist);
04494       return NULL;
04495    }
04496 
04497    for (tmp = var; tmp; tmp = tmp->next) {
04498       if (!newpeername && !strcasecmp(tmp->name, "name")) {
04499          newpeername = tmp->value;
04500       }
04501    }
04502    
04503    if (!newpeername) {  /* Did not find peer in realtime */
04504       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr);
04505       if(peerlist)
04506          ast_config_destroy(peerlist);
04507       else
04508          ast_variables_destroy(var);
04509       return NULL;
04510    }
04511 
04512 
04513    /* Peer found in realtime, now build it in memory */
04514    peer = build_peer(newpeername, var, varregs, TRUE, devstate_only);
04515    if (!peer) {
04516       if(peerlist)
04517          ast_config_destroy(peerlist);
04518       else {
04519          ast_variables_destroy(var);
04520          ast_variables_destroy(varregs);
04521       }
04522       return NULL;
04523    }
04524 
04525    ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
04526 
04527    if (ast_test_flag(&